← Back to team overview

ayatana-commits team mailing list archive

[Branch ~dbusmenu-team/dbusmenu/trunk] Rev 21: Managing the lifecycle of the menu item more directly and making sure to remove them from the men...

 

Merge authors:
  Ted Gould (ted)
Related merge proposals:
  https://code.launchpad.net/~ted/dbusmenu/errr-reordering/+merge/12803
  proposed by: Ted Gould (ted)
  review: Approve - Cody Russell (bratsche)
------------------------------------------------------------
revno: 21 [merge]
committer: Ted Gould <ted@xxxxxxxxxxxxx>
branch nick: trunk
timestamp: Fri 2009-10-02 16:31:22 -0500
message:
  Managing the lifecycle of the menu item more directly and making sure to remove them from the menu when they're not children of it anymore.
added:
  tests/test-gtk-reorder-server.c
modified:
  .bzrignore
  configure.ac
  libdbusmenu-glib/client.c
  libdbusmenu-glib/menuitem.c
  libdbusmenu-gtk/Makefile.am
  libdbusmenu-gtk/client.c
  libdbusmenu-gtk/menu.c
  tests/Makefile.am
  tests/test-glib-simple-items.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 '.bzrignore'
--- .bzrignore	2009-09-02 18:29:01 +0000
+++ .bzrignore	2009-09-30 20:52:42 +0000
@@ -42,3 +42,9 @@
 mago.results
 test-glib-simple-items
 libdbusmenu-gtk/libdbusmenu_gtk_la-menuitem.lo
+tests/test-glib-layout
+tests/test-glib-properties
+tests/test-gtk-label
+tests/test-gtk-reorder-server.c
+tests/test-gtk-reorder-server
+tests/test-gtk-reorder

=== modified file 'configure.ac'
--- configure.ac	2009-09-24 21:07:24 +0000
+++ configure.ac	2009-10-01 16:59:21 +0000
@@ -84,6 +84,16 @@
 AM_GLIB_GNU_GETTEXT
 
 ###########################
+# Massive Debugging
+###########################
+
+with_massivedebugging="no"
+AC_ARG_ENABLE(massivedebugging, AS_HELP_STRING([--enable-massivedebugging], [Print out so much information your brain will hurt]), with_massivedebugging=$enableval, with_massivedebugging=no)
+if test "x$with_massivedebugging" = "xyes"; then
+	AC_DEFINE([MASSIVEDEBUGGING], [1], [Print everyting])
+fi
+
+###########################
 # Files
 ###########################
 
@@ -109,5 +119,6 @@
 libdbusmenu Configuration:
 
 	Prefix:                 $prefix
+	Massive Debugging:      $with_massivedebugging
 ])
 

