]> git.mdlowis.com Git - proto/labwc.git/commitdiff
cursor.c: Keep sending adjusted motion events while button is pressed
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Sat, 26 Feb 2022 00:21:39 +0000 (01:21 +0100)
committerJohan Malm <jgm323@gmail.com>
Mon, 21 Mar 2022 17:56:48 +0000 (17:56 +0000)
This allows to keep dragging a scrollbar or selecting text even when
moving outside of the window. Fixes #241

include/labwc.h
src/cursor.c
src/xdg.c
src/xwayland.c

index 43ce6d2d8cdb8b8980acd21b866869080b7e1dfb..07909228618f2670dfaaa93e69c79660b64e61a9 100644 (file)
@@ -82,6 +82,18 @@ struct seat {
        /* if set, views cannot receive focus */
        struct wlr_layer_surface_v1 *focused_layer;
 
+       /**
+        * active_view will usually be NULL and is only set on button press
+        * while the mouse is over a view surface and reset to NULL on button
+        * release.
+        * It is used to send cursor motion events to a surface even though
+        * the cursor has left the surface in the meantime.
+        *
+        * This allows to keep dragging a scrollbar or selecting text even
+        * when moving outside of the window.
+        */
+       struct view *active_view;
+
        struct wl_client *active_client_while_inhibited;
        struct wl_list inputs;
        struct wl_listener new_input;
index a3590eabe8802157880d2a93bfa3ea9aa4f22649..29e8eb5f0b244cf2ef0a21024383a3bd88929bc1 100644 (file)
@@ -195,6 +195,15 @@ process_cursor_motion(struct server *server, uint32_t time)
        } else if (server->input_mode == LAB_INPUT_STATE_RESIZE) {
                process_cursor_resize(server, time);
                return;
+       } else if (server->seat.active_view && !server->seat.drag_icon) {
+               /* Button has been pressed while over a view surface */
+               struct view *view = server->seat.active_view;
+               double sx = server->seat.cursor->x - view->x;
+               double sy = server->seat.cursor->y - view->y;
+               sx = sx < 0 ? 0 : (sx > view->w ? view->w : sx);
+               sy = sy < 0 ? 0 : (sy > view->h ? view->h : sy);
+               wlr_seat_pointer_notify_motion(server->seat.seat, time, sx, sy);
+               return;
        }
 
        /* Otherwise, find view under the pointer and send the event along */
@@ -317,6 +326,7 @@ start_drag(struct wl_listener *listener, void *data)
 {
        struct seat *seat = wl_container_of(listener, seat, start_drag);
        struct wlr_drag *wlr_drag = data;
+       seat->active_view = NULL;
        seat->drag_icon = wlr_drag->icon;
        wl_signal_add(&seat->drag_icon->events.destroy, &seat->destroy_drag);
 }
@@ -647,6 +657,8 @@ cursor_button(struct wl_listener *listener, void *data)
 
        /* handle _release_ */
        if (event->state == WLR_BUTTON_RELEASED) {
+               server->seat.active_view = NULL;
+
                if (server->input_mode == LAB_INPUT_STATE_MENU) {
                        if (close_menu) {
                                if (server->menu_current) {
@@ -674,6 +686,10 @@ cursor_button(struct wl_listener *listener, void *data)
        }
 
        /* Handle _press */
+       if (view_area == LAB_SSD_CLIENT) {
+               server->seat.active_view = view;
+       }
+
        if (server->input_mode == LAB_INPUT_STATE_MENU) {
                if (view_area != LAB_SSD_MENU) {
                        /* We close the menu on release so we don't leak a stray release */
index dc534499f83dd852128e386d64e4e482751db8be..2e01a3c95e88f18bf677df916a87126949690a0b 100644 (file)
--- a/src/xdg.c
+++ b/src/xdg.c
@@ -85,6 +85,9 @@ handle_destroy(struct wl_listener *listener, void *data)
                wlr_foreign_toplevel_handle_v1_destroy(view->toplevel_handle);
        }
        interactive_end(view);
+       if (view->server->seat.active_view == view) {
+               view->server->seat.active_view = NULL;
+       }
        wl_list_remove(&view->link);
        wl_list_remove(&view->destroy.link);
        if (view->scene_tree) {
index a3da7b903112314da7b44d15648e9b38c293fa6a..88f8c5f0095492147357f32a9ddfa9a39f3b599b 100644 (file)
@@ -99,6 +99,9 @@ handle_destroy(struct wl_listener *listener, void *data)
                wlr_foreign_toplevel_handle_v1_destroy(view->toplevel_handle);
        }
        interactive_end(view);
+       if (view->server->seat.active_view == view) {
+               view->server->seat.active_view = NULL;
+       }
        view->xwayland_surface = NULL;
        wl_list_remove(&view->link);
        wl_list_remove(&view->map.link);