[gtk/action-muxer-speedup: 8/11] inspector: Make the actions tab work again



commit 01dff4dcfd0a46ff57d80502fafa474a3f7060fe
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Jul 19 01:56:00 2020 -0400

    inspector: Make the actions tab work again
    
    Bring back the actions tab; we don't receive
    changes anymore, since GtkActionMuxer lost
    the GActionGroup signals for this, and the
    action observer machinery has no way to listen
    for all changes.

 gtk/inspector/action-editor.c |  63 ++++++++-----
 gtk/inspector/action-editor.h |   2 +-
 gtk/inspector/action-holder.c |  16 ++--
 gtk/inspector/action-holder.h |   6 +-
 gtk/inspector/actions.c       | 210 ++++++++++++++++--------------------------
 5 files changed, 131 insertions(+), 166 deletions(-)
---
diff --git a/gtk/inspector/action-editor.c b/gtk/inspector/action-editor.c
index 2617dad9f9..6e01cf1b12 100644
--- a/gtk/inspector/action-editor.c
+++ b/gtk/inspector/action-editor.c
@@ -27,12 +27,13 @@
 #include "gtkbox.h"
 #include "gtkboxlayout.h"
 #include "gtkorientable.h"
+#include "gtkactionmuxerprivate.h"
 
 struct _GtkInspectorActionEditor
 {
   GtkWidget parent;
 
-  GActionGroup *group;
+  GObject *owner;
   gchar *name;
   gboolean enabled;
   const GVariantType *parameter_type;
@@ -51,7 +52,7 @@ typedef struct
 enum
 {
   PROP_0,
-  PROP_GROUP,
+  PROP_OWNER,
   PROP_NAME,
   PROP_SIZEGROUP
 };
@@ -208,7 +209,10 @@ activate_action (GtkWidget                *button,
 
   if (r->parameter_entry)
     parameter = variant_editor_get_value (r->parameter_entry);
-  g_action_group_activate_action (r->group, r->name, parameter);
+  if (G_IS_ACTION_GROUP (r->owner))
+    g_action_group_activate_action (G_ACTION_GROUP (r->owner), r->name, parameter);
+  else if (GTK_IS_ACTION_MUXER (r->owner))
+    gtk_action_muxer_activate_action (GTK_ACTION_MUXER (r->owner), r->name, parameter);
 }
 
 static void
@@ -233,7 +237,12 @@ state_changed (GtkWidget *editor,
 
   value = variant_editor_get_value (editor);
   if (value)
-    g_action_group_change_action_state (r->group, r->name, value);
+    {
+      if (G_IS_ACTION_GROUP (r->owner))
+        g_action_group_change_action_state (G_ACTION_GROUP (r->owner), r->name, value);
+      else if (GTK_IS_ACTION_MUXER (r->owner))
+        gtk_action_muxer_change_action_state (GTK_ACTION_MUXER (r->owner), r->name, value);
+    }
 }
 
 static void
@@ -287,8 +296,16 @@ constructed (GObject *object)
   GtkWidget *activate;
   GtkWidget *label;
 
-  r->enabled = g_action_group_get_action_enabled (r->group, r->name);
-  state = g_action_group_get_action_state (r->group, r->name);
+  if (G_IS_ACTION_GROUP (r->owner))
+    g_action_group_query_action (G_ACTION_GROUP (r->owner), r->name,
+                                 &r->enabled, &r->parameter_type, NULL, NULL,
+                                 &state);
+  else if (GTK_IS_ACTION_MUXER (r->owner))
+    gtk_action_muxer_query_action (GTK_ACTION_MUXER (r->owner), r->name,
+                                   &r->enabled, &r->parameter_type, NULL, NULL,
+                                   &state);
+  else
+    state = NULL;
 
   row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
   activate = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
@@ -302,7 +319,6 @@ constructed (GObject *object)
   gtk_widget_set_sensitive (r->activate_button, r->enabled);
   gtk_box_append (GTK_BOX (activate), r->activate_button);
 
-  r->parameter_type = g_action_group_get_action_parameter_type (r->group, r->name);
   if (r->parameter_type)
     {
       r->parameter_entry = variant_editor_new (r->parameter_type, parameter_changed, r);
@@ -326,10 +342,13 @@ constructed (GObject *object)
       gtk_widget_set_parent (row, GTK_WIDGET (r));
     }
 
-  g_signal_connect (r->group, "action-enabled-changed",
-                    G_CALLBACK (action_enabled_changed_cb), r);
-  g_signal_connect (r->group, "action-state-changed",
-                    G_CALLBACK (action_state_changed_cb), r);
+  if (G_IS_ACTION_GROUP (r->owner))
+    {
+      g_signal_connect (r->owner, "action-enabled-changed",
+                        G_CALLBACK (action_enabled_changed_cb), r);
+      g_signal_connect (r->owner, "action-state-changed",
+                        G_CALLBACK (action_state_changed_cb), r);
+    }
 }
 
 static void
