From: Hirohito Higashi Date: Wed, 12 Aug 2026 19:11:17 +0000 (+0000) Subject: patch 9.2.0948: GTK4: mouse move starts Visual selection after a dialog X-Git-Tag: v9.2.0948^0 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9a5aa22e769f57433698d4e3ea044a85cd737e0c;p=thirdparty%2Fvim.git patch 9.2.0948: GTK4: mouse move starts Visual selection after a dialog Problem: In GTK4, when a dialog pops up while a mouse button is pressed, moving the mouse afterwards starts a Visual selection without any button being held down. Solution: Forget about the pressed mouse button when a mouse move reports that no button is down, since the button release event may have gone to another widget (Hirohito Higashi). related: #20907 related: #21014 closes: #21022 Co-Authored-By: Claude Opus 5 (1M context) Signed-off-by: Hirohito Higashi Signed-off-by: Christian Brabandt --- diff --git a/src/gui_gtk4.c b/src/gui_gtk4.c index d128a6b999..5b31e587ba 100644 --- a/src/gui_gtk4.c +++ b/src/gui_gtk4.c @@ -1896,9 +1896,11 @@ modifiers_gdk2mouse(guint state) return modifiers; } +// GdkModifierType has no mask covering the mouse buttons only. +#define ANY_BUTTON_MASK (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK \ + | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK | GDK_BUTTON5_MASK) + // Track which mouse button is currently pressed for drag detection. -// GtkEventControllerMotion's modifier state may not include button masks -// on all backends (e.g. Wayland), so we track it ourselves. // -1 means no button is pressed (MOUSE_LEFT is 0x00, so can't use 0). static int mouse_pressed_button = -1; @@ -2019,15 +2021,28 @@ mouse_repeat_timer_cb(gpointer data UNUSED) motion_notify_event(GtkEventControllerMotion *controller UNUSED, double x, double y, gpointer data UNUSED) { + GdkEvent *event = gtk_event_controller_get_current_event( + GTK_EVENT_CONTROLLER(controller)); + + // The button release event may have gone to another widget, e.g. a modal + // dialog. Forget about the pressed button when no button is down anymore, + // otherwise moving the mouse would be taken for a drag. + if (mouse_pressed_button >= 0 && event != NULL + && !(gdk_event_get_modifier_state(event) & ANY_BUTTON_MASK)) + { + if (motion_repeat_timer != 0) + { + timeout_remove(motion_repeat_timer); + motion_repeat_timer = 0; + } + mouse_pressed_button = -1; + } + if (mouse_pressed_button >= 0) { GdkModifierType state; - GdkEvent *event; int w, h; - event = gtk_event_controller_get_current_event( - GTK_EVENT_CONTROLLER(controller)); - if (event != NULL) { cur_state = state = gdk_event_get_modifier_state(event); diff --git a/src/version.c b/src/version.c index 3b27eab8b9..e1d22170ad 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 948, /**/ 947, /**/