]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0948: GTK4: mouse move starts Visual selection after a dialog v9.2.0948
authorHirohito Higashi <h.east.727@gmail.com>
Wed, 12 Aug 2026 19:11:17 +0000 (19:11 +0000)
committerChristian Brabandt <cb@256bit.org>
Wed, 12 Aug 2026 19:11:17 +0000 (19:11 +0000)
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) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/gui_gtk4.c
src/version.c

index d128a6b9999201427d3b49ba7622d20d6c310f83..5b31e587bae73b7f4f37b2a1dd8ea97c0985ecc1 100644 (file)
@@ -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);
index 3b27eab8b99842858a02b538647aeeb190efef05..e1d22170adebb794446152d8a9d8e6596ffc2f7c 100644 (file)
@@ -763,6 +763,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    948,
 /**/
     947,
 /**/