Commit: patch 9.2.0948: GTK4: mouse move starts Visual selection after a dialog

1 view
Skip to first unread message

Christian Brabandt

unread,
Aug 12, 2026, 3:15:21 PM (23 hours ago) Aug 12
to vim...@googlegroups.com
patch 9.2.0948: GTK4: mouse move starts Visual selection after a dialog

Commit: https://github.com/vim/vim/commit/9a5aa22e769f57433698d4e3ea044a85cd737e0c
Author: Hirohito Higashi <h.eas...@gmail.com>
Date: Wed Aug 12 19:11:17 2026 +0000

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) <nor...@anthropic.com>
Signed-off-by: Hirohito Higashi <h.eas...@gmail.com>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/gui_gtk4.c b/src/gui_gtk4.c
index d128a6b99..5b31e587b 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 3b27eab8b..e1d22170a 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,
/**/
Reply all
Reply to author
Forward
0 new messages