Merge lp:~mterry/indicator-appmenu/gdbus into lp:indicator-appmenu/0.3

Proposed by Michael Terry
Status: Merged
Merged at revision: 86
Proposed branch: lp:~mterry/indicator-appmenu/gdbus
Merge into: lp:indicator-appmenu/0.3
Diff against target: 1428 lines (+597/-333)
8 files modified
configure.ac (+10/-4)
scripts/menu-pusher.c (+9/-8)
src/Makefile.am (+20/-18)
src/application-menu-renderer.xml (+1/-1)
src/clean-namespaces.xslt (+14/-0)
src/indicator-appmenu.c (+414/-228)
src/window-menus.c (+87/-43)
tools/mock-json-app.c (+42/-31)
To merge this branch: bzr merge lp:~mterry/indicator-appmenu/gdbus
Reviewer Review Type Date Requested Status
Ted Gould (community) Approve
Review via email: mp+46045@code.launchpad.net
To post a comment you must log in.
lp:~mterry/indicator-appmenu/gdbus updated
87. By Michael Terry

add log domain; don't detach menus that aren't attached

Revision history for this message
Ted Gould (ted) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'configure.ac'
2--- configure.ac 2010-10-06 18:43:21 +0000
3+++ configure.ac 2011-01-13 04:42:14 +0000
4@@ -47,15 +47,15 @@
5 ###########################
6
7 GTK_REQUIRED_VERSION=2.12
8+GIO_REQUIRED_VERSION=2.26
9 INDICATOR_REQUIRED_VERSION=0.3.14
10 DBUSMENUGTK_REQUIRED_VERSION=0.3.3
11-DBUS_GLIB_REQUIRED_VERSION=0.82
12 BAMF_REQUIRED_VERSION=0.2.53
13
14 PKG_CHECK_MODULES(INDICATOR, gtk+-2.0 >= $GTK_REQUIRED_VERSION
15+ gio-2.0 >= $GIO_REQUIRED_VERSION
16 indicator >= $INDICATOR_REQUIRED_VERSION
17- dbus-glib-1 >= $DBUS_GLIB_REQUIRED_VERSION
18- dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION
19+ dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
20 libbamf >= $BAMF_REQUIRED_VERSION)
21
22 AC_SUBST(INDICATOR_CFLAGS)
23@@ -68,13 +68,19 @@
24 DBUSMENU_JSONLOADER_REQUIRED_VERSION=0.3.3
25
26 PKG_CHECK_MODULES(INDICATORTEST,
27- dbusmenu-jsonloader >= $DBUSMENU_JSONLOADER_REQUIRED_VERSION
28+ dbusmenu-jsonloader-0.4 >= $DBUSMENU_JSONLOADER_REQUIRED_VERSION
29 )
30
31 AC_SUBST(INDICATORTEST_CFLAGS)
32 AC_SUBST(INDICATORTEST_LIBS)
33
34 ###########################
35+# XSLT Processor
36+###########################
37+
38+AC_PATH_PROG([XSLT_PROC], [xsltproc])
39+
40+###########################
41 # Check to see if we're local
42 ###########################
43
44
45=== modified file 'scripts/menu-pusher.c'
46--- scripts/menu-pusher.c 2010-07-20 21:48:25 +0000
47+++ scripts/menu-pusher.c 2011-01-13 04:42:14 +0000
48@@ -20,12 +20,11 @@
49 */
50
51 #include <gtk/gtk.h>
52-#include <dbus/dbus-glib.h>
53+#include <gio/gio.h>
54 #include <libdbusmenu-glib/menuitem.h>
55 #include <libdbusmenu-glib/server.h>
56 #include <libdbusmenu-gtk/menuitem.h>
57 #include "../src/dbus-shared.h"
58-#include "../src/application-menu-registrar-client.h"
59
60 int
61 main (int argv, char ** argc)
62@@ -73,16 +72,18 @@
63 dbusmenu_server_set_root(server, root);
64
65
66- DBusGConnection * session = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
67- g_return_val_if_fail(session != NULL, 1);
68-
69- DBusGProxy * proxy = dbus_g_proxy_new_for_name_owner(session, DBUS_NAME, REG_OBJECT, REG_IFACE, NULL);
70+ GDBusProxy * proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SESSION,
71+ G_DBUS_PROXY_FLAGS_NONE,
72+ NULL, DBUS_NAME,
73+ REG_OBJECT, REG_IFACE,
74+ NULL, NULL);
75 g_return_val_if_fail(proxy != NULL, 1);
76
77- org_ayatana_AppMenu_Registrar_register_window(proxy, 0, "/this/is/a/long/object/path", NULL);
78+ g_dbus_proxy_call_sync(proxy, "RegisterWindow",
79+ g_variant_new("(uo)", 0, "/this/is/a/long/object/path"),
80+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL);
81
82 gtk_main();
83
84-
85 return 0;
86 }
87
88=== modified file 'src/Makefile.am'
89--- src/Makefile.am 2010-09-03 16:30:59 +0000
90+++ src/Makefile.am 2011-01-13 04:42:14 +0000
91@@ -12,7 +12,6 @@
92 appmenulibdir = $(INDICATORDIR)
93 appmenulib_LTLIBRARIES = libappmenu.la
94 libappmenu_la_SOURCES = \
95- application-menu-registrar-server.h \
96 dbus-shared.h \
97 gdk-get-func.h \
98 gdk-get-func.c \
99@@ -20,8 +19,12 @@
100 indicator-appmenu.c \
101 indicator-appmenu-marshal.c \
102 window-menus.c \
103- window-menus.h
104-libappmenu_la_CFLAGS = $(INDICATOR_CFLAGS) -Wall -Wl,-Bsymbolic-functions -Wl,-z,defs -Wl,--as-needed -Werror
105+ window-menus.h \
106+ gen-application-menu-renderer.xml.c \
107+ gen-application-menu-renderer.xml.h \
108+ gen-application-menu-registrar.xml.c \
109+ gen-application-menu-registrar.xml.h
110+libappmenu_la_CFLAGS = $(INDICATOR_CFLAGS) -Wall -Wl,-Bsymbolic-functions -Wl,-z,defs -Wl,--as-needed -Werror -DG_LOG_DOMAIN=\"Indicator-Appmenu\"
111 libappmenu_la_LIBADD = $(INDICATOR_LIBS) -lX11
112 libappmenu_la_LDFLAGS = -module -avoid-version
113
114@@ -40,24 +43,23 @@
115 application-menu-renderer.xml \
116 application-menu-registrar.xml
117
118-%-client.h: %.xml
119- dbus-binding-tool \
120- --prefix=_$(notdir $(subst -,_,$(<:.xml=)))_client \
121- --mode=glib-client \
122- --output=$@ \
123- $<
124+gen-%.xml.c: %.xml
125+ @echo "Building $@ from $<"
126+ @echo "const char * _$(subst -,_,$(subst .,_,$(basename $<))) = " > $@
127+ @$(XSLT_PROC) $(srcdir)/clean-namespaces.xslt $< | \
128+ sed -e "s:\":\\\\\":g" -e s:^:\": -e s:\$$:\\\\n\": >> $@
129+ @echo ";" >> $@
130
131-%-server.h: %.xml
132- dbus-binding-tool \
133- --prefix=_$(notdir $(subst -,_,$(<:.xml=)))_server \
134- --mode=glib-server \
135- --output=$@ \
136- $<
137+gen-%.xml.h: %.xml
138+ @echo "Building $@ from $<"
139+ @echo "extern const char * _$(subst -,_,$(subst .,_,$(basename $<)));" > $@
140
141 BUILT_SOURCES += \
142- $(DBUS_SPECS:.xml=-client.h) \
143- $(DBUS_SPECS:.xml=-server.h)
144+ gen-application-menu-renderer.xml.c \
145+ gen-application-menu-renderer.xml.h \
146+ gen-application-menu-registrar.xml.c \
147+ gen-application-menu-registrar.xml.h
148
149 CLEANFILES += $(BUILT_SOURCES)
150
151-EXTRA_DIST += $(DBUS_SPECS)
152+EXTRA_DIST += $(DBUS_SPECS) clean-namespaces.xslt
153
154=== modified file 'src/application-menu-renderer.xml'
155--- src/application-menu-renderer.xml 2010-07-13 19:52:07 +0000
156+++ src/application-menu-renderer.xml 2011-01-13 04:42:14 +0000
157@@ -1,5 +1,5 @@
158 <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
159-<node name="/org/ayatana/AppMenu/Renderer">
160+<node name="/org/ayatana/AppMenu/Renderer" xmlns:dox="http://www.ayatana.org/dbus/dox.dtd">
161 <dox:d><![CDATA[
162 @mainpage
163  
164
165=== added file 'src/clean-namespaces.xslt'
166--- src/clean-namespaces.xslt 1970-01-01 00:00:00 +0000
167+++ src/clean-namespaces.xslt 2011-01-13 04:42:14 +0000
168@@ -0,0 +1,14 @@
169+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dox="http://www.ayatana.org/dbus/dox.dtd">
170+ <xsl:template match="*|@*">
171+ <xsl:copy>
172+ <xsl:apply-templates select="*|@*" />
173+ </xsl:copy>
174+ </xsl:template>
175+ <xsl:template match="@dox:*|dox:*"/>
176+ <xsl:template match="*">
177+ <xsl:element name="{local-name()}">
178+ <xsl:apply-templates select="@* | node()"/>
179+ </xsl:element>
180+ </xsl:template>
181+</xsl:stylesheet>
182+
183
184=== modified file 'src/indicator-appmenu.c'
185--- src/indicator-appmenu.c 2010-10-06 18:43:21 +0000
186+++ src/indicator-appmenu.c 2011-01-13 04:42:14 +0000
187@@ -25,11 +25,7 @@
188
189 #include <X11/Xlib.h>
190 #include <gdk/gdkx.h>
191-
192-#include <dbus/dbus-glib.h>
193-#include <dbus/dbus-glib-bindings.h>
194-#include <dbus/dbus-glib-lowlevel.h>
195-#include <dbus/dbus-gtype-specialized.h>
196+#include <gio/gio.h>
197
198 #include <libindicator/indicator.h>
199 #include <libindicator/indicator-object.h>
200@@ -39,6 +35,8 @@
201
202 #include <libbamf/bamf-matcher.h>
203
204+#include "gen-application-menu-registrar.xml.h"
205+#include "gen-application-menu-renderer.xml.h"
206 #include "indicator-appmenu-marshal.h"
207 #include "window-menus.h"
208 #include "dbus-shared.h"
209@@ -102,6 +100,10 @@
210 WindowMenus * desktop_menu;
211
212 IndicatorAppmenuDebug * debug;
213+
214+ GDBusConnection * bus;
215+ guint owner_id;
216+ guint dbus_registration;
217 };
218
219
220@@ -124,6 +126,9 @@
221 struct _IndicatorAppmenuDebug {
222 GObject parent;
223 IndicatorAppmenu * appmenu;
224+ GCancellable * bus_cancel;
225+ GDBusConnection * bus;
226+ guint dbus_registration;
227 };
228
229
230@@ -136,6 +141,7 @@
231 static void indicator_appmenu_finalize (GObject *object);
232 static void indicator_appmenu_debug_class_init (IndicatorAppmenuDebugClass *klass);
233 static void indicator_appmenu_debug_init (IndicatorAppmenuDebug *self);
234+static void indicator_appmenu_debug_dispose (GObject *object);
235 static void build_window_menus (IndicatorAppmenu * iapp);
236 static GList * get_entries (IndicatorObject * io);
237 static guint get_location (IndicatorObject * io,
238@@ -153,25 +159,6 @@
239 static void old_window (BamfMatcher * matcher,
240 BamfView * view,
241 gpointer user_data);
242-static gboolean _application_menu_registrar_server_register_window (IndicatorAppmenu * iapp,
243- guint windowid,
244- const gchar * objectpath,
245- DBusGMethodInvocation * method);
246-static gboolean _application_menu_registrar_server_unregister_window (IndicatorAppmenu * iapp,
247- guint windowid,
248- GError ** error);
249-static gboolean _application_menu_registrar_server_get_menu_for_window (IndicatorAppmenu * iapp,
250- guint windowid,
251- gchar ** objectpath,
252- gchar ** address,
253- GError ** error);
254-static gboolean _application_menu_registrar_server_get_menus (IndicatorAppmenu * iapp,
255- GPtrArray ** entries,
256- GError ** error);
257-static void request_name_cb (DBusGProxy *proxy,
258- guint result,
259- GError *error,
260- gpointer userdata);
261 static void window_entry_added (WindowMenus * mw,
262 IndicatorObjectEntry * entry,
263 gpointer user_data);
264@@ -186,22 +173,36 @@
265 BamfView * oldview,
266 BamfView * newview,
267 gpointer user_data);
268-static gboolean _application_menu_renderer_server_get_current_menu (IndicatorAppmenuDebug * iappd,
269- gchar ** objectpath,
270- gchar ** address,
271- GError ** error);
272-static gboolean _application_menu_renderer_server_activate_menu_item (IndicatorAppmenuDebug * iappd,
273- GArray * menulist,
274- GError ** error);
275-static gboolean _application_menu_renderer_server_dump_current_menu (IndicatorAppmenuDebug * iappd,
276- gchar ** jsondata,
277- GError ** error);
278-static gboolean _application_menu_renderer_server_dump_menu (IndicatorAppmenuDebug * iappd,
279- guint windowid,
280- gchar ** jsondata,
281- GError ** error);
282 static GQuark error_quark (void);
283 static gboolean retry_registration (gpointer user_data);
284+static void bus_method_call (GDBusConnection * connection,
285+ const gchar * sender,
286+ const gchar * path,
287+ const gchar * interface,
288+ const gchar * method,
289+ GVariant * params,
290+ GDBusMethodInvocation * invocation,
291+ gpointer user_data);
292+static void on_bus_acquired (GDBusConnection * connection,
293+ const gchar * name,
294+ gpointer user_data);
295+static void on_name_acquired (GDBusConnection * connection,
296+ const gchar * name,
297+ gpointer user_data);
298+static void on_name_lost (GDBusConnection * connection,
299+ const gchar * name,
300+ gpointer user_data);
301+static void dbg_bus_method_call (GDBusConnection * connection,
302+ const gchar * sender,
303+ const gchar * path,
304+ const gchar * interface,
305+ const gchar * method,
306+ GVariant * params,
307+ GDBusMethodInvocation * invocation,
308+ gpointer user_data);
309+static void dbg_bus_get_cb (GObject * object,
310+ GAsyncResult * res,
311+ gpointer user_data);
312
313 /* Unique error codes for debug interface */
314 enum {
315@@ -213,16 +214,21 @@
316 /**********************
317 DBus Interfaces
318 **********************/
319-#include "application-menu-registrar-server.h"
320-#include "application-menu-renderer-server.h"
321-
322-enum {
323- WINDOW_REGISTERED,
324- WINDOW_UNREGISTERED,
325- LAST_SIGNAL
326-};
327-
328-static guint signals[LAST_SIGNAL] = { 0 };
329+static GDBusNodeInfo * node_info = NULL;
330+static GDBusInterfaceInfo * interface_info = NULL;
331+static GDBusInterfaceVTable interface_table = {
332+ method_call: bus_method_call,
333+ get_property: NULL, /* No properties */
334+ set_property: NULL /* No properties */
335+};
336+
337+static GDBusNodeInfo * dbg_node_info = NULL;
338+static GDBusInterfaceInfo * dbg_interface_info = NULL;
339+static GDBusInterfaceVTable dbg_interface_table = {
340+ method_call: dbg_bus_method_call,
341+ get_property: NULL, /* No properties */
342+ set_property: NULL /* No properties */
343+};
344
345 G_DEFINE_TYPE (IndicatorAppmenu, indicator_appmenu, INDICATOR_OBJECT_TYPE);
346
347@@ -241,22 +247,24 @@
348 ioclass->get_location = get_location;
349 ioclass->entry_activate = entry_activate;
350
351- signals[WINDOW_REGISTERED] = g_signal_new("window-registered",
352- G_TYPE_FROM_CLASS(klass),
353- G_SIGNAL_RUN_LAST,
354- G_STRUCT_OFFSET (IndicatorAppmenuClass, window_registered),
355- NULL, NULL,
356- _indicator_appmenu_marshal_VOID__UINT_STRING_BOXED,
357- G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_STRING, DBUS_TYPE_G_OBJECT_PATH);
358- signals[WINDOW_UNREGISTERED] = g_signal_new("window-unregistered",
359- G_TYPE_FROM_CLASS(klass),
360- G_SIGNAL_RUN_LAST,
361- G_STRUCT_OFFSET (IndicatorAppmenuClass, window_unregistered),
362- NULL, NULL,
363- _indicator_appmenu_marshal_VOID__UINT,
364- G_TYPE_NONE, 1, G_TYPE_UINT);
365-
366- dbus_g_object_type_install_info(INDICATOR_APPMENU_TYPE, &dbus_glib__application_menu_registrar_server_object_info);
367+ /* Setting up the DBus interfaces */
368+ if (node_info == NULL) {
369+ GError * error = NULL;
370+
371+ node_info = g_dbus_node_info_new_for_xml(_application_menu_registrar, &error);
372+ if (error != NULL) {
373+ g_error("Unable to parse Application Menu Interface description: %s", error->message);
374+ g_error_free(error);
375+ }
376+ }
377+
378+ if (interface_info == NULL) {
379+ interface_info = g_dbus_node_info_lookup_interface(node_info, REG_IFACE);
380+
381+ if (interface_info == NULL) {
382+ g_error("Unable to find interface '" REG_IFACE "'");
383+ }
384+ }
385
386 return;
387 }
388@@ -273,6 +281,9 @@
389 self->active_stubs = STUBS_UNKNOWN;
390 self->close_item = NULL;
391 self->retry_registration = 0;
392+ self->bus = NULL;
393+ self->owner_id = 0;
394+ self->dbus_registration = 0;
395
396 /* Setup the entries for the fallbacks */
397 self->window_menus = g_array_sized_new(FALSE, FALSE, sizeof(IndicatorObjectEntry), 2);
398@@ -299,38 +310,8 @@
399
400 find_desktop_windows(self);
401
402- /* Register this object on DBus */
403- gboolean sent_registration = FALSE;
404- GError * error = NULL;
405- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
406- if (connection != NULL && error == NULL) {
407- dbus_g_connection_register_g_object(connection,
408- REG_OBJECT,
409- G_OBJECT(self));
410-
411- /* Request a name so others can find us */
412- DBusGProxy * dbus_proxy = dbus_g_proxy_new_for_name_owner(connection,
413- DBUS_SERVICE_DBUS,
414- DBUS_PATH_DBUS,
415- DBUS_INTERFACE_DBUS,
416- NULL);
417- if (dbus_proxy != NULL) {
418- org_freedesktop_DBus_request_name_async (dbus_proxy,
419- DBUS_NAME,
420- DBUS_NAME_FLAG_DO_NOT_QUEUE,
421- request_name_cb,
422- self);
423- sent_registration = TRUE;
424- } else {
425- g_warning("Unable to get proxy to DBus daemon");
426- }
427- } else {
428- g_warning("Unable to connect to session bus");
429- }
430-
431- if (!sent_registration) {
432- self->retry_registration = g_timeout_add_seconds(1, retry_registration, self);
433- }
434+ /* Request a name so others can find us */
435+ retry_registration(self);
436
437 /* Setup debug interface */
438 self->debug = g_object_new(INDICATOR_APPMENU_DEBUG_TYPE, NULL);
439@@ -339,6 +320,82 @@
440 return;
441 }
442
443+/* If we weren't able to register on the bus, then we need
444+ to try it all again. */
445+static gboolean
446+retry_registration (gpointer user_data)
447+{
448+ g_return_val_if_fail(IS_INDICATOR_APPMENU(user_data), FALSE);
449+ IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data);
450+
451+ iapp->owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
452+ DBUS_NAME,
453+ G_BUS_NAME_OWNER_FLAGS_NONE,
454+ iapp->dbus_registration == 0 ? on_bus_acquired : NULL,
455+ on_name_acquired,
456+ on_name_lost,
457+ g_object_ref(iapp),
458+ g_object_unref);
459+
460+ return TRUE;
461+}
462+
463+static void
464+on_bus_acquired (GDBusConnection * connection, const gchar * name,
465+ gpointer user_data)
466+{
467+ IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data);
468+ GError * error = NULL;
469+
470+ iapp->bus = connection;
471+
472+ /* Now register our object on our new connection */
473+ iapp->dbus_registration = g_dbus_connection_register_object(connection,
474+ REG_OBJECT,
475+ interface_info,
476+ &interface_table,
477+ user_data,
478+ NULL,
479+ &error);
480+
481+ if (error != NULL) {
482+ g_error("Unable to register the object to DBus: %s", error->message);
483+ g_error_free(error);
484+ g_bus_unown_name(iapp->owner_id);
485+ iapp->owner_id = 0;
486+ iapp->retry_registration = g_timeout_add_seconds(1, retry_registration, iapp);
487+ return;
488+ }
489+
490+ return;
491+}
492+
493+static void
494+on_name_acquired (GDBusConnection * connection, const gchar * name,
495+ gpointer user_data)
496+{
497+}
498+
499+static void
500+on_name_lost (GDBusConnection * connection, const gchar * name,
501+ gpointer user_data)
502+{
503+ IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data);
504+
505+ if (connection == NULL) {
506+ g_error("OMG! Unable to get a connection to DBus");
507+ }
508+ else {
509+ g_error("Unable to claim the name %s", DBUS_NAME);
510+ }
511+
512+ /* We can rest assured no one will register with us, but let's
513+ just ensure we're not showing anything. */
514+ switch_default_app(iapp, NULL, NULL);
515+
516+ iapp->owner_id = 0;
517+}
518+
519 /* Object refs decrement */
520 static void
521 indicator_appmenu_dispose (GObject *object)
522@@ -351,6 +408,22 @@
523 iapp->retry_registration = 0;
524 }
525
526+ if (iapp->dbus_registration != 0) {
527+ g_dbus_connection_unregister_object(iapp->bus, iapp->dbus_registration);
528+ /* Don't care if it fails, there's nothing we can do */
529+ iapp->dbus_registration = 0;
530+ }
531+
532+ if (iapp->bus != NULL) {
533+ g_object_unref(iapp->bus);
534+ iapp->bus = NULL;
535+ }
536+
537+ if (iapp->owner_id != 0) {
538+ g_bus_unown_name(iapp->owner_id);
539+ iapp->owner_id = 0;
540+ }
541+
542 /* bring down the matcher before resetting to no menu so we don't
543 get match signals */
544 if (iapp->matcher != NULL) {
545@@ -411,7 +484,28 @@
546 static void
547 indicator_appmenu_debug_class_init (IndicatorAppmenuDebugClass *klass)
548 {
549- dbus_g_object_type_install_info(INDICATOR_APPMENU_DEBUG_TYPE, &dbus_glib__application_menu_renderer_server_object_info);
550+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
551+
552+ object_class->dispose = indicator_appmenu_debug_dispose;
553+
554+ /* Setting up the DBus interfaces */
555+ if (dbg_node_info == NULL) {
556+ GError * error = NULL;
557+
558+ dbg_node_info = g_dbus_node_info_new_for_xml(_application_menu_renderer, &error);
559+ if (error != NULL) {
560+ g_error("Unable to parse Application Menu Renderer Interface description: %s", error->message);
561+ g_error_free(error);
562+ }
563+ }
564+
565+ if (dbg_interface_info == NULL) {
566+ dbg_interface_info = g_dbus_node_info_lookup_interface(dbg_node_info, DEBUG_IFACE);
567+
568+ if (dbg_interface_info == NULL) {
569+ g_error("Unable to find interface '" DEBUG_IFACE "'");
570+ }
571+ }
572
573 return;
574 }
575@@ -421,52 +515,107 @@
576 indicator_appmenu_debug_init (IndicatorAppmenuDebug *self)
577 {
578 self->appmenu = NULL;
579+ self->bus_cancel = NULL;
580+ self->bus = NULL;
581+ self->dbus_registration = 0;
582
583 /* Register this object on DBus */
584- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
585- dbus_g_connection_register_g_object(connection,
586- DEBUG_OBJECT,
587- G_OBJECT(self));
588-
589- return;
590-}
591-
592-/* If we weren't able to register on the bus, then we need
593- to try it all again. */
594-static gboolean
595-retry_registration (gpointer user_data)
596-{
597- g_return_val_if_fail(IS_INDICATOR_APPMENU(user_data), FALSE);
598- IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data);
599-
600- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
601- if (connection != NULL) {
602- dbus_g_connection_register_g_object(connection,
603- REG_OBJECT,
604- G_OBJECT(iapp));
605-
606- /* Request a name so others can find us */
607- DBusGProxy * dbus_proxy = dbus_g_proxy_new_for_name_owner(connection,
608- DBUS_SERVICE_DBUS,
609- DBUS_PATH_DBUS,
610- DBUS_INTERFACE_DBUS,
611- NULL);
612- if (dbus_proxy != NULL) {
613- org_freedesktop_DBus_request_name_async (dbus_proxy,
614- DBUS_NAME,
615- DBUS_NAME_FLAG_DO_NOT_QUEUE,
616- request_name_cb,
617- iapp);
618- iapp->retry_registration = 0;
619- return FALSE;
620- } else {
621- g_warning("Unable to get proxy to DBus daemon");
622- }
623- } else {
624- g_warning("Unable to connect to session bus");
625- }
626-
627- return TRUE;
628+ self->bus_cancel = g_cancellable_new();
629+ g_bus_get(G_BUS_TYPE_SESSION,
630+ self->bus_cancel,
631+ dbg_bus_get_cb,
632+ self);
633+
634+ return;
635+}
636+
637+static void
638+dbg_bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data)
639+{
640+ GError * error = NULL;
641+ GDBusConnection * connection = g_bus_get_finish(res, &error);
642+
643+ if (error != NULL) {
644+ g_error("OMG! Unable to get a connection to DBus: %s", error->message);
645+ g_error_free(error);
646+ return;
647+ }
648+
649+ IndicatorAppmenuDebug * iappd = (IndicatorAppmenuDebug *)user_data;
650+
651+ g_warn_if_fail(iappd->bus == NULL);
652+ iappd->bus = connection;
653+
654+ if (iappd->bus_cancel != NULL) {
655+ g_object_unref(iappd->bus_cancel);
656+ iappd->bus_cancel = NULL;
657+ }
658+
659+ /* Now register our object on our new connection */
660+ iappd->dbus_registration = g_dbus_connection_register_object(iappd->bus,
661+ DEBUG_OBJECT,
662+ dbg_interface_info,
663+ &dbg_interface_table,
664+ user_data,
665+ NULL,
666+ &error);
667+
668+ if (error != NULL) {
669+ g_error("Unable to register the object to DBus: %s", error->message);
670+ g_error_free(error);
671+ return;
672+ }
673+
674+ return;
675+}
676+
677+/* Object refs decrement */
678+static void
679+indicator_appmenu_debug_dispose (GObject *object)
680+{
681+ IndicatorAppmenuDebug * iappd = INDICATOR_APPMENU_DEBUG(object);
682+
683+ if (iappd->dbus_registration != 0) {
684+ g_dbus_connection_unregister_object(iappd->bus, iappd->dbus_registration);
685+ /* Don't care if it fails, there's nothing we can do */
686+ iappd->dbus_registration = 0;
687+ }
688+
689+ if (iappd->bus != NULL) {
690+ g_object_unref(iappd->bus);
691+ iappd->bus = NULL;
692+ }
693+
694+ if (iappd->bus_cancel != NULL) {
695+ g_cancellable_cancel(iappd->bus_cancel);
696+ g_object_unref(iappd->bus_cancel);
697+ iappd->bus_cancel = NULL;
698+ }
699+
700+ G_OBJECT_CLASS (indicator_appmenu_debug_parent_class)->dispose (object);
701+ return;
702+}
703+
704+static void
705+emit_signal (IndicatorAppmenu * iapp, const gchar * name, GVariant * variant)
706+{
707+ GError * error = NULL;
708+
709+ g_dbus_connection_emit_signal (iapp->bus,
710+ NULL,
711+ REG_OBJECT,
712+ REG_IFACE,
713+ name,
714+ variant,
715+ &error);
716+
717+ if (error != NULL) {
718+ g_error("Unable to send %s signal: %s", name, error->message);
719+ g_error_free(error);
720+ return;
721+ }
722+
723+ return;
724 }
725
726 /* Close the current application using magic */
727@@ -895,7 +1044,7 @@
728 gtk_widget_hide(GTK_WIDGET(entry->label));
729 }
730
731- if (entry->menu != NULL) {
732+ if (entry->menu != NULL && gtk_menu_get_attach_widget(entry->menu) != NULL) {
733 gtk_menu_detach(entry->menu);
734 }
735
736@@ -1064,10 +1213,10 @@
737 }
738
739 /* A new window wishes to register it's windows with us */
740-static gboolean
741-_application_menu_registrar_server_register_window (IndicatorAppmenu * iapp, guint windowid, const gchar * objectpath, DBusGMethodInvocation * method)
742+static GVariant *
743+register_window (IndicatorAppmenu * iapp, guint windowid, const gchar * objectpath,
744+ const gchar * sender)
745 {
746- const gchar * sender = dbus_g_method_get_sender(method);
747 g_debug("Registering window ID %d with path %s from %s", windowid, objectpath, sender);
748
749 if (g_hash_table_lookup(iapp->apps, GUINT_TO_POINTER(windowid)) == NULL && windowid != 0) {
750@@ -1078,7 +1227,8 @@
751
752 g_hash_table_insert(iapp->apps, GUINT_TO_POINTER(windowid), wm);
753
754- g_signal_emit(G_OBJECT(iapp), signals[WINDOW_REGISTERED], 0, windowid, sender, objectpath, TRUE);
755+ emit_signal(iapp, "WindowRegistered",
756+ g_variant_new("(uso)", windowid, sender, objectpath));
757
758 gpointer pdesktop = g_hash_table_lookup(iapp->desktop_windows, GUINT_TO_POINTER(windowid));
759 if (pdesktop != NULL) {
760@@ -1097,22 +1247,21 @@
761 }
762 }
763
764- dbus_g_method_return(method);
765- return TRUE;
766+ return g_variant_new("()");
767 }
768
769 /* Kindly remove an entry from our DB */
770-static gboolean
771-_application_menu_registrar_server_unregister_window (IndicatorAppmenu * iapp, guint windowid, GError ** error)
772+static GVariant *
773+unregister_window (IndicatorAppmenu * iapp, guint windowid)
774 {
775 /* TODO: Do it */
776
777- return FALSE;
778+ return g_variant_new("()");
779 }
780
781 /* Grab the menu information for a specific window */
782-static gboolean
783-_application_menu_registrar_server_get_menu_for_window (IndicatorAppmenu * iapp, guint windowid, gchar ** objectpath, gchar ** address, GError ** error)
784+static GVariant *
785+get_menu_for_window (IndicatorAppmenu * iapp, guint windowid, GError ** error)
786 {
787 WindowMenus * wm = NULL;
788
789@@ -1124,81 +1273,77 @@
790
791 if (wm == NULL) {
792 g_set_error_literal(error, error_quark(), ERROR_WINDOW_NOT_FOUND, "Window not found");
793- return FALSE;
794+ return NULL;
795 }
796
797- *objectpath = window_menus_get_path(wm);
798- *address = window_menus_get_address(wm);
799-
800- return TRUE;
801+ return g_variant_new("(so)", window_menus_get_address(wm),
802+ window_menus_get_path(wm));
803 }
804
805 /* Get all the menus we have */
806-static gboolean
807-_application_menu_registrar_server_get_menus (IndicatorAppmenu * iapp, GPtrArray ** entries, GError ** error)
808+static GVariant *
809+get_menus (IndicatorAppmenu * iapp, GError ** error)
810 {
811 if (iapp->apps == NULL) {
812 g_set_error_literal(error, error_quark(), ERROR_NO_APPLICATIONS, "No applications are registered");
813- return FALSE;
814+ return NULL;
815 }
816
817- *entries = g_ptr_array_new();
818-
819+ GVariantBuilder * builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
820 GList * appkeys = NULL;
821 for (appkeys = g_hash_table_get_keys(iapp->apps); appkeys != NULL; appkeys = g_list_next(appkeys)) {
822- GValueArray * structval = g_value_array_new(3);
823 gpointer hash_val = g_hash_table_lookup(iapp->apps, appkeys->data);
824
825 if (hash_val == NULL) { continue; }
826
827- GValue winid = {0};
828- g_value_init(&winid, G_TYPE_UINT);
829- g_value_set_uint(&winid, window_menus_get_xid(WINDOW_MENUS(hash_val)));
830- g_value_array_append(structval, &winid);
831- g_value_unset(&winid);
832-
833- GValue path = {0};
834- g_value_init(&path, DBUS_TYPE_G_OBJECT_PATH);
835- g_value_take_boxed(&path, window_menus_get_path(WINDOW_MENUS(hash_val)));
836- g_value_array_append(structval, &path);
837- g_value_unset(&path);
838-
839- GValue address = {0};
840- g_value_init(&address, G_TYPE_STRING);
841- g_value_take_string(&address, window_menus_get_address(WINDOW_MENUS(hash_val)));
842- g_value_array_append(structval, &address);
843- g_value_unset(&address);
844-
845- g_ptr_array_add(*entries, structval);
846+ g_variant_builder_add (builder, "(uso)",
847+ window_menus_get_xid(WINDOW_MENUS(hash_val)),
848+ window_menus_get_path(WINDOW_MENUS(hash_val)),
849+ window_menus_get_address(WINDOW_MENUS(hash_val)));
850 }
851
852- return TRUE;
853+ return g_variant_new("(a(uso))", builder);
854 }
855
856-/* Response to whether we got our name or not */
857+/* A method has been called from our dbus inteface. Figure out what it
858+ is and dispatch it. */
859 static void
860-request_name_cb (DBusGProxy *proxy, guint result, GError * inerror, gpointer userdata)
861+bus_method_call (GDBusConnection * connection, const gchar * sender,
862+ const gchar * path, const gchar * interface,
863+ const gchar * method, GVariant * params,
864+ GDBusMethodInvocation * invocation, gpointer user_data)
865 {
866- gboolean error = FALSE;
867-
868- if (inerror != NULL) {
869- g_warning("Unable to get name request: %s", inerror->message);
870- error = TRUE;
871- }
872-
873- if (!error && result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER && result != DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER) {
874- g_warning("The dbus name we want is already taken");
875- error = TRUE;
876- }
877-
878- if (error) {
879- /* We can rest assured no one will register with us, but let's
880- just ensure we're not showing anything. */
881- switch_default_app(INDICATOR_APPMENU(userdata), NULL, NULL);
882- }
883-
884- g_object_unref(proxy);
885-
886+ IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data);
887+ GVariant * retval = NULL;
888+ GError * error = NULL;
889+
890+ if (g_strcmp0(method, "RegisterWindow") == 0) {
891+ guint32 xid;
892+ const gchar * path;
893+ g_variant_get(params, "(u&o)", &xid, &path);
894+ retval = register_window(iapp, xid, path, sender);
895+ } else if (g_strcmp0(method, "UnregisterWindow") == 0) {
896+ guint32 xid;
897+ g_variant_get(params, "(u)", &xid);
898+ retval = unregister_window(iapp, xid);
899+ } else if (g_strcmp0(method, "GetMenuForWindow") == 0) {
900+ guint32 xid;
901+ g_variant_get(params, "(u)", &xid);
902+ retval = get_menu_for_window(iapp, xid, &error);
903+ } else if (g_strcmp0(method, "GetMenus") == 0) {
904+ retval = get_menus(iapp, &error);
905+ } else {
906+ g_warning("Calling method '%s' on the indicator service and it's unknown", method);
907+ }
908+
909+ if (error != NULL) {
910+ g_dbus_method_invocation_return_dbus_error(invocation,
911+ "org.ayatana.AppMenu.Error",
912+ error->message);
913+ g_error_free(error);
914+ } else {
915+ g_dbus_method_invocation_return_value(invocation, retval);
916+ }
917 return;
918 }
919
920@@ -1453,44 +1598,36 @@
921 }
922
923 /* Grab the location of the dbusmenu of the current menu */
924-static gboolean
925-_application_menu_renderer_server_get_current_menu (IndicatorAppmenuDebug * iappd, gchar ** objectpath, gchar ** address, GError ** error)
926+static GVariant *
927+get_current_menu (IndicatorAppmenuDebug * iappd, GError ** error)
928 {
929 IndicatorAppmenu * iapp = iappd->appmenu;
930
931 if (iapp->default_app == NULL) {
932 g_set_error_literal(error, error_quark(), ERROR_NO_DEFAULT_APP, "Not currently showing an application");
933- return FALSE;
934+ return NULL;
935 }
936
937- *objectpath = window_menus_get_path(iapp->default_app);
938- *address = window_menus_get_address(iapp->default_app);
939-
940- return TRUE;
941+ return g_variant_new("(so)", window_menus_get_address(iapp->default_app),
942+ window_menus_get_path(iapp->default_app));
943 }
944
945 /* Activate menu items through a script given as a parameter */
946-static gboolean
947-_application_menu_renderer_server_activate_menu_item (IndicatorAppmenuDebug * iappd, GArray * menulist, GError ** error)
948+static GVariant *
949+activate_menu_item (IndicatorAppmenuDebug * iappd, GVariantIter * iter, GError ** error)
950 {
951 /* TODO: Do it */
952
953- return FALSE;
954-}
955-
956-/* Dump the current menu to a JSON file */
957-static gboolean
958-_application_menu_renderer_server_dump_current_menu (IndicatorAppmenuDebug * iappd, gchar ** jsondata, GError ** error)
959-{
960- return _application_menu_renderer_server_dump_menu(iappd, 0, jsondata, error);
961+ return g_variant_new("()");
962 }
963
964 /* Dump a specific window's menus to a JSON file */
965-static gboolean
966-_application_menu_renderer_server_dump_menu (IndicatorAppmenuDebug * iappd, guint windowid, gchar ** jsondata, GError ** error)
967+static GVariant *
968+dump_menu (IndicatorAppmenuDebug * iappd, guint windowid, GError ** error)
969 {
970 IndicatorAppmenu * iapp = iappd->appmenu;
971 WindowMenus * wm = NULL;
972+ gchar * jsondata = NULL;
973
974 if (windowid == 0) {
975 wm = iapp->default_app;
976@@ -1500,7 +1637,7 @@
977
978 if (wm == NULL) {
979 g_set_error_literal(error, error_quark(), ERROR_WINDOW_NOT_FOUND, "Window not found");
980- return FALSE;
981+ return NULL;
982 }
983
984 GArray * strings = g_array_new(TRUE, FALSE, sizeof(gchar *));
985@@ -1548,10 +1685,59 @@
986 temp = g_strdup("}");
987 g_array_append_val(strings, temp);
988
989- *jsondata = g_strjoinv(NULL, (gchar **)strings->data);
990+ jsondata = g_strjoinv(NULL, (gchar **)strings->data);
991 g_strfreev((gchar **)strings->data);
992 g_array_free(strings, FALSE);
993
994- return TRUE;
995+ GVariant * rv = g_variant_new("(s)", jsondata);
996+ g_free(jsondata);
997+ return rv;
998+}
999+
1000+/* Dump the current menu to a JSON file */
1001+static GVariant *
1002+dump_current_menu (IndicatorAppmenuDebug * iappd, GError ** error)
1003+{
1004+ return dump_menu(iappd, 0, error);
1005+}
1006+
1007+/* A method has been called from our dbus inteface. Figure out what it
1008+ is and dispatch it. */
1009+static void
1010+dbg_bus_method_call (GDBusConnection * connection, const gchar * sender,
1011+ const gchar * path, const gchar * interface,
1012+ const gchar * method, GVariant * params,
1013+ GDBusMethodInvocation * invocation, gpointer user_data)
1014+{
1015+ IndicatorAppmenuDebug * iappd = INDICATOR_APPMENU_DEBUG(user_data);
1016+ GVariant * retval = NULL;
1017+ GError * error = NULL;
1018+
1019+ if (g_strcmp0(method, "GetCurrentMenu") == 0) {
1020+ retval = get_current_menu(iappd, &error);
1021+ } else if (g_strcmp0(method, "ActivateMenuItem") == 0) {
1022+ GVariantIter *iter;
1023+ g_variant_get(params, "(ai)", &iter);
1024+ retval = activate_menu_item(iappd, iter, &error);
1025+ g_variant_iter_free(iter);
1026+ } else if (g_strcmp0(method, "DumpCurrentMenu") == 0) {
1027+ retval = dump_current_menu(iappd, &error);
1028+ } else if (g_strcmp0(method, "DumpMenu") == 0) {
1029+ guint32 xid;
1030+ g_variant_get(params, "(u)", &xid);
1031+ retval = dump_menu(iappd, xid, &error);
1032+ } else {
1033+ g_warning("Calling method '%s' on the indicator service and it's unknown", method);
1034+ }
1035+
1036+ if (error != NULL) {
1037+ g_dbus_method_invocation_return_dbus_error(invocation,
1038+ "org.ayatana.AppMenu.Error",
1039+ error->message);
1040+ g_error_free(error);
1041+ } else {
1042+ g_dbus_method_invocation_return_value(invocation, retval);
1043+ }
1044+ return;
1045 }
1046
1047
1048=== modified file 'src/window-menus.c'
1049--- src/window-menus.c 2010-12-10 22:28:31 +0000
1050+++ src/window-menus.c 2011-01-13 04:42:14 +0000
1051@@ -24,8 +24,8 @@
1052 #endif
1053
1054 #include <libdbusmenu-gtk/menu.h>
1055-#include <dbus/dbus-glib.h>
1056 #include <glib.h>
1057+#include <gio/gio.h>
1058
1059 #include "window-menus.h"
1060 #include "indicator-appmenu-marshal.h"
1061@@ -37,13 +37,14 @@
1062 guint windowid;
1063 DbusmenuGtkClient * client;
1064 DbusmenuMenuitem * root;
1065- DBusGProxy * props;
1066+ GCancellable * props_cancel;
1067+ GDBusProxy * props;
1068 GArray * entries;
1069 gboolean error_state;
1070 guint retry_timer;
1071 gint retry_id;
1072 gchar * retry_name;
1073- GValue retry_data;
1074+ GVariant * retry_data;
1075 guint retry_timestamp;
1076 };
1077
1078@@ -77,12 +78,13 @@
1079 static void window_menus_init (WindowMenus *self);
1080 static void window_menus_dispose (GObject *object);
1081 static void window_menus_finalize (GObject *object);
1082-static void properties_destroyed (GObject * object, gpointer user_data);
1083+static void name_owner_changed (GObject * gobject, GParamSpec * pspec, gpointer user_data);
1084 static void root_changed (DbusmenuClient * client, DbusmenuMenuitem * new_root, gpointer user_data);
1085 static void menu_entry_added (DbusmenuMenuitem * root, DbusmenuMenuitem * newentry, guint position, gpointer user_data);
1086 static void menu_entry_removed (DbusmenuMenuitem * root, DbusmenuMenuitem * oldentry, gpointer user_data);
1087 static void menu_entry_realized (DbusmenuMenuitem * newentry, gpointer user_data);
1088 static void menu_child_realized (DbusmenuMenuitem * child, gpointer user_data);
1089+static void props_cb (GObject * object, GAsyncResult * res, gpointer user_data);
1090
1091 G_DEFINE_TYPE (WindowMenus, window_menus, G_TYPE_OBJECT);
1092
1093@@ -144,6 +146,7 @@
1094 WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(self);
1095
1096 priv->client = NULL;
1097+ priv->props_cancel = NULL;
1098 priv->props = NULL;
1099 priv->root = NULL;
1100 priv->error_state = FALSE;
1101@@ -176,11 +179,17 @@
1102 priv->props = NULL;
1103 }
1104
1105+ if (priv->props_cancel != NULL) {
1106+ g_cancellable_cancel(priv->props_cancel);
1107+ g_object_unref(priv->props_cancel);
1108+ priv->props_cancel = NULL;
1109+ }
1110+
1111 if (priv->retry_timer != 0) {
1112 g_source_remove(priv->retry_timer);
1113 priv->retry_timer = 0;
1114- g_value_unset(&priv->retry_data);
1115- g_value_reset(&priv->retry_data);
1116+ g_variant_unref(priv->retry_data);
1117+ priv->retry_data = NULL;
1118 g_free(priv->retry_name);
1119 priv->retry_name = NULL;
1120 }
1121@@ -227,11 +236,11 @@
1122 g_return_val_if_fail(IS_WINDOW_MENUS(user_data), FALSE);
1123 WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(user_data);
1124
1125- dbusmenu_client_send_event(DBUSMENU_CLIENT(priv->client), priv->retry_id, priv->retry_name, &priv->retry_data, priv->retry_timestamp);
1126+ dbusmenu_client_send_event(DBUSMENU_CLIENT(priv->client), priv->retry_id, priv->retry_name, priv->retry_data, priv->retry_timestamp);
1127
1128 priv->retry_timer = 0;
1129- g_value_unset(&priv->retry_data);
1130- g_value_reset(&priv->retry_data);
1131+ g_variant_unref(priv->retry_data);
1132+ priv->retry_data = NULL;
1133 g_free(priv->retry_name);
1134 priv->retry_name = NULL;
1135
1136@@ -240,7 +249,7 @@
1137
1138 /* Listen to whether our events are successfully sent */
1139 static void
1140-event_status (DbusmenuClient * client, DbusmenuMenuitem * mi, gchar * event, GValue * evdata, guint timestamp, GError * error, gpointer user_data)
1141+event_status (DbusmenuClient * client, DbusmenuMenuitem * mi, gchar * event, GVariant * evdata, guint timestamp, GError * error, gpointer user_data)
1142 {
1143 g_return_if_fail(IS_WINDOW_MENUS(user_data));
1144 WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(user_data);
1145@@ -266,8 +275,8 @@
1146 if (priv->retry_timer != 0) {
1147 g_source_remove(priv->retry_timer);
1148 priv->retry_timer = 0;
1149- g_value_unset(&priv->retry_data);
1150- g_value_reset(&priv->retry_data);
1151+ g_variant_unref(priv->retry_data);
1152+ priv->retry_data = NULL;
1153 g_free(priv->retry_name);
1154 priv->retry_name = NULL;
1155 }
1156@@ -297,8 +306,7 @@
1157
1158 priv->retry_id = dbusmenu_menuitem_get_id(mi);
1159 priv->retry_name = g_strdup(event);
1160- g_value_init(&priv->retry_data, G_VALUE_TYPE(evdata));
1161- g_value_copy(evdata, &priv->retry_data);
1162+ priv->retry_data = g_variant_ref(evdata);
1163 priv->retry_timestamp = timestamp;
1164 }
1165
1166@@ -360,26 +368,22 @@
1167 g_return_val_if_fail(dbus_addr != NULL, NULL);
1168 g_return_val_if_fail(dbus_object != NULL, NULL);
1169
1170- DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
1171- g_return_val_if_fail(session_bus != NULL, NULL);
1172-
1173 WindowMenus * newmenu = WINDOW_MENUS(g_object_new(WINDOW_MENUS_TYPE, NULL));
1174 WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(newmenu);
1175
1176 priv->windowid = windowid;
1177
1178- priv->props = dbus_g_proxy_new_for_name_owner(session_bus,
1179- dbus_addr,
1180- dbus_object,
1181- DBUS_INTERFACE_PROPERTIES,
1182- NULL);
1183- if (priv->props == NULL) {
1184- g_warning("Unable to get property proxy on '%s' object '%s'", dbus_addr, dbus_object);
1185- g_object_unref(newmenu);
1186- return NULL;
1187- }
1188-
1189- g_signal_connect(G_OBJECT(priv->props), "destroy", G_CALLBACK(properties_destroyed), newmenu);
1190+ /* Build the service proxy */
1191+ priv->props_cancel = g_cancellable_new();
1192+ g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION,
1193+ G_DBUS_PROXY_FLAGS_NONE,
1194+ NULL,
1195+ dbus_addr,
1196+ dbus_object,
1197+ "org.freedesktop.DBus.Properties",
1198+ priv->props_cancel,
1199+ props_cb,
1200+ newmenu);
1201
1202 priv->client = dbusmenu_gtkclient_new((gchar *)dbus_addr, (gchar *)dbus_object);
1203 GtkAccelGroup * agroup = gtk_accel_group_new();
1204@@ -397,17 +401,57 @@
1205 return newmenu;
1206 }
1207
1208-/* Respond to the proxies getting destoryed. I means that we need
1209- to kill ourselves. */
1210-static void
1211-properties_destroyed (GObject * object, gpointer user_data)
1212+/* Callback from trying to create the proxy for the service, this
1213+ could include starting the service. */
1214+static void
1215+props_cb (GObject * object, GAsyncResult * res, gpointer user_data)
1216+{
1217+ GError * error = NULL;
1218+
1219+ WindowMenus * self = WINDOW_MENUS(user_data);
1220+ g_return_if_fail(self != NULL);
1221+
1222+ WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(self);
1223+ GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
1224+
1225+ if (priv->props_cancel != NULL) {
1226+ g_object_unref(priv->props_cancel);
1227+ priv->props_cancel = NULL;
1228+ }
1229+
1230+ if (error != NULL) {
1231+ g_error("Could not grab DBus proxy for window %u: %s", priv->windowid, error->message);
1232+ g_error_free(error);
1233+ return;
1234+ }
1235+
1236+ /* Okay, we're good to grab the proxy at this point, we're
1237+ sure that it's ours. */
1238+ priv->props = proxy;
1239+
1240+ g_signal_connect(proxy, "notify::g-name-owner", G_CALLBACK(name_owner_changed), self);
1241+
1242+ return;
1243+}
1244+
1245+/* Gets called when the proxy changes owners, which is usually when it
1246+ drops off of the bus. */
1247+static void
1248+name_owner_changed (GObject * gobject, GParamSpec * pspec, gpointer user_data)
1249 {
1250 WindowMenus * wm = WINDOW_MENUS(user_data);
1251 WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(wm);
1252-
1253- priv->props = NULL;
1254+ GDBusProxy * proxy = G_DBUS_PROXY(gobject);
1255+
1256+ gchar * owner = g_dbus_proxy_get_name_owner(proxy);
1257+ if (owner != NULL) {
1258+ /* OK, carry on */
1259+ g_free (owner);
1260+ return;
1261+ }
1262+
1263+ /* We should die now */
1264 g_debug("Properties destroyed for window: %d", priv->windowid);
1265-
1266 g_object_unref(G_OBJECT(wm));
1267 return;
1268 }
1269@@ -554,13 +598,13 @@
1270 /* Respond to properties changing on the menu item so that we can
1271 properly hide and show them. */
1272 static void
1273-menu_prop_changed (DbusmenuMenuitem * item, const gchar * property, const GValue * value, gpointer user_data)
1274+menu_prop_changed (DbusmenuMenuitem * item, const gchar * property, GVariant * value, gpointer user_data)
1275 {
1276 IndicatorObjectEntry * entry = (IndicatorObjectEntry *)user_data;
1277 WMEntry * wmentry = (WMEntry *)user_data;
1278
1279 if (!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_VISIBLE)) {
1280- if (g_value_get_boolean(value)) {
1281+ if (g_variant_get_boolean(value)) {
1282 gtk_widget_show(GTK_WIDGET(entry->label));
1283 wmentry->hidden = FALSE;
1284 } else {
1285@@ -568,10 +612,10 @@
1286 wmentry->hidden = TRUE;
1287 }
1288 } else if (!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ENABLED)) {
1289- gtk_widget_set_sensitive(GTK_WIDGET(entry->label), g_value_get_boolean(value));
1290- wmentry->disabled = !g_value_get_boolean(value);
1291+ gtk_widget_set_sensitive(GTK_WIDGET(entry->label), g_variant_get_boolean(value));
1292+ wmentry->disabled = !g_variant_get_boolean(value);
1293 } else if (!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_LABEL)) {
1294- gtk_label_set_text_with_mnemonic(entry->label, g_value_get_string(value));
1295+ gtk_label_set_text_with_mnemonic(entry->label, g_variant_get_string(value, NULL));
1296 }
1297
1298 return;
1299@@ -609,7 +653,7 @@
1300
1301 g_signal_connect(G_OBJECT(newentry), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(menu_prop_changed), entry);
1302
1303- if (dbusmenu_menuitem_property_get_value(newentry, DBUSMENU_MENUITEM_PROP_VISIBLE) != NULL
1304+ if (dbusmenu_menuitem_property_get_variant(newentry, DBUSMENU_MENUITEM_PROP_VISIBLE) != NULL
1305 && dbusmenu_menuitem_property_get_bool(newentry, DBUSMENU_MENUITEM_PROP_VISIBLE) == FALSE) {
1306 gtk_widget_hide(GTK_WIDGET(entry->label));
1307 wmentry->hidden = TRUE;
1308@@ -618,7 +662,7 @@
1309 wmentry->hidden = FALSE;
1310 }
1311
1312- if (dbusmenu_menuitem_property_get_value (newentry, DBUSMENU_MENUITEM_PROP_ENABLED) != NULL) {
1313+ if (dbusmenu_menuitem_property_get_variant (newentry, DBUSMENU_MENUITEM_PROP_ENABLED) != NULL) {
1314 gboolean sensitive = dbusmenu_menuitem_property_get_bool(newentry, DBUSMENU_MENUITEM_PROP_ENABLED);
1315 gtk_widget_set_sensitive(GTK_WIDGET(entry->label), sensitive);
1316 wmentry->disabled = !sensitive;
1317
1318=== modified file 'tools/mock-json-app.c'
1319--- tools/mock-json-app.c 2010-07-20 21:48:25 +0000
1320+++ tools/mock-json-app.c 2011-01-13 04:42:14 +0000
1321@@ -22,43 +22,49 @@
1322
1323 #include <gtk/gtk.h>
1324 #include <gdk/gdkx.h>
1325-#include <dbus/dbus-glib.h>
1326+#include <gio/gio.h>
1327 #include <libdbusmenu-glib/server.h>
1328 #include <libdbusmenu-jsonloader/json-loader.h>
1329
1330 #include "../src/dbus-shared.h"
1331-#include "../src/application-menu-registrar-client.h"
1332
1333 #define MENU_PATH "/mock/json/app/menu"
1334
1335 GtkWidget * window = NULL;
1336 DbusmenuServer * server = NULL;
1337-DBusGProxy * registrar = NULL;
1338-
1339-static void
1340-register_cb (DBusGProxy *proxy, GError *error, gpointer userdata)
1341-{
1342- if (error != NULL) {
1343- g_warning("Unable to register: %s", error->message);
1344- }
1345- return;
1346-}
1347-
1348-static void
1349-dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, gpointer data)
1350-{
1351- if (new == NULL || new[0] == '\0') {
1352+GDBusProxy * registrar = NULL;
1353+
1354+static void
1355+dbus_owner_change (GObject *gobject, GParamSpec *pspec, gpointer user_data)
1356+{
1357+ GDBusProxy * proxy = G_DBUS_PROXY(gobject);
1358+
1359+ gchar * owner = g_dbus_proxy_get_name_owner(proxy);
1360+
1361+ if (owner == NULL || owner[0] == '\0') {
1362 /* We only care about folks coming on the bus. Exit quickly otherwise. */
1363+ g_free(owner);
1364 return;
1365 }
1366
1367- if (g_strcmp0(name, DBUS_NAME)) {
1368+ if (g_strcmp0(owner, DBUS_NAME)) {
1369 /* We only care about this address, reject all others. */
1370+ g_free(owner);
1371 return;
1372 }
1373
1374- org_ayatana_AppMenu_Registrar_register_window_async(registrar, GDK_WINDOW_XID (gtk_widget_get_window (window)), MENU_PATH, register_cb, NULL);
1375+ GError * error = NULL;
1376+ g_dbus_proxy_call_sync(registrar, "RegisterWindow",
1377+ g_variant_new("(uo)",
1378+ GDK_WINDOW_XID (gtk_widget_get_window (window)),
1379+ MENU_PATH),
1380+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL);
1381+ if (error != NULL) {
1382+ g_warning("Unable to register: %s", error->message);
1383+ g_error_free(error);
1384+ }
1385
1386+ g_free(owner);
1387 return;
1388 }
1389
1390@@ -71,21 +77,26 @@
1391 DbusmenuServer * server = dbusmenu_server_new(MENU_PATH);
1392 dbusmenu_server_set_root(server, root);
1393
1394- DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
1395- registrar = dbus_g_proxy_new_for_name(session_bus, DBUS_NAME, REG_OBJECT, REG_IFACE);
1396+ registrar = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SESSION,
1397+ G_DBUS_PROXY_FLAGS_NONE,
1398+ NULL, DBUS_NAME,
1399+ REG_OBJECT, REG_IFACE,
1400+ NULL, NULL);
1401 g_return_val_if_fail(registrar != NULL, FALSE);
1402
1403- org_ayatana_AppMenu_Registrar_register_window_async(registrar, GDK_WINDOW_XID (gtk_widget_get_window (window)), MENU_PATH, register_cb, NULL);
1404+ GError * error = NULL;
1405+ g_dbus_proxy_call_sync(registrar, "RegisterWindow",
1406+ g_variant_new("(uo)",
1407+ GDK_WINDOW_XID (gtk_widget_get_window (window)),
1408+ MENU_PATH),
1409+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1410+ if (error != NULL) {
1411+ g_warning("Unable to register: %s", error->message);
1412+ g_error_free(error);
1413+ }
1414
1415- DBusGProxy * dbus_proxy = dbus_g_proxy_new_for_name(session_bus,
1416- DBUS_SERVICE_DBUS,
1417- DBUS_PATH_DBUS,
1418- DBUS_INTERFACE_DBUS);
1419- dbus_g_proxy_add_signal(dbus_proxy, "NameOwnerChanged",
1420- G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
1421- G_TYPE_INVALID);
1422- dbus_g_proxy_connect_signal(dbus_proxy, "NameOwnerChanged",
1423- G_CALLBACK(dbus_owner_change), NULL, NULL);
1424+ g_signal_connect(registrar, "notify::g-name-owner",
1425+ G_CALLBACK(dbus_owner_change), NULL);
1426
1427 return FALSE;
1428 }

Subscribers

People subscribed via source and target branches