From 14059afdf1ca61a5db93cb549dfdbfcd59648c06 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 19 Jul 2020 01:56:00 -0400 Subject: [PATCH] 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 | 216 +++++++++++++--------------------- 5 files changed, 134 insertions(+), 169 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 **)¶meter, 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); } @@ -239,117 +254,61 @@ unbind_changes_cb (GtkSignalListItemFactory *factory, gtk_list_item_set_child (list_item, NULL); } -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) -{ - notify_action_changed (sl, group, action_name); -} - -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); -} - -static void -connect_group (GActionGroup *group, - GtkInspectorActions *sl) -{ - 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); -} - -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); -} - static void add_group (GtkInspectorActions *sl, - GtkStackPage *page, GActionGroup *group) { gint i; gchar **names; - g_object_set (page, "visible", TRUE, NULL); - - connect_group (group, sl); - names = g_action_group_list_actions (group); for (i = 0; names[i]; i++) - action_added_cb (group, names[i], sl); + action_added (G_OBJECT (group), names[i], sl); g_strfreev (names); - - g_set_object (&sl->group, group); } static void -remove_group (GtkInspectorActions *sl, - GtkStackPage *page, - GActionGroup *group) +add_muxer (GtkInspectorActions *sl, + GtkActionMuxer *muxer) { - disconnect_group (group, sl); + gint i; + gchar **names; - g_set_object (&sl->group, NULL); + 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 gboolean +reload (GtkInspectorActions *sl) +{ + g_list_store_remove_all (G_LIST_STORE (sl->actions)); + + 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; + + muxer = _gtk_widget_get_action_muxer (GTK_WIDGET (sl->object), FALSE); + if (muxer) + { + add_muxer (sl, muxer); + return TRUE; + } + } + + return FALSE; +} + +static void +refresh_all (GtkInspectorActions *sl) +{ + 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);