=== modified file 'libdbusmenu-glib/client.c'
--- libdbusmenu-glib/client.c	2009-10-02 13:52:39 +0000
+++ libdbusmenu-glib/client.c	2009-10-02 21:31:22 +0000
@@ -322,6 +322,10 @@
 static void
 id_prop_update (DBusGProxy * proxy, guint id, gchar * property, gchar * value, DbusmenuClient * client)
 {
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Property change sent to client for item %d property %s value %s", id, property, g_utf8_strlen(value, 50) < 25 ? value : "<too long>");
+	#endif
+
 	DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
 	g_return_if_fail(priv->root != NULL);
 
@@ -337,6 +341,10 @@
 static void
 id_update (DBusGProxy * proxy, guint id, DbusmenuClient * client)
 {
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Client side ID update: %d", id);
+	#endif 
+
 	DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
 	g_return_if_fail(priv->root != NULL);
 
@@ -414,6 +422,9 @@
 	if (priv->root != NULL) {
 		g_object_unref(G_OBJECT(priv->root));
 		priv->root = NULL;
+		#ifdef MASSIVEDEBUGGING
+		g_debug("Proxies destroyed, signaling a root change and a layout update.");
+		#endif
 		g_signal_emit(G_OBJECT(userdata), signals[ROOT_CHANGED], 0, NULL, TRUE);
 		g_signal_emit(G_OBJECT(userdata), signals[LAYOUT_UPDATED], 0, TRUE);
 	}
@@ -606,6 +617,9 @@
 		handled = newfunc(propdata->item, propdata->parent, propdata->client);
 	}
 
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Client has realized a menuitem: %d", dbusmenu_menuitem_get_id(propdata->item));
+	#endif
 	g_signal_emit(G_OBJECT(propdata->item), DBUSMENU_MENUITEM_SIGNAL_REALIZED_ID, 0, TRUE);
 
 	if (!handled) {
@@ -643,7 +657,9 @@
 parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, DBusGProxy * proxy)
 {
 	guint id = parse_node_get_id(node);
-	/* g_debug("Looking at node with id: %d", id); */
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Client looking at node with id: %d", id);
+	#endif
 	if (item == NULL || dbusmenu_menuitem_get_id(item) != id || id == 0) {
 		if (item != NULL) {
 			if (parent != NULL) {
@@ -707,7 +723,9 @@
 	GList * oldchildleft = NULL;
 	for (oldchildleft = oldchildren; oldchildleft != NULL; oldchildleft = g_list_next(oldchildleft)) {
 		DbusmenuMenuitem * oldmi = DBUSMENU_MENUITEM(oldchildleft->data);
+		#ifdef MASSIVEDEBUGGING
 		g_debug("Unref'ing menu item with layout update. ID: %d", dbusmenu_menuitem_get_id(oldmi));
+		#endif
 		g_object_unref(G_OBJECT(oldmi));
 	}
 	g_list_free(oldchildren);
@@ -720,6 +738,10 @@
 static gint
 parse_layout (DbusmenuClient * client, const gchar * layout)
 {
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Client Parsing a new layout");
+	#endif 
+
 	DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
 
 	xmlDocPtr xmldoc;
@@ -738,6 +760,9 @@
 	}
 
 	if (priv->root != oldroot) {
+		#ifdef MASSIVEDEBUGGING
+		g_debug("Client signaling root changed.");
+		#endif 
 		g_signal_emit(G_OBJECT(client), signals[ROOT_CHANGED], 0, priv->root, TRUE);
 	}
 
@@ -772,6 +797,9 @@
 
 	priv->my_revision = rev;
 	/* g_debug("Root is now: 0x%X", (unsigned int)priv->root); */
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Client signaling layout has changed.");
+	#endif 
 	g_signal_emit(G_OBJECT(client), signals[LAYOUT_UPDATED], 0, TRUE);
 
 	if (priv->my_revision < priv->current_revision) {
@@ -860,6 +888,10 @@
 		return NULL;
 	}
 
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Client get root: %X", (guint)priv->root);
+	#endif
+
 	return priv->root;
 }
 
@@ -892,6 +924,10 @@
 
 	DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
 
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Adding a type handler for '%s'", type);
+	#endif
+
 	if (priv->type_handlers == NULL) {
 		g_warning("Type handlers hashtable not built");
 		return FALSE;

=== modified file 'libdbusmenu-glib/menuitem.c'
--- libdbusmenu-glib/menuitem.c	2009-09-21 20:01:40 +0000
+++ libdbusmenu-glib/menuitem.c	2009-10-01 19:23:35 +0000
@@ -32,6 +32,11 @@
 #include "menuitem.h"
 #include "menuitem-marshal.h"
 
+#ifdef MASSIVEDEBUGGING
+#define LABEL(x)  dbusmenu_menuitem_property_get(DBUSMENU_MENUITEM(x), DBUSMENU_MENUITEM_PROP_LABEL)
+#define ID(x)     dbusmenu_menuitem_get_id(DBUSMENU_MENUITEM(x))
+#endif
+
 /* Private */
 /**
 	DbusmenuMenuitemPrivate:
@@ -362,6 +367,9 @@
 static void
 take_children_signal (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
 	g_signal_emit(G_OBJECT(user_data), signals[CHILD_REMOVED], 0, DBUSMENU_MENUITEM(data), TRUE);
 	return;
 }
@@ -404,6 +412,11 @@
 guint
 dbusmenu_menuitem_get_position (DbusmenuMenuitem * mi, DbusmenuMenuitem * parent)
 {
+	#ifdef MASSIVEDEBUGGING
+	if (!DBUSMENU_IS_MENUITEM(mi))     g_warning("Getting position of %d (%s), it's at: %d (mi fail)", ID(mi), LABEL(mi), 0);
+	if (!DBUSMENU_IS_MENUITEM(parent)) g_warning("Getting position of %d (%s), it's at: %d (parent fail)", ID(mi), LABEL(mi), 0);
+	#endif
+
 	/* TODO: I'm not too happy returning zeros here.  But that's all I've got */
 	g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), 0);
 	g_return_val_if_fail(DBUSMENU_IS_MENUITEM(parent), 0);
@@ -417,6 +430,10 @@
 
 	if (childs == NULL) return 0;
 
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Getting position of %d (%s), it's at: %d", ID(mi), LABEL(mi), count);
+	#endif
+
 	return count;
 }
 
@@ -438,6 +455,9 @@
 
 	DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
 	priv->children = g_list_append(priv->children, child);
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Menuitem %d (%s) signalling child added %d (%s) at %d", ID(mi), LABEL(mi), ID(child), LABEL(child), g_list_length(priv->children) - 1);
+	#endif
 	g_signal_emit(G_OBJECT(mi), signals[CHILD_ADDED], 0, child, g_list_length(priv->children) - 1, TRUE);
 	return TRUE;
 }
@@ -460,6 +480,9 @@
 
 	DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
 	priv->children = g_list_prepend(priv->children, child);
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Menuitem %d (%s) signalling child added %d (%s) at %d", ID(mi), LABEL(mi), ID(child), LABEL(child), 0);
+	#endif
 	g_signal_emit(G_OBJECT(mi), signals[CHILD_ADDED], 0, child, 0, TRUE);
 	return TRUE;
 }
