← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~ted/appmenu-gtk/dbusmenu-0.4 into lp:appmenu-gtk

 

Ted Gould has proposed merging lp:~ted/appmenu-gtk/dbusmenu-0.4 into lp:appmenu-gtk.

Requested reviews:
  Canonical Desktop Experience Team (canonical-dx-team)

For more details, see:
https://code.launchpad.net/~ted/appmenu-gtk/dbusmenu-0.4/+merge/45455

Ports to the new dbusmenu and GDBus
-- 
https://code.launchpad.net/~ted/appmenu-gtk/dbusmenu-0.4/+merge/45455
Your team ayatana-commits is subscribed to branch lp:appmenu-gtk.
=== modified file 'configure.ac'
--- configure.ac	2010-09-13 16:40:28 +0000
+++ configure.ac	2011-01-06 21:37:01 +0000
@@ -25,10 +25,10 @@
 ###########################
 
 GTK_REQUIRED_VERSION=2.18
-DBUSMENU_REQUIRED_VERSION=0.3.3
+DBUSMENU_REQUIRED_VERSION=0.3.90
 
 PKG_CHECK_MODULES(APPMENU, gtk+-2.0 >= $GTK_REQUIRED_VERSION
-                           dbusmenu-gtk >= $DBUSMENU_REQUIRED_VERSION)
+                           dbusmenu-gtk-0.4 >= $DBUSMENU_REQUIRED_VERSION)
 
 AC_SUBST(APPMENU_CFLAGS)
 AC_SUBST(APPMENU_LIBS)

=== modified file 'src/Makefile.am'
--- src/Makefile.am	2010-05-27 20:02:28 +0000
+++ src/Makefile.am	2011-01-06 21:37:01 +0000
@@ -1,18 +1,16 @@
 CLEANFILES =
 DISTCLEANFILES =
 BUILT_SOURCES =
+EXTRA_DIST=
 
 moduledir = $(libdir)/gtk-2.0/2.10.0/menuproxies
 module_LTLIBRARIES = libappmenu.la
 
-sources_h =			\
-	bridge.h
-
-EXTRA_DIST = application-menu-registrar.xml	\
-	$(sources_h)
-
 libappmenu_la_SOURCES =		\
-	bridge.c
+	bridge.c \
+	bridge.h \
+	gen-application-menu-registrar.xml.c \
+	gen-application-menu-registrar.xml.h
 
 libappmenu_la_CPPFLAGS =	\
 	-Wall -Werror		\
@@ -39,23 +37,19 @@
 	$(GCC_FLAGS)			\
 	$(MAINTAINER_CFLAGS)
 
-%-client.h: %.xml
-	dbus-binding-tool						\
-		--prefix=_$(notdir $(subst -,_,$(<:.xml=)))_client	\
-		--mode=glib-client					\
-		--output=$@						\
-		$<
-
-%-server.h: %.xml
-	dbus-binding-tool						\
-		--prefix=_$(notdir $(subst -,_,$(<:.xml=)))_server	\
-		--mode=glib-server					\
-		--output=$@						\
-		$<
-
-BUILT_SOURCES +=							\
-	$(DBUS_SPECS:.xml=-client.h)					\
-	$(DBUS_SPECS:.xml=-server.h)
+gen-%.xml.h: %.xml
+	@echo "Building $@ from $<"
+	@echo "extern const char * _$(subst -,_,$(subst .,_,$(basename $<)));" > $@
+
+gen-%.xml.c: %.xml
+	@echo "Building $@ from $<"
+	@echo "const char * _$(subst -,_,$(subst .,_,$(basename $<))) = " > $@
+	@sed -e "s:\":\\\\\":g" -e s:^:\": -e s:\$$:\\\\n\": $< >> $@
+	@echo ";" >> $@
+
+BUILT_SOURCES += \
+	gen-application-menu-registrar.xml.h \
+	gen-application-menu-registrar.xml.c
 
 CLEANFILES += $(BUILT_SOURCES)
 

