[PATCH] ui/gtk: Enable fullscreen and zoom hotkeys for detached windows

dongwon.kim@intel.com posted 1 patch 1 month, 3 weeks ago
ui/gtk.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 98 insertions(+), 4 deletions(-)
[PATCH] ui/gtk: Enable fullscreen and zoom hotkeys for detached windows
Posted by dongwon.kim@intel.com 1 month, 3 weeks ago
From: Dongwon Kim <dongwon.kim@intel.com>

Currently, the fullscreen toggle hotkey (Ctrl+Alt+f by default) and zoom
hotkeys (Ctrl+Alt++, Ctrl+Alt+-, Ctrl+Alt+0) only function for the main
QEMU window. When a VC is detached (untabified), it loses these capabilities.

Implement toggle helpers, gd_win_full_screen and zoom helpers
(gd_win_zoom_in, gd_win_zoom_out, gd_win_zoom_fixed) and connect them
to the detached window's accelerator group in gd_menu_untabify.

Also remove a leftover debug fprintf in gd_win_grab.

Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
---
 ui/gtk.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 98 insertions(+), 4 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index a723c8215d..632e302ed7 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1547,7 +1547,6 @@ static gboolean gd_win_grab(void *opaque)
 {
     VirtualConsole *vc = opaque;
 
-    fprintf(stderr, "%s: %s\n", __func__, vc->label);
     if (vc->s->ptr_owner) {
         gd_ungrab_pointer(vc->s);
     } else {
@@ -1556,6 +1555,86 @@ static gboolean gd_win_grab(void *opaque)
     return TRUE;
 }
 
+static gboolean gd_win_full_screen(void *opaque)
+{
+    VirtualConsole *vc = opaque;
+    GdkWindow *window;
+    GdkWindowState state;
+
+    if (!vc->window || !gtk_widget_get_realized(vc->window)) {
+        return TRUE;
+    }
+
+    window = gtk_widget_get_window(vc->window);
+    if (!window) {
+        return TRUE;
+    }
+
+    state = gdk_window_get_state(window);
+
+    if (state & GDK_WINDOW_STATE_FULLSCREEN) {
+        gtk_window_unfullscreen(GTK_WINDOW(vc->window));
+
+        if (vc->type == GD_VC_GFX) {
+            vc->gfx.scale_x = vc->gfx.preferred_scale;
+            vc->gfx.scale_y = vc->gfx.preferred_scale;
+            gd_update_windowsize(vc);
+        }
+    } else {
+        if (vc->type == GD_VC_GFX) {
+            gtk_widget_set_size_request(vc->gfx.drawing_area, -1, -1);
+        }
+        gtk_window_fullscreen(GTK_WINDOW(vc->window));
+    }
+
+    gd_update_cursor(vc);
+    return TRUE;
+}
+
+static gboolean gd_win_zoom_in(void *opaque)
+{
+    VirtualConsole *vc = opaque;
+    GtkDisplayState *s = vc->s;
+
+    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->zoom_fit_item),
+                                   FALSE);
+
+    vc->gfx.scale_x += VC_SCALE_STEP;
+    vc->gfx.scale_y += VC_SCALE_STEP;
+
+    gd_update_windowsize(vc);
+    return TRUE;
+}
+
+static gboolean gd_win_zoom_out(void *opaque)
+{
+    VirtualConsole *vc = opaque;
+    GtkDisplayState *s = vc->s;
+
+    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->zoom_fit_item),
+                                   FALSE);
+
+    vc->gfx.scale_x -= VC_SCALE_STEP;
+    vc->gfx.scale_y -= VC_SCALE_STEP;
+
+    vc->gfx.scale_x = MAX(vc->gfx.scale_x, VC_SCALE_MIN);
+    vc->gfx.scale_y = MAX(vc->gfx.scale_y, VC_SCALE_MIN);
+
+    gd_update_windowsize(vc);
+    return TRUE;
+}
+
+static gboolean gd_win_zoom_fixed(void *opaque)
+{
+    VirtualConsole *vc = opaque;
+
+    vc->gfx.scale_x = vc->gfx.preferred_scale;
+    vc->gfx.scale_y = vc->gfx.preferred_scale;
+
+    gd_update_windowsize(vc);
+    return TRUE;
+}
+
 static void gd_menu_untabify(GtkMenuItem *item, void *opaque)
 {
     GtkDisplayState *s = opaque;
@@ -1590,9 +1669,24 @@ static void gd_menu_untabify(GtkMenuItem *item, void *opaque)
             GtkAccelGroup *ag = gtk_accel_group_new();
             gtk_window_add_accel_group(GTK_WINDOW(vc->window), ag);
 
-            GClosure *cb = g_cclosure_new_swap(G_CALLBACK(gd_win_grab),
-                                               vc, NULL);
-            gtk_accel_group_connect(ag, GDK_KEY_g, HOTKEY_MODIFIERS, 0, cb);
+            gtk_accel_group_connect(ag, GDK_KEY_g, HOTKEY_MODIFIERS, 0,
+                    g_cclosure_new_swap(G_CALLBACK(gd_win_grab),
+                                        vc, NULL));
+            gtk_accel_group_connect(ag, GDK_KEY_f, HOTKEY_MODIFIERS, 0,
+                    g_cclosure_new_swap(G_CALLBACK(gd_win_full_screen),
+                                        vc, NULL));
+            gtk_accel_group_connect(ag, GDK_KEY_plus, HOTKEY_MODIFIERS, 0,
+                    g_cclosure_new_swap(G_CALLBACK(gd_win_zoom_in),
+                                        vc, NULL));
+            gtk_accel_group_connect(ag, GDK_KEY_equal, HOTKEY_MODIFIERS, 0,
+                    g_cclosure_new_swap(G_CALLBACK(gd_win_zoom_in),
+                                        vc, NULL));
+            gtk_accel_group_connect(ag, GDK_KEY_minus, HOTKEY_MODIFIERS, 0,
+                    g_cclosure_new_swap(G_CALLBACK(gd_win_zoom_out),
+                                        vc, NULL));
+            gtk_accel_group_connect(ag, GDK_KEY_0, HOTKEY_MODIFIERS, 0,
+                    g_cclosure_new_swap(G_CALLBACK(gd_win_zoom_fixed),
+                                        vc, NULL));
         }
 
         gd_rebuild_vc_menu(s);