@@ -483,6 +506,9 @@
 
 	DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
 	priv->children = g_list_remove(priv->children, child);
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Menuitem %d (%s) signalling child removed %d (%s)", ID(mi), LABEL(mi), ID(child), LABEL(child));
+	#endif
 	g_signal_emit(G_OBJECT(mi), signals[CHILD_REMOVED], 0, child, TRUE);
 	return TRUE;
 }
@@ -507,6 +533,9 @@
 
 	DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
 	priv->children = g_list_insert(priv->children, child, position);
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Menuitem %d (%s) signalling child added %d (%s) at %d", ID(mi), LABEL(mi), ID(child), LABEL(child), position);
+	#endif
 	g_signal_emit(G_OBJECT(mi), signals[CHILD_ADDED], 0, child, position, TRUE);
 	return TRUE;
 }
@@ -543,6 +572,9 @@
 	priv->children = g_list_remove(priv->children, child);
 	priv->children = g_list_insert(priv->children, child, position);
 
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Menuitem %d (%s) signalling child %d (%s) moved from %d to %d", ID(mi), LABEL(mi), ID(child), LABEL(child), oldpos, position);
+	#endif
 	g_signal_emit(G_OBJECT(mi), signals[CHILD_MOVED], 0, child, position, oldpos, TRUE);
 
 	return TRUE;
@@ -658,6 +690,9 @@
 	gchar * lval = g_strdup(value);
 
 	g_hash_table_insert(priv->properties, lprop, lval);
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Menuitem %d (%s) signalling property '%s' changed to '%s'", ID(mi), LABEL(mi), property, g_utf8_strlen(value, 50) < 25 ? value : "<too long>");
+	#endif
 	g_signal_emit(G_OBJECT(mi), signals[PROPERTY_CHANGED], 0, property, value, TRUE);
 
 	return TRUE;
@@ -882,6 +917,9 @@
 dbusmenu_menuitem_activate (DbusmenuMenuitem * mi)
 {
 	g_return_if_fail(DBUSMENU_IS_MENUITEM(mi));
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Menuitem %d (%s) activated", ID(mi), LABEL(mi));
+	#endif
 	g_signal_emit(G_OBJECT(mi), signals[ITEM_ACTIVATED], 0, TRUE);
 	return;
 }

=== modified file 'libdbusmenu-gtk/Makefile.am'
--- libdbusmenu-gtk/Makefile.am	2009-09-02 18:29:01 +0000
+++ libdbusmenu-gtk/Makefile.am	2009-10-01 19:22:18 +0000
@@ -26,7 +26,7 @@
 	-export-symbols-regex "^[^_].*"
 
 libdbusmenu_gtk_la_CFLAGS = \