=== modified file 'src/bridge.c'
--- src/bridge.c	2010-10-14 15:11:51 +0000
+++ src/bridge.c	2011-01-06 21:37:01 +0000
@@ -23,20 +23,16 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <dbus/dbus-glib-bindings.h>
-
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
+#include <gio/gio.h>
 
 #include <libdbusmenu-gtk/menuitem.h>
 #include <libdbusmenu-glib/menuitem.h>
 #include <libdbusmenu-glib/server.h>
 
 #include "bridge.h"
-#include "application-menu-registrar-client.h"
+#include "gen-application-menu-registrar.xml.h"
 
 #define APP_MENU_DBUS_NAME   "org.ayatana.AppMenu.Registrar"
 #define APP_MENU_DBUS_OBJECT "/org/ayatana/AppMenu/Registrar"
@@ -48,11 +44,6 @@
                                             GtkWidget         *child,
                                             guint              position);
 static gboolean app_menu_bridge_show_local (UbuntuMenuProxy   *proxy);
-static void     dbus_owner_change          (DBusGProxy        *proxy,
-                                            const gchar       *name,
-                                            const gchar       *prev,
-                                            const gchar       *new,
-                                            AppMenuBridge     *bridge);
 static void     toplevel_realized          (GtkWidget         *widget,
                                             gpointer           user_data);
 static void     toplevel_notify_cb         (GtkWidget         *widget,
@@ -64,6 +55,9 @@
                                             GtkWidget         *toplevel);
 static void app_menu_bridge_proxy_vanished (AppMenuBridge *bridge);
 static void app_menu_bridge_proxy_appeared (AppMenuBridge *bridge);
+static void appmenuproxy_created_cb        (GObject *          object,
+                                            GAsyncResult *     res,
+                                            gpointer           user_data);
 
 typedef struct _AppWindowContext AppWindowContext;
 
@@ -82,9 +76,7 @@
 {
   GList *windows;
 
-  DBusGConnection  *session_bus;
-  DBusGProxy       *dbusproxy;
-  DBusGProxy       *appmenuproxy;
+  GDBusProxy       *appmenuproxy;
   gboolean          online;
 };
 
@@ -108,42 +100,11 @@
 G_DEFINE_DYNAMIC_TYPE(AppMenuBridge, app_menu_bridge, UBUNTU_TYPE_MENU_PROXY)
 
 static GHashTable *rebuild_ids = NULL;
-
-
+static GDBusNodeInfo *      registrar_node_info = NULL;
+static GDBusInterfaceInfo * registrar_interface_info = NULL;
 static gboolean after_startup = FALSE;
 
 static void
-app_menu_bridge_setup_proxy (AppMenuBridge *bridge)
-{
-  bridge->priv->appmenuproxy = dbus_g_proxy_new_for_name_owner (bridge->priv->session_bus,
-                                                                APP_MENU_DBUS_NAME,
-                                                                APP_MENU_DBUS_OBJECT,
-                                                                APP_MENU_INTERFACE,
-                                                                NULL);
-
-  bridge->priv->online = TRUE;
-}
-
-/* Async callback from asking DBus if the registrar
-   exists on the bus */
-static void
-has_owner_cb (DBusGProxy *proxy, gboolean has_owner, GError *error, gpointer userdata)
-{
-	if (error != NULL) {
-		g_warning("Unable to check for Registrar owner: %s", error->message);
-		return;
-	}
-
-	if (has_owner) {
-		app_menu_bridge_proxy_appeared (APP_MENU_BRIDGE(userdata));
-	} else {
-		app_menu_bridge_proxy_vanished (APP_MENU_BRIDGE(userdata));
-	}
-
-	return;
-}
-
-static void
 activate_menu (AppMenuBridge *bridge,
                GtkWidget     *widget,
                gpointer       user_data)
@@ -176,37 +137,18 @@
   bridge->priv->windows = NULL;
 
   bridge->priv->appmenuproxy = NULL;