-- 
2.43.0


Re: [PATCH] ui/gtk: Enable fullscreen and zoom hotkeys for detached windows
Posted by Marc-André Lureau 1 week, 3 days ago
Hi

On Tue, Sep 15, 2026 at 11:02 PM <dongwon.kim@intel.com> wrote:
>
> From: Dongwon Kim <dongwon.kim@intel.com>
>
> Currently, the fullscreen toggle hotkey (Ctrl+Alt+f by default) and zoom
> hotkeys (Ctrl+Alt++, Ctrl+Alt+-, Ctrl+Alt+0) only function for the main
> QEMU window. When a VC is detached (untabified), it loses these capabilities.
>
> Implement toggle helpers, gd_win_full_screen and zoom helpers
> (gd_win_zoom_in, gd_win_zoom_out, gd_win_zoom_fixed) and connect them
> to the detached window's accelerator group in gd_menu_untabify.
>
> Also remove a leftover debug fprintf in gd_win_grab.
>
> Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
> Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
> ---
>  ui/gtk.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 98 insertions(+), 4 deletions(-)
>
> diff --git a/ui/gtk.c b/ui/gtk.c
> index a723c8215d..632e302ed7 100644
> --- a/ui/gtk.c
> +++ b/ui/gtk.c
> @@ -1547,7 +1547,6 @@ static gboolean gd_win_grab(void *opaque)
>  {
>      VirtualConsole *vc = opaque;
>
> -    fprintf(stderr, "%s: %s\n", __func__, vc->label);
>      if (vc->s->ptr_owner) {
>          gd_ungrab_pointer(vc->s);
>      } else {
> @@ -1556,6 +1555,86 @@ static gboolean gd_win_grab(void *opaque)
>      return TRUE;
>  }
>
> +static gboolean gd_win_full_screen(void *opaque)
> +{
> +    VirtualConsole *vc = opaque;
> +    GdkWindow *window;
> +    GdkWindowState state;
> +
> +    if (!vc->window || !gtk_widget_get_realized(vc->window)) {
> +        return TRUE;
> +    }
> +
> +    window = gtk_widget_get_window(vc->window);
> +    if (!window) {
> +        return TRUE;
> +    }
> +
> +    state = gdk_window_get_state(window);
> +
> +    if (state & GDK_WINDOW_STATE_FULLSCREEN) {
> +        gtk_window_unfullscreen(GTK_WINDOW(vc->window));
> +
> +        if (vc->type == GD_VC_GFX) {
> +            vc->gfx.scale_x = vc->gfx.preferred_scale;
> +            vc->gfx.scale_y = vc->gfx.preferred_scale;
> +            gd_update_windowsize(vc);
> +        }
> +    } else {
> +        if (vc->type == GD_VC_GFX) {
> +            gtk_widget_set_size_request(vc->gfx.drawing_area, -1, -1);
> +        }
> +        gtk_window_fullscreen(GTK_WINDOW(vc->window));
> +    }
> +
> +    gd_update_cursor(vc);
> +    return TRUE;
> +}
> +
> +static gboolean gd_win_zoom_in(void *opaque)
> +{
> +    VirtualConsole *vc = opaque;
> +    GtkDisplayState *s = vc->s;
> +
> +    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->zoom_fit_item),
> +                                   FALSE);
> +
> +    vc->gfx.scale_x += VC_SCALE_STEP;
> +    vc->gfx.scale_y += VC_SCALE_STEP;
> +
> +    gd_update_windowsize(vc);
> +    return TRUE;
> +}
> +
> +static gboolean gd_win_zoom_out(void *opaque)
> +{
> +    VirtualConsole *vc = opaque;
> +    GtkDisplayState *s = vc->s;
> +
> +    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->zoom_fit_item),
> +                                   FALSE);
> +
> +    vc->gfx.scale_x -= VC_SCALE_STEP;
> +    vc->gfx.scale_y -= VC_SCALE_STEP;
> +
> +    vc->gfx.scale_x = MAX(vc->gfx.scale_x, VC_SCALE_MIN);
> +    vc->gfx.scale_y = MAX(vc->gfx.scale_y, VC_SCALE_MIN);
> +
> +    gd_update_windowsize(vc);
> +    return TRUE;
> +}
> +
> +static gboolean gd_win_zoom_fixed(void *opaque)
> +{
> +    VirtualConsole *vc = opaque;
> +
> +    vc->gfx.scale_x = vc->gfx.preferred_scale;
> +    vc->gfx.scale_y = vc->gfx.preferred_scale;
> +
> +    gd_update_windowsize(vc);
> +    return TRUE;
> +}
> +