-	$(DBUSMENUGTK_CFLAGS) -I$(srcdir)/.. -Wall -Werror
+	$(DBUSMENUGTK_CFLAGS) -I$(srcdir)/.. -Wall -Werror -DG_DISABLE_DEPRECATED -DG_LOG_DOMAIN="\"LIBDBUSMENU-GTK\""
 
 libdbusmenu_gtk_la_LIBADD = \
 	../libdbusmenu-glib/libdbusmenu-glib.la \

=== modified file 'libdbusmenu-gtk/client.c'
--- libdbusmenu-gtk/client.c	2009-09-09 21:50:48 +0000
+++ libdbusmenu-gtk/client.c	2009-10-02 20:01:16 +0000
@@ -159,7 +159,9 @@
 static void
 destoryed_dbusmenuitem_cb (gpointer udata, GObject * dbusmenuitem)
 {
-	/* g_debug("DbusmenuMenuitem was destroyed"); */
+	#ifdef MASSIVEDEBUGGING
+	g_debug("DbusmenuMenuitem was destroyed");
+	#endif
 	gtk_widget_destroy(GTK_WIDGET(udata));
 	return;
 }
@@ -176,6 +178,15 @@
 	return;
 }
 
+#ifdef MASSIVEDEBUGGING
+static void
+destroy_gmi (GtkMenuItem * gmi, DbusmenuMenuitem * mi)
+{
+	g_debug("Destorying GTK Menuitem for %d", dbusmenu_menuitem_get_id(mi));
+	return;
+}
+#endif
+
 /**
 	dbusmenu_gtkclient_newitem_base:
 	@client: The client handling everything on this connection
@@ -195,8 +206,16 @@
 void
 dbusmenu_gtkclient_newitem_base (DbusmenuGtkClient * client, DbusmenuMenuitem * item, GtkMenuItem * gmi, DbusmenuMenuitem * parent)
 {
+	#ifdef MASSIVEDEBUGGING
+	g_debug("GTK Client new item base for %d", dbusmenu_menuitem_get_id(item));
+	#endif
+
 	/* Attach these two */
 	g_object_set_data(G_OBJECT(item), data_menuitem, gmi);
+	g_object_ref(G_OBJECT(gmi));
+	#ifdef MASSIVEDEBUGGING
+	g_signal_connect(G_OBJECT(gmi), "destroy", G_CALLBACK(destroy_gmi), item);
+	#endif
 
 	/* DbusmenuMenuitem signals */
 	g_signal_connect(G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(menu_prop_change_cb), gmi);
@@ -222,6 +241,10 @@
 static void
 new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, DbusmenuGtkClient * gtkclient)
 {
+	#ifdef MASSIVEDEBUGGING
+	g_debug("GTK Client new child for %d on %d at %d", dbusmenu_menuitem_get_id(mi), dbusmenu_menuitem_get_id(child), position);
+	#endif
+
 	if (dbusmenu_menuitem_get_root(mi)) { return; }
 
 	gpointer ann_menu = g_object_get_data(G_OBJECT(mi), data_menu);
@@ -316,14 +339,13 @@
 	g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), NULL);
 	g_return_val_if_fail(DBUSMENU_IS_MENUITEM(item), NULL);
 
-	GtkMenuItem * mi = GTK_MENU_ITEM(g_object_get_data(G_OBJECT(item), data_menuitem));
-	if (mi == NULL) {
-		// new_menuitem(DBUSMENU_CLIENT(client), item, NULL);
+	gpointer data = g_object_get_data(G_OBJECT(item), data_menuitem);
+	if (data == NULL) {
 		g_warning("GTK not updated");
-		mi = GTK_MENU_ITEM(g_object_get_data(G_OBJECT(item), data_menuitem));
+		return NULL;
 	}
 
-	return mi;
+	return GTK_MENU_ITEM(data);
 }
 
 /* The base type handler that builds a plain ol'

=== modified file 'libdbusmenu-gtk/menu.c'
--- libdbusmenu-gtk/menu.c	2009-09-09 22:09:10 +0000
+++ libdbusmenu-gtk/menu.c	2009-10-02 01:44:05 +0000
@@ -185,6 +185,28 @@
 
 /* Internal Functions */
 
