← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~mterry/indicator-appmenu/gdbus into lp:indicator-appmenu

 

Michael Terry has proposed merging lp:~mterry/indicator-appmenu/gdbus into lp:indicator-appmenu.

Requested reviews:
  Indicator Applet Developers (indicator-applet-developers)

For more details, see:
https://code.launchpad.net/~mterry/indicator-appmenu/gdbus/+merge/46045
-- 
https://code.launchpad.net/~mterry/indicator-appmenu/gdbus/+merge/46045
Your team ayatana-commits is subscribed to branch lp:indicator-appmenu.
=== modified file 'configure.ac'
--- configure.ac	2010-10-06 18:43:21 +0000
+++ configure.ac	2011-01-12 21:23:11 +0000
@@ -47,15 +47,15 @@
 ###########################
 
 GTK_REQUIRED_VERSION=2.12
+GIO_REQUIRED_VERSION=2.26
 INDICATOR_REQUIRED_VERSION=0.3.14
 DBUSMENUGTK_REQUIRED_VERSION=0.3.3
-DBUS_GLIB_REQUIRED_VERSION=0.82
 BAMF_REQUIRED_VERSION=0.2.53
 
 PKG_CHECK_MODULES(INDICATOR, gtk+-2.0 >= $GTK_REQUIRED_VERSION
+                             gio-2.0 >= $GIO_REQUIRED_VERSION
                              indicator >= $INDICATOR_REQUIRED_VERSION
-                             dbus-glib-1 >= $DBUS_GLIB_REQUIRED_VERSION
-                             dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION
+                             dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
                              libbamf >= $BAMF_REQUIRED_VERSION)
 
 AC_SUBST(INDICATOR_CFLAGS)
@@ -68,13 +68,19 @@
 DBUSMENU_JSONLOADER_REQUIRED_VERSION=0.3.3
 
 PKG_CHECK_MODULES(INDICATORTEST,
-                  dbusmenu-jsonloader >= $DBUSMENU_JSONLOADER_REQUIRED_VERSION
+                  dbusmenu-jsonloader-0.4 >= $DBUSMENU_JSONLOADER_REQUIRED_VERSION
                  )
 
 AC_SUBST(INDICATORTEST_CFLAGS)
 AC_SUBST(INDICATORTEST_LIBS)
 
 ###########################
+# XSLT Processor
+###########################
+
+AC_PATH_PROG([XSLT_PROC], [xsltproc])
+
+###########################
 # Check to see if we're local
 ###########################
 

=== modified file 'scripts/menu-pusher.c'
--- scripts/menu-pusher.c	2010-07-20 21:48:25 +0000
+++ scripts/menu-pusher.c	2011-01-12 21:23:11 +0000
@@ -20,12 +20,11 @@
 */
 
 #include <gtk/gtk.h>
-#include <dbus/dbus-glib.h>
+#include <gio/gio.h>
 #include <libdbusmenu-glib/menuitem.h>
 #include <libdbusmenu-glib/server.h>
 #include <libdbusmenu-gtk/menuitem.h>
 #include "../src/dbus-shared.h"
-#include "../src/application-menu-registrar-client.h"
 
 int
 main (int argv, char ** argc)
@@ -73,16 +72,18 @@
 	dbusmenu_server_set_root(server, root);
 
 
-	DBusGConnection * session = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
-	g_return_val_if_fail(session != NULL, 1);
-
-	DBusGProxy * proxy = dbus_g_proxy_new_for_name_owner(session, DBUS_NAME, REG_OBJECT, REG_IFACE, NULL);
+	GDBusProxy * proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SESSION,
+	                                                   G_DBUS_PROXY_FLAGS_NONE,
+	                                                   NULL, DBUS_NAME,
+	                                                   REG_OBJECT, REG_IFACE,
+	                                                   NULL, NULL);
 	g_return_val_if_fail(proxy != NULL, 1);
 
-	org_ayatana_AppMenu_Registrar_register_window(proxy, 0, "/this/is/a/long/object/path", NULL);
+	g_dbus_proxy_call_sync(proxy, "RegisterWindow",
+	                       g_variant_new("(uo)", 0, "/this/is/a/long/object/path"),
+	                       G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL);
 
 	gtk_main();
 
-
 	return 0;
 }

=== modified file 'src/Makefile.am'
--- src/Makefile.am	2010-09-03 16:30:59 +0000
+++ src/Makefile.am	2011-01-12 21:23:11 +0000
@@ -12,7 +12,6 @@
 appmenulibdir = $(INDICATORDIR)
 appmenulib_LTLIBRARIES = libappmenu.la
 libappmenu_la_SOURCES = \
-	application-menu-registrar-server.h \
 	dbus-shared.h \
 	gdk-get-func.h \
 	gdk-get-func.c \
@@ -20,7 +19,11 @@
 	indicator-appmenu.c \
 	indicator-appmenu-marshal.c \
 	window-menus.c \
-	window-menus.h
+	window-menus.h \
+	gen-application-menu-renderer.xml.c \
+	gen-application-menu-renderer.xml.h \
+	gen-application-menu-registrar.xml.c \
+	gen-application-menu-registrar.xml.h
 libappmenu_la_CFLAGS = $(INDICATOR_CFLAGS) -Wall -Wl,-Bsymbolic-functions -Wl,-z,defs -Wl,--as-needed -Werror
 libappmenu_la_LIBADD = $(INDICATOR_LIBS) -lX11
 libappmenu_la_LDFLAGS = -module -avoid-version
@@ -40,24 +43,23 @@
 	application-menu-renderer.xml \
 	application-menu-registrar.xml
 
-%-client.h: %.xml
-	dbus-binding-tool \
-		--prefix=_$(notdir $(subst -,_,$(<:.xml=)))_client \
-		--mode=glib-client \
-		--output=$@ \
-		$<
+gen-%.xml.c: %.xml
+	@echo "Building $@ from $<"
+	@echo "const char * _$(subst -,_,$(subst .,_,$(basename $<))) = " > $@
+	@$(XSLT_PROC) $(srcdir)/clean-namespaces.xslt $< | \
+		sed -e "s:\":\\\\\":g" -e s:^:\": -e s:\$$:\\\\n\": >> $@
+	@echo ";" >> $@
 
-%-server.h: %.xml
-	dbus-binding-tool \
-		--prefix=_$(notdir $(subst -,_,$(<:.xml=)))_server \
-		--mode=glib-server \
-		--output=$@ \
-		$<
+gen-%.xml.h: %.xml
+	@echo "Building $@ from $<"
+	@echo "extern const char * _$(subst -,_,$(subst .,_,$(basename $<)));" > $@
 
 BUILT_SOURCES += \
-	$(DBUS_SPECS:.xml=-client.h) \
-	$(DBUS_SPECS:.xml=-server.h)
+	gen-application-menu-renderer.xml.c \
+	gen-application-menu-renderer.xml.h \
+	gen-application-menu-registrar.xml.c \
+	gen-application-menu-registrar.xml.h
 
 CLEANFILES += $(BUILT_SOURCES)
 
