[vim/vim] gtk3(wayland): mouse press inside window triggers VISUAL selection, even if dialog takes focus (Issue #20907)

dezza (Vim Github Repository) <[email protected]> Sat, 01 Aug 2026 02:57:30 -0700
Newsgroups gmane.editors.vim.devel
Message-ID <vim/vim/issues/[email protected]>
dezza created an issue (vim/vim#20907)

### Steps to reproduce

When pressing inside the main window, before FocusGained dialog this happens:

Button press/release `252`,`272` - handled in `process_motion_notify`.

Following does not reproduce the exact issue, its just a helper to keep a dialog when `focus_in` and `KE_FOCUSGAINED` (`FocusGained`, `autocmd-events`) event happen.
```sh
augroup Repro
autocmd!
autocmd FocusGained * call confirm('wow')
augroup END
```

(*debug print locations*)
```diff
diff --git a/src/gui_gtk.c b/src/gui_gtk.c
index 5dd25efc9..d6553aef0 100644
--- a/src/gui_gtk.c
+++ b/src/gui_gtk.c
@@ -1710,6 +1710,11 @@ gui_mch_dialog(int	type,	    // type of dialog
     DialogInfo  dialoginfo;
 
     ++gui.dialogs_active;
+    fprintf(stderr,
+	    "dialog open: active=%d pending=%d hold=%d in_focus=%d\n",
+	    gui.dialogs_active, gui.dialog_focus_pending,
+	    hold_gui_events, gui.in_focus);
+    fflush(stderr);
 
     dialog = create_message_dialog(type, title, message);
     dialoginfo.dialog = GTK_DIALOG(dialog);
@@ -1796,8 +1801,13 @@ gui_mch_dialog(int	type,	    // type of dialog
 	gtk_widget_destroy(dialog);
     }
 
+    fprintf(stderr,
+	    "dialog close: active=%d pending=%d hold=%d in_focus=%d\n",
+	    gui.dialogs_active, gui.dialog_focus_pending,
+	    hold_gui_events, gui.in_focus);
+    fflush(stderr);
     if (gui.dialogs_active > 0)
-    --gui.dialogs_active;
+	--gui.dialogs_active;
     return response > 0 ? response : 0;
 }
 
diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c
index f45494088..04ad2d815 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -1089,6 +1089,11 @@ focus_in_event(GtkWidget *widget,
 	       gpointer data UNUSED)
 {
 #ifdef FEAT_GUI_DIALOG
+    fprintf(stderr,
+	    "focus in: active=%d pending=%d hold=%d in_focus=%d\n",
+	    gui.dialogs_active, gui.dialog_focus_pending,
+	    hold_gui_events, gui.in_focus);
+    fflush(stderr);
     if (gui.dialog_focus_pending > 0)
     {
 	--gui.dialog_focus_pending;
@@ -1099,6 +1104,11 @@ focus_in_event(GtkWidget *widget,
     else
 #endif
 	gui_focus_change(TRUE);
+    fprintf(stderr,
+	    "focus in done: active=%d pending=%d hold=%d in_focus=%d\n",
+	    gui.dialogs_active, gui.dialog_focus_pending,
+	    hold_gui_events, gui.in_focus);
+    fflush(stderr);
 
     if (blink_state == BLINK_NONE)
 	gui_mch_start_blink();
@@ -1116,12 +1126,25 @@ focus_out_event(GtkWidget *widget UNUSED,
 		GdkEventFocus *event UNUSED,
 		gpointer data UNUSED)
 {
-#ifdef FEAT_GUI_DIALOG
+    fprintf(stderr,
+	    "focus out: active=%d pending=%d hold=%d in_focus=%d\n",
+	    gui.dialogs_active, gui.dialog_focus_pending,
+	    hold_gui_events, gui.in_focus);
+    fflush(stderr);
     if (gui.dialogs_active > 0)
 	++gui.dialog_focus_pending;
-#endif
+    fprintf(stderr,
+	    "focus out queued: active=%d pending=%d hold=%d in_focus=%d\n",
+	    gui.dialogs_active, gui.dialog_focus_pending,
+	    hold_gui_events, gui.in_focus);
+    fflush(stderr);
 
     gui_focus_change(FALSE);
+    fprintf(stderr,
+	    "focus out done: active=%d pending=%d hold=%d in_focus=%d\n",
+	    gui.dialogs_active, gui.dialog_focus_pending,
+	    hold_gui_events, gui.in_focus);
+    fflush(stderr);
 
     if (blink_state != BLINK_NONE)
 	gui_mch_stop_blink(TRUE);
@@ -1857,6 +1880,14 @@ process_motion_notify(int x, int y, GdkModifierType state)
     // translate modifier coding between the main engine and GTK
     vim_modifiers = modifiers_gdk2mouse(state);
 
+    // no event
+    fprintf(stderr,
+	    "button press: active=%d pending=%d in_focus=%d "
+	    "button=%u state=%u drag=%u\n",
+	    gui.dialogs_active, gui.dialog_focus_pending, gui.in_focus,
+	    button, state, dragging_button_state);
+    fflush(stderr);
+
     // inform the editor engine about the occurrence of this event
     gui_send_mouse_event(button, x, y, FALSE, vim_modifiers);
 
@@ -2084,7 +2115,12 @@ button_press_event(GtkWidget *widget,
 #endif
 
     vim_modifiers = modifiers_gdk2mouse(event->state);
-
+    fprintf(stderr,
+	    "button press: active=%d pending=%d in_focus=%d "
+	    "button=%u state=%u drag=%u\n",
+	    gui.dialogs_active, gui.dialog_focus_pending, gui.in_focus,
+	    event->button, event->state, dragging_button_state);
+    fflush(stderr);
     gui_send_mouse_event(button, x, y, repeated_click, vim_modifiers);
 
     return TRUE;
@@ -2228,6 +2264,12 @@ button_release_event(GtkWidget *widget UNUSED,
 
     vim_modifiers = modifiers_gdk2mouse(event->state);
 
+    fprintf(stderr,
+	    "button press: active=%d pending=%d in_focus=%d "
+	    "button=%u state=%u drag=%u\n",
+	    gui.dialogs_active, gui.dialog_focus_pending, gui.in_focus,
+	    event->button, event->state, dragging_button_state);
+    fflush(stderr);
     gui_send_mouse_event(MOUSE_RELEASE, x, y, FALSE, vim_modifiers);
 
     switch (event->button)
```

Initial press into unfocused window recording before `gui_send_mouse_event` without triggering additional events on both backends:



### Expected behaviour

When unfocused an initial press inside main window on re-focusing should not trigger a 'visual'

### Version of Vim

9.2.881 +PR 20894

### Environment

Operating System: openSUSE Tumbleweed
Terminal: ghostty
Value of $TERM: xterm-ghostty
Shell: bash

### Logs and stack traces

```shell
# WAYLAND

focus in: active=0 pending=0 hold=0 in_focus=0 
focus in done: active=0 pending=0 hold=0 in_focus=1

button press: active=0 pending=0 in_focus=1 button=1 state=16 drag=256

dialog open: active=1 pending=0 hold=0

in_focus=1 focus out: active=1 pending=0 hold=0 in_focus=1 focus out queued: active=1 pending=1 hold=0 in_focus=1 focus out done: active=1 pending=1 hold=0 in_focus=0


# X11

focus in: active=0 pending=0 hold=0 in_focus=0
focus in done: active=0 pending=0 hold=0 in_focus=1

dialog open: active=1 pending=0 hold=0 in_focus=1 

focus out: active=1 pending=0 hold=0 in_focus=1 
focus out queued: active=1 pending=1 hold=0 in_focus=1
focus out done: active=1 pending=1 hold=0 in_focus=0
```

-- 
Reply to this email directly or view it on GitHub:
https://github.com/vim/vim/issues/20907
You are receiving this because you are subscribed to this thread.

Message ID: <vim/vim/issues/[email protected]>

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups "vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/vim_dev/vim/vim/issues/20907%40github.com.