summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk/gtklabel.c108
-rw-r--r--gtk/gtklabel.h5
-rw-r--r--gtk/gtkmain.c23
-rw-r--r--gtk/gtkmenu.c12
-rw-r--r--gtk/gtkmenubar.c1
-rw-r--r--gtk/gtkmenuitem.c3
-rw-r--r--gtk/gtkmenushell.c86
-rw-r--r--gtk/gtkmenushell.h6
-rw-r--r--gtk/gtksettings.c20
-rw-r--r--gtk/gtkwindow.c94
-rw-r--r--gtk/gtkwindow.h3
11 files changed, 353 insertions, 8 deletions
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index 73fa93a35b..475d84278b 100644
--- a/gtk/gtklabel.c
+++ b/gtk/gtklabel.c
@@ -58,6 +58,8 @@ typedef struct
gint wrap_width;
gint width_chars;
gint max_width_chars;
+
+ gboolean mnemonics_visible;
} GtkLabelPrivate;
/* Notes about the handling of links:
@@ -264,6 +266,9 @@ static void gtk_label_buildable_custom_finished (GtkBuildable *builda
gpointer user_data);
+static void connect_mnemonics_visible_notify (GtkLabel *label);
+
+
/* For selectable labels: */
static void gtk_label_move_cursor (GtkLabel *label,
GtkMovementStep step,
@@ -1037,6 +1042,8 @@ gtk_label_init (GtkLabel *label)
label->mnemonic_widget = NULL;
label->mnemonic_window = NULL;
+ priv->mnemonics_visible = TRUE;
+
gtk_label_set_text (label, "");
}
@@ -1486,7 +1493,9 @@ gtk_label_setup_mnemonic (GtkLabel *label,
}
if (label->mnemonic_keyval == GDK_VoidSymbol)
- goto done;
+ goto done;
+
+ connect_mnemonics_visible_notify (GTK_LABEL (widget));
toplevel = gtk_widget_get_toplevel (widget);
if (GTK_WIDGET_TOPLEVEL (toplevel))
@@ -1565,6 +1574,65 @@ label_shortcut_setting_changed (GtkSettings *settings)
}
static void
+mnemonics_visible_apply (GtkWidget *widget,
+ gboolean mnemonics_visible)
+{
+ GtkLabel *label;
+ GtkLabelPrivate *priv;
+
+ label = GTK_LABEL (widget);
+
+ if (!label->use_underline)
+ return;
+
+ priv = GTK_LABEL_GET_PRIVATE (label);
+
+ mnemonics_visible = mnemonics_visible != FALSE;
+
+ if (priv->mnemonics_visible != mnemonics_visible)
+ {
+ priv->mnemonics_visible = mnemonics_visible;
+
+ gtk_label_recalculate (label);
+ }
+}
+
+static void
+label_mnemonics_visible_traverse_container (GtkWidget *widget,
+ gpointer data)
+{
+ gboolean mnemonics_visible = GPOINTER_TO_INT (data);
+
+ _gtk_label_mnemonics_visible_apply_recursively (widget, mnemonics_visible);
+}
+
+void
+_gtk_label_mnemonics_visible_apply_recursively (GtkWidget *widget,
+ gboolean mnemonics_visible)
+{
+ if (GTK_IS_LABEL (widget))
+ mnemonics_visible_apply (widget, mnemonics_visible);
+ else if (GTK_IS_CONTAINER (widget))
+ gtk_container_forall (GTK_CONTAINER (widget),
+ label_mnemonics_visible_traverse_container,
+ GINT_TO_POINTER (mnemonics_visible));
+}
+
+static void
+label_mnemonics_visible_changed (GtkWindow *window,
+ GParamSpec *pspec,
+ gpointer data)
+{
+ gboolean mnemonics_visible;
+
+ g_object_get (window, "mnemonics-visible", &mnemonics_visible, NULL);
+
+ gtk_container_forall (GTK_CONTAINER (window),
+ label_mnemonics_visible_traverse_container,
+ GINT_TO_POINTER (mnemonics_visible));
+}
+
+static void
gtk_label_screen_changed (GtkWidget *widget,
GdkScreen *old_screen)
{
@@ -2420,6 +2488,7 @@ static void
gtk_label_set_pattern_internal (GtkLabel *label,
const gchar *pattern)
{
+ GtkLabelPrivate *priv = GTK_LABEL_GET_PRIVATE (label);
PangoAttrList *attrs;
gboolean enable_mnemonics;
@@ -2432,7 +2501,8 @@ gtk_label_set_pattern_internal (GtkLabel *label,
"gtk-enable-mnemonics", &enable_mnemonics,
NULL);
- if (enable_mnemonics && pattern)
+ if (enable_mnemonics && priv->mnemonics_visible && pattern &&
+ GTK_WIDGET_IS_SENSITIVE (label))
attrs = gtk_label_pattern_to_attrs (label, pattern);
else
attrs = NULL;
@@ -4179,6 +4249,38 @@ gtk_label_button_release (GtkWidget *widget,
}
static void
+connect_mnemonics_visible_notify (GtkLabel *label)
+{
+ GtkLabelPrivate *priv = GTK_LABEL_GET_PRIVATE (label);
+ GtkWidget *toplevel;
+ gboolean connected;
+
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (label));
+
+ if (!GTK_IS_WINDOW (toplevel))
+ return;
+
+ /* always set up this widgets initial value */
+ priv->mnemonics_visible =
+ gtk_window_get_mnemonics_visible (GTK_WINDOW (toplevel));
+
+ connected =
+ GPOINTER_TO_INT (g_object_get_data (G_OBJECT (toplevel),
+ "gtk-label-mnemonics-visible-connected"));
+
+ if (!connected)
+ {
+ g_signal_connect (toplevel,
+ "notify::mnemonics-visible",
+ G_CALLBACK (label_mnemonics_visible_changed),
+ label);
+ g_object_set_data (G_OBJECT (toplevel),
+ "gtk-label-mnemonics-visible-connected",
+ GINT_TO_POINTER (1));
+ }
+}
+
+static void
drag_begin_cb (GtkWidget *widget,
GdkDragContext *context,
gpointer data)
@@ -5707,7 +5809,7 @@ gtk_label_activate_current_link (GtkLabel *label)
if (window &&
window->default_widget != widget &&
!(widget == window->focus_widget &&
- (!window->default_widget || !GTK_WIDGET_SENSITIVE (window->default_widget))))
+ (!window->default_widget || !GTK_WIDGET_IS_SENSITIVE (window->default_widget))))
gtk_window_activate_default (window);
}
}
diff --git a/gtk/gtklabel.h b/gtk/gtklabel.h
index d44b142fad..88a9db7ddf 100644
--- a/gtk/gtklabel.h
+++ b/gtk/gtklabel.h
@@ -197,6 +197,11 @@ guint gtk_label_parse_uline (GtkLabel *label,
#endif /* GTK_DISABLE_DEPRECATED */
+/* private */
+
+void _gtk_label_mnemonics_visible_apply_recursively (GtkWidget *widget,
+ gboolean mnemonics_visible);
+
G_END_DECLS
#endif /* __GTK_LABEL_H__ */
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index 581403b541..af03f3578e 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -63,6 +63,8 @@
#include "gtktooltip.h"
#include "gtkdebug.h"
#include "gtkalias.h"
+#include "gtkmenu.h"
+#include "gdk/gdkkeysyms.h"
#include "gdk/gdkprivate.h" /* for GDK_WINDOW_DESTROYED */
@@ -1613,6 +1615,27 @@ gtk_main_do_event (GdkEvent *event)
if (gtk_invoke_key_snoopers (grab_widget, event))
break;
}
+ /* catch alt press to enable auto-mnemonics */
+ if (event->key.keyval == GDK_Alt_L || event->key.keyval == GDK_Alt_R)
+ {
+ gboolean auto_mnemonics;
+
+ g_object_get (gtk_widget_get_settings (grab_widget),
+ "gtk-auto-mnemonics", &auto_mnemonics, NULL);
+
+ if (auto_mnemonics)
+ {
+ gboolean mnemonics_visible;
+ GtkWidget *window;
+
+ mnemonics_visible = (event->type == GDK_KEY_PRESS);
+
+ window = gtk_widget_get_toplevel (grab_widget);
+
+ if (GTK_IS_WINDOW (window))
+ gtk_window_set_mnemonics_visible (GTK_WINDOW (window), mnemonics_visible);
+ }
+ }
/* else fall through */
case GDK_MOTION_NOTIFY:
case GDK_BUTTON_RELEASE:
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c
index e8813c9f0d..241ef413ed 100644
--- a/gtk/gtkmenu.c
+++ b/gtk/gtkmenu.c
@@ -1616,6 +1616,18 @@ gtk_menu_popup (GtkMenu *menu,
if (xgrab_shell == widget)
popup_grab_on_window (widget->window, activate_time, grab_keyboard); /* Should always succeed */
gtk_grab_add (GTK_WIDGET (menu));
+
+ if (parent_menu_shell)
+ {
+ gboolean keyboard_mode;
+
+ keyboard_mode = _gtk_menu_shell_get_keyboard_mode (GTK_MENU_SHELL (parent_menu_shell));
+ _gtk_menu_shell_set_keyboard_mode (menu_shell, keyboard_mode);
+ }
+ else if (menu_shell->button == 0) /* a keynav-activated context menu */
+ _gtk_menu_shell_set_keyboard_mode (menu_shell, TRUE);
+
+ _gtk_menu_shell_update_mnemonics (menu_shell);
}
void
diff --git a/gtk/gtkmenubar.c b/gtk/gtkmenubar.c
index a54e456d1b..3d2bbb513c 100644
--- a/gtk/gtkmenubar.c
+++ b/gtk/gtkmenubar.c
@@ -625,6 +625,7 @@ window_key_press_handler (GtkWidget *widget,
{
GtkMenuShell *menu_shell = GTK_MENU_SHELL (menubars->data);
+ _gtk_menu_shell_set_keyboard_mode (menu_shell, TRUE);
_gtk_menu_shell_activate (menu_shell);
gtk_menu_shell_select_first (menu_shell, FALSE);
diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c
index 13db059bd4..1f3e1a9691 100644
--- a/gtk/gtkmenuitem.c
+++ b/gtk/gtkmenuitem.c
@@ -1374,6 +1374,9 @@ static gboolean
gtk_menu_item_mnemonic_activate (GtkWidget *widget,
gboolean group_cycling)
{
+ if (GTK_IS_MENU_SHELL (widget->parent))
+ _gtk_menu_shell_set_keyboard_mode (GTK_MENU_SHELL (widget->parent), TRUE);
+
if (group_cycling &&
widget->parent &&
GTK_IS_MENU_SHELL (widget->parent) &&
diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c
index 910c760d56..4f7d82c8ea 100644
--- a/gtk/gtkmenushell.c
+++ b/gtk/gtkmenushell.c
@@ -30,6 +30,7 @@
#include "gdk/gdkkeysyms.h"
#include "gtkbindings.h"
#include "gtkkeyhash.h"
+#include "gtklabel.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
#include "gtkmenu.h"
@@ -773,6 +774,76 @@ gtk_menu_shell_button_release (GtkWidget *widget,
return TRUE;
}
+void
+_gtk_menu_shell_set_keyboard_mode (GtkMenuShell *menu_shell,
+ gboolean keyboard_mode)
+{
+ menu_shell->keyboard_mode = keyboard_mode;
+}
+
+gboolean
+_gtk_menu_shell_get_keyboard_mode (GtkMenuShell *menu_shell)
+{
+ return menu_shell->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)
+ {
+ /* 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->keyboard_mode)
+ target->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->keyboard_mode &&
+ ((target->active_menu_item && !found) ||
+ (target == menu_shell &&
+ !target->parent_menu_shell &&
+ gtk_widget_has_grab (target)));
+
+ /* While menus are up, only show underlines inside the menubar,
+ * not in the entire window.
+ */
+ if (GTK_IS_MENU_BAR (target))
+ _gtk_label_mnemonics_visible_apply_recursively (GTK_WIDGET (target),
+ mnemonics_visible);
+ else
+ gtk_window_set_mnemonics_visible (GTK_WINDOW (gtk_widget_get_toplevel (target)),
+ mnemonics_visible);
+
+ if (target->active_menu_item)
+ found = TRUE;
+
+ target = GTK_MENU_SHELL (target->parent_menu_shell);
+ }
+}
+
static gint
gtk_menu_shell_key_press (GtkWidget *widget,
GdkEventKey *event)
@@ -780,9 +851,11 @@ gtk_menu_shell_key_press (GtkWidget *widget,
GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget);
gboolean enable_mnemonics;
+ menu_shell->keyboard_mode = TRUE;
+
if (!menu_shell->active_menu_item && menu_shell->parent_menu_shell)
return gtk_widget_event (menu_shell->parent_menu_shell, (GdkEvent *)event);
-
+
if (gtk_bindings_activate_event (GTK_OBJECT (widget), event))
return TRUE;
@@ -992,11 +1065,15 @@ gtk_real_menu_shell_deactivate (GtkMenuShell *menu_shell)
if (menu_shell->have_xgrab)
{
GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (menu_shell));
-
+
menu_shell->have_xgrab = FALSE;
gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME);
gdk_display_keyboard_ungrab (display, GDK_CURRENT_TIME);
}
+
+ menu_shell->keyboard_mode = FALSE;
+
+ _gtk_menu_shell_update_mnemonics (menu_shell);
}
}
@@ -1079,6 +1156,8 @@ gtk_menu_shell_real_select_item (GtkMenuShell *menu_shell,
GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement);
gtk_menu_item_select (GTK_MENU_ITEM (menu_shell->active_menu_item));
+ _gtk_menu_shell_update_mnemonics (menu_shell);
+
/* This allows the bizarre radio buttons-with-submenus-display-history
* behavior
*/
@@ -1095,6 +1174,7 @@ gtk_menu_shell_deselect (GtkMenuShell *menu_shell)
{
gtk_menu_item_deselect (GTK_MENU_ITEM (menu_shell->active_menu_item));
menu_shell->active_menu_item = NULL;
+ _gtk_menu_shell_update_mnemonics (menu_shell);
}
}
@@ -1340,6 +1420,7 @@ gtk_real_menu_shell_move_current (GtkMenuShell *menu_shell,
* menu.
*/
_gtk_menu_item_popdown_submenu (menu_shell->active_menu_item);
+ _gtk_menu_shell_update_mnemonics (menu_shell);
}
else if (parent_menu_shell)
{
@@ -1347,6 +1428,7 @@ gtk_real_menu_shell_move_current (GtkMenuShell *menu_shell,
{
/* close menu when returning from submenu. */
_gtk_menu_item_popdown_submenu (GTK_MENU (menu_shell)->parent_menu_item);
+ _gtk_menu_shell_update_mnemonics (parent_menu_shell);
break;
}
diff --git a/gtk/gtkmenushell.h b/gtk/gtkmenushell.h
index e8281bcbb4..614d3975f2 100644
--- a/gtk/gtkmenushell.h
+++ b/gtk/gtkmenushell.h
@@ -65,6 +65,7 @@ struct _GtkMenuShell
guint GSEAL (ignore_leave) : 1; /* unused */
guint GSEAL (menu_flag) : 1; /* unused */
guint GSEAL (ignore_enter) : 1;
+ guint GSEAL (keyboard_mode) : 1;
};
struct _GtkMenuShellClass
@@ -130,6 +131,11 @@ gboolean gtk_menu_shell_get_take_focus (GtkMenuShell *menu_shell);
void gtk_menu_shell_set_take_focus (GtkMenuShell *menu_shell,
gboolean take_focus);
+void _gtk_menu_shell_update_mnemonics (GtkMenuShell *menu_shell);
+void _gtk_menu_shell_set_keyboard_mode (GtkMenuShell *menu_shell,
+ gboolean keyboard_mode);
+gboolean _gtk_menu_shell_get_keyboard_mode (GtkMenuShell *menu_shell);
+
G_END_DECLS
#endif /* __GTK_MENU_SHELL_H__ */
diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c
index 9e28fb9229..a7ca546a08 100644
--- a/gtk/gtksettings.c
+++ b/gtk/gtksettings.c
@@ -124,7 +124,8 @@ enum {
PROP_ENABLE_EVENT_SOUNDS,
PROP_ENABLE_TOOLTIPS,
PROP_TOOLBAR_STYLE,
- PROP_TOOLBAR_ICON_SIZE
+ PROP_TOOLBAR_ICON_SIZE,
+ PROP_AUTO_MNEMONICS
};
@@ -999,6 +1000,23 @@ gtk_settings_class_init (GtkSettingsClass *class)
GTK_PARAM_READWRITE),
gtk_rc_property_parse_enum);
g_assert (result == PROP_TOOLBAR_ICON_SIZE);
+
+ /**
+ * GtkSettings:gtk-auto-mnemonics:
+ *
+ * Whether mnemonics should be automatically shown and hidden when the user
+ * presses the mnemonic activator.
+ *
+ * Since: 2.20
+ */
+ result = settings_install_property_parser (class,
+ g_param_spec_boolean ("gtk-auto-mnemonics",
+ P_("Auto Mnemonics"),
+ P_("Whether mnemonics should be automatically shown and hidden when the user presses the mnemonic activator."),
+ FALSE,
+ GTK_PARAM_READWRITE),
+ NULL);
+ g_assert (result == PROP_AUTO_MNEMONICS);
}
static void
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index f01820d1fb..f5ec59ff40 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -101,6 +101,8 @@ enum {
/* Writeonly properties */
PROP_STARTUP_ID,
+ PROP_MNEMONICS_VISIBLE,
+
LAST_ARG
};
@@ -185,6 +187,9 @@ struct _GtkWindowPrivate
guint opacity_set : 1;
guint builder_visible : 1;
+ guint mnemonics_visible : 1;
+ guint mnemonics_visible_set : 1;
+
GdkWindowTypeHint type_hint;
gdouble opacity;
@@ -230,6 +235,8 @@ static gint gtk_window_client_event (GtkWidget *widget,
static void gtk_window_check_resize (GtkContainer *container);
static gint gtk_window_focus (GtkWidget *widget,
GtkDirectionType direction);
+static void gtk_window_grab_notify (GtkWidget *widget,
+ gboolean was_grabbed);
static void gtk_window_real_set_focus (GtkWindow *window,
GtkWidget *focus);
@@ -456,9 +463,9 @@ gtk_window_class_init (GtkWindowClass *klass)
widget_class->focus_out_event = gtk_window_focus_out_event;
widget_class->client_event = gtk_window_client_event;
widget_class->focus = gtk_window_focus;
-
widget_class->expose_event = gtk_window_expose;
-
+ widget_class->grab_notify = gtk_window_grab_notify;
+
container_class->check_resize = gtk_window_check_resize;
klass->set_focus = gtk_window_real_set_focus;
@@ -591,6 +598,13 @@ gtk_window_class_init (GtkWindowClass *klass)
P_("Icon for this window"),
GDK_TYPE_PIXBUF,
GTK_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_MNEMONICS_VISIBLE,
+ g_param_spec_boolean ("mnemonics-visible",
+ P_("Mnemonics Visible"),
+ P_("Whether mnemonics are currently visible in this window"),
+ TRUE,
+ GTK_PARAM_READWRITE));
/**
* GtkWindow:icon-name:
@@ -929,6 +943,7 @@ gtk_window_init (GtkWindow *window)
priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
priv->opacity = 1.0;
priv->startup_id = NULL;
+ priv->mnemonics_visible = TRUE;
colormap = _gtk_widget_peek_colormap ();
if (colormap)
@@ -951,9 +966,12 @@ gtk_window_set_property (GObject *object,
GParamSpec *pspec)
{
GtkWindow *window;
+ GtkWindowPrivate *priv;
window = GTK_WINDOW (object);
+ priv = GTK_WINDOW_GET_PRIVATE (window);
+
switch (prop_id)
{
case PROP_TYPE:
@@ -1050,6 +1068,9 @@ gtk_window_set_property (GObject *object,
case PROP_OPACITY:
gtk_window_set_opacity (window, g_value_get_double (value));
break;
+ case PROP_MNEMONICS_VISIBLE:
+ gtk_window_set_mnemonics_visible (window, g_value_get_boolean (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1165,6 +1186,9 @@ gtk_window_get_property (GObject *object,
case PROP_OPACITY:
g_value_set_double (value, gtk_window_get_opacity (window));
break;
+ case PROP_MNEMONICS_VISIBLE:
+ g_value_set_boolean (value, priv->mnemonics_visible);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -4537,6 +4561,7 @@ gtk_window_map (GtkWidget *widget)
GtkWindow *window = GTK_WINDOW (widget);
GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
GdkWindow *toplevel;
+ gboolean auto_mnemonics;
GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
@@ -4612,6 +4637,14 @@ gtk_window_map (GtkWidget *widget)
gdk_notify_startup_complete ();
}
}
+
+ /* if auto-mnemonics is enabled and mnemonics visible is not already set
+ * (as in the case of popup menus), then hide mnemonics initially
+ */
+ g_object_get (gtk_widget_get_settings (widget), "gtk-auto-mnemonics",
+ &auto_mnemonics, NULL);
+ if (auto_mnemonics && !priv->mnemonics_visible_set)
+ gtk_window_set_mnemonics_visible (window, FALSE);
}
static gboolean
@@ -5288,10 +5321,18 @@ gtk_window_focus_out_event (GtkWidget *widget,
GdkEventFocus *event)
{
GtkWindow *window = GTK_WINDOW (widget);
+ gboolean auto_mnemonics;
_gtk_window_set_has_toplevel_focus (window, FALSE);
_gtk_window_set_is_active (window, FALSE);
+ /* set the mnemonic-visible property to false */
+ g_object_get (gtk_widget_get_settings (widget),
+ "gtk-auto-mnemonics", &auto_mnemonics, NULL);
+ if (auto_mnemonics)
+ gtk_window_set_mnemonics_visible (window, FALSE);
+
+
return FALSE;
}
@@ -8432,6 +8473,55 @@ gtk_window_get_window_type (GtkWindow *window)
return window->type;
}
+gboolean
+gtk_window_get_mnemonics_visible (GtkWindow *window)
+{
+ GtkWindowPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
+
+ priv = GTK_WINDOW_GET_PRIVATE (window);
+
+ return priv->mnemonics_visible;
+}
+
+void
+gtk_window_set_mnemonics_visible (GtkWindow *window,
+ gboolean setting)
+{
+ GtkWindowPrivate *priv;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
+ priv = GTK_WINDOW_GET_PRIVATE (window);
+
+ setting = setting != FALSE;
+
+ if (priv->mnemonics_visible != setting)
+ {
+ priv->mnemonics_visible = setting;
+ g_object_notify (G_OBJECT (window), "mnemonics-visible");
+ }
+
+ priv->mnemonics_visible_set = TRUE;
+}
+
+static void
+gtk_window_grab_notify (GtkWidget *widget,
+ gboolean was_grabbed)
+{
+ gboolean auto_mnemonics;
+
+ if (was_grabbed)
+ return;
+
+ g_object_get (gtk_widget_get_settings (widget), "gtk-auto-mnemonics",
+ &auto_mnemonics, NULL);
+
+ if (auto_mnemonics)
+ gtk_window_set_mnemonics_visible (GTK_WINDOW (widget), FALSE);
+}
+
#if defined (G_OS_WIN32) && !defined (_WIN64)
#undef gtk_window_set_icon_from_file
diff --git a/gtk/gtkwindow.h b/gtk/gtkwindow.h
index dc59dfe08a..1b4362feaa 100644
--- a/gtk/gtkwindow.h
+++ b/gtk/gtkwindow.h
@@ -230,6 +230,9 @@ gboolean gtk_window_get_focus_on_map (GtkWindow *window);
void gtk_window_set_destroy_with_parent (GtkWindow *window,
gboolean setting);
gboolean gtk_window_get_destroy_with_parent (GtkWindow *window);
+void gtk_window_set_mnemonics_visible (GtkWindow *window,
+ gboolean setting);
+gboolean gtk_window_get_mnemonics_visible (GtkWindow *window);
void gtk_window_set_resizable (GtkWindow *window,
gboolean resizable);