-EXTRA_DIST += $(DBUS_SPECS)
+EXTRA_DIST += $(DBUS_SPECS) clean-namespaces.xslt

=== modified file 'src/application-menu-renderer.xml'
--- src/application-menu-renderer.xml	2010-07-13 19:52:07 +0000
+++ src/application-menu-renderer.xml	2011-01-12 21:23:11 +0000
@@ -1,5 +1,5 @@
 <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
-<node name="/org/ayatana/AppMenu/Renderer">
+<node name="/org/ayatana/AppMenu/Renderer" xmlns:dox="http://www.ayatana.org/dbus/dox.dtd";>
 	<dox:d><![CDATA[
 	  @mainpage
 	 

=== added file 'src/clean-namespaces.xslt'
--- src/clean-namespaces.xslt	1970-01-01 00:00:00 +0000
+++ src/clean-namespaces.xslt	2011-01-12 21:23:11 +0000
@@ -0,0 +1,14 @@
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; xmlns:dox="http://www.ayatana.org/dbus/dox.dtd";>
+	<xsl:template match="*|@*">
+		<xsl:copy>
+			<xsl:apply-templates select="*|@*" />
+		</xsl:copy>
+	</xsl:template>
+	<xsl:template match="@dox:*|dox:*"/>
+	<xsl:template match="*">
+		<xsl:element name="{local-name()}">
+			<xsl:apply-templates select="@* | node()"/>
+		</xsl:element>
+	</xsl:template>
+</xsl:stylesheet>
+

=== modified file 'src/indicator-appmenu.c'
--- src/indicator-appmenu.c	2010-10-06 18:43:21 +0000
+++ src/indicator-appmenu.c	2011-01-12 21:23:11 +0000
@@ -25,11 +25,7 @@
 
 #include <X11/Xlib.h>
 #include <gdk/gdkx.h>
-
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-bindings.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <dbus/dbus-gtype-specialized.h>
+#include <gio/gio.h>
 
 #include <libindicator/indicator.h>
 #include <libindicator/indicator-object.h>
@@ -39,6 +35,8 @@
 
 #include <libbamf/bamf-matcher.h>
 
+#include "gen-application-menu-registrar.xml.h"
+#include "gen-application-menu-renderer.xml.h"
 #include "indicator-appmenu-marshal.h"
 #include "window-menus.h"
 #include "dbus-shared.h"
@@ -102,6 +100,10 @@
 	WindowMenus * desktop_menu;
 
 	IndicatorAppmenuDebug * debug;
+
+	GDBusConnection * bus;
+	guint owner_id;
+	guint dbus_registration;
 };
 
 
@@ -124,6 +126,9 @@
 struct _IndicatorAppmenuDebug {
 	GObject parent;
 	IndicatorAppmenu * appmenu;
+	GCancellable * bus_cancel;
+	GDBusConnection * bus;
+	guint dbus_registration;
 };
 
 
@@ -136,6 +141,7 @@
 static void indicator_appmenu_finalize                               (GObject *object);
 static void indicator_appmenu_debug_class_init                       (IndicatorAppmenuDebugClass *klass);
 static void indicator_appmenu_debug_init                             (IndicatorAppmenuDebug *self);
+static void indicator_appmenu_debug_dispose                          (GObject *object);
 static void build_window_menus                                       (IndicatorAppmenu * iapp);
 static GList * get_entries                                           (IndicatorObject * io);
 static guint get_location                                            (IndicatorObject * io,
@@ -153,25 +159,6 @@
 static void old_window                                               (BamfMatcher * matcher,
                                                                       BamfView * view,
                                                                       gpointer user_data);
-static gboolean _application_menu_registrar_server_register_window   (IndicatorAppmenu * iapp,
-                                                                      guint windowid,
-                                                                      const gchar * objectpath,
-                                                                      DBusGMethodInvocation * method);
-static gboolean _application_menu_registrar_server_unregister_window (IndicatorAppmenu * iapp,
-                                                                      guint windowid,
-                                                                      GError ** error);
-static gboolean _application_menu_registrar_server_get_menu_for_window (IndicatorAppmenu * iapp,
-                                                                      guint windowid,
-                                                                      gchar ** objectpath,
-                                                                      gchar ** address,
-                                                                      GError ** error);
-static gboolean _application_menu_registrar_server_get_menus         (IndicatorAppmenu * iapp,
-                                                                      GPtrArray ** entries,
-                                                                      GError ** error);
-static void request_name_cb                                          (DBusGProxy *proxy,
-                                                                      guint result,
-                                                                      GError *error,
-                                                                      gpointer userdata);
 static void window_entry_added                                       (WindowMenus * mw,
                                                                       IndicatorObjectEntry * entry,
                                                                       gpointer user_data);
@@ -186,22 +173,36 @@
                                                                       BamfView * oldview,
                                                                       BamfView * newview,
                                                                       gpointer user_data);
-static gboolean _application_menu_renderer_server_get_current_menu   (IndicatorAppmenuDebug * iappd,
-                                                                      gchar ** objectpath,
-                                                                      gchar ** address,
-                                                                      GError ** error);
-static gboolean _application_menu_renderer_server_activate_menu_item (IndicatorAppmenuDebug * iappd,
-                                                                      GArray * menulist,
-                                                                      GError ** error);
-static gboolean _application_menu_renderer_server_dump_current_menu  (IndicatorAppmenuDebug * iappd,
-                                                                      gchar ** jsondata,
-                                                                      GError ** error);
-static gboolean _application_menu_renderer_server_dump_menu          (IndicatorAppmenuDebug * iappd,
-                                                                      guint windowid,
-                                                                      gchar ** jsondata,
-                                                                      GError ** error);
 static GQuark error_quark                                            (void);
 static gboolean retry_registration                                   (gpointer user_data);
+static void bus_method_call                                          (GDBusConnection * connection,
+                                                                      const gchar * sender,
+                                                                      const gchar * path,
+                                                                      const gchar * interface,
+                                                                      const gchar * method,
+                                                                      GVariant * params,
+                                                                      GDBusMethodInvocation * invocation,
+                                                                      gpointer user_data);
+static void on_bus_acquired                                          (GDBusConnection * connection,
+                                                                      const gchar * name,
+                                                                      gpointer user_data);
+static void on_name_acquired                                         (GDBusConnection * connection,
+                                                                      const gchar * name,
+                                                                      gpointer user_data);
+static void on_name_lost                                             (GDBusConnection * connection,
+                                                                      const gchar * name,
+                                                                      gpointer user_data);
+static void dbg_bus_method_call                                      (GDBusConnection * connection,
+                                                                      const gchar * sender,
+                                                                      const gchar * path,
+                                                                      const gchar * interface,
+                                                                      const gchar * method,
+                                                                      GVariant * params,
+                                                                      GDBusMethodInvocation * invocation,
+                                                                      gpointer user_data);
+static void dbg_bus_get_cb                                           (GObject * object,
+                                                                      GAsyncResult * res,
+                                                                      gpointer user_data);
 
 /* Unique error codes for debug interface */
 enum {
@@ -213,16 +214,21 @@
 /**********************
   DBus Interfaces
  **********************/
-#include "application-menu-registrar-server.h"
-#include "application-menu-renderer-server.h"
-
-enum {
-	WINDOW_REGISTERED,
-	WINDOW_UNREGISTERED,
-	LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
+static GDBusNodeInfo *      node_info = NULL;
+static GDBusInterfaceInfo * interface_info = NULL;
+static GDBusInterfaceVTable interface_table = {
+       method_call:    bus_method_call,
+       get_property:   NULL, /* No properties */
+       set_property:   NULL  /* No properties */
+};
+
+static GDBusNodeInfo *      dbg_node_info = NULL;
+static GDBusInterfaceInfo * dbg_interface_info = NULL;
+static GDBusInterfaceVTable dbg_interface_table = {
+       method_call:    dbg_bus_method_call,
+       get_property:   NULL, /* No properties */
+       set_property:   NULL  /* No properties */
+};
 
 G_DEFINE_TYPE (IndicatorAppmenu, indicator_appmenu, INDICATOR_OBJECT_TYPE);
 
@@ -241,22 +247,24 @@
 	ioclass->get_location = get_location;
 	ioclass->entry_activate = entry_activate;
 
-	signals[WINDOW_REGISTERED] =  g_signal_new("window-registered",
-	                                      G_TYPE_FROM_CLASS(klass),
-	                                      G_SIGNAL_RUN_LAST,
-	                                      G_STRUCT_OFFSET (IndicatorAppmenuClass, window_registered),
-	                                      NULL, NULL,
-	                                      _indicator_appmenu_marshal_VOID__UINT_STRING_BOXED,
-	                                      G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_STRING, DBUS_TYPE_G_OBJECT_PATH);
-	signals[WINDOW_UNREGISTERED] =  g_signal_new("window-unregistered",
-	                                      G_TYPE_FROM_CLASS(klass),
-	                                      G_SIGNAL_RUN_LAST,
-	                                      G_STRUCT_OFFSET (IndicatorAppmenuClass, window_unregistered),
-	                                      NULL, NULL,
-	                                      _indicator_appmenu_marshal_VOID__UINT,
-	                                      G_TYPE_NONE, 1, G_TYPE_UINT);
-
-	dbus_g_object_type_install_info(INDICATOR_APPMENU_TYPE, &dbus_glib__application_menu_registrar_server_object_info);
+	/* Setting up the DBus interfaces */
+	if (node_info == NULL) {
+		GError * error = NULL;
+
+		node_info = g_dbus_node_info_new_for_xml(_application_menu_registrar, &error);
+		if (error != NULL) {
+			g_error("Unable to parse Application Menu Interface description: %s", error->message);
+			g_error_free(error);
+		}
+	}
+
+	if (interface_info == NULL) {
+		interface_info = g_dbus_node_info_lookup_interface(node_info, REG_IFACE);
+
+		if (interface_info == NULL) {
+			g_error("Unable to find interface '" REG_IFACE "'");
+		}
+	}
 
 	return;
 }
@@ -273,6 +281,9 @@
 	self->active_stubs = STUBS_UNKNOWN;
 	self->close_item = NULL;
 	self->retry_registration = 0;
+	self->bus = NULL;
+	self->owner_id = 0;
+	self->dbus_registration = 0;
 
 	/* Setup the entries for the fallbacks */
 	self->window_menus = g_array_sized_new(FALSE, FALSE, sizeof(IndicatorObjectEntry), 2);
@@ -299,38 +310,8 @@
 
 	find_desktop_windows(self);
 
-	/* Register this object on DBus */
-	gboolean sent_registration = FALSE;
-	GError * error = NULL;
-	DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
-	if (connection != NULL && error == NULL) {
-		dbus_g_connection_register_g_object(connection,
-		                                    REG_OBJECT,
-		                                    G_OBJECT(self));
-
-		/* Request a name so others can find us */
-		DBusGProxy * dbus_proxy = dbus_g_proxy_new_for_name_owner(connection,
-		                                                   DBUS_SERVICE_DBUS,
-		                                                   DBUS_PATH_DBUS,
-		                                                   DBUS_INTERFACE_DBUS,
-		                                                   NULL);
-		if (dbus_proxy != NULL) {
-			org_freedesktop_DBus_request_name_async (dbus_proxy,
-		                                         	DBUS_NAME,
-		                                         	DBUS_NAME_FLAG_DO_NOT_QUEUE,
-		                                         	request_name_cb,
-		                                         	self);
-			sent_registration = TRUE;
-		} else {
-			g_warning("Unable to get proxy to DBus daemon");
-		}
-	} else {
-		g_warning("Unable to connect to session bus");
-	}
-
-	if (!sent_registration) {
-		self->retry_registration = g_timeout_add_seconds(1, retry_registration, self);
-	}
+	/* Request a name so others can find us */
+	retry_registration(self);
 
 	/* Setup debug interface */
 	self->debug = g_object_new(INDICATOR_APPMENU_DEBUG_TYPE, NULL);
@@ -339,6 +320,82 @@
 	return;
 }
 
+/* If we weren't able to register on the bus, then we need
+   to try it all again. */
+static gboolean
+retry_registration (gpointer user_data)
+{
+	g_return_val_if_fail(IS_INDICATOR_APPMENU(user_data), FALSE);
+	IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data);
+
+	iapp->owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
+	                                 DBUS_NAME,
+	                                 G_BUS_NAME_OWNER_FLAGS_NONE,
+	                                 iapp->dbus_registration == 0 ? on_bus_acquired : NULL,
+	                                 on_name_acquired,
+	                                 on_name_lost,
+	                                 g_object_ref(iapp),
+	                                 g_object_unref);
+
+	return TRUE;
+}
+
+static void
+on_bus_acquired (GDBusConnection * connection, const gchar * name,
+                 gpointer user_data)
+{
+	IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data);
+	GError * error = NULL;
+
+	iapp->bus = connection;
+
+	/* Now register our object on our new connection */
+	iapp->dbus_registration = g_dbus_connection_register_object(connection,
+	                                                            REG_OBJECT,
+	                                                            interface_info,
+	                                                            &interface_table,
+	                                                            user_data,
+	                                                            NULL,
+	                                                            &error);
+
+	if (error != NULL) {
+		g_error("Unable to register the object to DBus: %s", error->message);
+		g_error_free(error);
+		g_bus_unown_name(iapp->owner_id);
+		iapp->owner_id = 0;
+		iapp->retry_registration = g_timeout_add_seconds(1, retry_registration, iapp);
+		return;
+	}
+
+	return;	
+}
+
+static void
+on_name_acquired (GDBusConnection * connection, const gchar * name,
+                  gpointer user_data)
+{
+}
+
+static void
+on_name_lost (GDBusConnection * connection, const gchar * name,
+              gpointer user_data)
+{
+	IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data);
+
+	if (connection == NULL) {
+		g_error("OMG! Unable to get a connection to DBus");
+	}
+	else {
+		g_error("Unable to claim the name %s", DBUS_NAME);
+	}
+
+	/* We can rest assured no one will register with us, but let's
+	   just ensure we're not showing anything. */
+	switch_default_app(iapp, NULL, NULL);
+
+	iapp->owner_id = 0;
+}
+
 /* Object refs decrement */
 static void
 indicator_appmenu_dispose (GObject *object)
