[gtk/submenu-action-fixes: 1407/1409] menutrackeritem: Make submenu-actions work again




commit db2e5648c9103dcad8ab62ab7025ca83d58428ac
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Mar 8 00:45:35 2021 -0500

    menutrackeritem: Make submenu-actions work again
    
    This broke when GtkActionMuxer stopped being a
    GActionGroup.

 gtk/gtkmenutrackeritem.c | 125 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 81 insertions(+), 44 deletions(-)
---
diff --git a/gtk/gtkmenutrackeritem.c b/gtk/gtkmenutrackeritem.c
index 1f621ed3d1..134831fda6 100644
--- a/gtk/gtkmenutrackeritem.c
+++ b/gtk/gtkmenutrackeritem.c
@@ -809,13 +809,57 @@ gtk_menu_tracker_item_activated (GtkMenuTrackerItem *self)
     g_variant_unref (action_target);
 }
 
-typedef struct
-{
+typedef struct {
+  GObject parent;
+
   GtkMenuTrackerItem *item;
   char               *submenu_action;
   gboolean            first_time;
 } GtkMenuTrackerOpener;
 
+typedef struct {
+  GObjectClass parent_class;
+} GtkMenuTrackerOpenerClass;
+
+static void gtk_menu_tracker_opener_observer_iface_init (GtkActionObserverInterface *iface);
+
+GType gtk_menu_tracker_opener_get_type (void) G_GNUC_CONST;
+
+G_DEFINE_TYPE_WITH_CODE (GtkMenuTrackerOpener, gtk_menu_tracker_opener, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTION_OBSERVER, 
gtk_menu_tracker_opener_observer_iface_init))
+
+static void
+gtk_menu_tracker_opener_init (GtkMenuTrackerOpener *self)
+{
+}
+
+static void
+gtk_menu_tracker_opener_finalize (GObject *object)
+{
+  GtkMenuTrackerOpener *opener = (GtkMenuTrackerOpener *)object;
+
+  gtk_action_observable_unregister_observer (opener->item->observable,
+                                             opener->submenu_action,
+                                             (GtkActionObserver *)opener);
+
+  if (GTK_IS_ACTION_MUXER (opener->item->observable))
+    gtk_action_muxer_change_action_state (GTK_ACTION_MUXER (opener->item->observable),
+                                          opener->submenu_action,
+                                          g_variant_new_boolean (FALSE));
+
+  gtk_menu_tracker_item_set_submenu_shown (opener->item, FALSE);
+
+  g_free (opener->submenu_action);
+
+  G_OBJECT_CLASS (gtk_menu_tracker_opener_parent_class)->finalize (object);
+}
+
+static void
+gtk_menu_tracker_opener_class_init (GtkMenuTrackerOpenerClass *class)
+{
+  G_OBJECT_CLASS (class)->finalize = gtk_menu_tracker_opener_finalize;
+}
+
 static void
 gtk_menu_tracker_opener_update (GtkMenuTrackerOpener *opener)
 {
@@ -862,57 +906,49 @@ gtk_menu_tracker_opener_update (GtkMenuTrackerOpener *opener)
 }
 
 static void
-gtk_menu_tracker_opener_added (GActionGroup *group,
-                               const char   *action_name,
-                               gpointer      user_data)
+gtk_menu_tracker_opener_added (GtkActionObserver   *observer,
+                               GtkActionObservable *observable,
+                               const char          *action_name,
+                               const GVariantType  *parameter_type,
+                               gboolean             enabled,
+                               GVariant            *state)
 {
-  GtkMenuTrackerOpener *opener = user_data;
-
-  if (g_str_equal (action_name, opener->submenu_action))
-    gtk_menu_tracker_opener_update (opener);
+  gtk_menu_tracker_opener_update ((GtkMenuTrackerOpener *)observer);
 }
 
 static void
-gtk_menu_tracker_opener_removed (GActionGroup *action_group,
-                                 const char   *action_name,
-                                 gpointer      user_data)
+gtk_menu_tracker_opener_removed (GtkActionObserver   *observer,
+                                 GtkActionObservable *observable,
+                                 const char          *action_name)
 {
-  GtkMenuTrackerOpener *opener = user_data;
-
-  if (g_str_equal (action_name, opener->submenu_action))
-    gtk_menu_tracker_opener_update (opener);
+  gtk_menu_tracker_opener_update ((GtkMenuTrackerOpener *)observer);
 }
 
 static void
