fix DnD: drag icon follows cursor, clean up listeners
Update drag_icon_tree position in handle_pointer_motion so the icon follows the cursor during drag. Use wlr_scene_drag_icon_create for proper lifecycle. Remove listeners in handle_drag_destroy. Always forward button releases so drags end correctly.
This commit is contained in:
parent
ce696a72a0
commit
976bcce34c
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
/* Currently active external wlr_drag (NULL if none). */
|
||||
struct wlr_drag *wl_current_drag = NULL;
|
||||
static struct wlr_scene_tree *drag_icon_tree = NULL;
|
||||
struct wlr_scene_tree *drag_icon_tree = NULL;
|
||||
|
||||
void handle_drag_motion(struct wl_listener *listener, void *data);
|
||||
void handle_drag_drop(struct wl_listener *listener, void *data);
|
||||
|
|
@ -38,12 +38,11 @@ handle_seat_request_start_drag(struct wl_listener *listener, void *data)
|
|||
wl_signal_add(&ev->drag->events.drop, &wl_drag_drop_listener);
|
||||
wl_signal_add(&ev->drag->events.destroy, &wl_drag_destroy_listener);
|
||||
|
||||
/* Render the drag icon surface if provided */
|
||||
if (ev->drag->icon && ev->drag->icon->surface && wl_state.scene) {
|
||||
/* Render the drag icon using wlroots' built-in scene helper */
|
||||
if (ev->drag->icon && wl_state.scene) {
|
||||
struct wlr_scene_tree *parent = wl_state.level_trees[WL_LAYER_OVERLAY]
|
||||
? wl_state.level_trees[WL_LAYER_OVERLAY] : &wl_state.scene->tree;
|
||||
drag_icon_tree = wlr_scene_subsurface_tree_create(parent,
|
||||
ev->drag->icon->surface);
|
||||
drag_icon_tree = wlr_scene_drag_icon_create(parent, ev->drag->icon);
|
||||
if (drag_icon_tree)
|
||||
wlr_scene_node_set_position(&drag_icon_tree->node,
|
||||
(int)wl_state.pointer_x, (int)wl_state.pointer_y);
|
||||
|
|
@ -158,9 +157,12 @@ handle_drag_destroy(struct wl_listener *listener, void *data)
|
|||
(void)listener;
|
||||
(void)data;
|
||||
wwarning("wl_backend: external DND finished");
|
||||
if (drag_icon_tree) {
|
||||
wlr_scene_node_destroy(&drag_icon_tree->node);
|
||||
wl_list_remove(&wl_drag_motion_listener.link);
|
||||
wl_list_remove(&wl_drag_drop_listener.link);
|
||||
wl_list_remove(&wl_drag_destroy_listener.link);
|
||||
wl_list_init(&wl_drag_motion_listener.link);
|
||||
wl_list_init(&wl_drag_drop_listener.link);
|
||||
wl_list_init(&wl_drag_destroy_listener.link);
|
||||
drag_icon_tree = NULL;
|
||||
}
|
||||
wl_current_drag = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -327,7 +327,9 @@ handle_pointer_button(struct wl_listener *listener, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
if (forward_to_client && wl_state.seat->pointer_state.focused_surface) {
|
||||
if (forward_to_client &&
|
||||
(wl_state.seat->pointer_state.focused_surface ||
|
||||
ev->state == WLR_BUTTON_RELEASED)) {
|
||||
wlr_seat_pointer_notify_button(wl_state.seat, ev->time_msec,
|
||||
ev->button, ev->state);
|
||||
wlr_seat_pointer_notify_frame(wl_state.seat);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_pointer.h>
|
||||
#include <wlr/types/wlr_seat.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "../../screen.h"
|
||||
#include "wl_types.h"
|
||||
|
|
@ -144,6 +145,12 @@ handle_pointer_motion(struct wl_listener *listener, void *data)
|
|||
}
|
||||
if (wl_state.grab_type) { wl_grab_apply_motion(); return; }
|
||||
wl_update_pointer_focus(ev->time_msec);
|
||||
|
||||
/* Update drag icon position if a drag is active */
|
||||
extern struct wlr_scene_tree *drag_icon_tree;
|
||||
if (drag_icon_tree)
|
||||
wlr_scene_node_set_position(&drag_icon_tree->node,
|
||||
wl_state.pointer_x, wl_state.pointer_y);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
38
wm.log
38
wm.log
|
|
@ -1,25 +1,17 @@
|
|||
[Thread debugging using libthread_db enabled]
|
||||
Using host libthread_db library "/usr/lib64/libthread_db.so.1".
|
||||
[New Thread 0x7fffe25ff6c0 (LWP 1941648)]
|
||||
[New Thread 0x7fffe1dfe6c0 (LWP 1941649)]
|
||||
[New Thread 0x7fffe11ff6c0 (LWP 1941650)]
|
||||
[New Thread 0x7fffe09fe6c0 (LWP 1941651)]
|
||||
[Thread 0x7fffe09fe6c0 (LWP 1941651) exited]
|
||||
[Thread 0x7fffe11ff6c0 (LWP 1941650) exited]
|
||||
[New Thread 0x7fffe11ff6c0 (LWP 1941652)]
|
||||
[New Thread 0x7fffe09fe6c0 (LWP 1941653)]
|
||||
[New Thread 0x7fffd3bff6c0 (LWP 1941654)]
|
||||
[New Thread 0x7fffd33fe6c0 (LWP 1941655)]
|
||||
[New Thread 0x7fffd29fd6c0 (LWP 1941656)]
|
||||
[Detaching after vfork from child process 1941657]
|
||||
[Detaching after fork from child process 1941658]
|
||||
[Thread 0x7fffd33fe6c0 (LWP 1941655) exited]
|
||||
[Thread 0x7fffd3bff6c0 (LWP 1941654) exited]
|
||||
[Thread 0x7fffe09fe6c0 (LWP 1941653) exited]
|
||||
[Thread 0x7fffe11ff6c0 (LWP 1941652) exited]
|
||||
[Thread 0x7fffe1dfe6c0 (LWP 1941649) exited]
|
||||
[Thread 0x7fffe25ff6c0 (LWP 1941648) exited]
|
||||
[Thread 0x7ffff67c92c0 (LWP 1941645) exited]
|
||||
[Thread 0x7fffd29fd6c0 (LWP 1941656) exited]
|
||||
[New process 1941645]
|
||||
[Inferior 1 (process 1941645) exited normally]
|
||||
[New Thread 0x7fffe21ff6c0 (LWP 193764)]
|
||||
[New Thread 0x7fffe19fe6c0 (LWP 193765)]
|
||||
[New Thread 0x7fffe0dff6c0 (LWP 193766)]
|
||||
[New Thread 0x7fffdbfff6c0 (LWP 193767)]
|
||||
[Thread 0x7fffdbfff6c0 (LWP 193767) exited]
|
||||
[Thread 0x7fffe0dff6c0 (LWP 193766) exited]
|
||||
[New Thread 0x7fffe0dff6c0 (LWP 193768)]
|
||||
[New Thread 0x7fffdbfff6c0 (LWP 193769)]
|
||||
[New Thread 0x7fffdb7fe6c0 (LWP 193770)]
|
||||
[New Thread 0x7fffdaffd6c0 (LWP 193771)]
|
||||
[New Thread 0x7fffda5fc6c0 (LWP 193772)]
|
||||
[Detaching after fork from child process 193773]
|
||||
[Detaching after vfork from child process 193774]
|
||||
[Detaching after fork from child process 193775]
|
||||
[Detaching after fork from child process 193783]
|
||||
|
|
|
|||
Loading…
Reference in New Issue