]> git.mdlowis.com Git - proto/labwc.git/commitdiff
src/cursor.c: Fix branch condition for out-of-view selecting/dragging
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Tue, 24 May 2022 11:02:51 +0000 (13:02 +0200)
committerJohan Malm <johanmalm@users.noreply.github.com>
Tue, 24 May 2022 16:35:32 +0000 (17:35 +0100)
Instead of using the stored view for comparison use the actual surface.

Before this patch, there were situations where the branch intended for
out-of-window text selection / scrollbar dragging was used even though
the cursor never left the surface.

Partly fixes #340

include/labwc.h
src/cursor.c
src/view.c

index 147358783b19319010fad7ddb454793650bb182b..079585ed71ab1f541d2a169b6a4f1817af5eb428 100644 (file)
@@ -91,16 +91,19 @@ struct seat {
        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.
+        * pressed view/surface 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 {
+               struct view *view;
+               struct wlr_surface *surface;
+       } pressed;
 
        struct wl_client *active_client_while_inhibited;
        struct wl_list inputs;
index 21a0e2b71bed2f6e8ceb68f836317437f09e2e7e..81d527ad6ef3b9c43677cedf763b2e8f3327d3e4 100644 (file)
@@ -293,22 +293,27 @@ process_cursor_motion(struct server *server, uint32_t time)
                hover->node = NULL;
        }
 
-       if (server->seat.active_view && !server->seat.drag_icon) {
+       if (server->seat.pressed.surface &&
+                       server->seat.pressed.surface != surface &&
+                       !server->seat.drag_icon) {
                /*
                 * Button has been pressed while over a view surface
                 * and is still held down. Just send the adjusted motion
                 * events to the focused surface so we can keep scrolling
                 * or selecting text even if the cursor moves outside of
                 * the surface.
+                *
+                * TODO: This seems to miss calculations for invisible CSD borders.
+                *       Tracked at https://github.com/labwc/labwc/issues/340
                 */
-               view = server->seat.active_view;
-               double sx = server->seat.cursor->x - view->x;
-               double sy = server->seat.cursor->y - view->y;
+               view = server->seat.pressed.view;
+               sx = server->seat.cursor->x - view->x;
+               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);
-       } else if (surface &&
-           !input_inhibit_blocks_surface(&server->seat, surface->resource)) {
+       } else if (surface && !input_inhibit_blocks_surface(
+                       &server->seat, surface->resource)) {
                bool focus_changed =
                        wlr_seat->pointer_state.focused_surface != surface;
                /*
@@ -359,7 +364,8 @@ 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->pressed.view = NULL;
+       seat->pressed.surface = NULL;
        seat->drag_icon = wlr_drag->icon;
        if (!seat->drag_icon) {
                wlr_log(WLR_ERROR,
@@ -706,7 +712,8 @@ cursor_button(struct wl_listener *listener, void *data)
 
        /* handle _release_ */
        if (event->state == WLR_BUTTON_RELEASED) {
-               server->seat.active_view = NULL;
+               server->seat.pressed.view = NULL;
+               server->seat.pressed.surface = NULL;
 
                if (server->input_mode == LAB_INPUT_STATE_MENU) {
                        if (close_menu) {
@@ -742,7 +749,8 @@ cursor_button(struct wl_listener *listener, void *data)
 
        /* Handle _press */
        if (view_area == LAB_SSD_CLIENT) {
-               server->seat.active_view = view;
+               server->seat.pressed.view = view;
+               server->seat.pressed.surface = surface;
        }
 
        if (server->input_mode == LAB_INPUT_STATE_MENU) {
index cb8b0b02441169ad4486ba23bf9e2f2b8084dfa4..443b6e643815035e1678a396ce2f9cbe3214f3b8 100644 (file)
@@ -686,8 +686,9 @@ view_destroy(struct view *view)
        }
        interactive_end(view);
 
-       if (view->server->seat.active_view == view) {
-               view->server->seat.active_view = NULL;
+       if (view->server->seat.pressed.view == view) {
+               view->server->seat.pressed.view = NULL;
+               view->server->seat.pressed.surface = NULL;
        }
 
        if (view->server->cycle_view == view) {