@@ -342,8 +361,8 @@ dispose (GObject *object)
   g_clear_object (&r->sg);
   if (r->state_type)
     g_variant_type_free (r->state_type);
-  g_signal_handlers_disconnect_by_func (r->group, action_enabled_changed_cb, r);
-  g_signal_handlers_disconnect_by_func (r->group, action_state_changed_cb, r);
+  g_signal_handlers_disconnect_by_func (r->owner, action_enabled_changed_cb, r);
+  g_signal_handlers_disconnect_by_func (r->owner, action_state_changed_cb, r);
 
   while ((child = gtk_widget_get_first_child (GTK_WIDGET (r))))
     gtk_widget_unparent (child);
@@ -361,8 +380,8 @@ get_property (GObject    *object,
 
   switch (param_id)
     {
-    case PROP_GROUP:
-      g_value_set_object (value, r->group);
+    case PROP_OWNER:
+      g_value_set_object (value, r->owner);
       break;
 
     case PROP_NAME:
@@ -389,8 +408,8 @@ set_property (GObject      *object,
 
   switch (param_id)
     {
-    case PROP_GROUP:
-      r->group = g_value_get_object (value);
+    case PROP_OWNER:
+      r->owner = g_value_get_object (value);
       break;
 
     case PROP_NAME:
@@ -419,9 +438,9 @@ gtk_inspector_action_editor_class_init (GtkInspectorActionEditorClass *klass)
   object_class->get_property = get_property;
   object_class->set_property = set_property;
 
-  g_object_class_install_property (object_class, PROP_GROUP,
-      g_param_spec_object ("group", "Action Group", "The Action Group containing the action",
-                           G_TYPE_ACTION_GROUP, G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
+  g_object_class_install_property (object_class, PROP_OWNER,
+      g_param_spec_object ("owner", "Owner", "The owner of the action",
+                           G_TYPE_OBJECT, G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (object_class, PROP_NAME,
       g_param_spec_string ("name", "Name", "The action name",
@@ -434,12 +453,12 @@ gtk_inspector_action_editor_class_init (GtkInspectorActionEditorClass *klass)
 }
 
 GtkWidget *
-gtk_inspector_action_editor_new (GActionGroup *group,
+gtk_inspector_action_editor_new (GObject      *owner,
                                  const gchar  *name,
                                  GtkSizeGroup *activate)
 {
   return g_object_new (GTK_TYPE_INSPECTOR_ACTION_EDITOR,
-                       "group", group,
+                       "owner", owner,
                        "name", name,
                        "sizegroup", activate,
                        NULL);
diff --git a/gtk/inspector/action-editor.h b/gtk/inspector/action-editor.h
index d767229cf4..5940008a56 100644
--- a/gtk/inspector/action-editor.h
+++ b/gtk/inspector/action-editor.h
@@ -33,7 +33,7 @@ typedef struct _GtkInspectorActionEditor GtkInspectorActionEditor;
 G_BEGIN_DECLS
 
 GType      gtk_inspector_action_editor_get_type (void);
-GtkWidget *gtk_inspector_action_editor_new      (GActionGroup *group,
+GtkWidget *gtk_inspector_action_editor_new      (GObject      *owner,
                                                  const gchar  *name,
                                                  GtkSizeGroup *activate);
 void       gtk_inspector_action_editor_update   (GtkInspectorActionEditor *r,
diff --git a/gtk/inspector/action-holder.c b/gtk/inspector/action-holder.c
index fafef70c93..199741e3d2 100644
--- a/gtk/inspector/action-holder.c
+++ b/gtk/inspector/action-holder.c
@@ -4,7 +4,7 @@
 struct _ActionHolder {
   GObject instance;
 
-  GActionGroup *group;
+  GObject *owner;
   char *name;
 };
 
@@ -20,7 +20,7 @@ action_holder_finalize (GObject *object)
 {
   ActionHolder *holder = ACTION_HOLDER (object);
 
-  g_object_unref (holder->group);
+  g_object_unref (holder->owner);
   g_free (holder->name);
 
   G_OBJECT_CLASS (action_holder_parent_class)->finalize (object);
@@ -35,23 +35,23 @@ action_holder_class_init (ActionHolderClass *class)
 }
 
 ActionHolder *
-action_holder_new (GActionGroup *group,
-                   const char   *name)
+action_holder_new (GObject    *owner,
+                   const char *name)
 {
   ActionHolder *holder;
 
   holder = g_object_new (ACTION_TYPE_HOLDER, NULL);
 
-  holder->group = g_object_ref (group);
+  holder->owner = g_object_ref (owner);
   holder->name = g_strdup (name);
 
   return holder;
 }
 
-GActionGroup *
-action_holder_get_group (ActionHolder *holder)
+GObject *
+action_holder_get_owner (ActionHolder *holder)
 {
-  return holder->group;
+  return holder->owner;
 }
 
 const char *
diff --git a/gtk/inspector/action-holder.h b/gtk/inspector/action-holder.h
index b18df67c03..a3294e835d 100644
--- a/gtk/inspector/action-holder.h
+++ b/gtk/inspector/action-holder.h
@@ -8,10 +8,10 @@
 
 G_DECLARE_FINAL_TYPE (ActionHolder, action_holder, ACTION, HOLDER, GObject)
 
-ActionHolder * action_holder_new     (GActionGroup *group,
-                                      const char   *name);
+ActionHolder * action_holder_new     (GObject    *owner,
+                                      const char *name);
 
-GActionGroup *action_holder_get_group (ActionHolder *holder);
+GObject      *action_holder_get_owner (ActionHolder *holder);
 const char   *action_holder_get_name  (ActionHolder *holder);
 
 #endif /* __ACTION_HOLDER_H__ */
diff --git a/gtk/inspector/actions.c b/gtk/inspector/actions.c
index 467af310e8..0819f66f9a 100644
--- a/gtk/inspector/actions.c
+++ b/gtk/inspector/actions.c
@@ -44,7 +44,8 @@ struct _GtkInspectorActions
   GtkWidget *list;
   GtkWidget *button;
 
-  GActionGroup *group;
+  GObject *object;
+
   GListModel *actions;
   GtkColumnViewColumn *name;
 };
@@ -73,16 +74,15 @@ gtk_inspector_actions_init (GtkInspectorActions *sl)
 }
 
 static void
-action_added_cb (GActionGroup        *group,
-                 const gchar         *action_name,
-                 GtkInspectorActions *sl)
+action_added (GObject             *owner,
+              const gchar         *action_name,
+              GtkInspectorActions *sl)
 {
-  ActionHolder *holder = action_holder_new (group, action_name);
+  ActionHolder *holder = action_holder_new (owner, action_name);
   g_list_store_append (G_LIST_STORE (sl->actions), holder);
   g_object_unref (holder);
 }
 
-
 static void
 setup_name_cb (GtkSignalListItemFactory *factory,
                GtkListItem              *list_item)
@@ -124,16 +124,20 @@ bind_enabled_cb (GtkSignalListItemFactory *factory,
 {
   gpointer item;
   GtkWidget *label;
-  GActionGroup *group;
+  GObject *owner;
   const char *name;
-  gboolean enabled;
+  gboolean enabled = FALSE;
 
   item = gtk_list_item_get_item (list_item);
   label = gtk_list_item_get_child (list_item);
 
-  group = action_holder_get_group (ACTION_HOLDER (item));
+  owner = action_holder_get_owner (ACTION_HOLDER (item));
   name = action_holder_get_name (ACTION_HOLDER (item));
-  enabled = g_action_group_get_action_enabled (group, name);
+  if (G_IS_ACTION_GROUP (owner))
+    enabled = g_action_group_get_action_enabled (G_ACTION_GROUP (owner), name);
+  else if (GTK_IS_ACTION_MUXER (owner))
+    gtk_action_muxer_query_action (GTK_ACTION_MUXER (owner), name,
+                                   &enabled, NULL, NULL, NULL, NULL);
 
   gtk_label_set_label (GTK_LABEL (label), enabled ? "+" : "-");
 }
@@ -156,16 +160,20 @@ bind_parameter_cb (GtkSignalListItemFactory *factory,
 {
   gpointer item;
   GtkWidget *label;
-  GActionGroup *group;
+  GObject *owner;
   const char *name;
   const char *parameter;
 
   item = gtk_list_item_get_item (list_item);
   label = gtk_list_item_get_child (list_item);
 
-  group = action_holder_get_group (ACTION_HOLDER (item));
+  owner = action_holder_get_owner (ACTION_HOLDER (item));
   name = action_holder_get_name (ACTION_HOLDER (item));
-  parameter = (const gchar *)g_action_group_get_action_parameter_type (group, name);
+  if (G_IS_ACTION_GROUP (owner))
+    parameter = (const gchar *)g_action_group_get_action_parameter_type (G_ACTION_GROUP (owner), name);
+  else if (GTK_IS_ACTION_MUXER (owner))
+    gtk_action_muxer_query_action (GTK_ACTION_MUXER (owner), name,
+                                   NULL, (const GVariantType **)&parameter, NULL, NULL, NULL);
 
   gtk_label_set_label (GTK_LABEL (label), parameter);
 }
@@ -190,7 +198,7 @@ bind_state_cb (GtkSignalListItemFactory *factory,
 {
   gpointer item;
   GtkWidget *label;
-  GActionGroup *group;
+  GObject *owner;
   const char *name;
   GVariant *state;
   char *state_string;
@@ -198,9 +206,16 @@ bind_state_cb (GtkSignalListItemFactory *factory,
   item = gtk_list_item_get_item (list_item);
   label = gtk_list_item_get_child (list_item);
 
-  group = action_holder_get_group (ACTION_HOLDER (item));
+  owner = action_holder_get_owner (ACTION_HOLDER (item));
   name = action_holder_get_name (ACTION_HOLDER (item));
-  state = g_action_group_get_action_state (group, name);
+  if (G_IS_ACTION_GROUP (owner))
+    state = g_action_group_get_action_state (G_ACTION_GROUP (owner), name);
+  else if (GTK_IS_ACTION_MUXER (owner))
+    gtk_action_muxer_query_action (GTK_ACTION_MUXER (owner), name,
+                                   NULL, NULL, NULL, NULL, &state);
+  else
+    state = NULL;
+
   if (state)
     state_string = g_variant_print (state, FALSE);
   else
@@ -218,16 +233,16 @@ bind_changes_cb (GtkSignalListItemFactory *factory,
                  GtkListItem              *list_item)
 {
   gpointer item;
-  GActionGroup *group;
+  GObject *owner;
   const char *name;
   GtkWidget *editor;
 
   item = gtk_list_item_get_item (list_item);
 
-  group = action_holder_get_group (ACTION_HOLDER (item));
+  owner = action_holder_get_owner (ACTION_HOLDER (item));
   name = action_holder_get_name (ACTION_HOLDER (item));
 
-  editor = gtk_inspector_action_editor_new (group, name, NULL);
+  editor = gtk_inspector_action_editor_new (owner, name, NULL);
   gtk_widget_add_css_class (editor, "cell");
   gtk_list_item_set_child (list_item, editor);
 }
@@ -240,116 +255,60 @@ unbind_changes_cb (GtkSignalListItemFactory *factory,
 }
 
 static void
-action_removed_cb (GActionGroup        *group,
-                   const gchar         *action_name,
-                   GtkInspectorActions *sl)
-{
-  int i;
-
-  for (i = 0; i < g_list_model_get_n_items (sl->actions); i++)
-    {
-      ActionHolder *holder = g_list_model_get_item (sl->actions, i);
-
-      if (group == action_holder_get_group (holder) &&
-          strcmp (action_name, action_holder_get_name (holder)) == 0)
-        g_list_store_remove (G_LIST_STORE (sl->actions), i);
-
-      g_object_unref (holder);
-    }
-}
-
-static void
-notify_action_changed (GtkInspectorActions *sl,
-                       GActionGroup        *group,
-                       const char          *action_name)
-{
-  int i;
-
-  for (i = 0; i < g_list_model_get_n_items (sl->actions); i++)
-    {
-      ActionHolder *holder = g_list_model_get_item (sl->actions, i);
-
-      if (group == action_holder_get_group (holder) &&
-          strcmp (action_name, action_holder_get_name (holder)) == 0)
-        g_list_model_items_changed (sl->actions, i, 1, 1);
-
-      g_object_unref (holder);
-    }
-}
-
-static void
-action_enabled_changed_cb (GActionGroup        *group,
-                           const gchar         *action_name,
-                           gboolean             enabled,
-                           GtkInspectorActions *sl)
-{
-  notify_action_changed (sl, group, action_name);
-}
-
-static void
-action_state_changed_cb (GActionGroup        *group,
-                         const gchar         *action_name,
-                         GVariant            *state,
-                         GtkInspectorActions *sl)
+add_group (GtkInspectorActions *sl,
+           GActionGroup        *group)
 {
-  notify_action_changed (sl, group, action_name);
-}
+  gint i;
+  gchar **names;
 
-static void
-refresh_all (GtkInspectorActions *sl)
-{
-  guint n = g_list_model_get_n_items (sl->actions);
-  g_list_model_items_changed (sl->actions, 0, n, n);
+  names = g_action_group_list_actions (group);
+  for (i = 0; names[i]; i++)
+    action_added (G_OBJECT (group), names[i], sl);
+  g_strfreev (names);
 }
 
 static void
-connect_group (GActionGroup *group,
-               GtkInspectorActions *sl)
+add_muxer (GtkInspectorActions *sl,
+           GtkActionMuxer      *muxer)
 {
-  g_signal_connect (group, "action-added", G_CALLBACK (action_added_cb), sl);
-  g_signal_connect (group, "action-removed", G_CALLBACK (action_removed_cb), sl);
-  g_signal_connect (group, "action-enabled-changed", G_CALLBACK (action_enabled_changed_cb), sl);
-  g_signal_connect (group, "action-state-changed", G_CALLBACK (action_state_changed_cb), sl);
-}
+  gint i;
+  gchar **names;
 
-static void
-disconnect_group (GActionGroup *group,
-                  GtkInspectorActions *sl)
-{
-  g_signal_handlers_disconnect_by_func (group, action_added_cb, sl);
-  g_signal_handlers_disconnect_by_func (group, action_removed_cb, sl);
-  g_signal_handlers_disconnect_by_func (group, action_enabled_changed_cb, sl);
-  g_signal_handlers_disconnect_by_func (group, action_state_changed_cb, sl);
+  names = gtk_action_muxer_list_actions (muxer);
+  for (i = 0; names[i]; i++)
+    action_added (G_OBJECT (muxer), names[i], sl);
+  g_strfreev (names);
 }
 
-static void
-add_group (GtkInspectorActions *sl,
-           GtkStackPage        *page,
-           GActionGroup        *group)
+static gboolean
+reload (GtkInspectorActions *sl)
 {
-  gint i;
-  gchar **names;
-
-  g_object_set (page, "visible", TRUE, NULL);
+  g_list_store_remove_all (G_LIST_STORE (sl->actions));
 
-  connect_group (group, sl);
+  if (GTK_IS_APPLICATION (sl->object))
+    {
+      add_group (sl, G_ACTION_GROUP (sl->object));
+      return TRUE;
+    }
+  else if (GTK_IS_WIDGET (sl->object))
+    {
+      GtkActionMuxer *muxer;
 
-  names = g_action_group_list_actions (group);
-  for (i = 0; names[i]; i++)
-    action_added_cb (group, names[i], sl);
-  g_strfreev (names);
+      muxer = _gtk_widget_get_action_muxer (GTK_WIDGET (sl->object), FALSE);
+      if (muxer)
+        {
+          add_muxer (sl, muxer);
+          return TRUE;
+        }
+    }
 
-  g_set_object (&sl->group, group);
+  return FALSE;
 }
 
 static void
-remove_group (GtkInspectorActions *sl,
-              GtkStackPage        *page,
-              GActionGroup        *group)
+refresh_all (GtkInspectorActions *sl)
 {
-  disconnect_group (group, sl);
-
-  g_set_object (&sl->group, NULL);
+  reload (sl);
 }
 
 void
@@ -358,29 +317,15 @@ gtk_inspector_actions_set_object (GtkInspectorActions *sl,
 {
   GtkWidget *stack;
   GtkStackPage *page;
+  gboolean loaded;
 
   stack = gtk_widget_get_parent (GTK_WIDGET (sl));
   page = gtk_stack_get_page (GTK_STACK (stack), GTK_WIDGET (sl));
+  gtk_stack_page_set_visible (page, FALSE);
 
-  g_object_set (page, "visible", FALSE, NULL);
-
-  if (sl->group)
-    remove_group (sl, page, sl->group);
-
-  g_list_store_remove_all (G_LIST_STORE (sl->actions));
-
-  if (GTK_IS_APPLICATION (object))
-    add_group (sl, page, G_ACTION_GROUP (object));
-  else if (GTK_IS_WIDGET (object))
-    {
-#if 0
-      GtkActionMuxer *muxer;
-
-      muxer = _gtk_widget_get_action_muxer (GTK_WIDGET (object), FALSE);
-      if (muxer)
-        add_group (sl, page, G_ACTION_GROUP (muxer));
-#endif
-    }
+  g_set_object (&sl->object, object);
+  loaded = reload (sl);
+  gtk_stack_page_set_visible (page, loaded);
 
   gtk_column_view_sort_by_column (GTK_COLUMN_VIEW (sl->list), sl->name, GTK_SORT_ASCENDING);
 }
@@ -449,7 +394,7 @@ constructed (GObject *object)
                                                                NULL, NULL));
   gtk_column_view_column_set_sorter (sl->name, sorter);
   g_object_unref (sorter);
-  
+
   sl->actions = G_LIST_MODEL (g_list_store_new (ACTION_TYPE_HOLDER));
   sorted = G_LIST_MODEL (gtk_sort_list_model_new (sl->actions,
                                                   gtk_column_view_get_sorter (GTK_COLUMN_VIEW (sl->list))));
@@ -466,6 +411,7 @@ dispose (GObject *object)
   GtkWidget *child;
 
   g_clear_object (&sl->actions);
+  g_clear_object (&sl->object);
 
   while ((child = gtk_widget_get_first_child (GTK_WIDGET (sl))))
     gtk_widget_unparent (child);


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