+#ifdef MASSIVEDEBUGGING
+typedef struct {
+	GtkMenuItem * mi;
+	gint finalpos;
+	gboolean found;
+} menu_pos_t;
+
+static void
+find_pos (GtkWidget * widget, gpointer data)
+{
+	menu_pos_t * menu_pos = (menu_pos_t *)data;
+	if (menu_pos->found) return;
+	if ((gpointer)(menu_pos->mi) == (gpointer)widget) {
+		menu_pos->found = TRUE;
+	} else {
+		menu_pos->finalpos++;
+	}
+	return;
+}
+#endif
+
+
 /* Called when a new child of the root item is
    added.  Sets up a signal for when it's actually
    realized. */
@@ -192,7 +214,24 @@
 root_child_added (DbusmenuMenuitem * root, DbusmenuMenuitem * child, guint position, DbusmenuGtkMenu * menu)
 {
 	g_debug("Root new child");
+	DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(menu);
+
 	g_signal_connect(G_OBJECT(child), DBUSMENU_MENUITEM_SIGNAL_REALIZED, G_CALLBACK(child_realized), menu);
+
+	GtkMenuItem * mi = dbusmenu_gtkclient_menuitem_get(priv->client, child);
+	if (mi != NULL) {
+		GtkWidget * item = GTK_WIDGET(mi);
+		gtk_menu_insert(GTK_MENU(menu), item, position);
+		#ifdef MASSIVEDEBUGGING
+		menu_pos_t menu_pos;
+		menu_pos.mi = mi;
+		menu_pos.finalpos = 0;
+		menu_pos.found = FALSE;
+
+		gtk_container_foreach(GTK_CONTAINER(menu), find_pos, &menu_pos);
+		g_debug("Menu position requested was %d but got %d", position, menu_pos.finalpos);
+		#endif
+	}
 	return;
 }
 