This duplicates existing code. Can you refactor it so we avoid logic
duplication?

btw, it would make sense to send a patch series now that you have 2
ui/gtk patches and more to come.

thanks

>  static void gd_menu_untabify(GtkMenuItem *item, void *opaque)
>  {
>      GtkDisplayState *s = opaque;
> @@ -1590,9 +1669,24 @@ static void gd_menu_untabify(GtkMenuItem *item, void *opaque)
>              GtkAccelGroup *ag = gtk_accel_group_new();
>              gtk_window_add_accel_group(GTK_WINDOW(vc->window), ag);
>
> -            GClosure *cb = g_cclosure_new_swap(G_CALLBACK(gd_win_grab),
> -                                               vc, NULL);
> -            gtk_accel_group_connect(ag, GDK_KEY_g, HOTKEY_MODIFIERS, 0, cb);
> +            gtk_accel_group_connect(ag, GDK_KEY_g, HOTKEY_MODIFIERS, 0,
> +                    g_cclosure_new_swap(G_CALLBACK(gd_win_grab),
> +                                        vc, NULL));
> +            gtk_accel_group_connect(ag, GDK_KEY_f, HOTKEY_MODIFIERS, 0,
> +                    g_cclosure_new_swap(G_CALLBACK(gd_win_full_screen),
> +                                        vc, NULL));
> +            gtk_accel_group_connect(ag, GDK_KEY_plus, HOTKEY_MODIFIERS, 0,
> +                    g_cclosure_new_swap(G_CALLBACK(gd_win_zoom_in),
> +                                        vc, NULL));
> +            gtk_accel_group_connect(ag, GDK_KEY_equal, HOTKEY_MODIFIERS, 0,
> +                    g_cclosure_new_swap(G_CALLBACK(gd_win_zoom_in),
> +                                        vc, NULL));
> +            gtk_accel_group_connect(ag, GDK_KEY_minus, HOTKEY_MODIFIERS, 0,
> +                    g_cclosure_new_swap(G_CALLBACK(gd_win_zoom_out),
> +                                        vc, NULL));
> +            gtk_accel_group_connect(ag, GDK_KEY_0, HOTKEY_MODIFIERS, 0,
> +                    g_cclosure_new_swap(G_CALLBACK(gd_win_zoom_fixed),
> +                                        vc, NULL));
>          }
>
>          gd_rebuild_vc_menu(s);
> --
> 2.43.0
>
>