@@ -351,6 +408,22 @@
 		iapp->retry_registration = 0;
 	}
 
+	if (iapp->dbus_registration != 0) {
+		g_dbus_connection_unregister_object(iapp->bus, iapp->dbus_registration);
+		/* Don't care if it fails, there's nothing we can do */
+		iapp->dbus_registration = 0;
+	}
+
+	if (iapp->bus != NULL) {
+		g_object_unref(iapp->bus);
+		iapp->bus = NULL;
+	}
+
+	if (iapp->owner_id != 0) {
+		g_bus_unown_name(iapp->owner_id);
+		iapp->owner_id = 0;
+	}
+
 	/* bring down the matcher before resetting to no menu so we don't
 	   get match signals */
 	if (iapp->matcher != NULL) {
@@ -411,7 +484,28 @@
 static void
 indicator_appmenu_debug_class_init (IndicatorAppmenuDebugClass *klass)
 {
-	dbus_g_object_type_install_info(INDICATOR_APPMENU_DEBUG_TYPE, &dbus_glib__application_menu_renderer_server_object_info);
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->dispose = indicator_appmenu_debug_dispose;
+
+	/* Setting up the DBus interfaces */
+	if (dbg_node_info == NULL) {
+		GError * error = NULL;
+
+		dbg_node_info = g_dbus_node_info_new_for_xml(_application_menu_renderer, &error);
+		if (error != NULL) {
+			g_error("Unable to parse Application Menu Renderer Interface description: %s", error->message);
+			g_error_free(error);
+		}
+	}
+
+	if (dbg_interface_info == NULL) {
+		dbg_interface_info = g_dbus_node_info_lookup_interface(dbg_node_info, DEBUG_IFACE);
+
+		if (dbg_interface_info == NULL) {
+			g_error("Unable to find interface '" DEBUG_IFACE "'");
+		}
+	}
 
 	return;
 }
@@ -421,52 +515,107 @@
 indicator_appmenu_debug_init (IndicatorAppmenuDebug *self)
 {
 	self->appmenu = NULL;
+	self->bus_cancel = NULL;
+	self->bus = NULL;
+	self->dbus_registration = 0;
 
 	/* Register this object on DBus */
-	DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
-	dbus_g_connection_register_g_object(connection,
-	                                    DEBUG_OBJECT,
-	                                    G_OBJECT(self));
-
-	return;
-}
-
-/* If we weren't able to register on the bus, then we need
-   to try it all again. */
-static gboolean
-retry_registration (gpointer user_data)
-{
-	g_return_val_if_fail(IS_INDICATOR_APPMENU(user_data), FALSE);
-	IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data);
-
-	DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
-	if (connection != NULL) {
-		dbus_g_connection_register_g_object(connection,
-		                                    REG_OBJECT,
-		                                    G_OBJECT(iapp));
-
-		/* Request a name so others can find us */
-		DBusGProxy * dbus_proxy = dbus_g_proxy_new_for_name_owner(connection,
-		                                                   DBUS_SERVICE_DBUS,
-		                                                   DBUS_PATH_DBUS,
-		                                                   DBUS_INTERFACE_DBUS,
-		                                                   NULL);
-		if (dbus_proxy != NULL) {
-			org_freedesktop_DBus_request_name_async (dbus_proxy,
-		                                         	DBUS_NAME,
-		                                         	DBUS_NAME_FLAG_DO_NOT_QUEUE,
-		                                         	request_name_cb,
-		                                         	iapp);
-			iapp->retry_registration = 0;
-			return FALSE;
-		} else {
-			g_warning("Unable to get proxy to DBus daemon");
-		}
-	} else {
-		g_warning("Unable to connect to session bus");
-	}
-
-	return TRUE;
+	self->bus_cancel = g_cancellable_new();
+	g_bus_get(G_BUS_TYPE_SESSION,
+	          self->bus_cancel,
+	          dbg_bus_get_cb,
+	          self);
+
+	return;
+}
+
+static void
+dbg_bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data)
+{
+	GError * error = NULL;
+	GDBusConnection * connection = g_bus_get_finish(res, &error);
+
+	if (error != NULL) {
+		g_error("OMG! Unable to get a connection to DBus: %s", error->message);
+		g_error_free(error);
+		return;
+	}
+
+	IndicatorAppmenuDebug * iappd = (IndicatorAppmenuDebug *)user_data;
+
+	g_warn_if_fail(iappd->bus == NULL);
+	iappd->bus = connection;
+
+	if (iappd->bus_cancel != NULL) {
+		g_object_unref(iappd->bus_cancel);
+		iappd->bus_cancel = NULL;
+	}
+
+	/* Now register our object on our new connection */
+	iappd->dbus_registration = g_dbus_connection_register_object(iappd->bus,
+	                                                             DEBUG_OBJECT,
+	                                                             dbg_interface_info,
+	                                                             &dbg_interface_table,
+	                                                             user_data,
+	                                                             NULL,
+	                                                             &error);
+
+	if (error != NULL) {
+		g_error("Unable to register the object to DBus: %s", error->message);
+		g_error_free(error);
+		return;
+	}
+
+	return;	
+}
+
+/* Object refs decrement */
+static void
+indicator_appmenu_debug_dispose (GObject *object)
+{
+	IndicatorAppmenuDebug * iappd = INDICATOR_APPMENU_DEBUG(object);
+
+	if (iappd->dbus_registration != 0) {
+		g_dbus_connection_unregister_object(iappd->bus, iappd->dbus_registration);
+		/* Don't care if it fails, there's nothing we can do */
+		iappd->dbus_registration = 0;
+	}
+
+	if (iappd->bus != NULL) {
+		g_object_unref(iappd->bus);
+		iappd->bus = NULL;
+	}
+
+	if (iappd->bus_cancel != NULL) {
+		g_cancellable_cancel(iappd->bus_cancel);
+		g_object_unref(iappd->bus_cancel);
+		iappd->bus_cancel = NULL;
+	}
+
+	G_OBJECT_CLASS (indicator_appmenu_debug_parent_class)->dispose (object);
+	return;
+}
+
+static void
+emit_signal (IndicatorAppmenu * iapp, const gchar * name, GVariant * variant)
+{
+	GError * error = NULL;
+
+	g_dbus_connection_emit_signal (iapp->bus,
+		                       NULL,
+		                       REG_OBJECT,
+		                       REG_IFACE,
+		                       name,
+		                       variant,
+		                       &error);
+
+	if (error != NULL) {
+		g_error("Unable to send %s signal: %s", name, error->message);
+		g_error_free(error);
+		return;
+	}
+
+	return;
 }
 
 /* Close the current application using magic */
