]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0712: GTK4: dialogs not handling mnemonics correctly v9.2.0712
authorFoxe Chen <chen.foxe@gmail.com>
Tue, 23 Jun 2026 20:32:43 +0000 (20:32 +0000)
committerChristian Brabandt <cb@256bit.org>
Tue, 23 Jun 2026 20:37:19 +0000 (20:37 +0000)
Problem:  GTK4: dialogs not handling mnemonics correctly
Solution: Allow using mnemonics without alt key (Foxe Chen).

closes: #20618

Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/gui_gtk4.c
src/version.c

index 7084516d87642c4d928952b4d121796185896cd4..fe9381f2f6e4c11ac8fc862c5effcf9abef7cbe1 100644 (file)
@@ -5209,6 +5209,13 @@ typedef struct
     gboolean   *done;
 } DialogButtonState;
 
+typedef struct
+{
+    GtkWidget  *win;
+    gboolean   *done;
+    gboolean   no_alt;
+} DialogState;
+
     static void
 dialog_button_clicked_cb(GtkButton *button, DialogButtonState *state)
 {
@@ -5222,13 +5229,16 @@ dialog_key_pressed_cb(
        guint                   keyval,
        guint                   keycode,
        GdkModifierType         state,
-       gboolean                *done)
+       DialogState             *dstate)
 {
     if (keyval == GDK_KEY_Escape)
     {
-       *done = TRUE;
+       *dstate->done = TRUE;
        return TRUE;
     }
+
+    if (dstate->no_alt && !(state & gtk_accelerator_get_default_mod_mask()))
+       return gtk_widget_mnemonic_activate(dstate->win, FALSE);
     return FALSE;
 }
 
@@ -5264,6 +5274,7 @@ gui_mch_dialog(
     int                        response = -1;
     gboolean           done = FALSE;
     gboolean           win_closed = FALSE;
+    DialogState                state;
 
     utf8_title = CONVERT_TO_UTF8(title);
     if (utf8_title != NULL)
@@ -5306,13 +5317,14 @@ gui_mch_dialog(
     gtk_label_set_max_width_chars(GTK_LABEL(label), 40);
     gtk_box_append(GTK_BOX(message_box), label);
 
-    // Close the dialog when the <Esc> key is pressed. the GTK3 GUI also allows
-    // mnemonics without <Alt> key, but that behaviour comes from GTK+ 1.2 (from
-    // 1999!), so most users probably don't care...
+    // Close the dialog when the <Esc> key is pressed. Also allow using
+    // mnemonics without <Alt> key (if there is no text field).
     key_controller = gtk_event_controller_key_new();
     g_signal_connect(key_controller, "key-pressed",
-           G_CALLBACK(dialog_key_pressed_cb), &done);
+           G_CALLBACK(dialog_key_pressed_cb), &state);
     gtk_widget_add_controller(GTK_WIDGET(win), key_controller);
+    state.done = &done;
+    state.win = GTK_WIDGET(win);
 
     if (textfield != NULL)
     {
@@ -5331,6 +5343,30 @@ gui_mch_dialog(
        // (which is set as the default widget).
        gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
        gtk_box_append(GTK_BOX(vertbox), entry);
+       state.no_alt = FALSE;
+    }
+    else
+    {
+       GListModel  *controllers;
+       int         len;
+
+       // Set all shortcut controllers in the window to not require a modifier
+       // for mnemonics.
+       controllers = gtk_widget_observe_controllers(GTK_WIDGET(win));
+       len  = g_list_model_get_n_items(controllers);
+       for (int i = 0; i < len; i++)
+       {
+           GtkEventController *controller;
+
+           controller = g_list_model_get_item(controllers, i);
+           if (GTK_IS_SHORTCUT_CONTROLLER(controller))
+               gtk_shortcut_controller_set_mnemonics_modifiers(
+                       GTK_SHORTCUT_CONTROLLER(controller), 0);
+       }
+       g_object_unref(controllers);
+
+       gtk_window_set_mnemonics_visible(win, TRUE);
+       state.no_alt = TRUE;
     }
 
     if (buttons != NULL)
index c3ae1b07d9bd54ce6846f2ab6c0c37e3c5ad7596..b03ecdf3072f153f05cac04488f61349f36d05ef 100644 (file)
@@ -759,6 +759,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    712,
 /**/
     711,
 /**/