mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-19 01:40:10 +00:00
Improve the behaviour of automatic mnemonics
With this change, key events continue to go to an open menu even when the pointer is moved over a non-selectable menuitem. The mnemonics are shown and hidden accordingly.
This commit is contained in:
parent
f3f44d6650
commit
a085bb1f0b
@ -3262,7 +3262,10 @@ gtk_menu_motion_notify (GtkWidget *widget,
|
||||
*/
|
||||
if (!_gtk_menu_item_is_selectable (menu_item))
|
||||
{
|
||||
gtk_menu_shell_deselect (menu_shell);
|
||||
/* We really want to deselect, but this gives the menushell code
|
||||
* a chance to do some bookkeeping about the menuitem.
|
||||
*/
|
||||
gtk_menu_shell_select_item (menu_shell, menu_item);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -137,6 +137,10 @@ struct _GtkMenuShellPrivate
|
||||
|
||||
guint take_focus : 1;
|
||||
guint activated_submenu : 1;
|
||||
/* This flag is a crutch to keep mnemonics in the same menu
|
||||
* if the user moves the mouse over an unselectable menuitem.
|
||||
*/
|
||||
guint in_unselectable_item : 1;
|
||||
};
|
||||
|
||||
static void gtk_menu_shell_set_property (GObject *object,
|
||||
@ -805,6 +809,7 @@ _gtk_menu_shell_update_mnemonics (GtkMenuShell *menu_shell)
|
||||
found = FALSE;
|
||||
while (target)
|
||||
{
|
||||
GtkMenuShellPrivate *priv = GTK_MENU_SHELL_GET_PRIVATE (target);
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (target));
|
||||
|
||||
/* The idea with keyboard mode is that once you start using
|
||||
@ -824,7 +829,7 @@ _gtk_menu_shell_update_mnemonics (GtkMenuShell *menu_shell)
|
||||
* dismissing menus.
|
||||
*/
|
||||
mnemonics_visible = target->keyboard_mode &&
|
||||
((target->active_menu_item && !found) ||
|
||||
(((target->active_menu_item || priv->in_unselectable_item) && !found) ||
|
||||
(target == menu_shell &&
|
||||
!target->parent_menu_shell &&
|
||||
gtk_widget_has_grab (GTK_WIDGET (target))));
|
||||
@ -841,7 +846,7 @@ _gtk_menu_shell_update_mnemonics (GtkMenuShell *menu_shell)
|
||||
else
|
||||
gtk_window_set_mnemonics_visible (GTK_WINDOW (toplevel), mnemonics_visible);
|
||||
|
||||
if (target->active_menu_item)
|
||||
if (target->active_menu_item || priv->in_unselectable_item)
|
||||
found = TRUE;
|
||||
|
||||
target = GTK_MENU_SHELL (target->parent_menu_shell);
|
||||
@ -853,11 +858,12 @@ gtk_menu_shell_key_press (GtkWidget *widget,
|
||||
GdkEventKey *event)
|
||||
{
|
||||
GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget);
|
||||
GtkMenuShellPrivate *priv = GTK_MENU_SHELL_GET_PRIVATE (menu_shell);
|
||||
gboolean enable_mnemonics;
|
||||
|
||||
menu_shell->keyboard_mode = TRUE;
|
||||
|
||||
if (!menu_shell->active_menu_item && menu_shell->parent_menu_shell)
|
||||
if (!(menu_shell->active_menu_item || priv->in_unselectable_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))
|
||||
@ -890,11 +896,20 @@ gtk_menu_shell_enter_notify (GtkWidget *widget,
|
||||
|
||||
menu_item = gtk_get_event_widget ((GdkEvent*) event);
|
||||
|
||||
if (!menu_item ||
|
||||
(GTK_IS_MENU_ITEM (menu_item) &&
|
||||
!_gtk_menu_item_is_selectable (menu_item)))
|
||||
if (!menu_item)
|
||||
return TRUE;
|
||||
|
||||
if (GTK_IS_MENU_ITEM (menu_item) &&
|
||||
!_gtk_menu_item_is_selectable (menu_item))
|
||||
{
|
||||
GtkMenuShellPrivate *priv;
|
||||
|
||||
priv = GTK_MENU_SHELL_GET_PRIVATE (menu_shell);
|
||||
priv->in_unselectable_item = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (menu_item->parent == widget &&
|
||||
GTK_IS_MENU_ITEM (menu_item))
|
||||
{
|
||||
@ -966,7 +981,14 @@ gtk_menu_shell_leave_notify (GtkWidget *widget,
|
||||
menu_item = GTK_MENU_ITEM (event_widget);
|
||||
|
||||
if (!_gtk_menu_item_is_selectable (event_widget))
|
||||
{
|
||||
GtkMenuShellPrivate *priv;
|
||||
|
||||
priv = GTK_MENU_SHELL_GET_PRIVATE (menu_shell);
|
||||
priv->in_unselectable_item = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((menu_shell->active_menu_item == event_widget) &&
|
||||
(menu_item->submenu == NULL))
|
||||
@ -1149,7 +1171,14 @@ gtk_menu_shell_real_select_item (GtkMenuShell *menu_shell,
|
||||
gtk_menu_shell_deselect (menu_shell);
|
||||
|
||||
if (!_gtk_menu_item_is_selectable (menu_item))
|
||||
{
|
||||
GtkMenuShellPrivate *priv = GTK_MENU_SHELL_GET_PRIVATE (menu_shell);
|
||||
|
||||
priv->in_unselectable_item = TRUE;
|
||||
_gtk_menu_shell_update_mnemonics (menu_shell);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
menu_shell->active_menu_item = menu_item;
|
||||
if (pack_dir == GTK_PACK_DIRECTION_TTB || pack_dir == GTK_PACK_DIRECTION_BTT)
|
||||
@ -1396,10 +1425,13 @@ static void
|
||||
gtk_real_menu_shell_move_current (GtkMenuShell *menu_shell,
|
||||
GtkMenuDirectionType direction)
|
||||
{
|
||||
GtkMenuShellPrivate *priv = GTK_MENU_SHELL_GET_PRIVATE (menu_shell);
|
||||
GtkMenuShell *parent_menu_shell = NULL;
|
||||
gboolean had_selection;
|
||||
gboolean touchscreen_mode;
|
||||
|
||||
priv->in_unselectable_item = FALSE;
|
||||
|
||||
had_selection = menu_shell->active_menu_item != NULL;
|
||||
|
||||
g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu_shell)),
|
||||
|
Loading…
Reference in New Issue
Block a user