-- 
Marc-André Lureau
RE: [PATCH] ui/gtk: Enable fullscreen and zoom hotkeys for detached windows
Posted by Kim, Dongwon 1 week, 2 days ago
Hi Marc-André,

> Subject: Re: [PATCH] ui/gtk: Enable fullscreen and zoom hotkeys for detached
> windows
> 
> Hi
> 
> On Tue, Sep 15, 2026 at 11:02 PM <dongwon.kim@intel.com> wrote:
> >
> > From: Dongwon Kim <dongwon.kim@intel.com>
> >
> > Currently, the fullscreen toggle hotkey (Ctrl+Alt+f by default) and
> > zoom hotkeys (Ctrl+Alt++, Ctrl+Alt+-, Ctrl+Alt+0) only function for
> > the main QEMU window. When a VC is detached (untabified), it loses these
> capabilities.
> >
> > Implement toggle helpers, gd_win_full_screen and zoom helpers
> > (gd_win_zoom_in, gd_win_zoom_out, gd_win_zoom_fixed) and connect
> them
> > to the detached window's accelerator group in gd_menu_untabify.
> >
> > Also remove a leftover debug fprintf in gd_win_grab.
> >
> > Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
> > Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
> > ---
> >  ui/gtk.c | 102
> > ++++++++++++++++++++++++++++++++++++++++++++++++++++---
> >  1 file changed, 98 insertions(+), 4 deletions(-)
> >
> > diff --git a/ui/gtk.c b/ui/gtk.c
> > index a723c8215d..632e302ed7 100644
> > --- a/ui/gtk.c
> > +++ b/ui/gtk.c
> > @@ -1547,7 +1547,6 @@ static gboolean gd_win_grab(void *opaque)  {
> >      VirtualConsole *vc = opaque;
> >
> > -    fprintf(stderr, "%s: %s\n", __func__, vc->label);
> >      if (vc->s->ptr_owner) {
> >          gd_ungrab_pointer(vc->s);
> >      } else {
> > @@ -1556,6 +1555,86 @@ static gboolean gd_win_grab(void *opaque)
> >      return TRUE;
> >  }
> >
> > +static gboolean gd_win_full_screen(void *opaque) {
> > +    VirtualConsole *vc = opaque;
> > +    GdkWindow *window;
> > +    GdkWindowState state;
> > +
> > +    if (!vc->window || !gtk_widget_get_realized(vc->window)) {
> > +        return TRUE;
> > +    }
> > +
> > +    window = gtk_widget_get_window(vc->window);
> > +    if (!window) {
> > +        return TRUE;
> > +    }
> > +
> > +    state = gdk_window_get_state(window);
> > +
> > +    if (state & GDK_WINDOW_STATE_FULLSCREEN) {
> > +        gtk_window_unfullscreen(GTK_WINDOW(vc->window));
> > +
> > +        if (vc->type == GD_VC_GFX) {
> > +            vc->gfx.scale_x = vc->gfx.preferred_scale;
> > +            vc->gfx.scale_y = vc->gfx.preferred_scale;
> > +            gd_update_windowsize(vc);
> > +        }
> > +    } else {
> > +        if (vc->type == GD_VC_GFX) {
> > +            gtk_widget_set_size_request(vc->gfx.drawing_area, -1, -1);
> > +        }
> > +        gtk_window_fullscreen(GTK_WINDOW(vc->window));
> > +    }
> > +
> > +    gd_update_cursor(vc);
> > +    return TRUE;
> > +}
> > +
> > +static gboolean gd_win_zoom_in(void *opaque) {
> > +    VirtualConsole *vc = opaque;
> > +    GtkDisplayState *s = vc->s;
> > +
> > +    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s-
> >zoom_fit_item),
> > +                                   FALSE);
> > +
> > +    vc->gfx.scale_x += VC_SCALE_STEP;
> > +    vc->gfx.scale_y += VC_SCALE_STEP;
> > +
> > +    gd_update_windowsize(vc);
> > +    return TRUE;
> > +}
> > +
> > +static gboolean gd_win_zoom_out(void *opaque) {
> > +    VirtualConsole *vc = opaque;
> > +    GtkDisplayState *s = vc->s;
> > +
> > +    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s-
> >zoom_fit_item),
> > +                                   FALSE);
> > +
> > +    vc->gfx.scale_x -= VC_SCALE_STEP;
> > +    vc->gfx.scale_y -= VC_SCALE_STEP;
> > +
> > +    vc->gfx.scale_x = MAX(vc->gfx.scale_x, VC_SCALE_MIN);
> > +    vc->gfx.scale_y = MAX(vc->gfx.scale_y, VC_SCALE_MIN);
> > +
> > +    gd_update_windowsize(vc);
> > +    return TRUE;
> > +}
> > +
> > +static gboolean gd_win_zoom_fixed(void *opaque) {
> > +    VirtualConsole *vc = opaque;
> > +
> > +    vc->gfx.scale_x = vc->gfx.preferred_scale;
> > +    vc->gfx.scale_y = vc->gfx.preferred_scale;
> > +
> > +    gd_update_windowsize(vc);
> > +    return TRUE;
> > +}
> > +
> 
> This duplicates existing code. Can you refactor it so we avoid logic
> duplication?

