Merge lp:~chrisccoulson/libdbusmenu/more-memory-fixes into lp:libdbusmenu/0.5

Proposed by Chris Coulson
Status: Merged
Merged at revision: 232
Proposed branch: lp:~chrisccoulson/libdbusmenu/more-memory-fixes
Merge into: lp:libdbusmenu/0.5
Diff against target: 246 lines (+117/-8)
3 files modified
libdbusmenu-glib/menuitem.c (+100/-2)
libdbusmenu-glib/menuitem.h (+4/-0)
libdbusmenu-gtk/parser.c (+13/-6)
To merge this branch: bzr merge lp:~chrisccoulson/libdbusmenu/more-memory-fixes
Reviewer Review Type Date Requested Status
Ted Gould (community) Approve
Review via email: mp+51152@code.launchpad.net

Description of the change

More memory error fixes :)

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

A few comments:

* Please don't comment out code. Either delete or fix, we have version control to find old code if we need it.

* Added a check to see if we're the parent to delete or else we could end up with really weird unparenting from non-parents.

* get_parent() needs a transfer annotation

* please try to keep it to one feature/fix per branch as it makes it easier to review and understand the impact of the change.

* new functions need to be added to "sections.txt" for the documentation.

I fixed these and merged the whole thing in. Thanks for the investigation and fixing these!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libdbusmenu-glib/menuitem.c'
2--- libdbusmenu-glib/menuitem.c 2011-02-24 14:34:48 +0000
3+++ libdbusmenu-glib/menuitem.c 2011-02-24 15:48:24 +0000
4@@ -62,6 +62,7 @@
5 gboolean realized;
6 DbusmenuDefaults * defaults;
7 gboolean exposed;
8+ DbusmenuMenuitem * parent;
9 };
10
11 /* Signals */
12@@ -339,6 +340,11 @@
13 priv->defaults = NULL;
14 }
15
16+ if (priv->parent) {
17+ g_object_remove_weak_pointer(G_OBJECT(priv->parent), (gpointer *)&priv->parent);
18+ priv->parent = NULL;
19+ }
20+
21 G_OBJECT_CLASS (dbusmenu_menuitem_parent_class)->dispose (object);
22 return;
23 }
24@@ -565,11 +571,12 @@
25 /* For all the taken children we need to signal
26 that they were removed */
27 static void
28-take_children_signal (gpointer data, gpointer user_data)
29+take_children_helper (gpointer data, gpointer user_data)
30 {
31 #ifdef MASSIVEDEBUGGING
32 g_debug("Menuitem %d (%s) signalling child removed %d (%s)", ID(user_data), LABEL(user_data), ID(data), LABEL(data));
33 #endif
34+ dbusmenu_menuitem_unparent(DBUSMENU_MENUITEM(data));
35 g_signal_emit(G_OBJECT(user_data), signals[CHILD_REMOVED], 0, DBUSMENU_MENUITEM(data), TRUE);
36 return;
37 }
38@@ -595,7 +602,7 @@
39 DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
40 GList * children = priv->children;
41 priv->children = NULL;
42- g_list_foreach(children, take_children_signal, mi);
43+ g_list_foreach(children, take_children_helper, mi);
44
45 dbusmenu_menuitem_property_remove(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY);
46
47@@ -704,6 +711,10 @@
48 DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
49 g_return_val_if_fail(g_list_find(priv->children, child) == NULL, FALSE);
50
51+ if (!dbusmenu_menuitem_set_parent(child, mi)) {
52+ return FALSE;
53+ }
54+
55 if (priv->children == NULL && !dbusmenu_menuitem_property_exist(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY)) {
56 dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY, DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU);
57 }
58@@ -736,6 +747,10 @@
59 DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
60 g_return_val_if_fail(g_list_find(priv->children, child) == NULL, FALSE);
61
62+ if (!dbusmenu_menuitem_set_parent(child, mi)) {
63+ return FALSE;
64+ }
65+
66 if (priv->children == NULL && !dbusmenu_menuitem_property_exist(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY)) {
67 dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY, DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU);
68 }
69@@ -768,6 +783,7 @@
70
71 DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
72 priv->children = g_list_remove(priv->children, child);
73+ dbusmenu_menuitem_unparent(child);
74 #ifdef MASSIVEDEBUGGING
75 g_debug("Menuitem %d (%s) signalling child removed %d (%s)", ID(mi), LABEL(mi), ID(child), LABEL(child));
76 #endif
77@@ -802,6 +818,10 @@
78 DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
79 g_return_val_if_fail(g_list_find(priv->children, child) == NULL, FALSE);
80
81+ if (!dbusmenu_menuitem_set_parent(child, mi)) {
82+ return FALSE;
83+ }
84+
85 if (priv->children == NULL && !dbusmenu_menuitem_property_exist(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY)) {
86 dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY, DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU);
87 }
88@@ -937,6 +957,84 @@
89 }
90
91 /**
92+ * dbusmenu_menuitem_set_parent:
93+ * @mi: The #DbusmenuMenuitem for which to set the parent
94+ * @parent: The new parent #DbusmenuMenuitem
95+ *
96+ * Sets the parent of @mi to @parent. If @mi already
97+ * has a parent, then this call will fail. The parent will
98+ * be set automatically when using the usual methods to add a
99+ * child menuitem, so this function should not normally be
100+ * called directly
101+ *
102+ * Return value: Whether the parent was set successfully
103+ */
104+gboolean
105+dbusmenu_menuitem_set_parent (DbusmenuMenuitem * mi, DbusmenuMenuitem * parent)
106+{
107+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
108+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
109+
110+ DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
111+
112+ if (priv->parent != NULL) {
113+ g_warning ("Menu item already has a parent");
114+ return FALSE;
115+ }
116+
117+ priv->parent = parent;
118+ g_object_add_weak_pointer(G_OBJECT(priv->parent), (gpointer *)&priv->parent);
119+
120+ return TRUE;
121+}
122+
123+/**
124+ * dbusmenu_menuitem_unparent:
125+ * @mi: The #DbusmenuMenuitem to unparent
126+ *
127+ * Unparents the menu item @mi. If @mi doesn't have a
128+ * parent, then this call will fail. The menuitem will
129+ * be unparented automatically when using the usual methods
130+ * to delete a child menuitem, so this function should not
131+ * normally be called directly
132+ *
133+ * Return value: Whether the menu item was unparented successfully
134+ */
135+gboolean
136+dbusmenu_menuitem_unparent (DbusmenuMenuitem * mi)
137+{
138+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
139+ DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
140+
141+ if (priv->parent == NULL) {
142+ g_warning("Menu item doesn't have a parent");
143+ return FALSE;
144+ }
145+
146+ g_object_remove_weak_pointer(G_OBJECT(priv->parent), (gpointer *)&priv->parent);
147+ priv->parent = NULL;
148+
149+ return TRUE;
150+}
151+
152+/**
153+ * dbusmenu_menuitem_get_parent:
154+ * @mi: The #DbusmenuMenuitem for which to inspect the parent
155+ *
156+ * This function looks up the parent of @mi
157+ *
158+ * Return value: The parent of this menu item
159+ */
160+DbusmenuMenuitem *
161+dbusmenu_menuitem_get_parent (DbusmenuMenuitem * mi)
162+{
163+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), NULL);
164+ DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
165+
166+ return priv->parent;
167+}
168+
169+/**
170 * dbusmenu_menuitem_property_set:
171 * @mi: The #DbusmenuMenuitem to set the property on.
172 * @property: Name of the property to set.
173
174=== modified file 'libdbusmenu-glib/menuitem.h'
175--- libdbusmenu-glib/menuitem.h 2011-02-21 20:14:56 +0000
176+++ libdbusmenu-glib/menuitem.h 2011-02-24 15:48:24 +0000
177@@ -379,6 +379,10 @@
178 DbusmenuMenuitem * dbusmenu_menuitem_child_find (DbusmenuMenuitem * mi, gint id);
179 DbusmenuMenuitem * dbusmenu_menuitem_find_id (DbusmenuMenuitem * mi, gint id);
180
181+gboolean dbusmenu_menuitem_set_parent (DbusmenuMenuitem * mi, DbusmenuMenuitem * parent);
182+gboolean dbusmenu_menuitem_unparent (DbusmenuMenuitem *mi);
183+DbusmenuMenuitem * dbusmenu_menuitem_get_parent (DbusmenuMenuitem * mi);
184+
185 gboolean dbusmenu_menuitem_property_set (DbusmenuMenuitem * mi, const gchar * property, const gchar * value);
186 gboolean dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * property, GVariant * value);
187 gboolean dbusmenu_menuitem_property_set_bool (DbusmenuMenuitem * mi, const gchar * property, const gboolean value);
188
189=== modified file 'libdbusmenu-gtk/parser.c'
190--- libdbusmenu-gtk/parser.c 2011-02-23 14:34:36 +0000
191+++ libdbusmenu-gtk/parser.c 2011-02-24 15:48:24 +0000
192@@ -161,6 +161,15 @@
193 }
194 }
195
196+static void
197+widget_freed (gpointer data, GObject * obj)
198+{
199+ g_signal_handlers_disconnect_by_func(gtk_icon_theme_get_default(), G_CALLBACK(theme_changed_cb), obj);
200+
201+ return;
202+}
203+
204+#if 0
205 /* Called if we replace the cache on the object with a new
206 dbusmenu menuitem */
207 static void
208@@ -175,6 +184,7 @@
209
210 return;
211 }
212+#endif
213
214 /* Gets the positon of the child with its' parent if it has one.
215 Returns -1 if the position is unable to be calculated. */
216@@ -213,8 +223,9 @@
217 ParserData *pdata = g_new0 (ParserData, 1);
218 g_object_set_data_full(G_OBJECT(item), PARSER_DATA, pdata, parse_data_free);
219
220- g_object_set_data_full(G_OBJECT(widget), CACHED_MENUITEM, item, object_cache_freed);
221+ /* g_object_set_data_full(G_OBJECT(widget), CACHED_MENUITEM, item, object_cache_freed); */
222 g_object_weak_ref(G_OBJECT(item), dbusmenu_item_freed, NULL);
223+ g_object_weak_ref(G_OBJECT(widget), widget_freed, NULL);
224
225 pdata->widget = widget;
226 g_object_add_weak_pointer(G_OBJECT (widget), (gpointer*)&pdata->widget);
227@@ -310,10 +321,6 @@
228
229 /* Oops, let's tell our parents about us */
230 if (peek == NULL) {
231- /* TODO: Should we set a weak ref on the parent? */
232- g_object_set_data (G_OBJECT (thisitem),
233- "dbusmenu-parent",
234- recurse->parent);
235 gint pos = get_child_position (widget);
236 if (pos >= 0)
237 dbusmenu_menuitem_child_add_position (recurse->parent,
238@@ -802,7 +809,7 @@
239 G_CALLBACK (widget_notify_cb),
240 child);
241
242- DbusmenuMenuitem *parent = g_object_get_data (G_OBJECT (child), "dbusmenu-parent");
243+ DbusmenuMenuitem *parent = dbusmenu_menuitem_get_parent (child);
244
245 if (DBUSMENU_IS_MENUITEM (parent) && DBUSMENU_IS_MENUITEM (child))
246 {

Subscribers

People subscribed via source and target branches