+  g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION,
+                           G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+                           registrar_interface_info,
+                           APP_MENU_DBUS_NAME,
+                           APP_MENU_DBUS_OBJECT,
+                           APP_MENU_INTERFACE,
+                           NULL, /* TODO: cancelable */
+                           appmenuproxy_created_cb,
+                           bridge);
 
   bridge->priv->online = FALSE;
 
-  bridge->priv->session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
-
-  bridge->priv->dbusproxy = dbus_g_proxy_new_for_name (bridge->priv->session_bus,
-                                                       DBUS_SERVICE_DBUS,
-                                                       DBUS_PATH_DBUS,
-                                                       DBUS_INTERFACE_DBUS);
-
-  if (bridge->priv->dbusproxy)
-    {
-      dbus_g_proxy_add_signal (bridge->priv->dbusproxy,
-                               "NameOwnerChanged",
-                               G_TYPE_STRING,
-                               G_TYPE_STRING,
-                               G_TYPE_STRING,
-                               G_TYPE_INVALID);
-
-      dbus_g_proxy_connect_signal (bridge->priv->dbusproxy,
-                                   "NameOwnerChanged",
-                                   G_CALLBACK (dbus_owner_change),
-                                   bridge,
-                                   NULL);
-
-      org_freedesktop_DBus_name_has_owner_async (bridge->priv->dbusproxy,
-                                                 APP_MENU_DBUS_NAME,
-                                                 has_owner_cb,
-                                                 bridge);
-    }
-
   g_signal_connect (bridge,
                     "activate-menu",
                     G_CALLBACK (activate_menu),
@@ -225,18 +167,6 @@
       g_object_unref (bridge->priv->appmenuproxy);
       bridge->priv->appmenuproxy = NULL;
     }
-
-  if (bridge->priv->dbusproxy)
-    {
-      g_object_unref (bridge->priv->dbusproxy);
-      bridge->priv->dbusproxy = NULL;
-    }
-
-  if (bridge->priv->session_bus)
-    {
-      g_object_unref (bridge->priv->session_bus);
-      bridge->priv->session_bus = NULL;
-    }
 }
 
 static void
@@ -321,6 +251,26 @@
   object_class->finalize = app_menu_bridge_finalize;
 
   g_type_class_add_private (class, sizeof (AppMenuBridgePrivate));
+
+	if (registrar_node_info == NULL) {
+		GError * error = NULL;
+
+		registrar_node_info = g_dbus_node_info_new_for_xml(_application_menu_registrar, &error);
+		if (error != NULL) {
+			g_error("Unable to parse app menu registrar Interface description: %s", error->message);
+			g_error_free(error);
+		}
+	}
+
+	if (registrar_interface_info == NULL) {
+		registrar_interface_info = g_dbus_node_info_lookup_interface(registrar_node_info, APP_MENU_INTERFACE);
+
+		if (registrar_interface_info == NULL) {
+			g_error("Unable to find interface '" APP_MENU_INTERFACE "'");
+		}
+	}
+
+	return;
 }
 
 static void
@@ -343,14 +293,21 @@
 }
 
 static void