@@ -212,6 +251,12 @@
 root_child_delete (DbusmenuMenuitem * root, DbusmenuMenuitem * child, DbusmenuGtkMenu * menu)
 {
 	g_debug("Root child deleted");
+	DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(menu);
+	GtkWidget * item = GTK_WIDGET(dbusmenu_gtkclient_menuitem_get(priv->client, child));
+	if (item != NULL) {
+		gtk_container_remove(GTK_CONTAINER(menu), item);
+	}
+
 	if (g_list_length(dbusmenu_menuitem_get_children(root)) == 0) {
 		gtk_widget_hide(GTK_WIDGET(menu));
 	}
@@ -223,6 +268,7 @@
 static void
 child_realized (DbusmenuMenuitem * child, gpointer userdata)
 {
+	g_debug("Root child realized");
 	g_return_if_fail(DBUSMENU_IS_GTKMENU(userdata));
 
 	DbusmenuGtkMenu * menu = DBUSMENU_GTKMENU(userdata);

=== modified file 'tests/Makefile.am'
--- tests/Makefile.am	2009-07-01 05:34:05 +0000
+++ tests/Makefile.am	2009-09-30 20:52:42 +0000
@@ -1,12 +1,15 @@
 SUBDIRS = dbusmenu-gtk
 
-check: tests
-
 DBUS_RUNNER=dbus-test-runner --dbus-config /usr/share/dbus-test-runner/session.conf
 
-tests: test-glib-layout test-glib-properties test-gtk-label test-glib-simple-items
+TESTS = \
+	test-glib-layout \
+	test-glib-properties \
+	test-gtk-label \
+	test-glib-simple-items \
+	test-gtk-reorder
 
-libexec_PROGRAMS = \
+check_PROGRAMS = \
 	glib-server-nomenu \
 	test-glib-layout-client \
 	test-glib-layout-server \
@@ -14,7 +17,8 @@
 	test-glib-properties-server \
 	test-gtk-label-client \
 	test-gtk-label-server \
-	test-glib-simple-items
+	test-glib-simple-items \
+	test-gtk-reorder-server
 
 glib_server_nomenu_SOURCES = \
 	glib-server-nomenu.c
@@ -27,10 +31,14 @@
 	../libdbusmenu-glib/libdbusmenu-glib.la \
 	$(DBUSMENUGLIB_LIBS)
 
-
+######################
+# Test Glib Layout
+######################
 
 test-glib-layout: test-glib-layout-client test-glib-layout-server
-	$(DBUS_RUNNER) --task ./test-glib-layout-client --task-name Client --task ./test-glib-layout-server --task-name Server --ignore-return
+	@echo "#!/bin/sh" > test-glib-layout
+	@echo $(DBUS_RUNNER) --task ./test-glib-layout-client --task-name Client --task ./test-glib-layout-server --task-name Server --ignore-return >> test-glib-layout
+	@chmod +x test-glib-layout
 
 test_glib_layout_server_SOURCES = \
 	test-glib-layout.h \
@@ -57,9 +65,14 @@
 	$(DBUSMENUGLIB_LIBS)
 
 
+######################
+# Test Glib Properties
+######################
 
 test-glib-properties: test-glib-properties-client test-glib-properties-server
-	$(DBUS_RUNNER) --task ./test-glib-properties-client --task-name Client --task ./test-glib-properties-server --task-name Server --ignore-return
+	@echo "#!/bin/sh" > test-glib-properties
+	@echo $(DBUS_RUNNER) --task ./test-glib-properties-client --task-name Client --task ./test-glib-properties-server --task-name Server --ignore-return >> test-glib-properties
+	@chmod +x test-glib-properties
 
 test_glib_properties_server_SOURCES = \
 	test-glib-properties.h \
@@ -85,6 +98,9 @@
 	../libdbusmenu-glib/libdbusmenu-glib.la \
 	$(DBUSMENUGLIB_LIBS)
 
+#########################
+# Test Glib Simple Items
+#########################
 
 test_glib_simple_items_SOURCES = \
 	test-glib-simple-items.c
@@ -97,9 +113,14 @@
 	../libdbusmenu-glib/libdbusmenu-glib.la \
 	$(DBUSMENUGLIB_LIBS)
 
+#########################
+# Test GTK Label
+#########################
 
 test-gtk-label: test-gtk-label-client test-gtk-label-server test-gtk-label.json
-	$(DBUS_RUNNER) --task ./test-gtk-label-client --task-name Client --task ./test-gtk-label-server --parameter $(srcdir)/test-gtk-label.json --task-name Server --ignore-return
+	@echo "#!/bin/sh" > test-gtk-label
+	@echo $(DBUS_RUNNER) --task ./test-gtk-label-client --task-name Client --task ./test-gtk-label-server --parameter $(srcdir)/test-gtk-label.json --task-name Server --ignore-return >> test-gtk-label
+	@chmod +x test-gtk-label
 
 test_gtk_label_server_SOURCES = \
 	test-gtk-label-server.c
@@ -131,7 +152,34 @@
 	$(DBUSMENUGTK_LIBS) \
 	$(DBUSMENUTESTS_LIBS)
 
-
+#########################
+# Test GTK Reorder
+#########################
+
+test-gtk-reorder: test-gtk-label-client test-gtk-reorder-server
+	@echo "#!/bin/sh" > test-gtk-reorder
+	@echo $(DBUS_RUNNER) --task ./test-gtk-label-client --task-name Client --task ./test-gtk-reorder-server --parameter $(srcdir)/test-gtk-label.json --task-name Server --ignore-return >> test-gtk-reorder
+	@chmod +x test-gtk-reorder
+
+test_gtk_reorder_server_SOURCES = \
+	test-gtk-reorder-server.c
+
+test_gtk_reorder_server_CFLAGS = \
+	-I $(srcdir)/.. \
+	$(DBUSMENUGTK_CFLAGS) \
+	$(DBUSMENUTESTS_CFLAGS) \
+	$(DBUSMENUGLIB_CFLAGS) -Wall -Werror
+
+test_gtk_reorder_server_LDADD = \
+	../libdbusmenu-glib/libdbusmenu-glib.la \
+	../libdbusmenu-gtk/libdbusmenu-gtk.la \
+	$(DBUSMENUGTK_LIBS) \
+	$(DBUSMENUTESTS_LIBS)
+
+
+#########################
+# Other
+#########################
 
 examplesdir = $(docdir)/examples/
 

=== modified file 'tests/test-glib-simple-items.c'
--- tests/test-glib-simple-items.c	2009-07-01 05:34:05 +0000
+++ tests/test-glib-simple-items.c	2009-09-30 19:58:04 +0000
@@ -25,6 +25,13 @@
 	return;
 }
 
+static gboolean
+quititall (gpointer data)
+{
+	g_main_quit(mainloop);
+	return FALSE;
+}
+
 int
 main (int argc, char ** argv)
 {
@@ -37,6 +44,8 @@
 
 	dummy_users(root_menuitem);
 
+	g_timeout_add_seconds(1, quititall, NULL);
+
     mainloop = g_main_loop_new(NULL, FALSE);
     g_main_loop_run(mainloop);
 

=== added file 'tests/test-gtk-reorder-server.c'
--- tests/test-gtk-reorder-server.c	1970-01-01 00:00:00 +0000
+++ tests/test-gtk-reorder-server.c	2009-09-30 21:53:08 +0000
@@ -0,0 +1,119 @@
+/*
+A test for libdbusmenu to ensure its quality.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+    Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it 
+under the terms of the GNU General Public License version 3, as published 
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but 
+WITHOUT ANY WARRANTY; without even the implied warranties of 
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
+PURPOSE.  See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along 
+with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <libdbusmenu-glib/menuitem.h>
+#include <libdbusmenu-glib/server.h>
+
+#define NUMBER_TESTS    5
+#define NUMBER_ENTRIES  5
+
+guint ordering [NUMBER_TESTS][NUMBER_ENTRIES] = {
+	{0, 1, 2, 3, 4},
+	{1, 2, 3, 4, 0},
+	{3, 1, 4, 2, 0},
+	{4, 3, 2, 1, 0},
+	{0, 1, 2, 3, 4}
+};
+
+gchar * names [NUMBER_ENTRIES] = {
+	"One", "Two", "Three", "Four", "Five"
+};
+
+DbusmenuMenuitem * entries[NUMBER_ENTRIES] = {0};
+DbusmenuMenuitem * root = NULL;
+
+gint test = 0;
+
+static DbusmenuServer * server = NULL;
+static GMainLoop * mainloop = NULL;
+
+static gboolean
+timer_func (gpointer data)
+{
+	if (test == NUMBER_TESTS) {
+		g_main_quit(mainloop);
+		return FALSE;
+	}
+
+	g_debug("Testing pattern %d", test);
+
+	int i;
+	for (i = 0; i < NUMBER_ENTRIES; i++) {
+		g_debug("Putting entry '%d' at position '%d'", i, ordering[test][i]);
+		dbusmenu_menuitem_child_reorder(root, entries[i], ordering[test][i]);
+		dbusmenu_menuitem_property_set(entries[i], "label", names[i]);
+	}
+
+	test++;
+	return TRUE;
+}
+
+int
+main (int argc, char ** argv)
+{
+	GError * error = NULL;
+
+	g_type_init();
+
+	DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+	g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
+
+	DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+	guint nameret = 0;
+
+	if (!org_freedesktop_DBus_request_name(bus_proxy, "glib.label.test", 0, &nameret, &error)) {
+		g_error("Unable to call to request name");
+		return 1;
+	}
+
+	if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+		g_error("Unable to get name");
+		return 1;
+	}
+
+	server = dbusmenu_server_new("/org/test");
+	root = dbusmenu_menuitem_new();
+	dbusmenu_server_set_root(server, root);
+
+	int i;
+	for (i = 0; i < NUMBER_ENTRIES; i++) {
+		entries[i] = dbusmenu_menuitem_new();
+		dbusmenu_menuitem_child_append(root, entries[i]);
+	}
+
+	timer_func(NULL);
+	g_timeout_add_seconds(5, timer_func, NULL);
+
+	mainloop = g_main_loop_new(NULL, FALSE);
+	g_main_loop_run(mainloop);
+
+	g_debug("Quiting");
+
+	return 0;
+}
+