[gtk+] gtkwindow: Use actions from focused widget to activate accel



commit 235837ad4932e60f46db97934be1dfb5200e185e
Author: Carlos Soriano <carlos sorian89 gmail com>
Date:   Wed Dec 3 15:53:59 2014 +0100

    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

 gtk/gtkactionhelper.c   |    2 +-
 gtk/gtkmenusectionbox.c |    2 +-
 gtk/gtkmenushell.c      |    2 +-
 gtk/gtkwidget.c         |   59 +++++++++++++++++++++++++++--------------------
 gtk/gtkwidgetprivate.h  |    3 +-
 gtk/gtkwindow.c         |    7 ++++-
 6 files changed, 45 insertions(+), 30 deletions(-)
---
diff --git a/gtk/gtkactionhelper.c b/gtk/gtkactionhelper.c
index a9276d5..50060ee 100644
--- a/gtk/gtkactionhelper.c
+++ b/gtk/gtkactionhelper.c
@@ -397,7 +397,7 @@ gtk_action_helper_new (GtkActionable *widget)
         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;
 }
diff --git a/gtk/gtkmenusectionbox.c b/gtk/gtkmenusectionbox.c
index 9905fa7..e6b9374 100644
--- a/gtk/gtkmenusectionbox.c
+++ b/gtk/gtkmenusectionbox.c
@@ -379,7 +379,7 @@ gtk_menu_section_box_new_toplevel (GtkStack    *stack,
   box = g_object_new (GTK_TYPE_MENU_SECTION_BOX, "margin", 10,  NULL);
   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,
                                        gtk_menu_section_box_insert_func,
                                        gtk_menu_section_box_remove_func, box);
diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c
index d1d0c7f..939d5f4 100644
--- a/gtk/gtkmenushell.c
+++ b/gtk/gtkmenushell.c
@@ -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 (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);
 
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index f0f2f6a..50ca98b 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -16481,45 +16481,54 @@ _gtk_widget_set_style (GtkWidget *widget,
   widget->priv->style = style;
 }
 
-void
-_gtk_widget_update_parent_muxer (GtkWidget *widget)
+GtkActionMuxer *
+_gtk_widget_get_parent_muxer (GtkWidget *widget,
+                              gboolean   create)
 {
-  GtkActionMuxer *parent_muxer;
-
-  if (widget->priv->muxer == NULL)
-    return;
+  GtkWidget *parent;
 
   if (GTK_IS_WINDOW (widget))
-    {
-      parent_muxer = gtk_application_get_parent_muxer_for_window (GTK_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
-    {
-      GtkWidget *parent;
+    parent = gtk_widget_get_parent (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);
 
-      parent_muxer = parent ? _gtk_widget_get_action_muxer (parent) : NULL;
-    }
+  return NULL;
+}
+
+void
+_gtk_widget_update_parent_muxer (GtkWidget *widget)
+{
+  if (widget->priv->muxer == NULL)
+    return;
 
-  gtk_action_muxer_set_parent (widget->priv->muxer, parent_muxer);
+  gtk_action_muxer_set_parent (widget->priv->muxer,
+                               _gtk_widget_get_parent_muxer (widget, TRUE));
 }
 
 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 ();
       _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 (name != NULL);
 
-  muxer = _gtk_widget_get_action_muxer (widget);
+  muxer = _gtk_widget_get_action_muxer (widget, TRUE);
 
   if (group)
     gtk_action_muxer_insert (muxer, name, group);
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index 6eddbb4..6fd7a63 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -151,7 +151,8 @@ void              _gtk_widget_invalidate_style_context     (GtkWidget    *widget
 void              _gtk_widget_style_context_invalidated    (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);
 GActionGroup *    _gtk_widget_get_action_group             (GtkWidget    *widget,
                                                             const gchar  *prefix);
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 16f7e04..842a5ff 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -11214,7 +11214,12 @@ gtk_window_activate_key (GtkWindow   *window,
 
               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,
                                                          G_ACTION_GROUP (muxer),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]