]> git.mdlowis.com Git - proto/labwc.git/commitdiff
Restore Drag mouse bindings and proper double click
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Sun, 27 Feb 2022 19:36:49 +0000 (20:36 +0100)
committerJohan Malm <jgm323@gmail.com>
Mon, 21 Mar 2022 18:08:04 +0000 (18:08 +0000)
Fixes #258 and #259

Reported-by: @ahmadraniri1994
Reported-by: @01micko
Suggested-by: bi4k8 <bi4k8@github>
include/labwc.h
src/cursor.c

index 10a8e58aaa216c9822be6ede3a4104d554ebbcec..97be5dfcacb9440097f390708c0d46cd2fb3bd58 100644 (file)
@@ -473,8 +473,9 @@ struct view *desktop_view_at_cursor(struct server *server);
  * cursor_rebase - set cursor icon for and send motion-event to surface below it
  * @seat - current seat
  * @time_msec - time now
+ * @force - disable check for skipping already focused surface
  */
-void cursor_rebase(struct seat *seat, uint32_t time_msec);
+void cursor_rebase(struct seat *seat, uint32_t time_msec, bool force);
 
 /**
  * cursor_set - set cursor icon
index 47d4b58e7a8f6a72e82975d113aca6cb93216109..b6aaa577760c9ef1c6d1a553e075fc24710bf556 100644 (file)
@@ -24,7 +24,7 @@ is_surface(enum ssd_part_type view_area)
 }
 
 void
-cursor_rebase(struct seat *seat, uint32_t time_msec)
+cursor_rebase(struct seat *seat, uint32_t time_msec, bool force)
 {
        double sx, sy;
        struct wlr_scene_node *node;
@@ -38,6 +38,20 @@ cursor_rebase(struct seat *seat, uint32_t time_msec)
        }
 
        if (surface) {
+               if (!force && surface == seat->seat->pointer_state.focused_surface) {
+                       /*
+                        * Usually we prevent re-entering an already focued surface
+                        * because it sends useless leave and enter events.
+                        *
+                        * They may also seriously confuse clients if sent between
+                        * connected events like a double click (#258) or fast scroll
+                        * events caused by a touchpad (#225).
+                        *
+                        * If we just want to update the cursor image though
+                        * the @force argument may be used to allow re-entering.
+                        */
+                       return;
+               }
                wlr_seat_pointer_notify_clear_focus(seat->seat);
                wlr_seat_pointer_notify_enter(seat->seat, surface, sx, sy);
                wlr_seat_pointer_notify_motion(seat->seat, time_msec, sx, sy);
@@ -195,15 +209,6 @@ 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 */
@@ -292,7 +297,21 @@ process_cursor_motion(struct server *server, uint32_t time)
                hover->node = NULL;
        }
 
-       if (surface &&
+       if (server->seat.active_view && !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.
+                */
+               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);
+       } else if (surface &&
            !input_inhibit_blocks_surface(&server->seat, surface->resource)) {
                bool focus_changed =
                        wlr_seat->pointer_state.focused_surface != surface;
@@ -316,6 +335,9 @@ process_cursor_motion(struct server *server, uint32_t time)
                /*
                 * Clear pointer focus so future button events and such are not
                 * sent to the last client to have the cursor over it.
+                *
+                * Except if we started pressing a button on the last client and
+                * are not currently in drag and drop mode.
                 */
                wlr_seat_pointer_clear_focus(wlr_seat);
        }
@@ -332,7 +354,8 @@ cursor_update_focus(struct server *server)
 {
        struct timespec now;
        clock_gettime(CLOCK_MONOTONIC, &now);
-       cursor_rebase(&server->seat, msec(&now));
+       /* Focus surface under cursor if it isn't already focused */
+       cursor_rebase(&server->seat, msec(&now), false);
 }
 
 void
@@ -693,7 +716,9 @@ cursor_button(struct wl_listener *listener, void *data)
                                server->input_mode = LAB_INPUT_STATE_PASSTHROUGH;
                                server->grabbed_view = NULL;
                        }
-                       cursor_rebase(&server->seat, event->time_msec);
+
+                       /* Focus surface under cursor and force updating the cursor icon */
+                       cursor_rebase(&server->seat, event->time_msec, true);
                        return;
                }
                goto mousebindings;