← Back to team overview

ayatana-commits team mailing list archive

[Branch ~dbusmenu-team/dbusmenu/trunk] Rev 232: Track the parent inside the menuitem instead of with a data property externally.

 

Merge authors:
  Chris Coulson (chrisccoulson)
  Ted Gould (ted)
Related merge proposals:
  https://code.launchpad.net/~chrisccoulson/dbusmenu/more-memory-fixes/+merge/51152
  proposed by: Chris Coulson (chrisccoulson)
  review: Approve - Ted Gould (ted)
------------------------------------------------------------
revno: 232 [merge]
committer: Ted Gould <ted@xxxxxxxx>
branch nick: trunk
timestamp: Thu 2011-02-24 10:33:40 -0600
message:
  Track the parent inside the menuitem instead of with a data property externally.
modified:
  docs/libdbusmenu-glib/reference/libdbusmenu-glib-sections.txt
  libdbusmenu-glib/menuitem.c
  libdbusmenu-glib/menuitem.h
  libdbusmenu-gtk/parser.c


--
lp:dbusmenu
https://code.launchpad.net/~dbusmenu-team/dbusmenu/trunk

Your team ayatana-commits is subscribed to branch lp:dbusmenu.
To unsubscribe from this branch go to https://code.launchpad.net/~dbusmenu-team/dbusmenu/trunk/+edit-subscription
=== modified file 'docs/libdbusmenu-glib/reference/libdbusmenu-glib-sections.txt'
--- docs/libdbusmenu-glib/reference/libdbusmenu-glib-sections.txt	2011-02-24 15:38:18 +0000
+++ docs/libdbusmenu-glib/reference/libdbusmenu-glib-sections.txt	2011-02-24 16:33:40 +0000
@@ -105,6 +105,9 @@
 dbusmenu_menuitem_handle_event
 dbusmenu_menuitem_send_about_to_show
 dbusmenu_menuitem_show_to_user
+dbusmenu_menuitem_get_parent
+dbusmenu_menuitem_set_parent
+dbusmenu_menuitem_unparent
 <SUBSECTION Standard>
 DBUSMENU_MENUITEM
 DBUSMENU_IS_MENUITEM

=== modified file 'libdbusmenu-glib/menuitem.c'
--- libdbusmenu-glib/menuitem.c	2011-02-24 15:44:53 +0000
+++ libdbusmenu-glib/menuitem.c	2011-02-24 16:33:40 +0000
@@ -62,6 +62,7 @@
 	gboolean realized;
 	DbusmenuDefaults * defaults;
 	gboolean exposed;
+	DbusmenuMenuitem * parent;
 };
 
 /* Signals */
@@ -357,6 +358,11 @@
 		priv->defaults = NULL;
 	}
 
+	if (priv->parent) {
+		g_object_remove_weak_pointer(G_OBJECT(priv->parent), (gpointer *)&priv->parent);
+		priv->parent = NULL;
+	}
+
 	G_OBJECT_CLASS (dbusmenu_menuitem_parent_class)->dispose (object);
 	return;
 }
@@ -583,11 +589,12 @@
 /* For all the taken children we need to signal
    that they were removed */
 static void
-take_children_signal (gpointer data, gpointer user_data)
+take_children_helper (gpointer data, gpointer user_data)
 {
 	#ifdef MASSIVEDEBUGGING
 	g_debug("Menuitem %d (%s) signalling child removed %d (%s)", ID(user_data), LABEL(user_data), ID(data), LABEL(data));
 	#endif
+	dbusmenu_menuitem_unparent(DBUSMENU_MENUITEM(data));
 	g_signal_emit(G_OBJECT(user_data), signals[CHILD_REMOVED], 0, DBUSMENU_MENUITEM(data), TRUE);
 	return;
 }
@@ -613,7 +620,7 @@
 	DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
 	GList * children = priv->children;
 	priv->children = NULL;
-	g_list_foreach(children, take_children_signal, mi);
+	g_list_foreach(children, take_children_helper, mi);
 
 	dbusmenu_menuitem_property_remove(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY);
 	
@@ -722,6 +729,10 @@
 	DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
 	g_return_val_if_fail(g_list_find(priv->children, child) == NULL, FALSE);
 
+	if (!dbusmenu_menuitem_set_parent(child, mi)) {
+		return FALSE;
+	}
+
 	if (priv->children == NULL && !dbusmenu_menuitem_property_exist(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY)) {
 		dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY, DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU);
 	}
@@ -754,6 +765,10 @@
 	DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
 	g_return_val_if_fail(g_list_find(priv->children, child) == NULL, FALSE);
 
+	if (!dbusmenu_menuitem_set_parent(child, mi)) {
+		return FALSE;
+	}
+
 	if (priv->children == NULL && !dbusmenu_menuitem_property_exist(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY)) {
 		dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY, DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU);
 	}
@@ -784,8 +799,14 @@
 	g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
 	g_return_val_if_fail(DBUSMENU_IS_MENUITEM(child), FALSE);
 
+	if (dbusmenu_menuitem_get_parent(child) != mi) {
+		g_warning("Trying to remove a child that doesn't believe we're it's parent.");
+		return FALSE;
+	}
+
 	DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
 	priv->children = g_list_remove(priv->children, child);
+	dbusmenu_menuitem_unparent(child);
 	#ifdef MASSIVEDEBUGGING
 	g_debug("Menuitem %d (%s) signalling child removed %d (%s)", ID(mi), LABEL(mi), ID(child), LABEL(child));
 	#endif