@@ -1064,10 +1213,10 @@
 }
 
 /* A new window wishes to register it's windows with us */
-static gboolean
-_application_menu_registrar_server_register_window (IndicatorAppmenu * iapp, guint windowid, const gchar * objectpath, DBusGMethodInvocation * method)
+static GVariant *
+register_window (IndicatorAppmenu * iapp, guint windowid, const gchar * objectpath,
+                 const gchar * sender)
 {
-	const gchar * sender = dbus_g_method_get_sender(method);
 	g_debug("Registering window ID %d with path %s from %s", windowid, objectpath, sender);
 
 	if (g_hash_table_lookup(iapp->apps, GUINT_TO_POINTER(windowid)) == NULL && windowid != 0) {
@@ -1078,7 +1227,8 @@
 
 		g_hash_table_insert(iapp->apps, GUINT_TO_POINTER(windowid), wm);
 
-		g_signal_emit(G_OBJECT(iapp), signals[WINDOW_REGISTERED], 0, windowid, sender, objectpath, TRUE);
+		emit_signal(iapp, "WindowRegistered",
+		            g_variant_new("(uso)", windowid, sender, objectpath));
 
 		gpointer pdesktop = g_hash_table_lookup(iapp->desktop_windows, GUINT_TO_POINTER(windowid));
 		if (pdesktop != NULL) {
@@ -1097,22 +1247,21 @@
 		}
 	}
 
-	dbus_g_method_return(method);
-	return TRUE;
+	return g_variant_new("()");
 }
 
 /* Kindly remove an entry from our DB */