-gtk_menu_tracker_opener_changed (GActionGroup *action_group,
-                                 const char   *action_name,
-                                 GVariant     *new_state,
-                                 gpointer      user_data)
+gtk_menu_tracker_opener_enabled_changed (GtkActionObserver   *observer,
+                                         GtkActionObservable *observable,
+                                         const char          *action_name,
+                                         gboolean             enabled)
 {
-  GtkMenuTrackerOpener *opener = user_data;
-
-  if (g_str_equal (action_name, opener->submenu_action))
-    gtk_menu_tracker_opener_update (opener);
+  gtk_menu_tracker_opener_update ((GtkMenuTrackerOpener *)observer);
 }
 
 static void
-gtk_menu_tracker_opener_free (gpointer data)
+gtk_menu_tracker_opener_state_changed (GtkActionObserver   *observer,
+                                       GtkActionObservable *observable,
+                                       const char          *action_name,
+                                       GVariant            *state)
 {
-  GtkMenuTrackerOpener *opener = data;
-
-  g_signal_handlers_disconnect_by_func (opener->item->observable, gtk_menu_tracker_opener_added, opener);
-  g_signal_handlers_disconnect_by_func (opener->item->observable, gtk_menu_tracker_opener_removed, opener);
-  g_signal_handlers_disconnect_by_func (opener->item->observable, gtk_menu_tracker_opener_changed, opener);
-
-  g_action_group_change_action_state (G_ACTION_GROUP (opener->item->observable),
-                                      opener->submenu_action,
-                                      g_variant_new_boolean (FALSE));
-
-  gtk_menu_tracker_item_set_submenu_shown (opener->item, FALSE);
-
-  g_free (opener->submenu_action);
+  gtk_menu_tracker_opener_update ((GtkMenuTrackerOpener *)observer);
+}
 
-  g_slice_free (GtkMenuTrackerOpener, opener);
+static void
+gtk_menu_tracker_opener_observer_iface_init (GtkActionObserverInterface *iface)
+{
+  iface->action_added = gtk_menu_tracker_opener_added;
+  iface->action_removed = gtk_menu_tracker_opener_removed;
+  iface->action_enabled_changed = gtk_menu_tracker_opener_enabled_changed;
+  iface->action_state_changed = gtk_menu_tracker_opener_state_changed;
 }
 
 static GtkMenuTrackerOpener *
@@ -921,7 +957,8 @@ gtk_menu_tracker_opener_new (GtkMenuTrackerItem *item,
 {
   GtkMenuTrackerOpener *opener;
 
-  opener = g_slice_new (GtkMenuTrackerOpener);
+  opener = g_object_new (gtk_menu_tracker_opener_get_type (), NULL);
+
   opener->first_time = TRUE;
   opener->item = item;
 
@@ -930,9 +967,9 @@ gtk_menu_tracker_opener_new (GtkMenuTrackerItem *item,
   else
     opener->submenu_action = g_strdup (submenu_action);
 
-  g_signal_connect (item->observable, "action-added", G_CALLBACK (gtk_menu_tracker_opener_added), opener);
-  g_signal_connect (item->observable, "action-removed", G_CALLBACK (gtk_menu_tracker_opener_removed), 
opener);
-  g_signal_connect (item->observable, "action-state-changed", G_CALLBACK (gtk_menu_tracker_opener_changed), 
opener);
+  gtk_action_observable_register_observer (item->observable,
+                                           opener->submenu_action,
+                                           (GtkActionObserver *)opener);
 
   gtk_menu_tracker_opener_update (opener);
 
@@ -962,7 +999,7 @@ gtk_menu_tracker_item_request_submenu_shown (GtkMenuTrackerItem *self,
       if (shown)
         g_object_set_data_full (G_OBJECT (self), "submenu-opener",
                                 gtk_menu_tracker_opener_new (self, submenu_action),
-                                gtk_menu_tracker_opener_free);
+                                g_object_unref);
       else
         g_object_set_data (G_OBJECT (self), "submenu-opener", NULL);
     }


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