@@ -820,6 +841,10 @@
 	DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
 	g_return_val_if_fail(g_list_find(priv->children, child) == NULL, FALSE);
 
+	if (!dbusmenu_menuitem_set_parent(child, mi)) {
+		return FALSE;
+	}
+
 	if (priv->children == NULL && !dbusmenu_menuitem_property_exist(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY)) {
 		dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY, DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU);
 	}
@@ -955,6 +980,84 @@
 }
 
 /**
+ * dbusmenu_menuitem_set_parent:
+ * @mi: The #DbusmenuMenuitem for which to set the parent
+ * @parent: The new parent #DbusmenuMenuitem
+ *
+ * Sets the parent of @mi to @parent. If @mi already
+ * has a parent, then this call will fail. The parent will
+ * be set automatically when using the usual methods to add a
+ * child menuitem, so this function should not normally be 
+ * called directly 
+ *
+ * Return value: Whether the parent was set successfully
+ */
+gboolean
+dbusmenu_menuitem_set_parent (DbusmenuMenuitem * mi, DbusmenuMenuitem * parent)
+{
+	g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
+	g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
+
+	DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+
+	if (priv->parent != NULL) {
+		g_warning ("Menu item already has a parent");
+		return FALSE;
+	}
+
+	priv->parent = parent;
+	g_object_add_weak_pointer(G_OBJECT(priv->parent), (gpointer *)&priv->parent);
+
+	return TRUE;
+}
+
+/**
+ * dbusmenu_menuitem_unparent:
+ * @mi: The #DbusmenuMenuitem to unparent
+ *
+ * Unparents the menu item @mi. If @mi doesn't have a
+ * parent, then this call will fail. The menuitem will
+ * be unparented automatically when using the usual methods
+ * to delete a child menuitem, so this function should not
+ * normally be called directly 
+ *
+ * Return value: Whether the menu item was unparented successfully
+ */
+gboolean
+dbusmenu_menuitem_unparent (DbusmenuMenuitem * mi)
+{
+	g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
+	DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+
+	if (priv->parent == NULL) {
+		g_warning("Menu item doesn't have a parent");
+		return FALSE;
+	}
+
+	g_object_remove_weak_pointer(G_OBJECT(priv->parent), (gpointer *)&priv->parent);
+	priv->parent = NULL;
+
+	return TRUE;
+}
+
+/**
+ * dbusmenu_menuitem_get_parent:
+ * @mi: The #DbusmenuMenuitem for which to inspect the parent
+ *
+ * This function looks up the parent of @mi
+ *
+ * Return value: (transfer none): The parent of this menu item
+ */
+DbusmenuMenuitem *
+dbusmenu_menuitem_get_parent (DbusmenuMenuitem * mi)
+{
+	g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), NULL);
+	DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+
+	return priv->parent;
+}
+
+/**
  * dbusmenu_menuitem_property_set:
  * @mi: The #DbusmenuMenuitem to set the property on.
  * @property: Name of the property to set.

=== modified file 'libdbusmenu-glib/menuitem.h'
--- libdbusmenu-glib/menuitem.h	2011-02-24 15:44:53 +0000
+++ libdbusmenu-glib/menuitem.h	2011-02-24 16:33:40 +0000
@@ -381,6 +381,10 @@
 DbusmenuMenuitem * dbusmenu_menuitem_child_find (DbusmenuMenuitem * mi, gint id);
 DbusmenuMenuitem * dbusmenu_menuitem_find_id (DbusmenuMenuitem * mi, gint id);
 
+gboolean dbusmenu_menuitem_set_parent (DbusmenuMenuitem * mi, DbusmenuMenuitem * parent);
+gboolean dbusmenu_menuitem_unparent (DbusmenuMenuitem *mi);
+DbusmenuMenuitem * dbusmenu_menuitem_get_parent (DbusmenuMenuitem * mi);
+
 gboolean dbusmenu_menuitem_property_set (DbusmenuMenuitem * mi, const gchar * property, const gchar * value);
 gboolean dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * property, GVariant * value);
 gboolean dbusmenu_menuitem_property_set_bool (DbusmenuMenuitem * mi, const gchar * property, const gboolean value);

=== modified file 'libdbusmenu-gtk/parser.c'
--- libdbusmenu-gtk/parser.c	2011-02-24 16:22:46 +0000
+++ libdbusmenu-gtk/parser.c	2011-02-24 16:33:40 +0000
@@ -303,10 +303,6 @@
 
 			/* Oops, let's tell our parents about us */
 			if (peek == NULL) {
-				/* TODO: Should we set a weak ref on the parent? */
-				g_object_set_data (G_OBJECT (thisitem),
-				                   "dbusmenu-parent",
-				                   recurse->parent);
 				gint pos = get_child_position (widget);
 				if (pos >= 0)
 					dbusmenu_menuitem_child_add_position (recurse->parent,
@@ -795,7 +791,7 @@
                                                 G_CALLBACK (widget_notify_cb),
                                                 child);
 
-          DbusmenuMenuitem *parent = g_object_get_data (G_OBJECT (child), "dbusmenu-parent");
+          DbusmenuMenuitem *parent = dbusmenu_menuitem_get_parent (child);
 
           if (DBUSMENU_IS_MENUITEM (parent) && DBUSMENU_IS_MENUITEM (child))
             {