]> git.mdlowis.com Git - proto/labwc.git/commitdiff
cursor: prevent Drag mousebinds from running without button press
authortokyo4j <hrak1529@gmail.com>
Mon, 23 Sep 2024 19:49:08 +0000 (04:49 +0900)
committerJohan Malm <johanmalm@users.noreply.github.com>
Tue, 1 Oct 2024 20:26:19 +0000 (21:26 +0100)
For `Drag` mousebinds, `pressed_in_context` is set by
`cursor_process_button_press()` and cleared by `cursor_process_motion()`
which runs actions bound to them. However, when `cursor_process_motion()`
is called while interactive move/resize, it doesn't clear
`pressed_in_context` due to the early-return and the `Drag` mousebinds are
unexpectedly executed on another call to `cursor_process_motion()` after
the interactive move/resize is finished by button release, even when the
button is not pressed.

So this commit fixes it by always clearing `pressed_in_context` on button
releases.

include/input/cursor.h
src/input/cursor.c
src/input/tablet.c

index 8087c49a0d55db3f3b54f8d173a49768b396dafd..4e62183d7c353e17f0dcffa21538212c1cb62e2c 100644 (file)
@@ -142,7 +142,7 @@ bool cursor_process_button_release(struct seat *seat, uint32_t button, uint32_t
  * Finishes cursor button release. The return value indicates if an interactive
  * move/resize had been finished. Should be called after notifying a client.
  */
-bool cursor_finish_button_release(struct seat *seat);
+bool cursor_finish_button_release(struct seat *seat, uint32_t button);
 
 void cursor_init(struct seat *seat);
 void cursor_reload(struct seat *seat);
index 68636f1aa6518ce2db03c47d1f2fcd0f4f68c158..6777faeaab9325f312f80860558443b56aa1e490 100644 (file)
@@ -903,15 +903,7 @@ handle_release_mousebinding(struct server *server,
                        actions_run(ctx->view, server, &mousebind->actions, ctx);
                }
        }
-       /*
-        * Clear "pressed" status for all bindings of this mouse button,
-        * regardless of whether handled or not
-        */
-       wl_list_for_each(mousebind, &rc.mousebinds, link) {
-               if (mousebind->button == button) {
-                       mousebind->pressed_in_context = false;
-               }
-       }
+
        return consumed_by_frame_context;
 }
 
@@ -1137,10 +1129,18 @@ cursor_process_button_release(struct seat *seat, uint32_t button,
 }
 
 bool
-cursor_finish_button_release(struct seat *seat)
+cursor_finish_button_release(struct seat *seat, uint32_t button)
 {
        struct server *server = seat->server;
 
+       /* Clear "pressed" status for all bindings of this mouse button */
+       struct mousebind *mousebind;
+       wl_list_for_each(mousebind, &rc.mousebinds, link) {
+               if (mousebind->button == button) {
+                       mousebind->pressed_in_context = false;
+               }
+       }
+
        if (server->input_mode == LAB_INPUT_STATE_MOVE
                        || server->input_mode == LAB_INPUT_STATE_RESIZE) {
                if (resize_outlines_enabled(server->grabbed_view)) {
@@ -1182,7 +1182,7 @@ cursor_button(struct wl_listener *listener, void *data)
                        wlr_seat_pointer_notify_button(seat->seat, event->time_msec,
                                event->button, event->state);
                }
-               cursor_finish_button_release(seat);
+               cursor_finish_button_release(seat, event->button);
                break;
        }
 }
@@ -1245,7 +1245,7 @@ cursor_emulate_button(struct seat *seat, uint32_t button,
                if (notify) {
                        wlr_seat_pointer_notify_button(seat->seat, time_msec, button, state);
                }
-               cursor_finish_button_release(seat);
+               cursor_finish_button_release(seat, button);
                break;
        }
 }
index 617af8fd68e2b545fe5c0b63cdc631f4b7e152fb..9a72e6e5df7a278fcc58aeb654ff93449d790830 100644 (file)
@@ -516,7 +516,7 @@ handle_tablet_tool_tip(struct wl_listener *listener, void *data)
                                wlr_tablet_v2_tablet_tool_notify_up(tool->tool_v2);
                        }
 
-                       bool exit_interactive = cursor_finish_button_release(tool->seat);
+                       bool exit_interactive = cursor_finish_button_release(tool->seat, BTN_LEFT);
                        if (exit_interactive && surface && tool->tool_v2->focused_surface) {
                                /*
                                 * Re-enter the surface after a resize/move to ensure