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

Proposed by Cody Russell
Status: Merged
Merged at revision: 101
Proposed branch: lp:~bratsche/appmenu-gtk/parent-tracking
Merge into: lp:appmenu-gtk/0.4
Diff against target: 127 lines (+53/-8)
1 file modified
src/bridge.c (+53/-8)
To merge this branch: bzr merge lp:~bratsche/appmenu-gtk/parent-tracking
Reviewer Review Type Date Requested Status
Ted Gould (community) Approve
Review via email: mp+37762@code.launchpad.net

Description of the change

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.

To post a comment you must log in.
Revision history for this message
Ted Gould (ted) wrote :

I'm trying to figure if we need a weak ref on the parent. I think that it's okay as you're not moving menuitems around to different parents anywhere else in appmenu-gtk. But, I think you should probably put a comment in for when something changes :)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/bridge.c'
2--- src/bridge.c 2010-09-29 17:14:35 +0000
3+++ src/bridge.c 2010-10-06 16:52:47 +0000
4@@ -696,6 +696,33 @@
5 }
6 }
7
8+/*
9+ * We probably should have added a 'remove' method to the UbuntuMenuProxy early on,
10+ * but it's late in the cycle now.
11+ */
12+static void
13+child_notify_cb (GtkWidget *widget,
14+ GParamSpec *pspec,
15+ DbusmenuMenuitem *mi)
16+{
17+ if (pspec->name == g_intern_static_string ("parent"))
18+ {
19+ if (gtk_widget_get_parent (widget) == NULL)
20+ {
21+ g_signal_handlers_disconnect_by_func (widget,
22+ G_CALLBACK (child_notify_cb),
23+ mi);
24+
25+ DbusmenuMenuitem *parent = g_object_get_data (G_OBJECT (mi), "dbusmenu-parent");
26+
27+ if (DBUSMENU_IS_MENUITEM (parent) && DBUSMENU_IS_MENUITEM (mi))
28+ {
29+ dbusmenu_menuitem_child_delete (parent, mi);
30+ }
31+ }
32+ }
33+}
34+
35 static DbusmenuMenuitem *
36 construct_dbusmenu_for_widget (GtkWidget *widget, gboolean previous_separator)
37 {
38@@ -718,6 +745,7 @@
39 else
40 {
41 gboolean visible = FALSE;
42+ gboolean sensitive = FALSE;
43 gboolean label_set = FALSE;
44
45 g_signal_connect (widget,
46@@ -776,16 +804,9 @@
47 if (!g_object_get_data (G_OBJECT (widget), "gtk-empty-menu-item") && !GTK_IS_TEAROFF_MENU_ITEM (widget))
48 {
49 visible = gtk_widget_get_visible (widget);
50+ sensitive = gtk_widget_get_sensitive (widget);
51 }
52
53- dbusmenu_menuitem_property_set_bool (mi,
54- DBUSMENU_MENUITEM_PROP_VISIBLE,
55- visible);
56-
57- dbusmenu_menuitem_property_set_bool (mi,
58- DBUSMENU_MENUITEM_PROP_ENABLED,
59- gtk_widget_get_sensitive (widget));
60-
61 dbusmenu_menuitem_property_set_shortcut_menuitem (mi, GTK_MENU_ITEM (widget));
62
63 g_signal_connect (G_OBJECT (widget),
64@@ -803,6 +824,9 @@
65
66 if (action)
67 {
68+ visible = gtk_action_is_visible (action);
69+ sensitive = gtk_action_is_sensitive (action);
70+
71 g_signal_connect_object (action, "notify",
72 G_CALLBACK (action_notify_cb),
73 mi,
74@@ -811,11 +835,24 @@
75 }
76 }
77
78+ dbusmenu_menuitem_property_set_bool (mi,
79+ DBUSMENU_MENUITEM_PROP_VISIBLE,
80+ visible);
81+
82+ dbusmenu_menuitem_property_set_bool (mi,
83+ DBUSMENU_MENUITEM_PROP_ENABLED,
84+ sensitive);
85+
86 g_signal_connect (G_OBJECT (mi),
87 DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
88 G_CALLBACK (item_activated),
89 widget);
90 }
91+
92+ g_signal_connect (widget,
93+ "notify",
94+ G_CALLBACK (child_notify_cb),
95+ mi);
96 }
97
98 return mi;
99@@ -947,6 +984,9 @@
100
101 if (!peek)
102 {
103+ g_object_set_data (G_OBJECT (recurse->stack[recurse->count]),
104+ "dbusmenu-parent",
105+ recurse->stack[recurse->count - 1]);
106 dbusmenu_menuitem_child_append (recurse->stack[recurse->count - 1],
107 recurse->stack[recurse->count]);
108 }
109@@ -967,6 +1007,10 @@
110
111 if (!peek)
112 {
113+ g_object_set_data (G_OBJECT (recurse->stack[recurse->count]),
114+ "dbusmenu-parent",
115+ recurse->stack[recurse->count - 1]);
116+
117 dbusmenu_menuitem_child_append (item, recurse->stack[recurse->count]);
118 }
119 }
120@@ -1290,6 +1334,7 @@
121 {
122 DbusmenuMenuitem *child_dmi = construct_dbusmenu_for_widget (child, FALSE);
123
124+ g_object_set_data (G_OBJECT (child_dmi), "dbusmenu-parent", mi);
125 dbusmenu_menuitem_child_add_position (mi,
126 child_dmi,
127 position);

Subscribers

People subscribed via source and target branches