[vim/vim] GTK4 gui cursor still is an outline after closing menu (Issue #20274)

2 views
Skip to first unread message

Foxe Chen

unread,
May 21, 2026, 12:20:49 AM (4 days ago) May 21
to vim/vim, Subscribed
64-bitman created an issue (vim/vim#20274)

Steps to reproduce

  1. Run this set guicursor=n-v-c:block-Cursor/lCursor,ve:ver35-Cursor,o:hor50-Cursor,i-ci:ver25-Cursor/lCursor,r-cr:hor20-Cursor/lCursor,sm:block-Cursor-blinkwait175-blinkoff150-blinkon175,a:blinkon0
  2. Click on one of the menu buttons on the toolbar
  3. Click again to hide the menu, without going into the drawing area box
  4. Cursor stays as an outline, only going back to a filled block when drawing area is hovered over.

https://github.com/user-attachments/assets/c5f70516-34cc-4ba0-87c8-a8dc4d892038

Expected behaviour

Cursor should revert to being a filled block when menu is closed

Version of Vim

9.2.506

Environment

Operating system: Arch Linux, Wayland

Logs and stack traces


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20274@github.com>

mattn

unread,
May 21, 2026, 2:04:00 AM (4 days ago) May 21
to vim/vim, Subscribed
mattn left a comment (vim/vim#20274)

Patch suggested by Claude Code; I haven't verified it myself, so I'd appreciate testing.

diff --git a/src/gui_gtk4.c b/src/gui_gtk4.c
diff --git a/src/gui_gtk4.c b/src/gui_gtk4.c
index 083ac9f400..18204de62b 100644
--- a/src/gui_gtk4.c
+++ b/src/gui_gtk4.c
@@ -282,6 +282,7 @@ static void leave_notify_event(GtkEventControllerMotion *controller, gpointer da
 static gboolean scroll_event(GtkEventControllerScroll *controller, double dx, double dy, gpointer data);
 static void focus_in_event(GtkEventControllerFocus *controller, gpointer data);
 static void focus_out_event(GtkEventControllerFocus *controller, gpointer data);
+static void window_active_changed(GObject *obj, GParamSpec *pspec, gpointer data);
 #ifdef FEAT_DND
 static gboolean drop_cb(GtkDropTarget *target, const GValue *value, double x, double y, gpointer data);
 #endif
@@ -455,6 +456,8 @@ gui_mch_init(void)
 
     g_signal_connect(G_OBJECT(gui.mainwin), "close-request",
 		     G_CALLBACK(delete_event_cb), NULL);
+    g_signal_connect(G_OBJECT(gui.mainwin), "notify::is-active",
+		     G_CALLBACK(window_active_changed), NULL);
 
     // A vertical box holds the menubar, toolbar and main text window.
     vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
@@ -1827,7 +1830,12 @@ scroll_event(GtkEventControllerScroll *controller UNUSED,
 focus_in_event(GtkEventControllerFocus *controller UNUSED,
 	gpointer data UNUSED)
 {
-    gui_focus_change(TRUE);
+    // The window-level handler drives gui.in_focus; only kick the blink
+    // here so the cursor animates when keyboard focus is in the drawing
+    // area.  Activating a menu popover moves widget focus off drawarea
+    // but the window is still active, so we must not flip gui.in_focus
+    // here -- doing so makes the cursor go outline while the menu is up
+    // (see issue #20274).
     if (blink_state == BLINK_NONE)
 	gui_mch_start_blink();
 }
@@ -1836,11 +1844,31 @@ focus_in_event(GtkEventControllerFocus *controller UNUSED,
 focus_out_event(GtkEventControllerFocus *controller UNUSED,
 	gpointer data UNUSED)
 {
-    gui_focus_change(FALSE);
     if (blink_state != BLINK_NONE)
 	gui_mch_stop_blink(TRUE);
 }
 
+    static void
+window_active_changed(GObject *obj, GParamSpec *pspec UNUSED,
+	gpointer data UNUSED)
+{
+    gboolean active = gtk_window_is_active(GTK_WINDOW(obj));
+
+    gui_focus_change(active);
+    if (active)
+    {
+	if (blink_state == BLINK_NONE)
+	    gui_mch_start_blink();
+	// When the window returns from the background with no focused
+	// widget, route keyboard input back to the drawing area.
+	if (gui.drawarea != NULL
+		&& gtk_window_get_focus(GTK_WINDOW(obj)) == NULL)
+	    gtk_widget_grab_focus(gui.drawarea);
+    }
+    else if (blink_state != BLINK_NONE)
+	gui_mch_stop_blink(TRUE);
+}
+
     static void
 drawarea_realize_cb(GtkWidget *widget UNUSED, gpointer data UNUSED)
 {


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20274/4505245814@github.com>

Foxe Chen

unread,
May 21, 2026, 3:34:49 PM (3 days ago) May 21
to vim/vim, Subscribed
64-bitman left a comment (vim/vim#20274)

It does fix the main issue, however now the cursor never becomes an outline when the menu is focused


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20274/4512108861@github.com>

mattn

unread,
May 24, 2026, 7:43:03 AM (18 hours ago) May 24
to vim/vim, Subscribed
mattn left a comment (vim/vim#20274)

Note: I went with a different approach in #20291. Instead of moving gui_focus_change to a window-level handler (which is what made the cursor stop going outline while a menu was focused), it leaves the drawarea focus handlers as-is and installs an emission hook on GtkPopover::closed that grabs focus back to the drawing area once a menubar popover closes. That should keep the outline-while-menu-focused behaviour you wanted while still restoring the solid cursor after the menu is dismissed without selecting an item. Could you give that PR a try?


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20274/4528441633@github.com>

Reply all
Reply to author
Forward
0 new messages