Yes, we can do that. I will fix it in v2.

> 
> btw, it would make sense to send a patch series now that you have 2 ui/gtk
> patches and more to come.

I do have a couple of other patches that I am working on in gtk-ui but it would take
more time to finalize those. Can we complete these two patches first? I will submit
a series from next time. 

> 
> thanks
> 
> >  static void gd_menu_untabify(GtkMenuItem *item, void *opaque)  {
> >      GtkDisplayState *s = opaque;
> > @@ -1590,9 +1669,24 @@ static void gd_menu_untabify(GtkMenuItem
> *item, void *opaque)
> >              GtkAccelGroup *ag = gtk_accel_group_new();
> >              gtk_window_add_accel_group(GTK_WINDOW(vc->window), ag);
> >
> > -            GClosure *cb = g_cclosure_new_swap(G_CALLBACK(gd_win_grab),
> > -                                               vc, NULL);
> > -            gtk_accel_group_connect(ag, GDK_KEY_g, HOTKEY_MODIFIERS, 0,
> cb);
> > +            gtk_accel_group_connect(ag, GDK_KEY_g, HOTKEY_MODIFIERS, 0,
> > +                    g_cclosure_new_swap(G_CALLBACK(gd_win_grab),
> > +                                        vc, NULL));
> > +            gtk_accel_group_connect(ag, GDK_KEY_f, HOTKEY_MODIFIERS, 0,
> > +                    g_cclosure_new_swap(G_CALLBACK(gd_win_full_screen),
> > +                                        vc, NULL));
> > +            gtk_accel_group_connect(ag, GDK_KEY_plus, HOTKEY_MODIFIERS,
> 0,
> > +                    g_cclosure_new_swap(G_CALLBACK(gd_win_zoom_in),
> > +                                        vc, NULL));
> > +            gtk_accel_group_connect(ag, GDK_KEY_equal, HOTKEY_MODIFIERS,
> 0,
> > +                    g_cclosure_new_swap(G_CALLBACK(gd_win_zoom_in),
> > +                                        vc, NULL));
> > +            gtk_accel_group_connect(ag, GDK_KEY_minus,
> HOTKEY_MODIFIERS, 0,
> > +                    g_cclosure_new_swap(G_CALLBACK(gd_win_zoom_out),
> > +                                        vc, NULL));
> > +            gtk_accel_group_connect(ag, GDK_KEY_0, HOTKEY_MODIFIERS, 0,
> > +                    g_cclosure_new_swap(G_CALLBACK(gd_win_zoom_fixed),
> > +                                        vc, NULL));
> >          }
> >
> >          gd_rebuild_vc_menu(s);
> > --
> > 2.43.0
> >
> >
> 
> 
> --
> Marc-André Lureau
[PATCH v2] ui/gtk: Register "Grab Input" shortcut to accel_group
Posted by dongwon.kim@intel.com 1 month, 3 weeks ago
From: Dongwon Kim <dongwon.kim@intel.com>