-register_application_window_cb (DBusGProxy     *proxy,
-                                GError         *error,
-                                void           *user_data)
+register_application_window_cb (GObject          *object,
+                                GAsyncResult     *res,
+                                void             *user_data)
 {
+  GError * error = NULL;
   AppWindowContext *context = (AppWindowContext *)user_data;
 
+  GVariant * variants = g_dbus_proxy_call_finish(G_DBUS_PROXY(object), res, &error);
+  g_variant_unref(variants);
+
   if (error != NULL)
     {
+      g_warning("Unable to register window with path '%s': %s", context->path, error->message);
+      g_error_free(error);
+
       if (context->bridge != NULL)
         {
           context->registered = FALSE;
@@ -387,11 +344,16 @@
 
       if (!context->registered && context->server != NULL && context->root != NULL && GTK_IS_WINDOW (widget) && bridge->priv->appmenuproxy != NULL)
         {
-          org_ayatana_AppMenu_Registrar_register_window_async (bridge->priv->appmenuproxy,
-                                                               GDK_WINDOW_XID (gtk_widget_get_window (widget)),
-                                                               context->path,
-                                                               register_application_window_cb,
-                                                               context);
+          g_dbus_proxy_call(bridge->priv->appmenuproxy,
+                            "RegisterWindow",
+                            g_variant_new("(uo)",
+                                          GDK_WINDOW_XID(gtk_widget_get_window(widget)),
+                                          context->path),
+                            G_DBUS_CALL_FLAGS_NONE,
+                            -1, /* timeout */
+                            NULL, /* cancelable */
+                            register_application_window_cb,
+                            context);
         }
     }
 }
@@ -424,30 +386,70 @@
 {
   bridge->priv->online = TRUE;
 
-  app_menu_bridge_setup_proxy (bridge);
-
   register_application_windows (bridge);
 }
 
-static void
-dbus_owner_change (DBusGProxy    *proxy,
-                   const gchar   *name,
-                   const gchar   *prev,
-                   const gchar   *new,
-                   AppMenuBridge *bridge)
-{
-  if (strlen (new) > 0 && strlen (prev) == 0)
-    {
-      if (g_strcmp0 (name, APP_MENU_DBUS_NAME) == 0 && (prev == NULL || strlen (prev) == 0))
-        {
-          app_menu_bridge_proxy_appeared (bridge);
-        }
-    }
-  else if (g_strcmp0 (name, APP_MENU_DBUS_NAME) == 0 && strlen (new) == 0 && strlen (prev) > 0)
-    {
-      app_menu_bridge_proxy_vanished (bridge);
-    }
-}
+/* Gets called anytime the name owner changes, this is typically
+   when the indicator crashes or gets removed. */
+static void
+appmenuproxy_owner_changed (GObject * object, GParamSpec * pspec, gpointer user_data)
+{
+	AppMenuBridge * bridge = APP_MENU_BRIDGE(user_data);
+	g_return_if_fail(bridge != NULL);
+
+	gchar * name = g_dbus_proxy_get_name_owner(bridge->priv->appmenuproxy);
+	if (name != NULL) {
+		g_free(name);
+		app_menu_bridge_proxy_appeared(bridge);
+	} else {
+		app_menu_bridge_proxy_vanished(bridge);
+	}
+
+	return;
+}
+
+/* Callback for the asyncronous creation of the proxy object.
+   If it is created successfully we act like it just appeared, otherwise
+   we error as if it vanished */
+static void
+appmenuproxy_created_cb (GObject * object, GAsyncResult * res, gpointer user_data)
+{
+	GError * error = NULL;
+	GDBusProxy * proxy = NULL;
+
+	proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
+	if (error != NULL) {
+		g_warning("Unable to create Ubuntu Menu Proxy: %s", error->message);
+		g_error_free(error);
+		/* No return, we want to still call vanished */
+	}
+
+	AppMenuBridge * bridge = APP_MENU_BRIDGE(user_data);
+	g_return_if_fail(bridge != NULL);
+
+	bridge->priv->appmenuproxy = proxy;
+
+	gchar * name = NULL;
+	if (proxy != NULL) {
+		name = g_dbus_proxy_get_name_owner(proxy);
+
+		g_signal_connect(G_OBJECT(proxy),
+		                 "notify::g-name-owner",
+		                 G_CALLBACK(appmenuproxy_owner_changed),
+		                 bridge);
+	}
+
+	/* Note: name will be NULL if proxy was NULL */
+	if (name != NULL) {
+		g_free(name);
+		app_menu_bridge_proxy_appeared(bridge);
+	} else {
+		app_menu_bridge_proxy_vanished(bridge);
+	}
+
+	return;
+}
+
 
 static GtkWidget *
 find_menu_label (GtkWidget *widget)


Follow ups