-static gboolean
-_application_menu_registrar_server_unregister_window (IndicatorAppmenu * iapp, guint windowid, GError ** error)
+static GVariant *
+unregister_window (IndicatorAppmenu * iapp, guint windowid)
 {
 	/* TODO: Do it */
 
-	return FALSE;
+	return g_variant_new("()");
 }
 
 /* Grab the menu information for a specific window */
-static gboolean
-_application_menu_registrar_server_get_menu_for_window (IndicatorAppmenu * iapp, guint windowid, gchar ** objectpath, gchar ** address, GError ** error)
+static GVariant *
+get_menu_for_window (IndicatorAppmenu * iapp, guint windowid, GError ** error)
 {
 	WindowMenus * wm = NULL;
 
@@ -1124,81 +1273,77 @@
 
 	if (wm == NULL) {
 		g_set_error_literal(error, error_quark(), ERROR_WINDOW_NOT_FOUND, "Window not found");
-		return FALSE;
+		return NULL;
 	}
 
-	*objectpath = window_menus_get_path(wm);
-	*address = window_menus_get_address(wm);
-
-	return TRUE;
+	return g_variant_new("(so)", window_menus_get_address(wm),
+	                     window_menus_get_path(wm));
 }
 
 /* Get all the menus we have */
-static gboolean
-_application_menu_registrar_server_get_menus (IndicatorAppmenu * iapp, GPtrArray ** entries, GError ** error)
+static GVariant *
+get_menus (IndicatorAppmenu * iapp, GError ** error)
 {
 	if (iapp->apps == NULL) {
 		g_set_error_literal(error, error_quark(), ERROR_NO_APPLICATIONS, "No applications are registered");
-		return FALSE;
+		return NULL;
 	}
 
-	*entries = g_ptr_array_new();
-
+	GVariantBuilder * builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
 	GList * appkeys = NULL;
 	for (appkeys = g_hash_table_get_keys(iapp->apps); appkeys != NULL; appkeys = g_list_next(appkeys)) {
-		GValueArray * structval = g_value_array_new(3);
 		gpointer hash_val = g_hash_table_lookup(iapp->apps, appkeys->data);
 
 		if (hash_val == NULL) { continue; }
 
-		GValue winid = {0};
-		g_value_init(&winid, G_TYPE_UINT);
-		g_value_set_uint(&winid, window_menus_get_xid(WINDOW_MENUS(hash_val)));
-		g_value_array_append(structval, &winid);
-		g_value_unset(&winid);
-
-		GValue path = {0};
-		g_value_init(&path, DBUS_TYPE_G_OBJECT_PATH);
-		g_value_take_boxed(&path, window_menus_get_path(WINDOW_MENUS(hash_val)));
-		g_value_array_append(structval, &path);
-		g_value_unset(&path);
-
-		GValue address = {0};
-		g_value_init(&address, G_TYPE_STRING);
-		g_value_take_string(&address, window_menus_get_address(WINDOW_MENUS(hash_val)));
-		g_value_array_append(structval, &address);
-		g_value_unset(&address);
-
-		g_ptr_array_add(*entries, structval);
+		g_variant_builder_add (builder, "(uso)",
+		                       window_menus_get_xid(WINDOW_MENUS(hash_val)),
+		                       window_menus_get_path(WINDOW_MENUS(hash_val)),
+		                       window_menus_get_address(WINDOW_MENUS(hash_val)));
 	}
 
-	return TRUE;
+	return g_variant_new("(a(uso))", builder);
 }
 
-/* Response to whether we got our name or not */
+/* A method has been called from our dbus inteface.  Figure out what it
+   is and dispatch it. */
 static void
-request_name_cb (DBusGProxy *proxy, guint result, GError * inerror, gpointer userdata)
+bus_method_call (GDBusConnection * connection, const gchar * sender,
+                 const gchar * path, const gchar * interface,
+                 const gchar * method, GVariant * params,
+                 GDBusMethodInvocation * invocation, gpointer user_data)
 {
-	gboolean error = FALSE;
-
-	if (inerror != NULL) {
-		g_warning("Unable to get name request: %s", inerror->message);
-		error = TRUE;
-	}
-
-	if (!error && result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER && result != DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER) {
-		g_warning("The dbus name we want is already taken");
-		error = TRUE;
-	}
-
-	if (error) {
-		/* We can rest assured no one will register with us, but let's
-		   just ensure we're not showing anything. */
-		switch_default_app(INDICATOR_APPMENU(userdata), NULL, NULL);
-	}
-
-	g_object_unref(proxy);
-
+	IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data);
+	GVariant * retval = NULL;
+	GError * error = NULL;
+
+	if (g_strcmp0(method, "RegisterWindow") == 0) {
+		guint32 xid;
+		const gchar * path;
+		g_variant_get(params, "(u&o)", &xid, &path);
+		retval = register_window(iapp, xid, path, sender);
+	} else if (g_strcmp0(method, "UnregisterWindow") == 0) {
+		guint32 xid;
+		g_variant_get(params, "(u)", &xid);
+		retval = unregister_window(iapp, xid);
+	} else if (g_strcmp0(method, "GetMenuForWindow") == 0) {
+		guint32 xid;
+		g_variant_get(params, "(u)", &xid);
+		retval = get_menu_for_window(iapp, xid, &error);
+	} else if (g_strcmp0(method, "GetMenus") == 0) {
+		retval = get_menus(iapp, &error);
+	} else {
+		g_warning("Calling method '%s' on the indicator service and it's unknown", method);
+	}
+
+	if (error != NULL) {
+		g_dbus_method_invocation_return_dbus_error(invocation,
+		                                           "org.ayatana.AppMenu.Error",
+		                                           error->message);
+		g_error_free(error);
+	} else {
+		g_dbus_method_invocation_return_value(invocation, retval);
+	}
 	return;
 }
 