The "Grab Input" shortcut key currently fails to trigger when the
window is in fullscreen mode because the menubar is hidden, which
disables GtkAccelMap-based shortcuts associated with it.

To ensure the accelerator remains active in fullscreen, connect it
directly to s->accel_group and explicitly set the hotkey display on
the menu item label.

v2: gd_accel_grab_input returns TRUE

Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
---
 ui/gtk.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 632e302ed7..c07f275537 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1932,6 +1932,14 @@ static void gd_menu_grab_input(GtkMenuItem *item, void *opaque)
     gd_update_cursor(vc);
 }
 
+static gboolean gd_accel_grab_input(void *opaque)
+{
+    GtkDisplayState *s = opaque;
+
+    gtk_menu_item_activate(GTK_MENU_ITEM(s->grab_item));
+    return TRUE;
+}
+
 static void gd_change_page(GtkNotebook *nb, gpointer arg1, guint arg2,
                            gpointer data)
 {
@@ -2611,6 +2619,7 @@ static void gd_create_menu_view(GtkDisplayState *s, DisplayOptions *opts)
 {
     GtkWidget *view_menu;
     GtkWidget *separator;
+    GtkWidget *child;
     QemuConsole *con;
     bool zoom_to_fit = false;
     int vc, i;
@@ -2669,12 +2678,15 @@ static void gd_create_menu_view(GtkDisplayState *s, DisplayOptions *opts)
     gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->grab_on_hover_item);
 
     s->grab_item = gtk_check_menu_item_new_with_mnemonic(_("_Grab Input"));
-    gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->grab_item),
-                                 "<QEMU>/View/Grab Input");
-    gtk_accel_map_add_entry("<QEMU>/View/Grab Input", GDK_KEY_g,
-                            HOTKEY_MODIFIERS);
     gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->grab_item);
-
+    gtk_accel_group_connect(s->accel_group, GDK_KEY_g, HOTKEY_MODIFIERS, 0,
+                            g_cclosure_new_swap(G_CALLBACK(gd_accel_grab_input),
+                                                s, NULL));
+    child = gtk_bin_get_child(GTK_BIN(s->grab_item));
+    if (GTK_IS_ACCEL_LABEL(child)) {
+        gtk_accel_label_set_accel(GTK_ACCEL_LABEL(child),
+                                  GDK_KEY_g, HOTKEY_MODIFIERS);
+    }
     separator = gtk_separator_menu_item_new();
     gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), separator);
 
-- 
2.43.0