+void
+_gtk_menu_shell_set_keyboard_mode (GtkMenuShell *menu_shell,
+ gboolean keyboard_mode)
+{
+ menu_shell->priv->keyboard_mode = keyboard_mode;
+}
+
+gboolean
+_gtk_menu_shell_get_keyboard_mode (GtkMenuShell *menu_shell)
+{
+ return menu_shell->priv->keyboard_mode;
+}
+
+void
+_gtk_menu_shell_update_mnemonics (GtkMenuShell *menu_shell)
+{
+ GtkMenuShell *target;
+ gboolean auto_mnemonics;
+ gboolean found;
+ gboolean mnemonics_visible;
+
+ g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu_shell)),
+ "gtk-auto-mnemonics", &auto_mnemonics,
+ NULL);
+
+ if (!auto_mnemonics)
+ return;
+
+ target = menu_shell;
+ found = FALSE;
+ while (target)
+ {
+ GtkMenuShellPrivate *priv = target->priv;
+ GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (target));
+
+ /* The idea with keyboard mode is that once you start using
+ * the keyboard to navigate the menus, we show mnemonics
+ * until the menu navigation is over. To that end, we spread
+ * the keyboard mode upwards in the menu hierarchy here.
+ * Also see gtk_menu_popup, where we inherit it downwards.
+ */
+ if (menu_shell->priv->keyboard_mode)
+ target->priv->keyboard_mode = TRUE;
+
+ /* While navigating menus, the first parent menu with an active
+ * item is the one where mnemonics are effective, as can be seen
+ * in gtk_menu_shell_key_press below.
+ * We also show mnemonics in context menus. The grab condition is
+ * necessary to ensure we remove underlines from menu bars when
+ * dismissing menus.
+ */
+ mnemonics_visible = target->priv->keyboard_mode &&
+ (((target->priv->active_menu_item || priv->in_unselectable_item) && !found) ||
+ (target == menu_shell &&
+ !target->priv->parent_menu_shell &&
+ gtk_widget_has_grab (GTK_WIDGET (target))));
+
+ /* While menus are up, only show underlines inside the menubar,
+ * not in the entire window.
+ */
+ if (GTK_IS_MENU_BAR (target))
+ {
+ gtk_window_set_mnemonics_visible (GTK_WINDOW (toplevel), FALSE);
+ _gtk_label_mnemonics_visible_apply_recursively (GTK_WIDGET (target),
+ mnemonics_visible);
+ }
+ else
+ gtk_window_set_mnemonics_visible (GTK_WINDOW (toplevel), mnemonics_visible);
+
+ if (target->priv->active_menu_item || priv->in_unselectable_item)
+ found = TRUE;
+
+ target = GTK_MENU_SHELL (target->priv->parent_menu_shell);
+ }
+}
+