Merge lp:~mterry/indicator-appmenu/gdbus into lp:indicator-appmenu/0.3
- gdbus
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ted Gould (community) | Approve | ||
Review via email: mp+46045@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- 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 | } |