gtkwindow: Use actions from focused widget to activate accel

Currently we only take into account the window GActionGroup for
activating the accels.

However, the application could have some custom GActionGroup in the
chain of focused widgets that could want to activate some action if
some accel is activated while that widget is focused.

To allow applications to set accels on widgets that use custom
GActionGroups, simply use the muxer of the focused widget, which
already contains the actions of the parents.

https://bugzilla.gnome.org/show_bug.cgi?id=740682
This commit is contained in:
Carlos Soriano 2014-12-03 15:53:59 +01:00 committed by Christian Hergert
parent 17fec70022
commit 235837ad49
6 changed files with 46 additions and 31 deletions

View File

@ -397,7 +397,7 @@ gtk_action_helper_new (GtkActionable *widget)
g_object_get (G_OBJECT (helper->widget), "active", &helper->active, NULL); g_object_get (G_OBJECT (helper->widget), "active", &helper->active, NULL);
} }
helper->action_context = _gtk_widget_get_action_muxer (GTK_WIDGET (widget)); helper->action_context = _gtk_widget_get_action_muxer (GTK_WIDGET (widget), TRUE);
return helper; return helper;
} }

View File

@ -379,7 +379,7 @@ gtk_menu_section_box_new_toplevel (GtkStack *stack,
box = g_object_new (GTK_TYPE_MENU_SECTION_BOX, "margin", 10, NULL); box = g_object_new (GTK_TYPE_MENU_SECTION_BOX, "margin", 10, NULL);
gtk_stack_add_named (stack, GTK_WIDGET (box), "main"); gtk_stack_add_named (stack, GTK_WIDGET (box), "main");
box->tracker = gtk_menu_tracker_new (GTK_ACTION_OBSERVABLE (_gtk_widget_get_action_muxer (GTK_WIDGET (box))), box->tracker = gtk_menu_tracker_new (GTK_ACTION_OBSERVABLE (_gtk_widget_get_action_muxer (GTK_WIDGET (box), TRUE)),
model, TRUE, FALSE, action_namespace, model, TRUE, FALSE, action_namespace,
gtk_menu_section_box_insert_func, gtk_menu_section_box_insert_func,
gtk_menu_section_box_remove_func, box); gtk_menu_section_box_remove_func, box);

View File

@ -2194,7 +2194,7 @@ gtk_menu_shell_bind_model (GtkMenuShell *menu_shell,
g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell));
g_return_if_fail (model == NULL || G_IS_MENU_MODEL (model)); g_return_if_fail (model == NULL || G_IS_MENU_MODEL (model));
muxer = _gtk_widget_get_action_muxer (GTK_WIDGET (menu_shell)); muxer = _gtk_widget_get_action_muxer (GTK_WIDGET (menu_shell), TRUE);
g_clear_pointer (&menu_shell->priv->tracker, gtk_menu_tracker_free); g_clear_pointer (&menu_shell->priv->tracker, gtk_menu_tracker_free);

View File

@ -16481,45 +16481,54 @@ _gtk_widget_set_style (GtkWidget *widget,
widget->priv->style = style; widget->priv->style = style;
} }
GtkActionMuxer *
_gtk_widget_get_parent_muxer (GtkWidget *widget,
gboolean create)
{
GtkWidget *parent;
if (GTK_IS_WINDOW (widget))
return gtk_application_get_parent_muxer_for_window (GTK_WINDOW (widget));
if (GTK_IS_MENU (widget))
parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
else if (GTK_IS_POPOVER (widget))
parent = gtk_popover_get_relative_to (GTK_POPOVER (widget));
else
parent = gtk_widget_get_parent (widget);
if (parent)
return _gtk_widget_get_action_muxer (parent, create);
return NULL;
}
void void
_gtk_widget_update_parent_muxer (GtkWidget *widget) _gtk_widget_update_parent_muxer (GtkWidget *widget)
{ {
GtkActionMuxer *parent_muxer;
if (widget->priv->muxer == NULL) if (widget->priv->muxer == NULL)
return; return;
if (GTK_IS_WINDOW (widget)) gtk_action_muxer_set_parent (widget->priv->muxer,
{ _gtk_widget_get_parent_muxer (widget, TRUE));
parent_muxer = gtk_application_get_parent_muxer_for_window (GTK_WINDOW (widget));
}
else
{
GtkWidget *parent;
if (GTK_IS_MENU (widget))
parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
else if (GTK_IS_POPOVER (widget))
parent = gtk_popover_get_relative_to (GTK_POPOVER (widget));
else
parent = gtk_widget_get_parent (widget);
parent_muxer = parent ? _gtk_widget_get_action_muxer (parent) : NULL;
}
gtk_action_muxer_set_parent (widget->priv->muxer, parent_muxer);
} }
GtkActionMuxer * GtkActionMuxer *
_gtk_widget_get_action_muxer (GtkWidget *widget) _gtk_widget_get_action_muxer (GtkWidget *widget,
gboolean create)
{ {
if (widget->priv->muxer == NULL) if (widget->priv->muxer)
return widget->priv->muxer;
if (create)
{ {
widget->priv->muxer = gtk_action_muxer_new (); widget->priv->muxer = gtk_action_muxer_new ();
_gtk_widget_update_parent_muxer (widget); _gtk_widget_update_parent_muxer (widget);
}
return widget->priv->muxer; return widget->priv->muxer;
}
else
return _gtk_widget_get_parent_muxer (widget, FALSE);
} }
/** /**
@ -16548,7 +16557,7 @@ gtk_widget_insert_action_group (GtkWidget *widget,
g_return_if_fail (GTK_IS_WIDGET (widget)); g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (name != NULL); g_return_if_fail (name != NULL);
muxer = _gtk_widget_get_action_muxer (widget); muxer = _gtk_widget_get_action_muxer (widget, TRUE);
if (group) if (group)
gtk_action_muxer_insert (muxer, name, group); gtk_action_muxer_insert (muxer, name, group);

View File

@ -151,7 +151,8 @@ void _gtk_widget_invalidate_style_context (GtkWidget *widget
void _gtk_widget_style_context_invalidated (GtkWidget *widget); void _gtk_widget_style_context_invalidated (GtkWidget *widget);
void _gtk_widget_update_parent_muxer (GtkWidget *widget); void _gtk_widget_update_parent_muxer (GtkWidget *widget);
GtkActionMuxer * _gtk_widget_get_action_muxer (GtkWidget *widget); GtkActionMuxer * _gtk_widget_get_action_muxer (GtkWidget *widget,
gboolean create);
gchar ** _gtk_widget_list_action_prefixes (GtkWidget *widget); gchar ** _gtk_widget_list_action_prefixes (GtkWidget *widget);
GActionGroup * _gtk_widget_get_action_group (GtkWidget *widget, GActionGroup * _gtk_widget_get_action_group (GtkWidget *widget,
const gchar *prefix); const gchar *prefix);

View File

@ -11214,7 +11214,12 @@ gtk_window_activate_key (GtkWindow *window,
if (window->priv->application) if (window->priv->application)
{ {
GtkActionMuxer *muxer = _gtk_widget_get_action_muxer (GTK_WIDGET (window)); GtkWidget *focused_widget = gtk_window_get_focus (window);
if (focused_widget == NULL)
return FALSE;
GtkActionMuxer *muxer = _gtk_widget_get_action_muxer (focused_widget, FALSE);
if (muxer == NULL)
return FALSE;
return gtk_application_activate_accel (window->priv->application, return gtk_application_activate_accel (window->priv->application,
G_ACTION_GROUP (muxer), G_ACTION_GROUP (muxer),