@@ -1453,44 +1598,36 @@
 }
 
 /* Grab the location of the dbusmenu of the current menu */
-static gboolean
-_application_menu_renderer_server_get_current_menu (IndicatorAppmenuDebug * iappd, gchar ** objectpath, gchar ** address, GError ** error)
+static GVariant *
+get_current_menu (IndicatorAppmenuDebug * iappd, GError ** error)
 {
 	IndicatorAppmenu * iapp = iappd->appmenu;
 
 	if (iapp->default_app == NULL) {
 		g_set_error_literal(error, error_quark(), ERROR_NO_DEFAULT_APP, "Not currently showing an application");
-		return FALSE;
+		return NULL;
 	}
 
-	*objectpath = window_menus_get_path(iapp->default_app);
-	*address = window_menus_get_address(iapp->default_app);
-
-	return TRUE;
+	return g_variant_new("(so)", window_menus_get_address(iapp->default_app),
+	                     window_menus_get_path(iapp->default_app));
 }
 
 /* Activate menu items through a script given as a parameter */
-static gboolean
-_application_menu_renderer_server_activate_menu_item (IndicatorAppmenuDebug * iappd, GArray * menulist, GError ** error)
+static GVariant *
+activate_menu_item (IndicatorAppmenuDebug * iappd, GVariantIter * iter, GError ** error)
 {
 	/* TODO: Do it */
 
-	return FALSE;
-}
-
-/* Dump the current menu to a JSON file */
-static gboolean
-_application_menu_renderer_server_dump_current_menu  (IndicatorAppmenuDebug * iappd, gchar ** jsondata, GError ** error)
-{
-	return _application_menu_renderer_server_dump_menu(iappd, 0, jsondata, error);
+	return g_variant_new("()");
 }
 
 /* Dump a specific window's menus to a JSON file */
-static gboolean
-_application_menu_renderer_server_dump_menu (IndicatorAppmenuDebug * iappd, guint windowid, gchar ** jsondata, GError ** error)
+static GVariant *
+dump_menu (IndicatorAppmenuDebug * iappd, guint windowid, GError ** error)
 {
 	IndicatorAppmenu * iapp = iappd->appmenu;
 	WindowMenus * wm = NULL;
+	gchar * jsondata = NULL;
 
 	if (windowid == 0) {
 		wm = iapp->default_app;
@@ -1500,7 +1637,7 @@
 
 	if (wm == NULL) {
 		g_set_error_literal(error, error_quark(), ERROR_WINDOW_NOT_FOUND, "Window not found");
-		return FALSE;
+		return NULL;
 	}
 
 	GArray * strings = g_array_new(TRUE, FALSE, sizeof(gchar *));
@@ -1548,10 +1685,59 @@
 	temp = g_strdup("}");
 	g_array_append_val(strings, temp);
 
-	*jsondata = g_strjoinv(NULL, (gchar **)strings->data);
+	jsondata = g_strjoinv(NULL, (gchar **)strings->data);
 	g_strfreev((gchar **)strings->data);
 	g_array_free(strings, FALSE);
 
-	return TRUE;
+	GVariant * rv = g_variant_new("(s)", jsondata);
+	g_free(jsondata);
+	return rv;
+}
+
+/* Dump the current menu to a JSON file */
+static GVariant *
+dump_current_menu  (IndicatorAppmenuDebug * iappd, GError ** error)
+{
+	return dump_menu(iappd, 0, error);
+}
+
+/* A method has been called from our dbus inteface.  Figure out what it
+   is and dispatch it. */
+static void
+dbg_bus_method_call (GDBusConnection * connection, const gchar * sender,
+                     const gchar * path, const gchar * interface,
+                     const gchar * method, GVariant * params,
+                     GDBusMethodInvocation * invocation, gpointer user_data)
+{
+	IndicatorAppmenuDebug * iappd = INDICATOR_APPMENU_DEBUG(user_data);
+	GVariant * retval = NULL;
+	GError * error = NULL;
+
+	if (g_strcmp0(method, "GetCurrentMenu") == 0) {
+		retval = get_current_menu(iappd, &error);
+	} else if (g_strcmp0(method, "ActivateMenuItem") == 0) {
+		GVariantIter *iter;
+		g_variant_get(params, "(ai)", &iter);
+		retval = activate_menu_item(iappd, iter, &error);
+		g_variant_iter_free(iter);
+	} else if (g_strcmp0(method, "DumpCurrentMenu") == 0) {
+		retval = dump_current_menu(iappd, &error);
+	} else if (g_strcmp0(method, "DumpMenu") == 0) {
+		guint32 xid;
+		g_variant_get(params, "(u)", &xid);
+		retval = dump_menu(iappd, xid, &error);
+	} else {
+		g_warning("Calling method '%s' on the indicator service and it's unknown", method);
+	}
+
+	if (error != NULL) {
+		g_dbus_method_invocation_return_dbus_error(invocation,
+		                                           "org.ayatana.AppMenu.Error",
+		                                           error->message);
+		g_error_free(error);
+	} else {
+		g_dbus_method_invocation_return_value(invocation, retval);
+	}
+	return;
 }
 

=== modified file 'src/window-menus.c'
--- src/window-menus.c	2010-12-10 22:28:31 +0000
+++ src/window-menus.c	2011-01-12 21:23:11 +0000
@@ -24,8 +24,8 @@
 #endif
 
 #include <libdbusmenu-gtk/menu.h>
-#include <dbus/dbus-glib.h>
 #include <glib.h>
+#include <gio/gio.h>
 
 #include "window-menus.h"
 #include "indicator-appmenu-marshal.h"
@@ -37,13 +37,14 @@
 	guint windowid;
 	DbusmenuGtkClient * client;
 	DbusmenuMenuitem * root;
-	DBusGProxy * props;
+	GCancellable * props_cancel;
+	GDBusProxy * props;
 	GArray * entries;
 	gboolean error_state;
 	guint   retry_timer;
 	gint    retry_id;
 	gchar * retry_name;
-	GValue  retry_data;
+	GVariant * retry_data;
 	guint   retry_timestamp;
 };
 
@@ -77,12 +78,13 @@
 static void window_menus_init       (WindowMenus *self);
 static void window_menus_dispose    (GObject *object);
 static void window_menus_finalize   (GObject *object);
-static void properties_destroyed    (GObject * object, gpointer user_data);
+static void name_owner_changed      (GObject * gobject, GParamSpec * pspec, gpointer user_data);
 static void root_changed            (DbusmenuClient * client, DbusmenuMenuitem * new_root, gpointer user_data);
 static void menu_entry_added        (DbusmenuMenuitem * root, DbusmenuMenuitem * newentry, guint position, gpointer user_data);
 static void menu_entry_removed      (DbusmenuMenuitem * root, DbusmenuMenuitem * oldentry, gpointer user_data);
 static void menu_entry_realized     (DbusmenuMenuitem * newentry, gpointer user_data);
 static void menu_child_realized     (DbusmenuMenuitem * child, gpointer user_data);
