← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~bratsche/appmenu-gtk/parent-tracking into lp:appmenu-gtk

 

Cody Russell has proposed merging lp:~bratsche/appmenu-gtk/parent-tracking into lp:appmenu-gtk.

Requested reviews:
  Canonical Desktop Experience Team (canonical-dx-team)
Related bugs:
  #655241 The favorite folders appears several times in the markers menu
  https://bugs.launchpad.net/bugs/655241


dbusmenu doesn't have a way to retrieve the parent menuitem of a child, but we need that in order to delete a child.  So we'll use g_object_{set,get}_data() to track parents inside appmenu-gtk.

This fixes an issue with Nautilus's bookmark manager, where adding or removing a bookmark results in several copies of all the dynamic menuitems being added to that menu, and it keeps getting larger until Nautilus is restarted.
-- 
https://code.launchpad.net/~bratsche/appmenu-gtk/parent-tracking/+merge/37762
Your team ayatana-commits is subscribed to branch lp:appmenu-gtk.
=== modified file 'src/bridge.c'
--- src/bridge.c	2010-09-29 17:14:35 +0000
+++ src/bridge.c	2010-10-06 16:52:47 +0000
@@ -696,6 +696,33 @@
     }
 }
 
+/*
+ * We probably should have added a 'remove' method to the UbuntuMenuProxy early on,
+ * but it's late in the cycle now.
+ */
+static void
+child_notify_cb (GtkWidget        *widget,
+                 GParamSpec       *pspec,
+                 DbusmenuMenuitem *mi)
+{
+  if (pspec->name == g_intern_static_string ("parent"))
+    {
+      if (gtk_widget_get_parent (widget) == NULL)
+        {
+          g_signal_handlers_disconnect_by_func (widget,
+                                                G_CALLBACK (child_notify_cb),
+                                                mi);
+
+          DbusmenuMenuitem *parent = g_object_get_data (G_OBJECT (mi), "dbusmenu-parent");
+
+          if (DBUSMENU_IS_MENUITEM (parent) && DBUSMENU_IS_MENUITEM (mi))
+            {
+              dbusmenu_menuitem_child_delete (parent, mi);
+            }
+        }
+    }
+}
+
 static DbusmenuMenuitem *
 construct_dbusmenu_for_widget (GtkWidget *widget, gboolean previous_separator)
 {
@@ -718,6 +745,7 @@
       else
         {
           gboolean visible = FALSE;
+          gboolean sensitive = FALSE;
           gboolean label_set = FALSE;
 
           g_signal_connect (widget,
@@ -776,16 +804,9 @@
           if (!g_object_get_data (G_OBJECT (widget), "gtk-empty-menu-item") && !GTK_IS_TEAROFF_MENU_ITEM (widget))
             {
               visible = gtk_widget_get_visible (widget);
+              sensitive = gtk_widget_get_sensitive (widget);
             }
 
-          dbusmenu_menuitem_property_set_bool (mi,
-                                               DBUSMENU_MENUITEM_PROP_VISIBLE,
-                                               visible);
-
-          dbusmenu_menuitem_property_set_bool (mi,
-                                               DBUSMENU_MENUITEM_PROP_ENABLED,
-                                               gtk_widget_get_sensitive (widget));
-
           dbusmenu_menuitem_property_set_shortcut_menuitem (mi, GTK_MENU_ITEM (widget));
 
           g_signal_connect (G_OBJECT (widget),
@@ -803,6 +824,9 @@
 
                   if (action)
                     {
+                      visible = gtk_action_is_visible (action);
+                      sensitive = gtk_action_is_sensitive (action);
+
                       g_signal_connect_object (action, "notify",
                                                G_CALLBACK (action_notify_cb),
                                                mi,
@@ -811,11 +835,24 @@
                 }
             }
 
+          dbusmenu_menuitem_property_set_bool (mi,
+                                               DBUSMENU_MENUITEM_PROP_VISIBLE,
+                                               visible);
+
+          dbusmenu_menuitem_property_set_bool (mi,
+                                               DBUSMENU_MENUITEM_PROP_ENABLED,
+                                               sensitive);
+
           g_signal_connect (G_OBJECT (mi),
                             DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
                             G_CALLBACK (item_activated),
                             widget);
         }
+
+      g_signal_connect (widget,
+                        "notify",
+                        G_CALLBACK (child_notify_cb),
+                        mi);
     }
 
   return mi;
@@ -947,6 +984,9 @@
 
                   if (!peek)
                     {
+                      g_object_set_data (G_OBJECT (recurse->stack[recurse->count]),
+                                         "dbusmenu-parent",
+                                         recurse->stack[recurse->count - 1]);
                       dbusmenu_menuitem_child_append (recurse->stack[recurse->count - 1],
                                                       recurse->stack[recurse->count]);
                     }
@@ -967,6 +1007,10 @@
 
                       if (!peek)
                         {
+                          g_object_set_data (G_OBJECT (recurse->stack[recurse->count]),
+                                             "dbusmenu-parent",
+                                             recurse->stack[recurse->count - 1]);
+
                           dbusmenu_menuitem_child_append (item, recurse->stack[recurse->count]);
                         }
                     }
@@ -1290,6 +1334,7 @@
             {
               DbusmenuMenuitem *child_dmi = construct_dbusmenu_for_widget (child, FALSE);
 
+              g_object_set_data (G_OBJECT (child_dmi), "dbusmenu-parent", mi);
               dbusmenu_menuitem_child_add_position (mi,
                                                     child_dmi,
                                                     position);


Follow ups