+static void props_cb (GObject * object, GAsyncResult * res, gpointer user_data);
 
 G_DEFINE_TYPE (WindowMenus, window_menus, G_TYPE_OBJECT);
 
@@ -144,6 +146,7 @@
 	WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(self);
 
 	priv->client = NULL;
+	priv->props_cancel = NULL;
 	priv->props = NULL;
 	priv->root = NULL;
 	priv->error_state = FALSE;
@@ -176,11 +179,17 @@
 		priv->props = NULL;
 	}
 
+	if (priv->props_cancel != NULL) {
+		g_cancellable_cancel(priv->props_cancel);
+		g_object_unref(priv->props_cancel);
+		priv->props_cancel = NULL;
+	}
+
 	if (priv->retry_timer != 0) {
 		g_source_remove(priv->retry_timer);
 		priv->retry_timer = 0;
-		g_value_unset(&priv->retry_data);
-		g_value_reset(&priv->retry_data);
+		g_variant_unref(priv->retry_data);
+		priv->retry_data = NULL;
 		g_free(priv->retry_name);
 		priv->retry_name = NULL;
 	}
@@ -227,11 +236,11 @@
 	g_return_val_if_fail(IS_WINDOW_MENUS(user_data), FALSE);
 	WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(user_data);
 
-	dbusmenu_client_send_event(DBUSMENU_CLIENT(priv->client), priv->retry_id, priv->retry_name, &priv->retry_data, priv->retry_timestamp);
+	dbusmenu_client_send_event(DBUSMENU_CLIENT(priv->client), priv->retry_id, priv->retry_name, priv->retry_data, priv->retry_timestamp);
 
 	priv->retry_timer = 0;
-	g_value_unset(&priv->retry_data);
-	g_value_reset(&priv->retry_data);
+	g_variant_unref(priv->retry_data);
+	priv->retry_data = NULL;
 	g_free(priv->retry_name);
 	priv->retry_name = NULL;
 
@@ -240,7 +249,7 @@
 
 /* Listen to whether our events are successfully sent */
 static void
-event_status (DbusmenuClient * client, DbusmenuMenuitem * mi, gchar * event, GValue * evdata, guint timestamp, GError * error, gpointer user_data)
+event_status (DbusmenuClient * client, DbusmenuMenuitem * mi, gchar * event, GVariant * evdata, guint timestamp, GError * error, gpointer user_data)
 {
 	g_return_if_fail(IS_WINDOW_MENUS(user_data));
 	WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(user_data);
@@ -266,8 +275,8 @@
 		if (priv->retry_timer != 0) {
 			g_source_remove(priv->retry_timer);
 			priv->retry_timer = 0;
-			g_value_unset(&priv->retry_data);
-			g_value_reset(&priv->retry_data);
+			g_variant_unref(priv->retry_data);
+			priv->retry_data = NULL;
 			g_free(priv->retry_name);
 			priv->retry_name = NULL;
 		}
@@ -297,8 +306,7 @@
 
 		priv->retry_id = dbusmenu_menuitem_get_id(mi);
 		priv->retry_name = g_strdup(event);
-		g_value_init(&priv->retry_data, G_VALUE_TYPE(evdata));
-		g_value_copy(evdata, &priv->retry_data);
+		priv->retry_data = g_variant_ref(evdata);
 		priv->retry_timestamp = timestamp;
 	}
 
@@ -360,26 +368,22 @@
 	g_return_val_if_fail(dbus_addr != NULL, NULL);
 	g_return_val_if_fail(dbus_object != NULL, NULL);
 
-	DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
-	g_return_val_if_fail(session_bus != NULL, NULL);
-
 	WindowMenus * newmenu = WINDOW_MENUS(g_object_new(WINDOW_MENUS_TYPE, NULL));
 	WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(newmenu);
 
 	priv->windowid = windowid;
 
-	priv->props = dbus_g_proxy_new_for_name_owner(session_bus,
-	                                              dbus_addr,
-	                                              dbus_object,
-	                                              DBUS_INTERFACE_PROPERTIES,
-	                                              NULL);
-	if (priv->props == NULL) {
-		g_warning("Unable to get property proxy on '%s' object '%s'", dbus_addr, dbus_object);
-		g_object_unref(newmenu);
-		return NULL;
-	}
-
-	g_signal_connect(G_OBJECT(priv->props), "destroy", G_CALLBACK(properties_destroyed), newmenu);
+	/* Build the service proxy */
+	priv->props_cancel = g_cancellable_new();
+	g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION,
+			         G_DBUS_PROXY_FLAGS_NONE,
+			         NULL,
+	                         dbus_addr,
+	                         dbus_object,
+	                         "org.freedesktop.DBus.Properties",
+			         priv->props_cancel,
+			         props_cb,
+		                 newmenu);
 
 	priv->client = dbusmenu_gtkclient_new((gchar *)dbus_addr, (gchar *)dbus_object);
 	GtkAccelGroup * agroup = gtk_accel_group_new();
@@ -397,17 +401,57 @@
 	return newmenu;
 }
 
-/* Respond to the proxies getting destoryed.  I means that we need
-   to kill ourselves. */
-static void
-properties_destroyed (GObject * object, gpointer user_data)
+/* Callback from trying to create the proxy for the service, this
+   could include starting the service. */
+static void
+props_cb (GObject * object, GAsyncResult * res, gpointer user_data)
+{
+	GError * error = NULL;
+
+	WindowMenus * self = WINDOW_MENUS(user_data);
+	g_return_if_fail(self != NULL);
+
+	WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(self);
+	GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
+
+	if (priv->props_cancel != NULL) {
+		g_object_unref(priv->props_cancel);
+		priv->props_cancel = NULL;
+	}
+
+	if (error != NULL) {
+		g_error("Could not grab DBus proxy for window %u: %s", priv->windowid, error->message);
+		g_error_free(error);
+		return;
+	}
+
+	/* Okay, we're good to grab the proxy at this point, we're
+	sure that it's ours. */
+	priv->props = proxy;
+
+	g_signal_connect(proxy, "notify::g-name-owner", G_CALLBACK(name_owner_changed), self);
+
+	return;
+}
+
+/* Gets called when the proxy changes owners, which is usually when it
+   drops off of the bus. */
+static void
+name_owner_changed (GObject * gobject, GParamSpec * pspec, gpointer user_data)
 {
 	WindowMenus * wm = WINDOW_MENUS(user_data);
 	WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(wm);
-
-	priv->props = NULL;
+	GDBusProxy * proxy = G_DBUS_PROXY(gobject);
+
+	gchar * owner = g_dbus_proxy_get_name_owner(proxy);
+	if (owner != NULL) {
+		/* OK, carry on */
+		g_free (owner);
+		return;
+	}
+
+	/* We should die now */
 	g_debug("Properties destroyed for window: %d", priv->windowid);
-
 	g_object_unref(G_OBJECT(wm));
 	return;
 }
@@ -554,13 +598,13 @@
 /* Respond to properties changing on the menu item so that we can
    properly hide and show them. */
 static void
-menu_prop_changed (DbusmenuMenuitem * item, const gchar * property, const GValue * value, gpointer user_data)
+menu_prop_changed (DbusmenuMenuitem * item, const gchar * property, GVariant * value, gpointer user_data)
 {
 	IndicatorObjectEntry * entry = (IndicatorObjectEntry *)user_data;
 	WMEntry * wmentry = (WMEntry *)user_data;
 
 	if (!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_VISIBLE)) {
-		if (g_value_get_boolean(value)) {
+		if (g_variant_get_boolean(value)) {
 			gtk_widget_show(GTK_WIDGET(entry->label));
 			wmentry->hidden = FALSE;
 		} else {
@@ -568,10 +612,10 @@
 			wmentry->hidden = TRUE;
 		}
 	} else if (!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ENABLED)) {
-		gtk_widget_set_sensitive(GTK_WIDGET(entry->label), g_value_get_boolean(value));
-		wmentry->disabled = !g_value_get_boolean(value);
+		gtk_widget_set_sensitive(GTK_WIDGET(entry->label), g_variant_get_boolean(value));
+		wmentry->disabled = !g_variant_get_boolean(value);
 	} else if (!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_LABEL)) {
-		gtk_label_set_text_with_mnemonic(entry->label, g_value_get_string(value));
+		gtk_label_set_text_with_mnemonic(entry->label, g_variant_get_string(value, NULL));
 	}
 
 	return;
@@ -609,7 +653,7 @@
 
 	g_signal_connect(G_OBJECT(newentry), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(menu_prop_changed), entry);
 
-	if (dbusmenu_menuitem_property_get_value(newentry, DBUSMENU_MENUITEM_PROP_VISIBLE) != NULL
+	if (dbusmenu_menuitem_property_get_variant(newentry, DBUSMENU_MENUITEM_PROP_VISIBLE) != NULL
 		&& dbusmenu_menuitem_property_get_bool(newentry, DBUSMENU_MENUITEM_PROP_VISIBLE) == FALSE) {
 		gtk_widget_hide(GTK_WIDGET(entry->label));
 		wmentry->hidden = TRUE;
@@ -618,7 +662,7 @@
 		wmentry->hidden = FALSE;
 	}
 
-	if (dbusmenu_menuitem_property_get_value (newentry, DBUSMENU_MENUITEM_PROP_ENABLED) != NULL) {
+	if (dbusmenu_menuitem_property_get_variant (newentry, DBUSMENU_MENUITEM_PROP_ENABLED) != NULL) {
 		gboolean sensitive = dbusmenu_menuitem_property_get_bool(newentry, DBUSMENU_MENUITEM_PROP_ENABLED);
 		gtk_widget_set_sensitive(GTK_WIDGET(entry->label), sensitive);
 		wmentry->disabled = !sensitive;

=== modified file 'tools/mock-json-app.c'
--- tools/mock-json-app.c	2010-07-20 21:48:25 +0000
+++ tools/mock-json-app.c	2011-01-12 21:23:11 +0000
@@ -22,43 +22,49 @@
 
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
-#include <dbus/dbus-glib.h>
+#include <gio/gio.h>
 #include <libdbusmenu-glib/server.h>
 #include <libdbusmenu-jsonloader/json-loader.h>
 
 #include "../src/dbus-shared.h"
-#include "../src/application-menu-registrar-client.h"
 
 #define MENU_PATH "/mock/json/app/menu"
 
 GtkWidget * window = NULL;
 DbusmenuServer * server = NULL;
-DBusGProxy * registrar = NULL;
-
-static void
-register_cb (DBusGProxy *proxy, GError *error, gpointer userdata)
-{
-	if (error != NULL) {
-		g_warning("Unable to register: %s", error->message);
-	}
-	return;
-}
-
-static void
-dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, gpointer data)
-{
-	if (new == NULL || new[0] == '\0') {
+GDBusProxy * registrar = NULL;
+
+static void
+dbus_owner_change (GObject *gobject, GParamSpec *pspec, gpointer user_data)
+{
+	GDBusProxy * proxy = G_DBUS_PROXY(gobject);
+
+	gchar * owner = g_dbus_proxy_get_name_owner(proxy);
+
+	if (owner == NULL || owner[0] == '\0') {
 		/* We only care about folks coming on the bus.  Exit quickly otherwise. */
+		g_free(owner);
 		return;
 	}
 
-	if (g_strcmp0(name, DBUS_NAME)) {
+	if (g_strcmp0(owner, DBUS_NAME)) {
 		/* We only care about this address, reject all others. */
+		g_free(owner);
 		return;
 	}
 
-	org_ayatana_AppMenu_Registrar_register_window_async(registrar, GDK_WINDOW_XID (gtk_widget_get_window (window)), MENU_PATH, register_cb, NULL);
+	GError * error = NULL;
+	g_dbus_proxy_call_sync(registrar, "RegisterWindow",
+	                       g_variant_new("(uo)",
+	                                     GDK_WINDOW_XID (gtk_widget_get_window (window)),
+	                                     MENU_PATH),
+	                       G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL);
+	if (error != NULL) {
+		g_warning("Unable to register: %s", error->message);
+		g_error_free(error);
+	}
 
+	g_free(owner);
 	return;
 }
 
@@ -71,21 +77,26 @@
 	DbusmenuServer * server = dbusmenu_server_new(MENU_PATH);
 	dbusmenu_server_set_root(server, root);
 
-	DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
-	registrar = dbus_g_proxy_new_for_name(session_bus, DBUS_NAME, REG_OBJECT, REG_IFACE);
+	registrar = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SESSION,
+	                                          G_DBUS_PROXY_FLAGS_NONE,
+	                                          NULL, DBUS_NAME,
+	                                          REG_OBJECT, REG_IFACE,
+	                                          NULL, NULL);
 	g_return_val_if_fail(registrar != NULL, FALSE);
 
-	org_ayatana_AppMenu_Registrar_register_window_async(registrar, GDK_WINDOW_XID (gtk_widget_get_window (window)), MENU_PATH, register_cb, NULL);
+	GError * error = NULL;
+	g_dbus_proxy_call_sync(registrar, "RegisterWindow",
+	                       g_variant_new("(uo)",
+	                                     GDK_WINDOW_XID (gtk_widget_get_window (window)),
+	                                     MENU_PATH),
+	                       G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+	if (error != NULL) {
+		g_warning("Unable to register: %s", error->message);
+		g_error_free(error);
+	}
 
-	DBusGProxy * dbus_proxy = dbus_g_proxy_new_for_name(session_bus,
-		                                                DBUS_SERVICE_DBUS,
-		                                                DBUS_PATH_DBUS,
-		                                                DBUS_INTERFACE_DBUS);
-	dbus_g_proxy_add_signal(dbus_proxy, "NameOwnerChanged",
-	                        G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
-	                        G_TYPE_INVALID);
-	dbus_g_proxy_connect_signal(dbus_proxy, "NameOwnerChanged",
-	                            G_CALLBACK(dbus_owner_change), NULL, NULL);
+	g_signal_connect(registrar, "notify::g-name-owner",
+	                 G_CALLBACK(dbus_owner_change), NULL);
 
 	return FALSE;
 }


Follow ups