Merge lp:~ted/libdbusmenu/kill-dbus-glib into lp:libdbusmenu/0.5

Proposed by Ted Gould
Status: Merged
Merged at revision: 173
Proposed branch: lp:~ted/libdbusmenu/kill-dbus-glib
Merge into: lp:libdbusmenu/0.5
Diff against target: 9903 lines (+2587/-2202)
44 files modified
.bzrignore (+18/-1)
configure.ac (+12/-9)
libdbusmenu-glib/Makefile.am (+35/-33)
libdbusmenu-glib/clean-namespaces.xslt (+14/-0)
libdbusmenu-glib/client-marshal.list (+1/-1)
libdbusmenu-glib/client-menuitem.c (+3/-3)
libdbusmenu-glib/client.c (+425/-254)
libdbusmenu-glib/client.h (+2/-2)
libdbusmenu-glib/dbusmenu-glib-0.4.pc.in (+1/-1)
libdbusmenu-glib/menuitem-marshal.list (+1/-1)
libdbusmenu-glib/menuitem-private.h (+1/-0)
libdbusmenu-glib/menuitem-proxy.c (+6/-6)
libdbusmenu-glib/menuitem.c (+113/-83)
libdbusmenu-glib/menuitem.h (+5/-5)
libdbusmenu-glib/server-marshal.list (+1/-1)
libdbusmenu-glib/server.c (+547/-203)
libdbusmenu-gtk/Makefile.am (+27/-27)
libdbusmenu-gtk/client.c (+31/-42)
libdbusmenu-gtk/dbusmenu-gtk-0.4.pc.in (+1/-1)
libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc.in (+1/-1)
libdbusmenu-gtk/genericmenuitem.c (+2/-7)
libdbusmenu-gtk/menuitem.c (+39/-104)
tests/Makefile.am (+2/-2)
tests/json-loader.c (+59/-99)
tests/test-glib-events-client.c (+6/-8)
tests/test-glib-events-server.c (+28/-27)
tests/test-glib-layout-server.c (+28/-27)
tests/test-glib-objects.c (+19/-19)
tests/test-glib-properties-server.c (+1/-6)
tests/test-glib-proxy-client.c (+3/-4)
tests/test-glib-proxy-proxy.c (+27/-25)
tests/test-glib-proxy-server.c (+26/-25)
tests/test-glib-simple-items.c (+0/-3)
tests/test-glib-submenu-server.c (+28/-27)
tests/test-gtk-label-server.c (+29/-25)
tests/test-gtk-objects.c (+2/-2)
tests/test-gtk-reorder-server.c (+28/-27)
tests/test-gtk-shortcut-server.c (+28/-27)
tests/test-gtk-submenu-server.c (+28/-27)
tests/test-json-01.json (+822/-822)
tests/test-json-client.c (+34/-30)
tests/test-json-server.c (+34/-27)
tools/dbusmenu-dumper.c (+42/-136)
tools/testapp/main.c (+27/-22)
To merge this branch: bzr merge lp:~ted/libdbusmenu/kill-dbus-glib
Reviewer Review Type Date Requested Status
Mikkel Kamstrup Erlandsen (community) Approve
Aurélien Gâteau (community) static Approve
DBus Menu Team Pending
Review via email: mp+42543@code.launchpad.net

Description of the change

Changes from dbus-glib to GDBus. There's an API change along the way as we have to drop GValue for GVariant as well.

To post a comment you must log in.
Revision history for this message
David Barth (dbarth) wrote :

The review request is mostly for you guys to know what happens here, more than for spotting bugs.
The test suite passes, which is a strong indication of the quality of the port.

Revision history for this message
Aurélien Gâteau (agateau) wrote :

I don't know anything about gdbus so this is mostly a static generic review.

- You introduced an xslt file to filter out dox elements from the interface xml files, I assume this is because gdbus has a problem with them. Do they suggest other ways to document interfaces?

- There seems to be a vast amount of duplicated code for error handling. Can't this be factorized? I am thinking about blocks like these:

"""
if (priv->root == NULL) {
  g_dbus_method_invocation_return_error(invocation,
  error_quark(),
  NO_VALID_LAYOUT,
  "There currently isn't a layout in this server");
  return;
}
"""

"""
DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id);

if (mi == NULL) {
  g_dbus_method_invocation_return_error(invocation,
    error_quark(),
    INVALID_MENUITEM_ID,
    "The ID supplied %d does not refer to a menu item we have",
    parent);
    return;
}
"""

I think having macros like return_if_no_layout(priv) and get_menuitem_or_return(priv, id) would make the code shorter and easier to read.

review: Approve (static)
Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

I haven't looked deeply into this, but it looks very nice at glance. Very good work Ted! :-)

Because I on principle *must* comment something on such large reviews here's some feedback. All of these are really just personal programming style preferences, so disregard to your liking:

 a) I think that all the heap allocated GVariantBuilders and GVariantIters could just as well be stack allocated. Not that the increased memchurn by heap allocations will matter much compared to the socket io.

 b) For methods that return guint32 and gint32 i prefer also storing the return values not just in a guint or gint, since technically guint and int could be 64 bit. Although it's extremely unlikely to cause problems, it's theoretically possible (I think?)

 c) In your async calls where you pass 'self' as the userdata argument I think you need to g_object_ref(self) and the unref in the async callback. The self instance may be finalized the async call returns. This may not be a problem in this particular lib, but I've had problems with that in some of my own libs in the past.

review: Approve
lp:~ted/libdbusmenu/kill-dbus-glib updated
294. By Ted Gould

Updating to trunk with introspection fixes

295. By Ted Gould

Oops, wrong version -- fixed

296. By Ted Gould

Wrong directory for jsonloader header files.

Revision history for this message
Ted Gould (ted) wrote :

I agree with the points, but I'm going to table them to "future work" so that we can get this merged and stop blocking people. I don't believe that any of them are blockers.

To answer a couple of questions, yeah the GMarkup XML parse isn't very robust and so that's why I needed the XSLT. Most GNOME projects are using an XSLT script to turn the DBus API into docbook. Not sure that's better really :-/

I used the heap allocated Builders and Iters because well, I didn't understand them as well when I started. I've tried to refactor most of them to be stack allocated. I also want to start using them instead of arrays to collect things like IDs that are going to be turned into Variants in the end anyway. Lots of possibilities for improvement there.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2010-11-11 14:15:20 +0000
3+++ .bzrignore 2010-12-08 03:19:55 +0000
4@@ -182,7 +182,7 @@
5 docs/libdbusmenu-gtk/reference/tmpl/menuitem.sgml.bak
6 gtk-doc.make
7 m4/gtk-doc.m4
8-tests/dbusmenu-jsonloader.pc
9+tests/dbusmenu-jsonloader-0.4.pc
10 tests/libdbusmenu-jsonloader.la
11 tests/libdbusmenu_jsonloader_la-json-loader.lo
12 tests/test-json-server
13@@ -194,6 +194,13 @@
14 tests/test-glib-events
15 tests/test-glib-events-client
16 tests/test-glib-events-server
17+libdbusmenu-glib/dbus-menu.xml.c
18+libdbusmenu-glib/dbus-menu.xml.h
19+libdbusmenu-glib/libdbusmenu_glib_la-dbus-menu.xml.lo
20+libdbusmenu-glib/dbus-menu-clean.xml
21+libdbusmenu-glib/dbus-menu-clean.xml.c
22+libdbusmenu-glib/dbus-menu-clean.xml.h
23+libdbusmenu-glib/libdbusmenu_glib_la-dbus-menu-clean.xml.lo
24 libdbusmenu-gtk/DbusmenuGtk3-0.2.gir
25 libdbusmenu-gtk/DbusmenuGtk3-0.2.tmp.gir
26 libdbusmenu-gtk/DbusmenuGtk3-0.2.typelib
27@@ -203,3 +210,13 @@
28 libdbusmenu-gtk/libdbusmenu_gtk3_la-genericmenuitem.lo
29 libdbusmenu-gtk/libdbusmenu_gtk3_la-menu.lo
30 libdbusmenu-gtk/libdbusmenu_gtk3_la-menuitem.lo
31+libdbusmenu-glib/Dbusmenu-Glib-0.4.gir
32+libdbusmenu-glib/Dbusmenu-Glib-0.4.typelib
33+libdbusmenu-glib/Dbusmenu-Glib-0.4.vapi
34+libdbusmenu-glib/dbusmenu-glib-0.4.pc
35+libdbusmenu-gtk/DbusmenuGtk-0.4.gir
36+libdbusmenu-gtk/DbusmenuGtk-0.4.tmp.gir
37+libdbusmenu-gtk/DbusmenuGtk-0.4.typelib
38+libdbusmenu-gtk/DbusmenuGtk-0.4.vapi
39+libdbusmenu-gtk/dbusmenu-gtk-0.4.pc
40+libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc
41
42=== modified file 'configure.ac'
43--- configure.ac 2010-12-06 16:50:24 +0000
44+++ configure.ac 2010-12-08 03:19:55 +0000
45@@ -41,12 +41,11 @@
46 # Dependencies - GLib
47 ###########################
48
49-GLIB_REQUIRED_VERSION=2.18
50-DBUS_REQUIRED_VERSION=0.76
51+GLIB_REQUIRED_VERSION=2.26
52 XML_REQUIRED_VERSION=2.6
53
54 PKG_CHECK_MODULES(DBUSMENUGLIB, glib-2.0 >= $GLIB_REQUIRED_VERSION
55- dbus-glib-1 >= $DBUS_REQUIRED_VERSION
56+ gio-2.0 >= $GLIB_REQUIRED_VERSION
57 libxml-2.0 >= $XML_REQUIRED_VERSION)
58
59 AC_SUBST(DBUSMENUGLIB_CFLAGS)
60@@ -67,7 +66,6 @@
61 AS_IF([test "x$with_gtk" = x3],
62 [PKG_CHECK_MODULES(DBUSMENUGTK, gtk+-3.0 >= $GTK3_REQUIRED_VERSION
63 glib-2.0 >= $GLIB_REQUIRED_VERSION
64- dbus-glib-1 >= $DBUS_REQUIRED_VERSION
65 libxml-2.0 >= $XML_REQUIRED_VERSION)
66 AC_SUBST(DBUSMENUGTK_CFLAGS)
67 AC_SUBST(DBUSMENUGTK_LIBS)
68@@ -76,7 +74,6 @@
69 [test "x$with_gtk" = x2],
70 [PKG_CHECK_MODULES(DBUSMENUGTK, gtk+-2.0 >= $GTK_REQUIRED_VERSION
71 glib-2.0 >= $GLIB_REQUIRED_VERSION
72- dbus-glib-1 >= $DBUS_REQUIRED_VERSION
73 libxml-2.0 >= $XML_REQUIRED_VERSION)
74 AC_SUBST(DBUSMENUGTK_CFLAGS)
75 AC_SUBST(DBUSMENUGTK_LIBS)
76@@ -129,6 +126,12 @@
77 AC_PATH_PROG([VALA_API_GEN], [vapigen])
78
79 ###########################
80+# XSLT Processor
81+###########################
82+
83+AC_PATH_PROG([XSLT_PROC], [xsltproc])
84+
85+###########################
86 # Lib versioning
87 ###########################
88
89@@ -168,14 +171,14 @@
90 Makefile
91 po/Makefile.in
92 libdbusmenu-glib/Makefile
93-libdbusmenu-glib/dbusmenu-glib.pc
94+libdbusmenu-glib/dbusmenu-glib-0.4.pc
95 libdbusmenu-gtk/Makefile
96-libdbusmenu-gtk/dbusmenu-gtk.pc
97-libdbusmenu-gtk/dbusmenu-gtk3.pc
98+libdbusmenu-gtk/dbusmenu-gtk-0.4.pc
99+libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc
100 tools/Makefile
101 tools/testapp/Makefile
102 tests/Makefile
103-tests/dbusmenu-jsonloader.pc
104+tests/dbusmenu-jsonloader-0.4.pc
105 docs/Makefile
106 docs/libdbusmenu-glib/Makefile
107 docs/libdbusmenu-glib/reference/Makefile
108
109=== modified file 'libdbusmenu-glib/Makefile.am'
110--- libdbusmenu-glib/Makefile.am 2010-12-06 16:50:24 +0000
111+++ libdbusmenu-glib/Makefile.am 2010-12-08 03:19:55 +0000
112@@ -2,7 +2,8 @@
113 CLEANFILES =
114
115 EXTRA_DIST = \
116- dbusmenu-glib.pc.in \
117+ clean-namespaces.xslt \
118+ dbusmenu-glib-0.4.pc.in \
119 dbus-menu.xml \
120 client-marshal.list \
121 menuitem-marshal.list \
122@@ -11,7 +12,7 @@
123 lib_LTLIBRARIES = \
124 libdbusmenu-glib.la
125
126-libdbusmenu_glibincludedir=$(includedir)/libdbusmenu-0.1/libdbusmenu-glib/
127+libdbusmenu_glibincludedir=$(includedir)/libdbusmenu-0.4/libdbusmenu-glib/
128
129 libdbusmenu_glibinclude_HEADERS = \
130 menuitem.h \
131@@ -20,8 +21,8 @@
132 client.h
133
134 libdbusmenu_glib_la_SOURCES = \
135- dbusmenu-server.h \
136- dbusmenu-client.h \
137+ dbus-menu-clean.xml.h \
138+ dbus-menu-clean.xml.c \
139 menuitem.h \
140 menuitem.c \
141 menuitem-marshal.h \
142@@ -51,12 +52,25 @@
143 libdbusmenu_glib_la_LIBADD = \
144 $(DBUSMENUGLIB_LIBS)
145
146-pkgconfig_DATA = dbusmenu-glib.pc
147+pkgconfig_DATA = dbusmenu-glib-0.4.pc
148 pkgconfigdir = $(libdir)/pkgconfig
149
150+%.xml.h: %.xml
151+ echo "extern const char * $(subst -,_,$(subst .,_,$(basename $@)));" > $@
152+
153+%.xml.c: %.xml
154+ echo "const char * $(subst -,_,$(subst .,_,$(basename $@))) = " > $@
155+ sed -e "s:\":\\\\\":g" -e s:^:\": -e s:\$$:\\\\n\": $< >> $@
156+ echo ";" >> $@
157+
158+dbus-menu-clean.xml: dbus-menu.xml
159+ $(XSLT_PROC) $(srcdir)/clean-namespaces.xslt $< > $@ || (rm -f $@ && /bin/false)
160+
161+CLEANFILES += dbus-menu-clean.xml
162+
163 BUILT_SOURCES = \
164- dbusmenu-client.h \
165- dbusmenu-server.h \
166+ dbus-menu-clean.xml.c \
167+ dbus-menu-clean.xml.h \
168 client-marshal.h \
169 client-marshal.c \
170 menuitem-marshal.h \
171@@ -64,19 +78,7 @@
172 server-marshal.h \
173 server-marshal.c
174
175-dbusmenu-server.h: dbus-menu.xml
176- dbus-binding-tool \
177- --prefix=_dbusmenu_server \
178- --mode=glib-server \
179- --output=dbusmenu-server.h \
180- $(srcdir)/dbus-menu.xml
181-
182-dbusmenu-client.h: dbus-menu.xml
183- dbus-binding-tool \
184- --prefix=_dbusmenu_client \
185- --mode=glib-client \
186- --output=dbusmenu-client.h \
187- $(srcdir)/dbus-menu.xml
188+CLEANFILES += $(BUILT_SOURCES)
189
190 client-marshal.h: $(srcdir)/client-marshal.list
191 glib-genmarshal --header \
192@@ -133,18 +135,18 @@
193
194 introspection_sources = $(libdbusmenu_glibinclude_HEADERS)
195
196-Dbusmenu_Glib-0.2.gir: libdbusmenu-glib.la
197-Dbusmenu_Glib_0_2_gir_INCLUDES = \
198+Dbusmenu_Glib-0.4.gir: libdbusmenu-glib.la
199+Dbusmenu_Glib_0_4_gir_INCLUDES = \
200 GObject-2.0
201-Dbusmenu_Glib_0_2_gir_CFLAGS = $(DBUSMENUGLIB_CFLAGS)
202-Dbusmenu_Glib_0_2_gir_LIBS = libdbusmenu-glib.la
203-Dbusmenu_Glib_0_2_gir_FILES = $(addprefix $(srcdir)/, $(introspection_sources))
204-Dbusmenu_Glib_0_2_gir_NAMESPACE = Dbusmenu
205-Dbusmenu_Glib_0_2_gir_VERSION = Glib-0.2
206-Dbusmenu_Glib_0_2_gir_PACKAGES = dbusmenu-glib
207-Dbusmenu_Glib_0_2_gir_SCANNER_FLAGS = $(INTROSPECTION_SCANNER_ARGS)
208+Dbusmenu_Glib_0_4_gir_CFLAGS = $(DBUSMENUGLIB_CFLAGS)
209+Dbusmenu_Glib_0_4_gir_LIBS = libdbusmenu-glib.la
210+Dbusmenu_Glib_0_4_gir_FILES = $(addprefix $(srcdir)/, $(introspection_sources))
211+Dbusmenu_Glib_0_4_gir_NAMESPACE = Dbusmenu
212+Dbusmenu_Glib_0_4_gir_VERSION = Glib-0.4
213+Dbusmenu_Glib_0_4_gir_PACKAGES = dbusmenu-glib
214+Dbusmenu_Glib_0_4_gir_SCANNER_FLAGS = $(INTROSPECTION_SCANNER_ARGS)
215
216-INTROSPECTION_GIRS += Dbusmenu-Glib-0.2.gir
217+INTROSPECTION_GIRS += Dbusmenu-Glib-0.4.gir
218
219 girdir = $(datadir)/gir-1.0
220 gir_DATA = $(INTROSPECTION_GIRS)
221@@ -163,10 +165,10 @@
222 if HAVE_INTROSPECTION
223
224 vapidir = $(datadir)/vala/vapi
225-vapi_DATA = Dbusmenu-Glib-0.2.vapi
226+vapi_DATA = Dbusmenu-Glib-0.4.vapi
227
228-Dbusmenu-Glib-0.2.vapi: Dbusmenu-Glib-0.2.gir
229- $(VALA_API_GEN) --library=Dbusmenu-Glib-0.2 $<
230+Dbusmenu-Glib-0.4.vapi: Dbusmenu-Glib-0.4.gir
231+ $(VALA_API_GEN) --library=Dbusmenu-Glib-0.4 $<
232
233 CLEANFILES += $(vapi_DATA)
234
235
236=== added file 'libdbusmenu-glib/clean-namespaces.xslt'
237--- libdbusmenu-glib/clean-namespaces.xslt 1970-01-01 00:00:00 +0000
238+++ libdbusmenu-glib/clean-namespaces.xslt 2010-12-08 03:19:55 +0000
239@@ -0,0 +1,14 @@
240+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dox="http://www.ayatana.org/dbus/dox.dtd">
241+ <xsl:template match="*|@*">
242+ <xsl:copy>
243+ <xsl:apply-templates select="*|@*" />
244+ </xsl:copy>
245+ </xsl:template>
246+ <xsl:template match="@dox:*|dox:*"/>
247+ <xsl:template match="*">
248+ <xsl:element name="{local-name()}">
249+ <xsl:apply-templates select="@* | node()"/>
250+ </xsl:element>
251+ </xsl:template>
252+</xsl:stylesheet>
253+
254
255=== modified file 'libdbusmenu-glib/client-marshal.list'
256--- libdbusmenu-glib/client-marshal.list 2010-08-26 19:45:26 +0000
257+++ libdbusmenu-glib/client-marshal.list 2010-12-08 03:19:55 +0000
258@@ -1,2 +1,2 @@
259 VOID: OBJECT, UINT
260-VOID: OBJECT, STRING, POINTER, UINT, POINTER
261+VOID: OBJECT, STRING, VARIANT, UINT, POINTER
262
263=== modified file 'libdbusmenu-glib/client-menuitem.c'
264--- libdbusmenu-glib/client-menuitem.c 2010-09-22 14:39:21 +0000
265+++ libdbusmenu-glib/client-menuitem.c 2010-12-08 03:19:55 +0000
266@@ -45,7 +45,7 @@
267 static void dbusmenu_client_menuitem_init (DbusmenuClientMenuitem *self);
268 static void dbusmenu_client_menuitem_dispose (GObject *object);
269 static void dbusmenu_client_menuitem_finalize (GObject *object);
270-static void handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp);
271+static void handle_event (DbusmenuMenuitem * mi, const gchar * name, GVariant * value, guint timestamp);
272 static void send_about_to_show (DbusmenuMenuitem * mi, void (*cb) (DbusmenuMenuitem * mi, gpointer user_data), gpointer cb_data);
273
274 G_DEFINE_TYPE (DbusmenuClientMenuitem, dbusmenu_client_menuitem, DBUSMENU_TYPE_MENUITEM);
275@@ -102,10 +102,10 @@
276
277 /* Passes the event signal on through the client. */
278 static void
279-handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp)
280+handle_event (DbusmenuMenuitem * mi, const gchar * name, GVariant * variant, guint timestamp)
281 {
282 DbusmenuClientMenuitemPrivate * priv = DBUSMENU_CLIENT_MENUITEM_GET_PRIVATE(mi);
283- dbusmenu_client_send_event(priv->client, dbusmenu_menuitem_get_id(mi), name, value, timestamp);
284+ dbusmenu_client_send_event(priv->client, dbusmenu_menuitem_get_id(mi), name, variant, timestamp);
285 return;
286 }
287
288
289=== modified file 'libdbusmenu-glib/client.c'
290--- libdbusmenu-glib/client.c 2010-10-14 13:57:10 +0000
291+++ libdbusmenu-glib/client.c 2010-12-08 03:19:55 +0000
292@@ -30,7 +30,7 @@
293 #include "config.h"
294 #endif
295
296-#include <dbus/dbus-glib-bindings.h>
297+#include <gio/gio.h>
298
299 #include <libxml/parser.h>
300 #include <libxml/tree.h>
301@@ -39,9 +39,9 @@
302 #include "menuitem.h"
303 #include "menuitem-private.h"
304 #include "client-menuitem.h"
305-#include "dbusmenu-client.h"
306 #include "server-marshal.h"
307 #include "client-marshal.h"
308+#include "dbus-menu-clean.xml.h"
309
310 /* How many property requests should we queue before
311 sending the message on dbus */
312@@ -64,6 +64,8 @@
313 LAST_SIGNAL
314 };
315
316+typedef void (*properties_func) (GVariant * properties, GError * error, gpointer user_data);
317+
318 static guint signals[LAST_SIGNAL] = { 0 };
319
320 struct _DbusmenuClientPrivate
321@@ -73,15 +75,18 @@
322 gchar * dbus_object;
323 gchar * dbus_name;
324
325- DBusGConnection * session_bus;
326- DBusGProxy * menuproxy;
327- DBusGProxy * propproxy;
328- DBusGProxyCall * layoutcall;
329+ GDBusConnection * session_bus;
330+ GCancellable * session_bus_cancel;
331+
332+ GDBusProxy * menuproxy;
333+ GCancellable * menuproxy_cancel;
334+
335+ GCancellable * layoutcall;
336
337 gint current_revision;
338 gint my_revision;
339
340- DBusGProxy * dbusproxy;
341+ guint dbusproxy;
342
343 GHashTable * type_handlers;
344
345@@ -101,7 +106,7 @@
346 typedef struct _properties_listener_t properties_listener_t;
347 struct _properties_listener_t {
348 gint id;
349- org_ayatana_dbusmenu_get_properties_reply callback;
350+ properties_func callback;
351 gpointer user_data;
352 gboolean replied;
353 };
354@@ -111,12 +116,13 @@
355 DbusmenuClient * client;
356 DbusmenuMenuitem * menuitem;
357 gchar * event;
358- GValue data;
359+ GVariant * variant;
360 guint timestamp;
361 };
362
363
364 #define DBUSMENU_CLIENT_GET_PRIVATE(o) (DBUSMENU_CLIENT(o)->priv)
365+#define DBUSMENU_INTERFACE "org.ayatana.dbusmenu"
366
367 /* GObject Stuff */
368 static void dbusmenu_client_class_init (DbusmenuClientClass *klass);
369@@ -126,19 +132,26 @@
370 static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec);
371 static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec);
372 /* Private Funcs */
373-static void layout_update (DBusGProxy * proxy, guint revision, gint parent, DbusmenuClient * client);
374-static void id_prop_update (DBusGProxy * proxy, gint id, gchar * property, GValue * value, DbusmenuClient * client);
375-static void id_update (DBusGProxy * proxy, gint id, DbusmenuClient * client);
376+static void layout_update (GDBusProxy * proxy, guint revision, gint parent, DbusmenuClient * client);
377+static void id_prop_update (GDBusProxy * proxy, gint id, gchar * property, GVariant * value, DbusmenuClient * client);
378+static void id_update (GDBusProxy * proxy, gint id, DbusmenuClient * client);
379 static void build_proxies (DbusmenuClient * client);
380 static gint parse_node_get_id (xmlNodePtr node);
381-static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, DBusGProxy * proxy);
382+static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, GDBusProxy * proxy);
383 static gint parse_layout (DbusmenuClient * client, const gchar * layout);
384-static void update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError * in_error, void * data);
385+static void update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data);
386 static void update_layout (DbusmenuClient * client);
387-static void menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data);
388-static void get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, org_ayatana_dbusmenu_get_properties_reply callback, gpointer user_data);
389+static void menuitem_get_properties_cb (GVariant * properties, GError * error, gpointer data);
390+static void get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, properties_func callback, gpointer user_data);
391 static GQuark error_domain (void);
392-static void item_activated (DBusGProxy * proxy, gint id, guint timestamp, DbusmenuClient * client);
393+static void item_activated (GDBusProxy * proxy, gint id, guint timestamp, DbusmenuClient * client);
394+static void menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data);
395+static void menuproxy_name_changed_cb (GObject * object, GParamSpec * pspec, gpointer user_data);
396+static void menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVariant * params, gpointer user_data);
397+
398+/* Globals */
399+static GDBusNodeInfo * dbusmenu_node_info = NULL;
400+static GDBusInterfaceInfo * dbusmenu_interface_info = NULL;
401
402 /* Build a type */
403 G_DEFINE_TYPE (DbusmenuClient, dbusmenu_client, G_TYPE_OBJECT);
404@@ -236,8 +249,8 @@
405 G_SIGNAL_RUN_LAST,
406 G_STRUCT_OFFSET (DbusmenuClientClass, event_result),
407 NULL, NULL,
408- _dbusmenu_client_marshal_VOID__OBJECT_STRING_POINTER_UINT_POINTER,
409- G_TYPE_NONE, 5, G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_POINTER);
410+ _dbusmenu_client_marshal_VOID__OBJECT_STRING_VARIANT_UINT_POINTER,
411+ G_TYPE_NONE, 5, G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_VARIANT, G_TYPE_UINT, G_TYPE_POINTER);
412
413 g_object_class_install_property (object_class, PROP_DBUSOBJECT,
414 g_param_spec_string(DBUSMENU_CLIENT_PROP_DBUS_OBJECT, "DBus Object we represent",
415@@ -250,6 +263,24 @@
416 NULL,
417 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
418
419+ if (dbusmenu_node_info == NULL) {
420+ GError * error = NULL;
421+
422+ dbusmenu_node_info = g_dbus_node_info_new_for_xml(dbus_menu_clean_xml, &error);
423+ if (error != NULL) {
424+ g_error("Unable to parse DBusmenu Interface description: %s", error->message);
425+ g_error_free(error);
426+ }
427+ }
428+
429+ if (dbusmenu_interface_info == NULL) {
430+ dbusmenu_interface_info = g_dbus_node_info_lookup_interface(dbusmenu_node_info, DBUSMENU_INTERFACE);
431+
432+ if (dbusmenu_interface_info == NULL) {
433+ g_error("Unable to find interface '" DBUSMENU_INTERFACE "'");
434+ }
435+ }
436+
437 return;
438 }
439
440@@ -266,14 +297,17 @@
441 priv->dbus_name = NULL;
442
443 priv->session_bus = NULL;
444+ priv->session_bus_cancel = NULL;
445+
446 priv->menuproxy = NULL;
447- priv->propproxy = NULL;
448+ priv->menuproxy_cancel = NULL;
449+
450 priv->layoutcall = NULL;
451
452 priv->current_revision = 0;
453 priv->my_revision = 0;
454
455- priv->dbusproxy = NULL;
456+ priv->dbusproxy = 0;
457
458 priv->type_handlers = g_hash_table_new_full(g_str_hash, g_str_equal,
459 g_free, NULL);
460@@ -317,7 +351,7 @@
461 if (localerror == NULL) {
462 g_set_error_literal(&localerror, error_domain(), 0, "DbusmenuClient Shutdown");
463 }
464- listener->callback(priv->menuproxy, NULL, localerror, listener->user_data);
465+ listener->callback(NULL, localerror, listener->user_data);
466 }
467 }
468 if (localerror != NULL) {
469@@ -329,22 +363,39 @@
470 }
471
472 if (priv->layoutcall != NULL) {
473- dbus_g_proxy_cancel_call(priv->menuproxy, priv->layoutcall);
474+ g_cancellable_cancel(priv->layoutcall);
475+ g_object_unref(priv->layoutcall);
476 priv->layoutcall = NULL;
477 }
478+
479+ /* Bring down the menu proxy, ensure we're not
480+ looking for one at the same time. */
481+ if (priv->menuproxy_cancel != NULL) {
482+ g_cancellable_cancel(priv->menuproxy_cancel);
483+ g_object_unref(priv->menuproxy_cancel);
484+ priv->menuproxy_cancel = NULL;
485+ }
486 if (priv->menuproxy != NULL) {
487 g_object_unref(G_OBJECT(priv->menuproxy));
488 priv->menuproxy = NULL;
489 }
490- if (priv->propproxy != NULL) {
491- g_object_unref(G_OBJECT(priv->propproxy));
492- priv->propproxy = NULL;
493- }
494- if (priv->dbusproxy != NULL) {
495- g_object_unref(G_OBJECT(priv->dbusproxy));
496- priv->dbusproxy = NULL;
497- }
498- priv->session_bus = NULL;
499+
500+ if (priv->dbusproxy != 0) {
501+ g_bus_unwatch_name(priv->dbusproxy);
502+ priv->dbusproxy = 0;
503+ }
504+
505+ /* Bring down the session bus, ensure we're not
506+ looking for one at the same time. */
507+ if (priv->session_bus_cancel != NULL) {
508+ g_cancellable_cancel(priv->session_bus_cancel);
509+ g_object_unref(priv->session_bus_cancel);
510+ priv->session_bus_cancel = NULL;
511+ }
512+ if (priv->session_bus != NULL) {
513+ g_object_unref(priv->session_bus);
514+ priv->session_bus = NULL;
515+ }
516
517 if (priv->root != NULL) {
518 g_object_unref(G_OBJECT(priv->root));
519@@ -449,47 +500,37 @@
520 /* Call back from getting the group properties, now we need
521 to unwind and call the various functions. */
522 static void
523-get_properties_callback (DBusGProxy *proxy, GPtrArray *OUT_properties, GError *error, gpointer userdata)
524+get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data)
525 {
526- GArray * listeners = (GArray *)userdata;
527+ GArray * listeners = (GArray *)user_data;
528 int i;
529+ GError * error = NULL;
530+ GVariant * params = NULL;
531
532- #ifdef MASSIVEDEBUGGING
533- g_debug("Get properties callback: %d", OUT_properties->len);
534- #endif
535+ params = g_dbus_proxy_call_finish(G_DBUS_PROXY(obj), res, &error);
536
537 if (error != NULL) {
538 /* If we get an error, all our callbacks need to hear about it. */
539 g_warning("Group Properties error: %s", error->message);
540 for (i = 0; i < listeners->len; i++) {
541 properties_listener_t * listener = &g_array_index(listeners, properties_listener_t, i);
542- listener->callback(proxy, NULL, error, listener->user_data);
543+ listener->callback(NULL, error, listener->user_data);
544 }
545 g_array_free(listeners, TRUE);
546 return;
547 }
548
549 /* Callback all the folks we can find */
550- for (i = 0; i < OUT_properties->len; i++) {
551- GValueArray * varray = (GValueArray *)g_ptr_array_index(OUT_properties, i);
552-
553- if (varray->n_values != 2) {
554- g_warning("Value Array is %d entries long but we expected 2.", varray->n_values);
555+ GVariantIter * iter = g_variant_iter_new(g_variant_get_child_value(params, 0));
556+ GVariant * child;
557+ while ((child = g_variant_iter_next_value(iter)) != NULL) {
558+ if (g_strcmp0(g_variant_get_type_string(child), "(ia{sv})") != 0) {
559+ g_warning("Properties return signature is not '(ia{sv})' it is '%s'", g_variant_get_type_string(child));
560 continue;
561 }
562
563- GValue * vid = g_value_array_get_nth(varray, 0);
564- GValue * vproperties = g_value_array_get_nth(varray, 1);
565-
566- if (G_VALUE_TYPE(vid) != G_TYPE_INT) {
567- g_warning("ID Entry not holding an int: %s", G_VALUE_TYPE_NAME(vid));
568- }
569- if (G_VALUE_TYPE(vproperties) != dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) {
570- g_warning("Properties Entry not holding an a{sv}: %s", G_VALUE_TYPE_NAME(vproperties));
571- }
572-
573- gint id = g_value_get_int(vid);
574- GHashTable * properties = g_value_get_boxed(vproperties);
575+ gint id = g_variant_get_int32(g_variant_get_child_value(child, 0));
576+ GVariant * properties = g_variant_get_child_value(child, 1);
577
578 properties_listener_t * listener = find_listener(listeners, 0, id);
579 if (listener == NULL) {
580@@ -498,22 +539,25 @@
581 }
582
583 if (!listener->replied) {
584- listener->callback(proxy, properties, NULL, listener->user_data);
585+ listener->callback(properties, NULL, listener->user_data);
586 listener->replied = TRUE;
587 } else {
588 g_warning("Odd, we've already replied to the listener on ID %d", id);
589 }
590 }
591+ g_variant_iter_free(iter);
592+ g_variant_unref(params);
593
594 /* Provide errors for those who we can't */
595 GError * localerror = NULL;
596 for (i = 0; i < listeners->len; i++) {
597 properties_listener_t * listener = &g_array_index(listeners, properties_listener_t, i);
598 if (!listener->replied) {
599+ g_warning("Generating properties error for: %d", listener->id);
600 if (localerror == NULL) {
601 g_set_error_literal(&localerror, error_domain(), 0, "Error getting properties for ID");
602 }
603- listener->callback(proxy, NULL, localerror, listener->user_data);
604+ listener->callback(NULL, localerror, listener->user_data);
605 }
606 }
607 if (localerror != NULL) {
608@@ -532,7 +576,7 @@
609 get_properties_idle (gpointer user_data)
610 {
611 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(user_data);
612- //org_ayatana_dbusmenu_get_properties_async(priv->menuproxy, id, properties, callback, user_data);
613+ g_return_val_if_fail(priv->menuproxy != NULL, TRUE);
614
615 if (priv->delayed_property_listeners->len == 0) {
616 g_warning("Odd, idle func got no listeners.");
617@@ -540,16 +584,35 @@
618 }
619
620 /* Build up an ID list to pass */
621- GArray * idlist = g_array_new(FALSE, FALSE, sizeof(gint));
622+ GVariantBuilder builder;
623+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
624+
625 gint i;
626 for (i = 0; i < priv->delayed_property_listeners->len; i++) {
627- g_array_append_val(idlist, g_array_index(priv->delayed_property_listeners, properties_listener_t, i).id);
628+ g_variant_builder_add(&builder, "i", g_array_index(priv->delayed_property_listeners, properties_listener_t, i).id);
629 }
630
631- org_ayatana_dbusmenu_get_group_properties_async(priv->menuproxy, idlist, (const gchar **)priv->delayed_property_list->data, get_properties_callback, priv->delayed_property_listeners);
632-
633- /* Free ID List */
634- g_array_free(idlist, TRUE);
635+ GVariant * variant_ids = g_variant_builder_end(&builder);
636+
637+ /* Build up a prop list to pass */
638+ g_variant_builder_init(&builder, g_variant_type_new("as"));
639+ /* TODO: need to use delayed property list here */
640+ GVariant * variant_props = g_variant_builder_end(&builder);
641+
642+ /* Combine them into a value for the parameter */
643+ g_variant_builder_init(&builder, G_VARIANT_TYPE_TUPLE);
644+ g_variant_builder_add_value(&builder, variant_ids);
645+ g_variant_builder_add_value(&builder, variant_props);
646+ GVariant * variant_params = g_variant_builder_end(&builder);
647+
648+ g_dbus_proxy_call(priv->menuproxy,
649+ "GetGroupProperties",
650+ variant_params,
651+ G_DBUS_CALL_FLAGS_NONE,
652+ -1, /* timeout */
653+ NULL, /* cancellable */
654+ get_properties_callback,
655+ priv->delayed_property_listeners);
656
657 /* Free properties */
658 gchar ** dataregion = (gchar **)g_array_free(priv->delayed_property_list, FALSE);
659@@ -583,22 +646,20 @@
660
661 get_properties_idle(client);
662
663- dbus_g_connection_flush(priv->session_bus);
664-
665 return;
666 }
667
668 /* A function to group all the get_properties commands to make them
669 more efficient over dbus. */
670 static void
671-get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, org_ayatana_dbusmenu_get_properties_reply callback, gpointer user_data)
672+get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, properties_func callback, gpointer user_data)
673 {
674 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
675 if (find_listener(priv->delayed_property_listeners, 0, id) != NULL) {
676 g_warning("Asking for properties from same ID twice: %d", id);
677 GError * localerror = NULL;
678 g_set_error_literal(&localerror, error_domain(), 0, "ID already queued");
679- callback(priv->menuproxy, NULL, localerror, user_data);
680+ callback(NULL, localerror, user_data);
681 g_error_free(localerror);
682 return;
683 }
684@@ -644,7 +705,7 @@
685
686 /* Called when a server item wants to activate the menu */
687 static void
688-item_activated (DBusGProxy * proxy, gint id, guint timestamp, DbusmenuClient * client)
689+item_activated (GDBusProxy * proxy, gint id, guint timestamp, DbusmenuClient * client)
690 {
691 g_return_if_fail(DBUSMENU_IS_CLIENT(client));
692
693@@ -668,7 +729,7 @@
694
695 /* Annoying little wrapper to make the right function update */
696 static void
697-layout_update (DBusGProxy * proxy, guint revision, gint parent, DbusmenuClient * client)
698+layout_update (GDBusProxy * proxy, guint revision, gint parent, DbusmenuClient * client)
699 {
700 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
701 priv->current_revision = revision;
702@@ -681,16 +742,8 @@
703 /* Signal from the server that a property has changed
704 on one of our menuitems */
705 static void
706-id_prop_update (DBusGProxy * proxy, gint id, gchar * property, GValue * value, DbusmenuClient * client)
707+id_prop_update (GDBusProxy * proxy, gint id, gchar * property, GVariant * value, DbusmenuClient * client)
708 {
709- #ifdef MASSIVEDEBUGGING
710- GValue valstr = {0};
711- g_value_init(&valstr, G_TYPE_STRING);
712- g_value_transform(value, &valstr);
713- g_debug("Property change sent to client for item %d property %s value %s", id, property, g_utf8_strlen(g_value_get_string(&valstr), 50) < 25 ? g_value_get_string(&valstr) : "<too long>");
714- g_value_unset(&valstr);
715- #endif
716-
717 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
718
719 g_return_if_fail(priv->root != NULL);
720@@ -703,7 +756,7 @@
721 return;
722 }
723
724- dbusmenu_menuitem_property_set_value(menuitem, property, value);
725+ dbusmenu_menuitem_property_set_variant(menuitem, property, value);
726
727 return;
728 }
729@@ -711,7 +764,7 @@
730 /* Oh, lots of updates now. That silly server, they want
731 to change all kinds of stuff! */
732 static void
733-id_update (DBusGProxy * proxy, gint id, DbusmenuClient * client)
734+id_update (GDBusProxy * proxy, gint id, DbusmenuClient * client)
735 {
736 #ifdef MASSIVEDEBUGGING
737 g_debug("Client side ID update: %d", id);
738@@ -731,83 +784,39 @@
739
740 /* Watches to see if our DBus savior comes onto the bus */
741 static void
742-dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, DbusmenuClient * client)
743+dbus_owner_change (GDBusConnection * connection, const gchar * name, const gchar * owner, gpointer user_data)
744 {
745- DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
746- /* g_debug("Owner change: %s %s %s", name, prev, new); */
747-
748- if (!(new[0] != '\0' && prev[0] == '\0')) {
749- /* If it's not someone new getting on the bus, sorry we
750- simply just don't care. It's not that your service isn't
751- important to someone, just not us. You'll find the right
752- process someday, there's lots of processes out there. */
753- return;
754- }
755-
756- if (g_strcmp0(name, priv->dbus_name)) {
757- /* Again, someone else's service. */
758- return;
759- }
760+ g_return_if_fail(DBUSMENU_IS_CLIENT(user_data));
761+
762+ DbusmenuClient * client = DBUSMENU_CLIENT(user_data);
763
764 /* Woot! A service for us to love and to hold for ever
765 and ever and ever! */
766 return build_proxies(client);
767 }
768
769-/* This is the response to see if the name has an owner. If
770- it does, then we should build the proxies here. Race condition
771- check. */
772-static void
773-name_owner_check (DBusGProxy *proxy, gboolean has_owner, GError *error, gpointer userdata)
774-{
775- if (error != NULL) {
776- return;
777- }
778-
779- if (!has_owner) {
780- return;
781- }
782-
783- DbusmenuClient * client = DBUSMENU_CLIENT(userdata);
784- build_proxies(client);
785- return;
786-}
787-
788 /* This function builds the DBus proxy which will look out for
789 the service coming up. */
790 static void
791 build_dbus_proxy (DbusmenuClient * client)
792 {
793 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
794- GError * error = NULL;
795-
796- if (priv->dbusproxy != NULL) {
797- return;
798- }
799-
800- priv->dbusproxy = dbus_g_proxy_new_for_name_owner (priv->session_bus,
801- DBUS_SERVICE_DBUS,
802- DBUS_PATH_DBUS,
803- DBUS_INTERFACE_DBUS,
804- &error);
805- if (error != NULL) {
806- g_debug("Oh, that's bad. That's really bad. We can't get a proxy to DBus itself? Seriously? Here's all I know: %s", error->message);
807- g_error_free(error);
808- return;
809- }
810-
811- dbus_g_proxy_add_signal(priv->dbusproxy, "NameOwnerChanged",
812- G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
813- G_TYPE_INVALID);
814- dbus_g_proxy_connect_signal(priv->dbusproxy, "NameOwnerChanged",
815- G_CALLBACK(dbus_owner_change), client, NULL);
816+
817+ if (priv->dbusproxy != 0) {
818+ return;
819+ }
820+
821+ priv->dbusproxy = g_bus_watch_name_on_connection(priv->session_bus,
822+ priv->dbus_name,
823+ G_BUS_NAME_WATCHER_FLAGS_NONE,
824+ dbus_owner_change,
825+ NULL,
826+ client,
827+ NULL);
828
829 /* Now let's check to make sure we're not in some race
830 condition case. */
831- org_freedesktop_DBus_name_has_owner_async(priv->dbusproxy,
832- priv->dbus_name,
833- name_owner_check,
834- client);
835+ /* TODO: Not sure how to check for names in GDBus */
836
837 return;
838 }
839@@ -831,7 +840,11 @@
840 }
841
842 if ((gpointer)priv->menuproxy == (gpointer)gobj_proxy) {
843- priv->layoutcall = NULL;
844+ if (priv->layoutcall != NULL) {
845+ g_cancellable_cancel(priv->layoutcall);
846+ g_object_unref(priv->layoutcall);
847+ priv->layoutcall = NULL;
848+ }
849 }
850
851 priv->current_revision = 0;
852@@ -841,75 +854,176 @@
853 return;
854 }
855
856+/* Respond to us getting the session bus (hopefully) or handle
857+ the error if not */
858+void
859+session_bus_cb (GObject * object, GAsyncResult * res, gpointer user_data)
860+{
861+ GError * error = NULL;
862+
863+ /* NOTE: We're not using any other variables before checking
864+ the result because they could be destroyed and thus invalid */
865+ GDBusConnection * bus = g_bus_get_finish(res, &error);
866+ if (error != NULL) {
867+ g_warning("Unable to get session bus: %s", error->message);
868+ g_error_free(error);
869+ return;
870+ }
871+
872+ /* If this wasn't cancelled, we should be good */
873+ DbusmenuClient * client = DBUSMENU_CLIENT(user_data);
874+ DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
875+ priv->session_bus = bus;
876+
877+ if (priv->session_bus_cancel != NULL) {
878+ g_object_unref(priv->session_bus_cancel);
879+ priv->session_bus_cancel = NULL;
880+ }
881+
882+ /* Retry to build the proxies now that we have a bus */
883+ build_proxies(DBUSMENU_CLIENT(user_data));
884+
885+ return;
886+}
887+
888 /* When we have a name and an object, build the two proxies and get the
889 first version of the layout */
890 static void
891 build_proxies (DbusmenuClient * client)
892 {
893 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
894- GError * error = NULL;
895
896 g_return_if_fail(priv->dbus_object != NULL);
897 g_return_if_fail(priv->dbus_name != NULL);
898
899- priv->session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
900- if (error != NULL) {
901- g_error("Unable to get session bus: %s", error->message);
902- g_error_free(error);
903- build_dbus_proxy(client);
904- return;
905- }
906-
907- priv->propproxy = dbus_g_proxy_new_for_name_owner(priv->session_bus,
908- priv->dbus_name,
909- priv->dbus_object,
910- DBUS_INTERFACE_PROPERTIES,
911- &error);
912- if (error != NULL) {
913- g_warning("Unable to get property proxy for %s on %s: %s", priv->dbus_name, priv->dbus_object, error->message);
914- g_error_free(error);
915- build_dbus_proxy(client);
916- return;
917- }
918- g_object_add_weak_pointer(G_OBJECT(priv->propproxy), (gpointer *)&priv->propproxy);
919- g_signal_connect(G_OBJECT(priv->propproxy), "destroy", G_CALLBACK(proxy_destroyed), client);
920-
921- priv->menuproxy = dbus_g_proxy_new_for_name_owner(priv->session_bus,
922- priv->dbus_name,
923- priv->dbus_object,
924- "org.ayatana.dbusmenu",
925- &error);
926- if (error != NULL) {
927- g_warning("Unable to get dbusmenu proxy for %s on %s: %s", priv->dbus_name, priv->dbus_object, error->message);
928- g_error_free(error);
929- build_dbus_proxy(client);
930- return;
931- }
932- g_object_add_weak_pointer(G_OBJECT(priv->menuproxy), (gpointer *)&priv->menuproxy);
933- g_signal_connect(G_OBJECT(priv->menuproxy), "destroy", G_CALLBACK(proxy_destroyed), client);
934+ if (priv->session_bus == NULL) {
935+ /* We don't have the session bus yet, that's okay, but
936+ we need to handle that. */
937+
938+ /* If we're already running we don't need to look again. */
939+ if (priv->session_bus_cancel == NULL) {
940+ priv->session_bus_cancel = g_cancellable_new();
941+
942+ /* Async get the session bus */
943+ g_bus_get(G_BUS_TYPE_SESSION, priv->session_bus_cancel, session_bus_cb, client);
944+ }
945+
946+ /* This function exists, it'll be called again when we get
947+ the session bus so this condition will be ignored */
948+ return;
949+ }
950+
951+ /* Build us a menu proxy */
952+ if (priv->menuproxy == NULL) {
953+
954+ /* Check to see if we're already building one */
955+ if (priv->menuproxy_cancel == NULL) {
956+ priv->menuproxy_cancel = g_cancellable_new();
957+
958+ g_dbus_proxy_new(priv->session_bus,
959+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
960+ dbusmenu_interface_info,
961+ priv->dbus_name,
962+ priv->dbus_object,
963+ DBUSMENU_INTERFACE,
964+ priv->menuproxy_cancel,
965+ menuproxy_build_cb,
966+ client);
967+ }
968+ }
969+
970+ return;
971+}
972+
973+/* Callback when we know if the menu proxy can be created or
974+ not and do something with it! */
975+static void
976+menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data)
977+{
978+ GError * error = NULL;
979+
980+ /* NOTE: We're not using any other variables before checking
981+ the result because they could be destroyed and thus invalid */
982+ GDBusProxy * proxy = g_dbus_proxy_new_finish(res, &error);
983+ if (error != NULL) {
984+ g_warning("Unable to get menu proxy: %s", error->message);
985+ g_error_free(error);
986+ return;
987+ }
988+
989+ /* If this wasn't cancelled, we should be good */
990+ DbusmenuClient * client = DBUSMENU_CLIENT(user_data);
991+ DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
992+ priv->menuproxy = proxy;
993+
994+ if (priv->menuproxy_cancel != NULL) {
995+ g_object_unref(priv->menuproxy_cancel);
996+ priv->menuproxy_cancel = NULL;
997+ }
998
999 /* If we get here, we don't need the DBus proxy */
1000- if (priv->dbusproxy != NULL) {
1001- g_object_unref(G_OBJECT(priv->dbusproxy));
1002- priv->dbusproxy = NULL;
1003- }
1004-
1005- dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__UINT_INT, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_INT, G_TYPE_INVALID);
1006- dbus_g_proxy_add_signal(priv->menuproxy, "LayoutUpdated", G_TYPE_UINT, G_TYPE_INT, G_TYPE_INVALID);
1007- dbus_g_proxy_connect_signal(priv->menuproxy, "LayoutUpdated", G_CALLBACK(layout_update), client, NULL);
1008-
1009- dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__INT_STRING_POINTER, G_TYPE_NONE, G_TYPE_INT, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
1010- dbus_g_proxy_add_signal(priv->menuproxy, "ItemPropertyUpdated", G_TYPE_INT, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
1011- dbus_g_proxy_connect_signal(priv->menuproxy, "ItemPropertyUpdated", G_CALLBACK(id_prop_update), client, NULL);
1012-
1013- dbus_g_proxy_add_signal(priv->menuproxy, "ItemUpdated", G_TYPE_INT, G_TYPE_INVALID);
1014- dbus_g_proxy_connect_signal(priv->menuproxy, "ItemUpdated", G_CALLBACK(id_update), client, NULL);
1015-
1016- dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__INT_UINT, G_TYPE_NONE, G_TYPE_INT, G_TYPE_UINT, G_TYPE_INVALID);
1017- dbus_g_proxy_add_signal(priv->menuproxy, "ItemActivationRequested", G_TYPE_INT, G_TYPE_UINT, G_TYPE_INVALID);
1018- dbus_g_proxy_connect_signal(priv->menuproxy, "ItemActivationRequested", G_CALLBACK(item_activated), client, NULL);
1019-
1020- update_layout(client);
1021+ if (priv->dbusproxy != 0) {
1022+ g_bus_unwatch_name(priv->dbusproxy);
1023+ priv->dbusproxy = 0;
1024+ }
1025+
1026+ g_signal_connect(priv->menuproxy, "g-signal", G_CALLBACK(menuproxy_signal_cb), client);
1027+ g_signal_connect(priv->menuproxy, "notify::g-name-owner", G_CALLBACK(menuproxy_name_changed_cb), client);
1028+
1029+ gchar * name_owner = g_dbus_proxy_get_name_owner(priv->menuproxy);
1030+ if (name_owner != NULL) {
1031+ update_layout(client);
1032+ g_free(name_owner);
1033+ }
1034+
1035+ return;
1036+}
1037+
1038+/* Handle the case where we change owners */
1039+static void
1040+menuproxy_name_changed_cb (GObject * object, GParamSpec * pspec, gpointer user_data)
1041+{
1042+ GDBusProxy * proxy = G_DBUS_PROXY(object);
1043+
1044+ gchar * owner = g_dbus_proxy_get_name_owner(proxy);
1045+
1046+ if (owner == NULL) {
1047+ /* Oh, no! We lost our owner! */
1048+ proxy_destroyed(G_OBJECT(proxy), user_data);
1049+ } else {
1050+ g_free(owner);
1051+ update_layout(DBUSMENU_CLIENT(user_data));
1052+ }
1053+
1054+ return;
1055+}
1056+
1057+/* Handle the signals out of the proxy */
1058+static void
1059+menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVariant * params, gpointer user_data)
1060+{
1061+ g_return_if_fail(DBUSMENU_IS_CLIENT(user_data));
1062+ DbusmenuClient * client = DBUSMENU_CLIENT(user_data);
1063+
1064+ if (g_strcmp0(signal, "LayoutUpdated") == 0) {
1065+ guint revision; gint parent;
1066+ g_variant_get(params, "(ui)", &revision, &parent);
1067+ layout_update(proxy, revision, parent, client);
1068+ } else if (g_strcmp0(signal, "ItemPropertyUpdated") == 0) {
1069+ gint id; gchar * property; GVariant * value;
1070+ g_variant_get(params, "(isv)", &id, &property, &value);
1071+ id_prop_update(proxy, id, property, value, client);
1072+ } else if (g_strcmp0(signal, "ItemUpdated") == 0) {
1073+ gint id;
1074+ g_variant_get(params, "(i)", &id);
1075+ id_update(proxy, id, client);
1076+ } else if (g_strcmp0(signal, "ItemActivationRequested") == 0) {
1077+ gint id; guint timestamp;
1078+ g_variant_get(params, "(iu)", &id, &timestamp);
1079+ item_activated(proxy, id, timestamp, client);
1080+ } else {
1081+ g_warning("Received signal '%s' from menu proxy that is unknown", signal);
1082+ }
1083
1084 return;
1085 }
1086@@ -948,32 +1062,38 @@
1087 return -1;
1088 }
1089
1090-/* A small helper that calls _property_set on each hash table
1091- entry in the properties hash. */
1092-static void
1093-get_properties_helper (gpointer key, gpointer value, gpointer data)
1094-{
1095- dbusmenu_menuitem_property_set_value((DbusmenuMenuitem *)data, (gchar *)key, (GValue *)value);
1096- return;
1097-}
1098-
1099 /* This is the callback for the properties on a menu item. There
1100 should be all of them in the Hash, and they we use foreach to
1101 copy them into the menuitem.
1102 This isn't the most efficient way. We can optimize this by
1103 somehow removing the foreach. But that is for later. */
1104 static void
1105-menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data)
1106+menuitem_get_properties_cb (GVariant * properties, GError * error, gpointer data)
1107 {
1108 g_return_if_fail(DBUSMENU_IS_MENUITEM(data));
1109+ DbusmenuMenuitem * item = DBUSMENU_MENUITEM(data);
1110+
1111 if (error != NULL) {
1112 g_warning("Error getting properties on a menuitem: %s", error->message);
1113 g_object_unref(data);
1114 return;
1115 }
1116- g_hash_table_foreach(properties, get_properties_helper, data);
1117- g_hash_table_destroy(properties);
1118+
1119+ GVariantIter * iter = g_variant_iter_new(properties);
1120+ gchar * key;
1121+ GVariant * value;
1122+
1123+ while (g_variant_iter_next(iter, "{sv}", &key, &value)) {
1124+ dbusmenu_menuitem_property_set_variant(item, key, value);
1125+
1126+ g_variant_unref(value);
1127+ g_free(key);
1128+ }
1129+
1130+ g_variant_iter_free(iter);
1131+
1132 g_object_unref(data);
1133+
1134 return;
1135 }
1136
1137@@ -981,7 +1101,7 @@
1138 is getting recycled with the update, but we think might have prop
1139 changes. */
1140 static void
1141-menuitem_get_properties_replace_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data)
1142+menuitem_get_properties_replace_cb (GVariant * properties, GError * error, gpointer data)
1143 {
1144 g_return_if_fail(DBUSMENU_IS_MENUITEM(data));
1145 gboolean have_error = FALSE;
1146@@ -994,14 +1114,14 @@
1147 GList * current_props = NULL;
1148
1149 for (current_props = dbusmenu_menuitem_properties_list(DBUSMENU_MENUITEM(data));
1150- current_props != NULL ; current_props = g_list_next(current_props)) {
1151- if (have_error || g_hash_table_lookup(properties, current_props->data) == NULL) {
1152- dbusmenu_menuitem_property_remove(DBUSMENU_MENUITEM(data), (const gchar *)current_props->data);
1153- }
1154+ current_props != NULL && have_error == FALSE;
1155+ current_props = g_list_next(current_props)) {
1156+ dbusmenu_menuitem_property_remove(DBUSMENU_MENUITEM(data), (const gchar *)current_props->data);
1157 }
1158+ g_list_free(current_props);
1159
1160 if (!have_error) {
1161- menuitem_get_properties_cb(proxy, properties, error, data);
1162+ menuitem_get_properties_cb(properties, error, data);
1163 } else {
1164 g_object_unref(data);
1165 }
1166@@ -1012,7 +1132,7 @@
1167 /* This is a different get properites call back that also sends
1168 new signals. It basically is a small wrapper around the original. */
1169 static void
1170-menuitem_get_properties_new_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data)
1171+menuitem_get_properties_new_cb (GVariant * properties, GError * error, gpointer data)
1172 {
1173 g_return_if_fail(data != NULL);
1174 newItemPropData * propdata = (newItemPropData *)data;
1175@@ -1028,7 +1148,7 @@
1176
1177 /* Extra ref as get_properties will unref once itself */
1178 g_object_ref(propdata->item);
1179- menuitem_get_properties_cb (proxy, properties, error, propdata->item);
1180+ menuitem_get_properties_cb (properties, error, propdata->item);
1181
1182 gboolean handled = FALSE;
1183
1184@@ -1064,28 +1184,39 @@
1185 /* Respond to the call function to make sure that the other side
1186 got it, or print a warning. */
1187 static void
1188-menuitem_call_cb (DBusGProxy * proxy, GError * error, gpointer userdata)
1189+menuitem_call_cb (GObject * proxy, GAsyncResult * res, gpointer userdata)
1190 {
1191+ GError * error = NULL;
1192 event_data_t * edata = (event_data_t *)userdata;
1193+ GVariant * params;
1194+
1195+ params = g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), res, &error);
1196
1197 if (error != NULL) {
1198 g_warning("Unable to call event '%s' on menu item %d: %s", edata->event, dbusmenu_menuitem_get_id(edata->menuitem), error->message);
1199 }
1200
1201- g_signal_emit(edata->client, signals[EVENT_RESULT], 0, edata->menuitem, edata->event, &edata->data, edata->timestamp, error, TRUE);
1202+ g_signal_emit(edata->client, signals[EVENT_RESULT], 0, edata->menuitem, edata->event, edata->variant, edata->timestamp, error, TRUE);
1203
1204- g_value_unset(&edata->data);
1205+ g_variant_unref(edata->variant);
1206 g_free(edata->event);
1207 g_object_unref(edata->menuitem);
1208 g_free(edata);
1209
1210+ if (G_UNLIKELY(error != NULL)) {
1211+ g_error_free(error);
1212+ }
1213+ if (G_LIKELY(params != NULL)) {
1214+ g_variant_unref(params);
1215+ }
1216+
1217 return;
1218 }
1219
1220 /* Sends the event over DBus to the server on the other side
1221 of the bus. */
1222 void
1223-dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name, const GValue * value, guint timestamp)
1224+dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name, GVariant * variant, guint timestamp)
1225 {
1226 g_return_if_fail(DBUSMENU_IS_CLIENT(client));
1227 g_return_if_fail(id >= 0);
1228@@ -1098,11 +1229,8 @@
1229 return;
1230 }
1231
1232- if (value == NULL) {
1233- GValue internalval = {0};
1234- g_value_init(&internalval, G_TYPE_INT);
1235- g_value_set_int(&internalval, 0);
1236- value = &internalval;
1237+ if (variant == NULL) {
1238+ variant = g_variant_new_int32(0);
1239 }
1240
1241 event_data_t * edata = g_new0(event_data_t, 1);
1242@@ -1110,15 +1238,18 @@
1243 edata->menuitem = mi;
1244 g_object_ref(edata->menuitem);
1245 edata->event = g_strdup(name);
1246- g_value_init(&edata->data, G_VALUE_TYPE(value));
1247- g_value_copy(value, &edata->data);
1248 edata->timestamp = timestamp;
1249+ edata->variant = variant;
1250+ g_variant_ref(variant);
1251
1252- DBusGAsyncData *stuff;
1253- stuff = g_slice_new (DBusGAsyncData);
1254- stuff->cb = G_CALLBACK (menuitem_call_cb);
1255- stuff->userdata = edata;
1256- dbus_g_proxy_begin_call_with_timeout (priv->menuproxy, "Event", org_ayatana_dbusmenu_event_async_callback, stuff, _dbus_glib_async_data_free, 1000, G_TYPE_INT, id, G_TYPE_STRING, name, G_TYPE_VALUE, value, G_TYPE_UINT, timestamp, G_TYPE_INVALID);
1257+ g_dbus_proxy_call(priv->menuproxy,
1258+ "Event",
1259+ g_variant_new("(isvu)", id, name, variant, timestamp),
1260+ G_DBUS_CALL_FLAGS_NONE,
1261+ 1000, /* timeout */
1262+ NULL, /* cancellable */
1263+ menuitem_call_cb,
1264+ edata);
1265
1266 return;
1267 }
1268@@ -1133,14 +1264,22 @@
1269 /* Reports errors and responds to update request that were a result
1270 of sending the about to show signal. */
1271 static void
1272-about_to_show_cb (DBusGProxy * proxy, gboolean need_update, GError * error, gpointer userdata)
1273+about_to_show_cb (GObject * proxy, GAsyncResult * res, gpointer userdata)
1274 {
1275+ gboolean need_update = FALSE;
1276+ GError * error = NULL;
1277 about_to_show_t * data = (about_to_show_t *)userdata;
1278+ GVariant * params = NULL;
1279+
1280+ params = g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), res, &error);
1281
1282 if (error != NULL) {
1283 g_warning("Unable to send about_to_show: %s", error->message);
1284 /* Note: we're just ensuring only the callback gets called */
1285 need_update = FALSE;
1286+ } else {
1287+ g_variant_get(params, "(b)", &need_update);
1288+ g_variant_unref(params);
1289 }
1290
1291 /* If we need to update, do that first. */
1292@@ -1171,7 +1310,14 @@
1293 data->cb_data = cb_data;
1294 g_object_ref(client);
1295
1296- org_ayatana_dbusmenu_about_to_show_async (priv->menuproxy, id, about_to_show_cb, data);
1297+ g_dbus_proxy_call(priv->menuproxy,
1298+ "AboutToShow",
1299+ g_variant_new("(i)", id),
1300+ G_DBUS_CALL_FLAGS_NONE,
1301+ -1, /* timeout */
1302+ NULL, /* cancellable */
1303+ about_to_show_cb,
1304+ data);
1305 return;
1306 }
1307
1308@@ -1217,7 +1363,7 @@
1309 /* Parse recursively through the XML and make it into
1310 objects as need be */
1311 static DbusmenuMenuitem *
1312-parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, DBusGProxy * proxy)
1313+parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, GDBusProxy * proxy)
1314 {
1315 /* First verify and figure out what we've got */
1316 gint id = parse_node_get_id(node);
1317@@ -1390,24 +1536,41 @@
1318
1319 /* When the layout property returns, here's where we take care of that. */
1320 static void
1321-update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError * error, void * data)
1322+update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data)
1323 {
1324+ GError * error = NULL;
1325+ GVariant * params = NULL;
1326+
1327+ params = g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), res, &error);
1328+
1329+ if (error != NULL) {
1330+ g_warning("Getting layout failed: %s", error->message);
1331+ return;
1332+ }
1333+
1334+ guint rev;
1335+ gchar * xml;
1336+
1337+ g_variant_get(params, "(us)", &rev, &xml);
1338+ g_variant_unref(params);
1339+
1340 DbusmenuClient * client = DBUSMENU_CLIENT(data);
1341 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
1342
1343- if (error != NULL) {
1344- g_warning("Getting layout failed on client %s object %s: %s", priv->dbus_name, priv->dbus_object, error->message);
1345- return;
1346- }
1347+ guint parseable = parse_layout(client, xml);
1348+ g_free(xml);
1349
1350- if (!parse_layout(client, xml)) {
1351+ if (parseable == 0) {
1352 g_warning("Unable to parse layout!");
1353 return;
1354 }
1355
1356 priv->my_revision = rev;
1357 /* g_debug("Root is now: 0x%X", (unsigned int)priv->root); */
1358- priv->layoutcall = NULL;
1359+ if (priv->layoutcall != NULL) {
1360+ g_object_unref(priv->layoutcall);
1361+ priv->layoutcall = NULL;
1362+ }
1363 #ifdef MASSIVEDEBUGGING
1364 g_debug("Client signaling layout has changed.");
1365 #endif
1366@@ -1433,14 +1596,26 @@
1367 return;
1368 }
1369
1370+ gchar * name_owner = g_dbus_proxy_get_name_owner(priv->menuproxy);
1371+ if (name_owner == NULL) {
1372+ return;
1373+ }
1374+ g_free(name_owner);
1375+
1376 if (priv->layoutcall != NULL) {
1377 return;
1378 }
1379
1380- priv->layoutcall = org_ayatana_dbusmenu_get_layout_async(priv->menuproxy,
1381- 0, /* Parent is the root */
1382- update_layout_cb,
1383- client);
1384+ priv->layoutcall = g_cancellable_new();
1385+
1386+ g_dbus_proxy_call(priv->menuproxy,
1387+ "GetLayout",
1388+ g_variant_new("(i)", 0), /* root */
1389+ G_DBUS_CALL_FLAGS_NONE,
1390+ -1, /* timeout */
1391+ priv->layoutcall, /* cancellable */
1392+ update_layout_cb,
1393+ client);
1394
1395 return;
1396 }
1397@@ -1493,10 +1668,6 @@
1398
1399 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
1400
1401- if (priv->propproxy == NULL) {
1402- return NULL;
1403- }
1404-
1405 #ifdef MASSIVEDEBUGGING
1406 g_debug("Client get root: %X", (guint)priv->root);
1407 #endif
1408
1409=== modified file 'libdbusmenu-glib/client.h'
1410--- libdbusmenu-glib/client.h 2010-10-12 21:14:21 +0000
1411+++ libdbusmenu-glib/client.h 2010-12-08 03:19:55 +0000
1412@@ -84,7 +84,7 @@
1413 void (*root_changed) (DbusmenuMenuitem * newroot);
1414 void (*new_menuitem) (DbusmenuMenuitem * newitem);
1415 void (*item_activate) (DbusmenuMenuitem * item, guint timestamp);
1416- void (*event_result) (DbusmenuMenuitem * item, gchar * event, GValue * data, guint timestamp, GError * error);
1417+ void (*event_result) (DbusmenuMenuitem * item, gchar * event, GVariant * data, guint timestamp, GError * error);
1418
1419 /*< Private >*/
1420 void (*reserved1) (void);
1421@@ -122,7 +122,7 @@
1422 void dbusmenu_client_send_event (DbusmenuClient * client,
1423 gint id,
1424 const gchar * name,
1425- const GValue * value,
1426+ GVariant * variant,
1427 guint timestamp);
1428 void dbusmenu_client_send_about_to_show(DbusmenuClient * client,
1429 gint id,
1430
1431=== renamed file 'libdbusmenu-glib/dbusmenu-glib.pc.in' => 'libdbusmenu-glib/dbusmenu-glib-0.4.pc.in'
1432--- libdbusmenu-glib/dbusmenu-glib.pc.in 2009-03-25 20:00:33 +0000
1433+++ libdbusmenu-glib/dbusmenu-glib-0.4.pc.in 2010-12-08 03:19:55 +0000
1434@@ -4,7 +4,7 @@
1435 bindir=@bindir@
1436 includedir=@includedir@
1437
1438-Cflags: -I${includedir}/libdbusmenu-0.1
1439+Cflags: -I${includedir}/libdbusmenu-0.4
1440 Requires: dbus-glib-1
1441 Libs: -L${libdir} -ldbusmenu-glib
1442
1443
1444=== modified file 'libdbusmenu-glib/menuitem-marshal.list'
1445--- libdbusmenu-glib/menuitem-marshal.list 2010-01-22 20:10:27 +0000
1446+++ libdbusmenu-glib/menuitem-marshal.list 2010-12-08 03:19:55 +0000
1447@@ -1,4 +1,4 @@
1448-VOID: STRING, POINTER
1449+VOID: STRING, VARIANT
1450 VOID: OBJECT, UINT, UINT
1451 VOID: OBJECT, UINT
1452 VOID: OBJECT
1453
1454=== modified file 'libdbusmenu-glib/menuitem-private.h'
1455--- libdbusmenu-glib/menuitem-private.h 2010-04-15 04:40:22 +0000
1456+++ libdbusmenu-glib/menuitem-private.h 2010-12-08 03:19:55 +0000
1457@@ -36,6 +36,7 @@
1458 void dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array);
1459 gboolean dbusmenu_menuitem_realized (DbusmenuMenuitem * mi);
1460 void dbusmenu_menuitem_set_realized (DbusmenuMenuitem * mi);
1461+GVariant * dbusmenu_menuitem_properties_variant (DbusmenuMenuitem * mi);
1462
1463 G_END_DECLS
1464
1465
1466=== modified file 'libdbusmenu-glib/menuitem-proxy.c'
1467--- libdbusmenu-glib/menuitem-proxy.c 2010-10-12 21:26:33 +0000
1468+++ libdbusmenu-glib/menuitem-proxy.c 2010-12-08 03:19:55 +0000
1469@@ -56,7 +56,7 @@
1470 static void dbusmenu_menuitem_proxy_finalize (GObject *object);
1471 static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec);
1472 static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec);
1473-static void handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp);
1474+static void handle_event (DbusmenuMenuitem * mi, const gchar * name, GVariant * variant, guint timestamp);
1475 static void add_menuitem (DbusmenuMenuitemProxy * pmi, DbusmenuMenuitem * mi);
1476 static void remove_menuitem (DbusmenuMenuitemProxy * pmi);
1477
1478@@ -162,21 +162,21 @@
1479 /* Takes the event and passes it along to the item that we're
1480 playing proxy for. */
1481 static void
1482-handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp)
1483+handle_event (DbusmenuMenuitem * mi, const gchar * name, GVariant * variant, guint timestamp)
1484 {
1485 g_return_if_fail(DBUSMENU_IS_MENUITEM_PROXY(mi));
1486 DbusmenuMenuitemProxyPrivate * priv = DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(mi);
1487 g_return_if_fail(priv->mi != NULL);
1488- return dbusmenu_menuitem_handle_event(priv->mi, name, value, timestamp);
1489+ return dbusmenu_menuitem_handle_event(priv->mi, name, variant, timestamp);
1490 }
1491
1492 /* Watches a property change and makes sure to put that value
1493 into our property list. */
1494 static void
1495-proxy_item_property_changed (DbusmenuMenuitem * mi, gchar * property, GValue * value, gpointer user_data)
1496+proxy_item_property_changed (DbusmenuMenuitem * mi, gchar * property, GVariant * variant, gpointer user_data)
1497 {
1498 DbusmenuMenuitemProxy * pmi = DBUSMENU_MENUITEM_PROXY(user_data);
1499- dbusmenu_menuitem_property_set_value(DBUSMENU_MENUITEM(pmi), property, value);
1500+ dbusmenu_menuitem_property_set_variant(DBUSMENU_MENUITEM(pmi), property, variant);
1501 return;
1502 }
1503
1504@@ -273,7 +273,7 @@
1505 GList * prop;
1506 for (prop = props; prop != NULL; prop = g_list_next(prop)) {
1507 gchar * prop_name = (gchar *)prop->data;
1508- dbusmenu_menuitem_property_set_value(DBUSMENU_MENUITEM(pmi), prop_name, dbusmenu_menuitem_property_get_value(priv->mi, prop_name));
1509+ dbusmenu_menuitem_property_set_variant(DBUSMENU_MENUITEM(pmi), prop_name, dbusmenu_menuitem_property_get_variant(priv->mi, prop_name));
1510 }
1511 g_list_free(props);
1512
1513
1514=== modified file 'libdbusmenu-glib/menuitem.c'
1515--- libdbusmenu-glib/menuitem.c 2010-10-12 21:21:44 +0000
1516+++ libdbusmenu-glib/menuitem.c 2010-12-08 03:19:55 +0000
1517@@ -94,7 +94,7 @@
1518 static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec);
1519 static void g_value_transform_STRING_BOOLEAN (const GValue * in, GValue * out);
1520 static void g_value_transform_STRING_INT (const GValue * in, GValue * out);
1521-static void handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp);
1522+static void handle_event (DbusmenuMenuitem * mi, const gchar * name, GVariant * value, guint timestamp);
1523 static void send_about_to_show (DbusmenuMenuitem * mi, void (*cb) (DbusmenuMenuitem * mi, gpointer user_data), gpointer cb_data);
1524
1525 /* GObject stuff */
1526@@ -129,8 +129,8 @@
1527 G_SIGNAL_RUN_LAST,
1528 G_STRUCT_OFFSET(DbusmenuMenuitemClass, property_changed),
1529 NULL, NULL,
1530- _dbusmenu_menuitem_marshal_VOID__STRING_POINTER,
1531- G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_POINTER);
1532+ _dbusmenu_menuitem_marshal_VOID__STRING_VARIANT,
1533+ G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VARIANT);
1534 /**
1535 DbusmenuMenuitem::item-activated:
1536 @arg0: The #DbusmenuMenuitem object.
1537@@ -271,15 +271,12 @@
1538
1539 static gint menuitem_next_id = 1;
1540
1541-/* A small little function to both clear the insides of a
1542- value as well as the memory it itself uses. */
1543+/* Make the unref function match the prototype need for the
1544+ hashtable destructor */
1545 static void
1546-_g_value_free (gpointer data)
1547+_g_variant_unref (gpointer data)
1548 {
1549- if (data == NULL) return;
1550- GValue * value = (GValue*)data;
1551- g_value_unset(value);
1552- g_free(data);
1553+ g_variant_unref((GVariant *)data);
1554 return;
1555 }
1556
1557@@ -295,7 +292,7 @@
1558 priv->id = -1;
1559 priv->children = NULL;
1560
1561- priv->properties = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, _g_value_free);
1562+ priv->properties = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, _g_variant_unref);
1563
1564 priv->root = FALSE;
1565 priv->realized = FALSE;
1566@@ -380,7 +377,7 @@
1567
1568 /* Handles the activate event if it is sent. */
1569 static void
1570-handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp)
1571+handle_event (DbusmenuMenuitem * mi, const gchar * name, GVariant * value, guint timestamp)
1572 {
1573 if (g_strcmp0(name, "clicked") == 0) {
1574 g_signal_emit(G_OBJECT(mi), signals[ITEM_ACTIVATED], 0, timestamp, TRUE);
1575@@ -916,10 +913,8 @@
1576 gboolean
1577 dbusmenu_menuitem_property_set (DbusmenuMenuitem * mi, const gchar * property, const gchar * value)
1578 {
1579- GValue val = {0};
1580- g_value_init(&val, G_TYPE_STRING);
1581- g_value_set_static_string(&val, value);
1582- return dbusmenu_menuitem_property_set_value(mi, property, &val);
1583+ GVariant * variant = g_variant_new("s", value);
1584+ return dbusmenu_menuitem_property_set_variant(mi, property, variant);
1585 }
1586
1587 /**
1588@@ -940,10 +935,8 @@
1589 gboolean
1590 dbusmenu_menuitem_property_set_bool (DbusmenuMenuitem * mi, const gchar * property, const gboolean value)
1591 {
1592- GValue val = {0};
1593- g_value_init(&val, G_TYPE_BOOLEAN);
1594- g_value_set_boolean(&val, value);
1595- return dbusmenu_menuitem_property_set_value(mi, property, &val);
1596+ GVariant * variant = g_variant_new("b", value);
1597+ return dbusmenu_menuitem_property_set_variant(mi, property, variant);
1598 }
1599
1600 /**
1601@@ -964,14 +957,12 @@
1602 gboolean
1603 dbusmenu_menuitem_property_set_int (DbusmenuMenuitem * mi, const gchar * property, const gint value)
1604 {
1605- GValue val = {0};
1606- g_value_init(&val, G_TYPE_INT);
1607- g_value_set_int(&val, value);
1608- return dbusmenu_menuitem_property_set_value(mi, property, &val);
1609+ GVariant * variant = g_variant_new("i", value);
1610+ return dbusmenu_menuitem_property_set_variant(mi, property, variant);
1611 }
1612
1613 /**
1614- dbusmenu_menuitem_property_set:
1615+ dbusmenu_menuitem_property_set_variant:
1616 @mi: The #DbusmenuMenuitem to set the property on.
1617 @property: Name of the property to set.
1618 @value: The value of the property.
1619@@ -986,37 +977,30 @@
1620 Return value: A boolean representing if the property value was set.
1621 */
1622 gboolean
1623-dbusmenu_menuitem_property_set_value (DbusmenuMenuitem * mi, const gchar * property, const GValue * value)
1624+dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * property, GVariant * value)
1625 {
1626 g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
1627 g_return_val_if_fail(property != NULL, FALSE);
1628- g_return_val_if_fail(G_IS_VALUE(value), FALSE);
1629
1630 DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
1631- /* g_debug("Setting a property. ID: %d Prop: %s Value: %s", priv->id, property, value); */
1632-
1633- #if 0
1634- gpointer lookup = g_hash_table_lookup(priv->properties, property);
1635- if (g_strcmp0((gchar *)lookup, value) == 0) {
1636- /* The value is the same as the value currently in the
1637- table so we don't really care. Just say everything's okay */
1638- return TRUE;
1639- }
1640- #endif
1641
1642 gchar * lprop = g_strdup(property);
1643- GValue * lval = g_new0(GValue, 1);
1644- g_value_init(lval, G_VALUE_TYPE(value));
1645- g_value_copy(value, lval);
1646-
1647- g_hash_table_replace(priv->properties, lprop, lval);
1648- #ifdef MASSIVEDEBUGGING
1649- gchar * valstr = g_strdup_value_contents(lval);
1650- g_debug("Menuitem %d (%s) signalling property '%s' changed to '%s'", ID(mi), LABEL(mi), property, g_utf8_strlen(valstr, 50) < 25 ? valstr : "<too long>");
1651- g_free(valstr);
1652- #endif
1653-
1654- g_signal_emit(G_OBJECT(mi), signals[PROPERTY_CHANGED], 0, lprop, lval, TRUE);
1655+ g_variant_ref(value);
1656+
1657+ gboolean replaced = FALSE;
1658+ gpointer currentval = g_hash_table_lookup(priv->properties, lprop);
1659+ if (currentval == NULL || !g_variant_equal((GVariant*)currentval, value)) {
1660+ g_hash_table_replace(priv->properties, lprop, value);
1661+ replaced = TRUE;
1662+ }
1663+
1664+ /* NOTE: The actual value is invalid at this point
1665+ becuse it has been unref'd when replaced in the hash
1666+ table. But the fact that there was a value is
1667+ the imporant part. */
1668+ if (currentval == NULL || replaced) {
1669+ g_signal_emit(G_OBJECT(mi), signals[PROPERTY_CHANGED], 0, lprop, value, TRUE);
1670+ }
1671
1672 return TRUE;
1673 }
1674@@ -1037,14 +1021,14 @@
1675 const gchar *
1676 dbusmenu_menuitem_property_get (DbusmenuMenuitem * mi, const gchar * property)
1677 {
1678- const GValue * value = dbusmenu_menuitem_property_get_value(mi, property);
1679- if (value == NULL) return NULL;
1680- if (G_VALUE_TYPE(value) != G_TYPE_STRING) return NULL;
1681- return g_value_get_string(value);
1682+ GVariant * variant = dbusmenu_menuitem_property_get_variant(mi, property);
1683+ if (variant == NULL) return NULL;
1684+ if (!g_variant_type_equal(g_variant_get_type(variant), G_VARIANT_TYPE_STRING)) return NULL;
1685+ return g_variant_get_string(variant, NULL);
1686 }
1687
1688 /**
1689- dbusmenu_menuitem_property_get_value:
1690+ dbusmenu_menuitem_property_get_variant:
1691 @mi: The #DbusmenuMenuitem to look for the property on.
1692 @property: The property to grab.
1693
1694@@ -1052,17 +1036,17 @@
1695 it exits. #NULL will be returned if the property doesn't
1696 exist.
1697
1698- Return value: A GValue for the property.
1699+ Return value: A GVariant for the property.
1700 */
1701-const GValue *
1702-dbusmenu_menuitem_property_get_value (DbusmenuMenuitem * mi, const gchar * property)
1703+GVariant *
1704+dbusmenu_menuitem_property_get_variant (DbusmenuMenuitem * mi, const gchar * property)
1705 {
1706 g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), NULL);
1707 g_return_val_if_fail(property != NULL, NULL);
1708
1709 DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
1710
1711- return (const GValue *)g_hash_table_lookup(priv->properties, property);
1712+ return (GVariant *)g_hash_table_lookup(priv->properties, property);
1713 }
1714
1715 /**
1716@@ -1078,19 +1062,25 @@
1717 gboolean
1718 dbusmenu_menuitem_property_get_bool (DbusmenuMenuitem * mi, const gchar * property)
1719 {
1720- const GValue * value = dbusmenu_menuitem_property_get_value(mi, property);
1721- if (value == NULL) return FALSE;
1722- if (G_VALUE_TYPE(value) != G_TYPE_BOOLEAN) {
1723- if (g_value_type_transformable(G_VALUE_TYPE(value), G_TYPE_BOOLEAN)) {
1724- GValue boolval = {0};
1725- g_value_init(&boolval, G_TYPE_BOOLEAN);
1726- g_value_transform(value, &boolval);
1727- return g_value_get_boolean(&boolval);
1728+ GVariant * variant = dbusmenu_menuitem_property_get_variant(mi, property);
1729+ if (variant == NULL) return FALSE;
1730+
1731+ if (g_variant_type_equal(g_variant_get_type(variant), G_VARIANT_TYPE_BOOLEAN)) {
1732+ return g_variant_get_boolean(variant);
1733+ }
1734+
1735+ if (g_variant_type_equal(g_variant_get_type(variant), G_VARIANT_TYPE_STRING)) {
1736+ const gchar * string = g_variant_get_string(variant, NULL);
1737+
1738+ if (!g_strcmp0(string, "TRUE") || !g_strcmp0(string, "true") || !g_strcmp0(string, "True")) {
1739+ return TRUE;
1740 } else {
1741 return FALSE;
1742 }
1743 }
1744- return g_value_get_boolean(value);
1745+
1746+ g_warning("Property '%s' has been requested as an boolean but is not one.", property);
1747+ return FALSE;
1748 }
1749
1750 /**
1751@@ -1106,19 +1096,20 @@
1752 gint
1753 dbusmenu_menuitem_property_get_int (DbusmenuMenuitem * mi, const gchar * property)
1754 {
1755- const GValue * value = dbusmenu_menuitem_property_get_value(mi, property);
1756- if (value == NULL) return 0;
1757- if (G_VALUE_TYPE(value) != G_TYPE_INT) {
1758- if (g_value_type_transformable(G_VALUE_TYPE(value), G_TYPE_INT)) {
1759- GValue intval = {0};
1760- g_value_init(&intval, G_TYPE_INT);
1761- g_value_transform(value, &intval);
1762- return g_value_get_int(&intval);
1763- } else {
1764- return 0;
1765- }
1766- }
1767- return g_value_get_int(value);
1768+ GVariant * variant = dbusmenu_menuitem_property_get_variant(mi, property);
1769+ if (variant == NULL) return 0;
1770+
1771+ if (g_variant_type_equal(g_variant_get_type(variant), G_VARIANT_TYPE_INT32)) {
1772+ return g_variant_get_int32(variant);
1773+ }
1774+
1775+ if (g_variant_type_equal(g_variant_get_type(variant), G_VARIANT_TYPE_STRING)) {
1776+ const gchar * string = g_variant_get_string(variant, NULL);
1777+ return atoi(string);
1778+ }
1779+
1780+ g_warning("Property '%s' has been requested as an int but is not one.", property);
1781+ return 0;
1782 }
1783
1784
1785@@ -1220,6 +1211,45 @@
1786 return ret;
1787 }
1788
1789+/* Looks at each value in the hashtable and tries to convert it
1790+ into a variant and add it to our variant builder */
1791+static void
1792+variant_helper (gpointer in_key, gpointer in_value, gpointer user_data)
1793+{
1794+ g_variant_builder_add((GVariantBuilder *)user_data, "{sv}", in_key, in_value);
1795+ return;
1796+}
1797+
1798+/**
1799+ dbusmenu_menuitem_properties_variant:
1800+ @mi: #DbusmenuMenuitem to get properties from
1801+
1802+ Grabs the properties of the menuitem as a GVariant with the
1803+ type "a{sv}".
1804+
1805+ Return Value: A GVariant of type "a{sv}" or NULL on error.
1806+*/
1807+GVariant *
1808+dbusmenu_menuitem_properties_variant (DbusmenuMenuitem * mi)
1809+{
1810+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), NULL);
1811+
1812+ DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
1813+
1814+ GVariant * final_variant = NULL;
1815+
1816+ if (g_hash_table_size(priv->properties) > 0) {
1817+ GVariantBuilder builder;
1818+ g_variant_builder_init(&builder, g_variant_type_new("a{sv}"));
1819+
1820+ g_hash_table_foreach(priv->properties, variant_helper, &builder);
1821+
1822+ final_variant = g_variant_builder_end(&builder);
1823+ }
1824+
1825+ return final_variant;
1826+}
1827+
1828 /**
1829 dbusmenu_menuitem_set_root:
1830 @mi: #DbusmenuMenuitem to set whether it's root
1831@@ -1332,7 +1362,7 @@
1832 dbusmenu_menuitem_handle_event:
1833 @mi: The #DbusmenuMenuitem to send the signal on.
1834 @name: The name of the signal
1835- @value: A value that could be set for the event
1836+ @variant: A value that could be set for the event
1837 @timestamp: The timestamp of when the event happened
1838
1839 This function is called to create an event. It is likely
1840@@ -1348,7 +1378,7 @@
1841 reason not to.
1842 */
1843 void
1844-dbusmenu_menuitem_handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp)
1845+dbusmenu_menuitem_handle_event (DbusmenuMenuitem * mi, const gchar * name, GVariant * variant, guint timestamp)
1846 {
1847 g_return_if_fail(DBUSMENU_IS_MENUITEM(mi));
1848 #ifdef MASSIVEDEBUGGING
1849@@ -1357,7 +1387,7 @@
1850 DbusmenuMenuitemClass * class = DBUSMENU_MENUITEM_GET_CLASS(mi);
1851
1852 if (class->handle_event != NULL) {
1853- return class->handle_event(mi, name, value, timestamp);
1854+ return class->handle_event(mi, name, variant, timestamp);
1855 }
1856 return;
1857 }
1858
1859=== modified file 'libdbusmenu-glib/menuitem.h'
1860--- libdbusmenu-glib/menuitem.h 2010-10-12 21:14:21 +0000
1861+++ libdbusmenu-glib/menuitem.h 2010-12-08 03:19:55 +0000
1862@@ -145,7 +145,7 @@
1863 GObjectClass parent_class;
1864
1865 /* Signals */
1866- void (*property_changed) (gchar * property, GValue * value);
1867+ void (*property_changed) (gchar * property, GVariant * value);
1868 void (*item_activated) (guint timestamp);
1869 void (*child_added) (DbusmenuMenuitem * child, guint position);
1870 void (*child_removed) (DbusmenuMenuitem * child);
1871@@ -154,7 +154,7 @@
1872
1873 /* Virtual functions */
1874 dbusmenu_menuitem_buildxml_slot_t buildxml;
1875- void (*handle_event) (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp);
1876+ void (*handle_event) (DbusmenuMenuitem * mi, const gchar * name, GVariant * value, guint timestamp);
1877 void (*send_about_to_show) (DbusmenuMenuitem * mi, void (*cb) (DbusmenuMenuitem * mi, gpointer user_data), gpointer cb_data);
1878
1879 void (*show_to_user) (DbusmenuMenuitem * mi, guint timestamp, gpointer cb_data);
1880@@ -188,11 +188,11 @@
1881 DbusmenuMenuitem * dbusmenu_menuitem_find_id (DbusmenuMenuitem * mi, gint id);
1882
1883 gboolean dbusmenu_menuitem_property_set (DbusmenuMenuitem * mi, const gchar * property, const gchar * value);
1884-gboolean dbusmenu_menuitem_property_set_value (DbusmenuMenuitem * mi, const gchar * property, const GValue * value);
1885+gboolean dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * property, GVariant * value);
1886 gboolean dbusmenu_menuitem_property_set_bool (DbusmenuMenuitem * mi, const gchar * property, const gboolean value);
1887 gboolean dbusmenu_menuitem_property_set_int (DbusmenuMenuitem * mi, const gchar * property, const gint value);
1888 const gchar * dbusmenu_menuitem_property_get (DbusmenuMenuitem * mi, const gchar * property);
1889-const GValue * dbusmenu_menuitem_property_get_value (DbusmenuMenuitem * mi, const gchar * property);
1890+GVariant * dbusmenu_menuitem_property_get_variant (DbusmenuMenuitem * mi, const gchar * property);
1891 gboolean dbusmenu_menuitem_property_get_bool (DbusmenuMenuitem * mi, const gchar * property);
1892 gint dbusmenu_menuitem_property_get_int (DbusmenuMenuitem * mi, const gchar * property);
1893 gboolean dbusmenu_menuitem_property_exist (DbusmenuMenuitem * mi, const gchar * property);
1894@@ -204,7 +204,7 @@
1895 gboolean dbusmenu_menuitem_get_root (DbusmenuMenuitem * mi);
1896
1897 void dbusmenu_menuitem_foreach (DbusmenuMenuitem * mi, void (*func) (DbusmenuMenuitem * mi, gpointer data), gpointer data);
1898-void dbusmenu_menuitem_handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp);
1899+void dbusmenu_menuitem_handle_event (DbusmenuMenuitem * mi, const gchar * name, GVariant * value, guint timestamp);
1900 void dbusmenu_menuitem_send_about_to_show (DbusmenuMenuitem * mi, void (*cb) (DbusmenuMenuitem * mi, gpointer user_data), gpointer cb_data);
1901
1902 void dbusmenu_menuitem_show_to_user (DbusmenuMenuitem * mi, guint timestamp);
1903
1904=== modified file 'libdbusmenu-glib/server-marshal.list'
1905--- libdbusmenu-glib/server-marshal.list 2010-07-20 21:15:25 +0000
1906+++ libdbusmenu-glib/server-marshal.list 2010-12-08 03:19:55 +0000
1907@@ -1,3 +1,3 @@
1908-VOID: INT, STRING, POINTER
1909+VOID: INT, STRING, VARIANT
1910 VOID: UINT, INT
1911 VOID: INT, UINT
1912
1913=== modified file 'libdbusmenu-glib/server.c'
1914--- libdbusmenu-glib/server.c 2010-10-12 21:22:56 +0000
1915+++ libdbusmenu-glib/server.c 2010-12-08 03:19:55 +0000
1916@@ -30,27 +30,18 @@
1917 #include "config.h"
1918 #endif
1919
1920+#include <gio/gio.h>
1921+
1922 #include "menuitem-private.h"
1923 #include "server.h"
1924 #include "server-marshal.h"
1925
1926-/* DBus Prototypes */
1927-static gboolean _dbusmenu_server_get_layout (DbusmenuServer * server, gint parent, guint * revision, gchar ** layout, GError ** error);
1928-static gboolean _dbusmenu_server_get_property (DbusmenuServer * server, gint id, gchar * property, gchar ** value, GError ** error);
1929-static gboolean _dbusmenu_server_get_properties (DbusmenuServer * server, gint id, gchar ** properties, GHashTable ** dict, GError ** error);
1930-static gboolean _dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, gchar ** properties, GPtrArray ** values, GError ** error);
1931-static gboolean _dbusmenu_server_event (DbusmenuServer * server, gint id, gchar * eventid, GValue * data, guint timestamp, GError ** error);
1932-static gboolean _dbusmenu_server_get_children (DbusmenuServer * server, gint id, GPtrArray * properties, GPtrArray ** output, GError ** error);
1933-static gboolean _dbusmenu_server_about_to_show (DbusmenuServer * server, gint id, gboolean * need_update, GError ** error);
1934-/* DBus Helpers */
1935-static void _gvalue_array_append_int(GValueArray *array, gint i);
1936-static void _gvalue_array_append_hashtable(GValueArray *array, GHashTable * dict);
1937-
1938-#include "dbusmenu-server.h"
1939+#include "dbus-menu-clean.xml.h"
1940
1941 static void layout_update_signal (DbusmenuServer * server);
1942
1943-#define DBUSMENU_VERSION_NUMBER 2
1944+#define DBUSMENU_VERSION_NUMBER 2
1945+#define DBUSMENU_INTERFACE "org.ayatana.dbusmenu"
1946
1947 /* Privates, I'll show you mine... */
1948 struct _DbusmenuServerPrivate
1949@@ -59,6 +50,10 @@
1950 gchar * dbusobject;
1951 gint layout_revision;
1952 guint layout_idle;
1953+
1954+ GDBusConnection * bus;
1955+ GCancellable * bus_lookup;
1956+ guint dbus_registration;
1957 };
1958
1959 #define DBUSMENU_SERVER_GET_PRIVATE(o) (DBUSMENU_SERVER(o)->priv)
1960@@ -88,22 +83,110 @@
1961 INVALID_PROPERTY_NAME,
1962 UNKNOWN_DBUS_ERROR,
1963 NOT_IMPLEMENTED,
1964+ NO_VALID_LAYOUT,
1965 LAST_ERROR
1966 };
1967
1968+/* Method Table */
1969+typedef void (*MethodTableFunc) (DbusmenuServer * server, GVariant * params, GDBusMethodInvocation * invocation);
1970+
1971+typedef struct _method_table_t method_table_t;
1972+struct _method_table_t {
1973+ const gchar * interned_name;
1974+ MethodTableFunc func;
1975+};
1976+
1977+enum {
1978+ METHOD_GET_LAYOUT = 0,
1979+ METHOD_GET_GROUP_PROPERTIES,
1980+ METHOD_GET_CHILDREN,
1981+ METHOD_GET_PROPERTY,
1982+ METHOD_GET_PROPERTIES,
1983+ METHOD_EVENT,
1984+ METHOD_ABOUT_TO_SHOW,
1985+ /* Counter, do not remove! */
1986+ METHOD_COUNT
1987+};
1988+
1989 /* Prototype */
1990-static void dbusmenu_server_class_init (DbusmenuServerClass *class);
1991-static void dbusmenu_server_init (DbusmenuServer *self);
1992-static void dbusmenu_server_dispose (GObject *object);
1993-static void dbusmenu_server_finalize (GObject *object);
1994-static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec);
1995-static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec);
1996-static void menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GValue * value, DbusmenuServer * server);
1997-static void menuitem_child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint pos, DbusmenuServer * server);
1998-static void menuitem_child_removed (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, DbusmenuServer * server);
1999-static void menuitem_signals_create (DbusmenuMenuitem * mi, gpointer data);
2000-static void menuitem_signals_remove (DbusmenuMenuitem * mi, gpointer data);
2001-static GQuark error_quark (void);
2002+static void dbusmenu_server_class_init (DbusmenuServerClass *class);
2003+static void dbusmenu_server_init (DbusmenuServer *self);
2004+static void dbusmenu_server_dispose (GObject *object);
2005+static void dbusmenu_server_finalize (GObject *object);
2006+static void set_property (GObject * obj,
2007+ guint id,
2008+ const GValue * value,
2009+ GParamSpec * pspec);
2010+static void get_property (GObject * obj,
2011+ guint id,
2012+ GValue * value,
2013+ GParamSpec * pspec);
2014+static void register_object (DbusmenuServer * server);
2015+static void bus_got_cb (GObject * obj,
2016+ GAsyncResult * result,
2017+ gpointer user_data);
2018+static void bus_method_call (GDBusConnection * connection,
2019+ const gchar * sender,
2020+ const gchar * path,
2021+ const gchar * interface,
2022+ const gchar * method,
2023+ GVariant * params,
2024+ GDBusMethodInvocation * invocation,
2025+ gpointer user_data);
2026+static GVariant * bus_get_prop (GDBusConnection * connection,
2027+ const gchar * sender,
2028+ const gchar * path,
2029+ const gchar * interface,
2030+ const gchar * property,
2031+ GError ** error,
2032+ gpointer user_data);
2033+static void menuitem_property_changed (DbusmenuMenuitem * mi,
2034+ gchar * property,
2035+ GVariant * variant,
2036+ DbusmenuServer * server);
2037+static void menuitem_child_added (DbusmenuMenuitem * parent,
2038+ DbusmenuMenuitem * child,
2039+ guint pos,
2040+ DbusmenuServer * server);
2041+static void menuitem_child_removed (DbusmenuMenuitem * parent,
2042+ DbusmenuMenuitem * child,
2043+ DbusmenuServer * server);
2044+static void menuitem_signals_create (DbusmenuMenuitem * mi,
2045+ gpointer data);
2046+static void menuitem_signals_remove (DbusmenuMenuitem * mi,
2047+ gpointer data);
2048+static GQuark error_quark (void);
2049+static void bus_get_layout (DbusmenuServer * server,
2050+ GVariant * params,
2051+ GDBusMethodInvocation * invocation);
2052+static void bus_get_group_properties (DbusmenuServer * server,
2053+ GVariant * params,
2054+ GDBusMethodInvocation * invocation);
2055+static void bus_get_children (DbusmenuServer * server,
2056+ GVariant * params,
2057+ GDBusMethodInvocation * invocation);
2058+static void bus_get_property (DbusmenuServer * server,
2059+ GVariant * params,
2060+ GDBusMethodInvocation * invocation);
2061+static void bus_get_properties (DbusmenuServer * server,
2062+ GVariant * params,
2063+ GDBusMethodInvocation * invocation);
2064+static void bus_event (DbusmenuServer * server,
2065+ GVariant * params,
2066+ GDBusMethodInvocation * invocation);
2067+static void bus_about_to_show (DbusmenuServer * server,
2068+ GVariant * params,
2069+ GDBusMethodInvocation * invocation);
2070+
2071+/* Globals */
2072+static GDBusNodeInfo * dbusmenu_node_info = NULL;
2073+static GDBusInterfaceInfo * dbusmenu_interface_info = NULL;
2074+static const GDBusInterfaceVTable dbusmenu_interface_table = {
2075+ method_call: bus_method_call,
2076+ get_property: bus_get_prop,
2077+ set_property: NULL /* No properties that can be set */
2078+};
2079+static method_table_t dbusmenu_method_table[METHOD_COUNT];
2080
2081 G_DEFINE_TYPE (DbusmenuServer, dbusmenu_server, G_TYPE_OBJECT);
2082
2083@@ -134,8 +217,8 @@
2084 G_SIGNAL_RUN_LAST,
2085 G_STRUCT_OFFSET(DbusmenuServerClass, id_prop_update),
2086 NULL, NULL,
2087- _dbusmenu_server_marshal_VOID__INT_STRING_POINTER,
2088- G_TYPE_NONE, 3, G_TYPE_INT, G_TYPE_STRING, G_TYPE_VALUE);
2089+ _dbusmenu_server_marshal_VOID__INT_STRING_VARIANT,
2090+ G_TYPE_NONE, 3, G_TYPE_INT, G_TYPE_STRING, G_TYPE_VARIANT);
2091 /**
2092 DbusmenuServer::id-update:
2093 @arg0: The #DbusmenuServer emitting the signal.
2094@@ -203,7 +286,45 @@
2095 DBUSMENU_VERSION_NUMBER, DBUSMENU_VERSION_NUMBER, DBUSMENU_VERSION_NUMBER,
2096 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
2097
2098- dbus_g_object_type_install_info(DBUSMENU_TYPE_SERVER, &dbus_glib__dbusmenu_server_object_info);
2099+ if (dbusmenu_node_info == NULL) {
2100+ GError * error = NULL;
2101+
2102+ dbusmenu_node_info = g_dbus_node_info_new_for_xml(dbus_menu_clean_xml, &error);
2103+ if (error != NULL) {
2104+ g_error("Unable to parse DBusmenu Interface description: %s", error->message);
2105+ g_error_free(error);
2106+ }
2107+ }
2108+
2109+ if (dbusmenu_interface_info == NULL) {
2110+ dbusmenu_interface_info = g_dbus_node_info_lookup_interface(dbusmenu_node_info, DBUSMENU_INTERFACE);
2111+
2112+ if (dbusmenu_interface_info == NULL) {
2113+ g_error("Unable to find interface '" DBUSMENU_INTERFACE "'");
2114+ }
2115+ }
2116+
2117+ /* Building our Method table :( */
2118+ dbusmenu_method_table[METHOD_GET_LAYOUT].interned_name = g_intern_static_string("GetLayout");
2119+ dbusmenu_method_table[METHOD_GET_LAYOUT].func = bus_get_layout;
2120+
2121+ dbusmenu_method_table[METHOD_GET_GROUP_PROPERTIES].interned_name = g_intern_static_string("GetGroupProperties");
2122+ dbusmenu_method_table[METHOD_GET_GROUP_PROPERTIES].func = bus_get_group_properties;
2123+
2124+ dbusmenu_method_table[METHOD_GET_CHILDREN].interned_name = g_intern_static_string("GetChildren");
2125+ dbusmenu_method_table[METHOD_GET_CHILDREN].func = bus_get_children;
2126+
2127+ dbusmenu_method_table[METHOD_GET_PROPERTY].interned_name = g_intern_static_string("GetProperty");
2128+ dbusmenu_method_table[METHOD_GET_PROPERTY].func = bus_get_property;
2129+
2130+ dbusmenu_method_table[METHOD_GET_PROPERTIES].interned_name = g_intern_static_string("GetProperties");
2131+ dbusmenu_method_table[METHOD_GET_PROPERTIES].func = bus_get_properties;
2132+
2133+ dbusmenu_method_table[METHOD_EVENT].interned_name = g_intern_static_string("Event");
2134+ dbusmenu_method_table[METHOD_EVENT].func = bus_event;
2135+
2136+ dbusmenu_method_table[METHOD_ABOUT_TO_SHOW].interned_name = g_intern_static_string("AboutToShow");
2137+ dbusmenu_method_table[METHOD_ABOUT_TO_SHOW].func = bus_about_to_show;
2138
2139 return;
2140 }
2141@@ -219,6 +340,9 @@
2142 priv->dbusobject = NULL;
2143 priv->layout_revision = 1;
2144 priv->layout_idle = 0;
2145+ priv->bus = NULL;
2146+ priv->bus_lookup = NULL;
2147+ priv->dbus_registration = 0;
2148
2149 return;
2150 }
2151@@ -237,6 +361,27 @@
2152 g_object_unref(priv->root);
2153 }
2154
2155+ if (priv->dbus_registration != 0) {
2156+ g_dbus_connection_unregister_object(priv->bus, priv->dbus_registration);
2157+ priv->dbus_registration = 0;
2158+ }
2159+
2160+ if (priv->bus != NULL) {
2161+ g_object_unref(priv->bus);
2162+ priv->bus = NULL;
2163+ }
2164+
2165+ if (priv->bus_lookup != NULL) {
2166+ if (!g_cancellable_is_cancelled(priv->bus_lookup)) {
2167+ /* Note, this may case the async function to run at
2168+ some point in the future. That's okay, it'll get an
2169+ error, but just FYI */
2170+ g_cancellable_cancel(priv->bus_lookup);
2171+ }
2172+ g_object_unref(priv->bus_lookup);
2173+ priv->bus_lookup = NULL;
2174+ }
2175+
2176 G_OBJECT_CLASS (dbusmenu_server_parent_class)->dispose (object);
2177 return;
2178 }
2179@@ -252,21 +397,21 @@
2180 set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec)
2181 {
2182 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(obj);
2183- GError * error = NULL;
2184
2185 switch (id) {
2186 case PROP_DBUS_OBJECT:
2187 g_return_if_fail(priv->dbusobject == NULL);
2188 priv->dbusobject = g_value_dup_string(value);
2189- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
2190-
2191- if (connection == NULL || error != NULL) {
2192- g_warning("Unable to get session bus: %s", error == NULL ? "No message" : error->message);
2193- if (error != NULL) { g_error_free(error); }
2194+
2195+ if (priv->bus == NULL) {
2196+ if (priv->bus_lookup == NULL) {
2197+ priv->bus_lookup = g_cancellable_new();
2198+ g_return_if_fail(priv->bus_lookup != NULL);
2199+ }
2200+
2201+ g_bus_get(G_BUS_TYPE_SESSION, priv->bus_lookup, bus_got_cb, obj);
2202 } else {
2203- dbus_g_connection_register_g_object(connection,
2204- priv->dbusobject,
2205- obj);
2206+ register_object(DBUSMENU_SERVER(obj));
2207 }
2208 break;
2209 case PROP_ROOT_NODE:
2210@@ -328,6 +473,115 @@
2211 return;
2212 }
2213
2214+/* Register the object on the dbus bus */
2215+static void
2216+register_object (DbusmenuServer * server)
2217+{
2218+ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
2219+
2220+ /* Object info */
2221+ g_return_if_fail(priv->bus != NULL);
2222+ g_return_if_fail(priv->dbusobject != NULL);
2223+
2224+ /* Class info */
2225+ g_return_if_fail(dbusmenu_node_info != NULL);
2226+ g_return_if_fail(dbusmenu_interface_info != NULL);
2227+
2228+ /* We might block on this in the future, but it'd be nice if
2229+ we could change the object path. Thinking about it... */
2230+ if (priv->dbus_registration != 0) {
2231+ g_dbus_connection_unregister_object(priv->bus, priv->dbus_registration);
2232+ priv->dbus_registration = 0;
2233+ }
2234+
2235+ GError * error = NULL;
2236+ priv->dbus_registration = g_dbus_connection_register_object(priv->bus,
2237+ priv->dbusobject,
2238+ dbusmenu_interface_info,
2239+ &dbusmenu_interface_table,
2240+ server,
2241+ NULL,
2242+ &error);
2243+
2244+ if (error != NULL) {
2245+ g_warning("Unable to register object on bus: %s", error->message);
2246+ g_error_free(error);
2247+ }
2248+
2249+ return;
2250+}
2251+
2252+/* Callback from asking GIO to get us the session bus */
2253+static void
2254+bus_got_cb (GObject * obj, GAsyncResult * result, gpointer user_data)
2255+{
2256+ GError * error = NULL;
2257+
2258+ GDBusConnection * bus = g_bus_get_finish(result, &error);
2259+
2260+ if (error != NULL) {
2261+ g_warning("Unable to get session bus: %s", error->message);
2262+ g_error_free(error);
2263+ return;
2264+ }
2265+
2266+ /* Note: We're not using the user_data before we check for
2267+ the error so that in the cancelled case at destruction of
2268+ the object we don't end up with an invalid object. */
2269+
2270+ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(user_data);
2271+ priv->bus = bus;
2272+
2273+ register_object(DBUSMENU_SERVER(user_data));
2274+
2275+ return;
2276+}
2277+
2278+/* Function for the GDBus vtable to handle all method calls and dish
2279+ them out the appropriate functions */
2280+static void
2281+bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * method, GVariant * params, GDBusMethodInvocation * invocation, gpointer user_data)
2282+{
2283+ int i;
2284+ const gchar * interned_method = g_intern_string(method);
2285+
2286+ for (i = 0; i < METHOD_COUNT; i++) {
2287+ if (dbusmenu_method_table[i].interned_name == interned_method) {
2288+ if (dbusmenu_method_table[i].func != NULL) {
2289+ return dbusmenu_method_table[i].func(DBUSMENU_SERVER(user_data), params, invocation);
2290+ } else {
2291+ /* If we have a null function we're responding but nothing else. */
2292+ g_warning("Invalid function call for '%s' with parameters: %s", method, g_variant_print(params, TRUE));
2293+ g_dbus_method_invocation_return_value(invocation, NULL);
2294+ return;
2295+ }
2296+ }
2297+ }
2298+
2299+ /* We're here because there's an error */
2300+ g_dbus_method_invocation_return_error(invocation,
2301+ error_quark(),
2302+ NOT_IMPLEMENTED,
2303+ "Unable to find method '%s'",
2304+ method);
2305+ return;
2306+}
2307+
2308+/* For the GDBus vtable but we only have one property so it's pretty
2309+ simple. */
2310+static GVariant *
2311+bus_get_prop (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * property, GError ** error, gpointer user_data)
2312+{
2313+ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(user_data);
2314+
2315+ /* None of these should happen */
2316+ g_return_val_if_fail(g_strcmp0(interface, DBUSMENU_INTERFACE) == 0, NULL);
2317+ g_return_val_if_fail(g_strcmp0(path, priv->dbusobject) == 0, NULL);
2318+ g_return_val_if_fail(g_strcmp0(property, "version") == 0, NULL);
2319+
2320+ return g_variant_new_uint32(DBUSMENU_VERSION_NUMBER);
2321+}
2322+
2323 /* Handle actually signalling in the idle loop. This way we collect all
2324 the updates. */
2325 static gboolean
2326@@ -337,6 +591,15 @@
2327 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
2328
2329 g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATED], 0, priv->layout_revision, 0, TRUE);
2330+ if (priv->dbusobject != NULL && priv->bus != NULL) {
2331+ g_dbus_connection_emit_signal(priv->bus,
2332+ NULL,
2333+ priv->dbusobject,
2334+ DBUSMENU_INTERFACE,
2335+ "LayoutUpdated",
2336+ g_variant_new("(ui)", priv->layout_revision, 0),
2337+ NULL);
2338+ }
2339
2340 priv->layout_idle = 0;
2341
2342@@ -358,9 +621,21 @@
2343 }
2344
2345 static void
2346-menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GValue * value, DbusmenuServer * server)
2347+menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GVariant * variant, DbusmenuServer * server)
2348 {
2349- g_signal_emit(G_OBJECT(server), signals[ID_PROP_UPDATE], 0, dbusmenu_menuitem_get_id(mi), property, value, TRUE);
2350+ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
2351+
2352+ g_signal_emit(G_OBJECT(server), signals[ID_PROP_UPDATE], 0, dbusmenu_menuitem_get_id(mi), property, variant, TRUE);
2353+
2354+ if (priv->dbusobject != NULL && priv->bus != NULL) {
2355+ g_dbus_connection_emit_signal(priv->bus,
2356+ NULL,
2357+ priv->dbusobject,
2358+ DBUSMENU_INTERFACE,
2359+ "ItemPropertyUpdated",
2360+ g_variant_new("(isv)", dbusmenu_menuitem_get_id(mi), property, variant),
2361+ NULL);
2362+ }
2363 return;
2364 }
2365
2366@@ -411,7 +686,20 @@
2367 static void
2368 menuitem_shown (DbusmenuMenuitem * mi, guint timestamp, DbusmenuServer * server)
2369 {
2370+ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
2371+
2372 g_signal_emit(G_OBJECT(server), signals[ITEM_ACTIVATION], 0, dbusmenu_menuitem_get_id(mi), timestamp, TRUE);
2373+
2374+ if (priv->dbusobject != NULL && priv->bus != NULL) {
2375+ g_dbus_connection_emit_signal(priv->bus,
2376+ NULL,
2377+ priv->dbusobject,
2378+ DBUSMENU_INTERFACE,
2379+ "ItemActivationRequested",
2380+ g_variant_new("(iu)", dbusmenu_menuitem_get_id(mi), timestamp),
2381+ NULL);
2382+ }
2383+
2384 return;
2385 }
2386
2387@@ -451,12 +739,15 @@
2388 }
2389
2390 /* DBus interface */
2391-static gboolean
2392-_dbusmenu_server_get_layout (DbusmenuServer * server, gint parent, guint * revision, gchar ** layout, GError ** error)
2393+static void
2394+bus_get_layout (DbusmenuServer * server, GVariant * params, GDBusMethodInvocation * invocation)
2395 {
2396 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
2397
2398- *revision = priv->layout_revision;
2399+ gint parent = 0;
2400+ g_variant_get(params, "(i)", &parent);
2401+
2402+ guint revision = priv->layout_revision;
2403 GPtrArray * xmlarray = g_ptr_array_new();
2404
2405 if (parent == 0) {
2406@@ -467,199 +758,234 @@
2407 dbusmenu_menuitem_buildxml(priv->root, xmlarray);
2408 }
2409 } else {
2410- DbusmenuMenuitem * item = dbusmenu_menuitem_find_id(priv->root, parent);
2411+ DbusmenuMenuitem * item = NULL;
2412+ if (priv->root != NULL) {
2413+ item = dbusmenu_menuitem_find_id(priv->root, parent);
2414+ }
2415+
2416 if (item == NULL) {
2417- if (error != NULL) {
2418- g_set_error(error,
2419- error_quark(),
2420- INVALID_MENUITEM_ID,
2421- "The ID supplied %d does not refer to a menu item we have",
2422- parent);
2423- }
2424- return FALSE;
2425+ g_dbus_method_invocation_return_error(invocation,
2426+ error_quark(),
2427+ INVALID_MENUITEM_ID,
2428+ "The ID supplied %d does not refer to a menu item we have",
2429+ parent);
2430+ return;
2431 }
2432 dbusmenu_menuitem_buildxml(item, xmlarray);
2433 }
2434 g_ptr_array_add(xmlarray, NULL);
2435
2436 /* build string */
2437- *layout = g_strjoinv("", (gchar **)xmlarray->pdata);
2438+ gchar * layout = g_strjoinv("", (gchar **)xmlarray->pdata);
2439
2440 g_ptr_array_foreach(xmlarray, xmlarray_foreach_free, NULL);
2441 g_ptr_array_free(xmlarray, TRUE);
2442
2443- return TRUE;
2444+ g_dbus_method_invocation_return_value(invocation,
2445+ g_variant_new("(us)",
2446+ revision,
2447+ layout));
2448+
2449+ g_free(layout);
2450+
2451+ return;
2452 }
2453
2454-static gboolean
2455-_dbusmenu_server_get_property (DbusmenuServer * server, gint id, gchar * property, gchar ** value, GError ** error)
2456+/* Get a single property off of a single menuitem */
2457+static void
2458+bus_get_property (DbusmenuServer * server, GVariant * params, GDBusMethodInvocation * invocation)
2459 {
2460 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
2461+
2462+ if (priv->root == NULL) {
2463+ g_dbus_method_invocation_return_error(invocation,
2464+ error_quark(),
2465+ NO_VALID_LAYOUT,
2466+ "There currently isn't a layout in this server");
2467+ return;
2468+ }
2469+
2470+ gint id = g_variant_get_int32(g_variant_get_child_value(params, 0));
2471+ const gchar * property = g_variant_get_string(g_variant_get_child_value(params, 1), NULL);
2472+
2473 DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id);
2474
2475 if (mi == NULL) {
2476- if (error != NULL) {
2477- g_set_error(error,
2478+ g_dbus_method_invocation_return_error(invocation,
2479 error_quark(),
2480 INVALID_MENUITEM_ID,
2481 "The ID supplied %d does not refer to a menu item we have",
2482 id);
2483- }
2484- return FALSE;
2485+ return;
2486 }
2487
2488- const gchar * prop = dbusmenu_menuitem_property_get(mi, property);
2489- if (prop == NULL) {
2490- if (error != NULL) {
2491- g_set_error(error,
2492+ GVariant * variant = dbusmenu_menuitem_property_get_variant(mi, property);
2493+ if (variant == NULL) {
2494+ g_dbus_method_invocation_return_error(invocation,
2495 error_quark(),
2496 INVALID_PROPERTY_NAME,
2497 "The property '%s' does not exist on menuitem with ID of %d",
2498 property,
2499 id);
2500- }
2501- return FALSE;
2502- }
2503-
2504- if (value == NULL) {
2505- if (error != NULL) {
2506- g_set_error(error,
2507- error_quark(),
2508- UNKNOWN_DBUS_ERROR,
2509- "Uhm, yeah. We didn't get anywhere to put the value, that's really weird. Seems impossible really.");
2510- }
2511- return FALSE;
2512- }
2513-
2514- *value = g_strdup(prop);
2515-
2516- return TRUE;
2517+ return;
2518+ }
2519+
2520+ g_dbus_method_invocation_return_value(invocation, g_variant_new("(v)", variant));
2521+ return;
2522 }
2523
2524-static gboolean
2525-_dbusmenu_server_get_properties (DbusmenuServer * server, gint id, gchar ** properties, GHashTable ** dict, GError ** error)
2526+/* Get some properties off of a single menuitem */
2527+static void
2528+bus_get_properties (DbusmenuServer * server, GVariant * params, GDBusMethodInvocation * invocation)
2529 {
2530 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
2531+
2532+ if (priv->root == NULL) {
2533+ g_dbus_method_invocation_return_error(invocation,
2534+ error_quark(),
2535+ NO_VALID_LAYOUT,
2536+ "There currently isn't a layout in this server");
2537+ return;
2538+ }
2539+
2540+ gint id = g_variant_get_int32(g_variant_get_child_value(params, 0));
2541+
2542 DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id);
2543
2544 if (mi == NULL) {
2545- if (error != NULL) {
2546- g_set_error(error,
2547+ g_dbus_method_invocation_return_error(invocation,
2548 error_quark(),
2549 INVALID_MENUITEM_ID,
2550 "The ID supplied %d does not refer to a menu item we have",
2551 id);
2552- }
2553- return FALSE;
2554+ return;
2555 }
2556
2557- *dict = dbusmenu_menuitem_properties_copy(mi);
2558-
2559- return TRUE;
2560+ GVariant * dict = dbusmenu_menuitem_properties_variant(mi);
2561+
2562+ g_dbus_method_invocation_return_value(invocation, g_variant_new("(a{sv})", dict));
2563+
2564+ return;
2565 }
2566
2567 /* Handles getting a bunch of properties from a variety of menu items
2568 to make one mega dbus message */
2569-static gboolean
2570-_dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, gchar ** properties, GPtrArray ** values, GError ** error)
2571-{
2572- /* Build an initial pointer array */
2573- *values = g_ptr_array_new();
2574-
2575- /* Go through each ID to get that ID's properties */
2576- int idcnt;
2577- for (idcnt = 0; idcnt < ids->len; idcnt++) {
2578- GHashTable * idprops = NULL;
2579- GError * error = NULL;
2580- gint id = g_array_index(ids, int, idcnt);
2581-
2582- /* Get the properties for this ID the old fashioned way. */
2583- if (!_dbusmenu_server_get_properties(server, id, properties, &idprops, &error)) {
2584- g_warning("Error getting the properties from ID %d: %s", id, error->message);
2585- g_error_free(error);
2586- error = NULL;
2587- continue;
2588- }
2589-
2590- GValueArray * valarray = g_value_array_new(2);
2591-
2592- _gvalue_array_append_int(valarray, id);
2593- _gvalue_array_append_hashtable(valarray, idprops);
2594-
2595- g_ptr_array_add(*values, valarray);
2596- }
2597-
2598- return TRUE;
2599-}
2600-
2601-/* Allocate a value on the stack for the int and append
2602- it to the array. */
2603-static void
2604-_gvalue_array_append_int(GValueArray *array, gint i)
2605-{
2606- GValue value = {0};
2607-
2608- g_value_init(&value, G_TYPE_INT);
2609- g_value_set_int(&value, i);
2610- g_value_array_append(array, &value);
2611- g_value_unset(&value);
2612-}
2613-
2614-/* Allocate a value on the stack for the hashtable and append
2615- it to the array. */
2616-static void
2617-_gvalue_array_append_hashtable(GValueArray *array, GHashTable * dict)
2618-{
2619- GValue value = {0};
2620-
2621- g_value_init(&value, dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE));
2622- g_value_set_boxed(&value, dict);
2623- g_value_array_append(array, &value);
2624- g_value_unset(&value);
2625-}
2626-
2627+static void
2628+bus_get_group_properties (DbusmenuServer * server, GVariant * params, GDBusMethodInvocation * invocation)
2629+{
2630+ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
2631+
2632+ if (priv->root == NULL) {
2633+ GVariant * idlist = g_variant_get_child_value(params, 0);
2634+ if (g_variant_n_children(idlist) == 1 && g_variant_get_int32(g_variant_get_child_value(idlist, 0)) == 0) {
2635+ GVariant * final = g_variant_parse(g_variant_type_new("(a(ia{sv}))"), "([(0, {})],)", NULL, NULL, NULL);
2636+ g_dbus_method_invocation_return_value(invocation, final);
2637+ return;
2638+ }
2639+
2640+ g_dbus_method_invocation_return_error(invocation,
2641+ error_quark(),
2642+ NO_VALID_LAYOUT,
2643+ "There currently isn't a layout in this server");
2644+ return;
2645+ }
2646+
2647+ GVariantIter ids;
2648+ g_variant_iter_init(&ids, g_variant_get_child_value(params, 0));
2649+
2650+ GVariantBuilder builder;
2651+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
2652+
2653+ gint id;
2654+ while (g_variant_iter_next(&ids, "i", &id)) {
2655+ DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id);
2656+ if (mi == NULL) continue;
2657+
2658+ GVariantBuilder wbuilder;
2659+ g_variant_builder_init(&wbuilder, G_VARIANT_TYPE_TUPLE);
2660+ g_variant_builder_add(&wbuilder, "i", id);
2661+ GVariant * props = dbusmenu_menuitem_properties_variant(mi);
2662+
2663+ if (props == NULL) {
2664+ props = g_variant_parse(g_variant_type_new("a{sv}"), "{}", NULL, NULL, NULL);
2665+ }
2666+
2667+ g_variant_builder_add_value(&wbuilder, props);
2668+ GVariant * mi_data = g_variant_builder_end(&wbuilder);
2669+
2670+ g_variant_builder_add_value(&builder, mi_data);
2671+ }
2672+
2673+ GVariant * ret = g_variant_builder_end(&builder);
2674+
2675+ g_variant_builder_init(&builder, G_VARIANT_TYPE_TUPLE);
2676+ g_variant_builder_add_value(&builder, ret);
2677+ GVariant * final = g_variant_builder_end(&builder);
2678+
2679+ g_dbus_method_invocation_return_value(invocation, final);
2680+
2681+ return;
2682+}
2683+
2684+/* Turn a menuitem into an variant and attach it to the
2685+ VariantBuilder we passed in */
2686 static void
2687 serialize_menuitem(gpointer data, gpointer user_data)
2688 {
2689 DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(data);
2690- GPtrArray * output = (GPtrArray *)(user_data);
2691+ GVariantBuilder * builder = (GVariantBuilder *)(user_data);
2692
2693 gint id = dbusmenu_menuitem_get_id(mi);
2694- GHashTable * dict = dbusmenu_menuitem_properties_copy(mi);
2695-
2696- GValueArray * item = g_value_array_new(2);
2697- _gvalue_array_append_int(item, id);
2698- _gvalue_array_append_hashtable(item, dict);
2699-
2700- g_ptr_array_add(output, item);
2701-
2702- g_hash_table_unref(dict);
2703+ GVariant * props = dbusmenu_menuitem_properties_variant(mi);
2704+
2705+ g_variant_builder_add(builder, "ia{sv}", id, props);
2706
2707 return;
2708 }
2709
2710-static gboolean
2711-_dbusmenu_server_get_children (DbusmenuServer * server, gint id, GPtrArray * properties, GPtrArray ** output, GError ** error)
2712+/* Gets the children and their properties of the ID that is
2713+ passed into the function */
2714+static void
2715+bus_get_children (DbusmenuServer * server, GVariant * params, GDBusMethodInvocation * invocation)
2716 {
2717 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
2718+ gint id = g_variant_get_int32(g_variant_get_child_value(params, 0));
2719+
2720+ if (priv->root == NULL) {
2721+ g_dbus_method_invocation_return_error(invocation,
2722+ error_quark(),
2723+ NO_VALID_LAYOUT,
2724+ "There currently isn't a layout in this server");
2725+ return;
2726+ }
2727+
2728 DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id);
2729
2730 if (mi == NULL) {
2731- if (error != NULL) {
2732- g_set_error(error,
2733- error_quark(),
2734- INVALID_MENUITEM_ID,
2735- "The ID supplied %d does not refer to a menu item we have",
2736- id);
2737- }
2738- return FALSE;
2739+ g_dbus_method_invocation_return_error(invocation,
2740+ error_quark(),
2741+ INVALID_MENUITEM_ID,
2742+ "The ID supplied %d does not refer to a menu item we have",
2743+ id);
2744+ return;
2745 }
2746
2747- *output = g_ptr_array_new();
2748 GList * children = dbusmenu_menuitem_get_children(mi);
2749- g_list_foreach(children, serialize_menuitem, *output);
2750-
2751- return TRUE;
2752+ GVariant * ret = NULL;
2753+
2754+ if (children != NULL) {
2755+ GVariantBuilder builder;
2756+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
2757+
2758+ g_list_foreach(children, serialize_menuitem, &builder);
2759+
2760+ ret = g_variant_new("(a(ia{svg}))", g_variant_builder_end(&builder));
2761+ } else {
2762+ ret = g_variant_parse(g_variant_type_new("(a(ia{sv}))"), "([(0, {})],)", NULL, NULL, NULL);
2763+ }
2764+
2765+ g_dbus_method_invocation_return_value(invocation, ret);
2766+ return;
2767 }
2768
2769 /* Structure for holding the event data for the idle function
2770@@ -668,7 +994,7 @@
2771 struct _idle_event_t {
2772 DbusmenuMenuitem * mi;
2773 gchar * eventid;
2774- GValue data;
2775+ GVariant * variant;
2776 guint timestamp;
2777 };
2778
2779@@ -679,66 +1005,84 @@
2780 {
2781 idle_event_t * data = (idle_event_t *)user_data;
2782
2783- dbusmenu_menuitem_handle_event(data->mi, data->eventid, &data->data, data->timestamp);
2784+ dbusmenu_menuitem_handle_event(data->mi, data->eventid, data->variant, data->timestamp);
2785
2786 g_object_unref(data->mi);
2787 g_free(data->eventid);
2788- g_value_unset(&data->data);
2789+ g_variant_unref(data->variant);
2790 g_free(data);
2791 return FALSE;
2792 }
2793
2794-/* Handles the even coming off of DBus */
2795-static gboolean
2796-_dbusmenu_server_event (DbusmenuServer * server, gint id, gchar * eventid, GValue * data, guint timestamp, GError ** error)
2797+/* Handles the events coming off of DBus */
2798+static void
2799+bus_event (DbusmenuServer * server, GVariant * params, GDBusMethodInvocation * invocation)
2800 {
2801 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
2802+
2803+ if (priv->root == NULL) {
2804+ g_dbus_method_invocation_return_error(invocation,
2805+ error_quark(),
2806+ NO_VALID_LAYOUT,
2807+ "There currently isn't a layout in this server");
2808+ return;
2809+ }
2810+
2811+ gint id = g_variant_get_int32(g_variant_get_child_value(params, 0));
2812 DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id);
2813
2814 if (mi == NULL) {
2815- if (error != NULL) {
2816- g_set_error(error,
2817- error_quark(),
2818- INVALID_MENUITEM_ID,
2819- "The ID supplied %d does not refer to a menu item we have",
2820- id);
2821- }
2822- return FALSE;
2823+ g_dbus_method_invocation_return_error(invocation,
2824+ error_quark(),
2825+ INVALID_MENUITEM_ID,
2826+ "The ID supplied %d does not refer to a menu item we have",
2827+ id);
2828+ return;
2829 }
2830
2831 idle_event_t * event_data = g_new0(idle_event_t, 1);
2832 event_data->mi = mi;
2833 g_object_ref(event_data->mi);
2834- event_data->eventid = g_strdup(eventid);
2835- event_data->timestamp = timestamp;
2836- g_value_init(&(event_data->data), G_VALUE_TYPE(data));
2837- g_value_copy(data, &(event_data->data));
2838+ event_data->eventid = g_strdup(g_variant_get_string(g_variant_get_child_value(params, 1), NULL));
2839+ event_data->timestamp = g_variant_get_uint32(g_variant_get_child_value(params, 3));
2840+ event_data->variant = g_variant_get_child_value(params, 2);
2841
2842 g_timeout_add(0, event_local_handler, event_data);
2843- return TRUE;
2844+
2845+ g_dbus_method_invocation_return_value(invocation, NULL);
2846+ return;
2847 }
2848
2849 /* Recieve the About To Show function. Pass it to our menu item. */
2850-static gboolean
2851-_dbusmenu_server_about_to_show (DbusmenuServer * server, gint id, gboolean * need_update, GError ** error)
2852+static void
2853+bus_about_to_show (DbusmenuServer * server, GVariant * params, GDBusMethodInvocation * invocation)
2854 {
2855 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
2856+
2857+ if (priv->root == NULL) {
2858+ g_dbus_method_invocation_return_error(invocation,
2859+ error_quark(),
2860+ NO_VALID_LAYOUT,
2861+ "There currently isn't a layout in this server");
2862+ return;
2863+ }
2864+
2865+ gint id = g_variant_get_int32(g_variant_get_child_value(params, 0));
2866 DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id);
2867
2868 if (mi == NULL) {
2869- if (error != NULL) {
2870- g_set_error(error,
2871- error_quark(),
2872- INVALID_MENUITEM_ID,
2873- "The ID supplied %d does not refer to a menu item we have",
2874- id);
2875- }
2876- return FALSE;
2877+ g_dbus_method_invocation_return_error(invocation,
2878+ error_quark(),
2879+ INVALID_MENUITEM_ID,
2880+ "The ID supplied %d does not refer to a menu item we have",
2881+ id);
2882+ return;
2883 }
2884
2885 /* GTK+ does not support about-to-show concept for now */
2886- *need_update = FALSE;
2887- return TRUE;
2888+ g_dbus_method_invocation_return_value(invocation,
2889+ g_variant_new("(b)", FALSE));
2890+ return;
2891 }
2892
2893 /* Public Interface */
2894
2895=== modified file 'libdbusmenu-gtk/Makefile.am'
2896--- libdbusmenu-gtk/Makefile.am 2010-12-06 16:50:24 +0000
2897+++ libdbusmenu-gtk/Makefile.am 2010-12-08 03:19:55 +0000
2898@@ -14,10 +14,10 @@
2899 endif
2900
2901 EXTRA_DIST = \
2902- dbusmenu-gtk.pc.in \
2903- dbusmenu-gtk3.pc.in
2904+ dbusmenu-gtk-0.4.pc.in \
2905+ dbusmenu-gtk3-0.4.pc.in
2906
2907-libdbusmenu_gtkincludedir=$(includedir)/libdbusmenu-0.1/libdbusmenu-gtk$(VER)/
2908+libdbusmenu_gtkincludedir=$(includedir)/libdbusmenu-0.4/libdbusmenu-gtk$(VER)/
2909
2910 libdbusmenu_gtkinclude_HEADERS = \
2911 client.h \
2912@@ -57,7 +57,7 @@
2913 libdbusmenu_gtk3_la_CFLAGS = $(libdbusmenu_gtk_la_CFLAGS)
2914 libdbusmenu_gtk3_la_LIBADD = $(libdbusmenu_gtk_la_LIBADD)
2915
2916-pkgconfig_DATA = dbusmenu-gtk$(VER).pc
2917+pkgconfig_DATA = dbusmenu-gtk$(VER)-0.4.pc
2918 pkgconfigdir = $(libdir)/pkgconfig
2919
2920 #########################
2921@@ -85,28 +85,28 @@
2922
2923 introspection_sources = $(libdbusmenu_gtkinclude_HEADERS)
2924
2925-DbusmenuGtk$(VER)-0.2.gir: libdbusmenu-gtk$(VER).la
2926-DbusmenuGtk_0_2_gir_INCLUDES = \
2927+DbusmenuGtk$(VER)-0.4.gir: libdbusmenu-gtk$(VER).la
2928+DbusmenuGtk_0_4_gir_INCLUDES = \
2929 GObject-2.0 \
2930 $(GTKGIR) \
2931- Dbusmenu-Glib-0.2
2932-DbusmenuGtk_0_2_gir_CFLAGS = $(DBUSMENUGTK_CFLAGS) -I$(top_srcdir)
2933-DbusmenuGtk_0_2_gir_LIBS = libdbusmenu-gtk$(VER).la
2934-DbusmenuGtk_0_2_gir_FILES = $(addprefix $(srcdir)/, $(introspection_sources))
2935-DbusmenuGtk_0_2_gir_NAMESPACE = DbusmenuGtk$(VER)
2936-DbusmenuGtk_0_2_gir_SCANNERFLAGS = $(INTROSPECTION_SCANNER_ARGS)
2937-DbusmenuGtk_0_2_gir_PACKAGES = dbusmenu-gtk$(VER)
2938+ Dbusmenu-Glib-0.4
2939+DbusmenuGtk_0_4_gir_CFLAGS = $(DBUSMENUGTK_CFLAGS) -I$(top_srcdir)
2940+DbusmenuGtk_0_4_gir_LIBS = libdbusmenu-gtk$(VER).la
2941+DbusmenuGtk_0_4_gir_FILES = $(addprefix $(srcdir)/, $(introspection_sources))
2942+DbusmenuGtk_0_4_gir_NAMESPACE = DbusmenuGtk$(VER)
2943+DbusmenuGtk_0_4_gir_SCANNERFLAGS = $(INTROSPECTION_SCANNER_ARGS)
2944+DbusmenuGtk_0_4_gir_PACKAGES = dbusmenu-gtk$(VER)
2945
2946 # We duplicate these for the same reason as libdbusmenu_gtk3includedir above
2947-DbusmenuGtk3_0_2_gir_INCLUDES = $(DbusmenuGtk_0_2_gir_INCLUDES)
2948-DbusmenuGtk3_0_2_gir_CFLAGS = $(DbusmenuGtk_0_2_gir_CFLAGS)
2949-DbusmenuGtk3_0_2_gir_LIBS = $(DbusmenuGtk_0_2_gir_LIBS)
2950-DbusmenuGtk3_0_2_gir_FILES = $(DbusmenuGtk_0_2_gir_FILES)
2951-DbusmenuGtk3_0_2_gir_NAMESPACE = $(DbusmenuGtk_0_2_gir_NAMESPACE)
2952-DbusmenuGtk3_0_2_gir_SCANNERFLAGS = $(DbusmenuGtk_0_2_gir_SCANNERFLAGS)
2953-DbusmenuGtk3_0_2_gir_PACKAGES = $(DbusmenuGtk_0_2_gir_PACKAGES)
2954+DbusmenuGtk3_0_4_gir_INCLUDES = $(DbusmenuGtk_0_4_gir_INCLUDES)
2955+DbusmenuGtk3_0_4_gir_CFLAGS = $(DbusmenuGtk_0_4_gir_CFLAGS)
2956+DbusmenuGtk3_0_4_gir_LIBS = $(DbusmenuGtk_0_4_gir_LIBS)
2957+DbusmenuGtk3_0_4_gir_FILES = $(DbusmenuGtk_0_4_gir_FILES)
2958+DbusmenuGtk3_0_4_gir_NAMESPACE = $(DbusmenuGtk_0_4_gir_NAMESPACE)
2959+DbusmenuGtk3_0_4_gir_SCANNERFLAGS = $(DbusmenuGtk_0_4_gir_SCANNERFLAGS)
2960+DbusmenuGtk3_0_4_gir_PACKAGES = $(DbusmenuGtk_0_4_gir_PACKAGES)
2961
2962-INTROSPECTION_GIRS += DbusmenuGtk$(VER)-0.2.gir
2963+INTROSPECTION_GIRS += DbusmenuGtk$(VER)-0.4.gir
2964
2965 girdir = $(datadir)/gir-1.0
2966 gir_DATA = $(INTROSPECTION_GIRS)
2967@@ -125,24 +125,24 @@
2968 if HAVE_INTROSPECTION
2969
2970 vapidir = $(datadir)/vala/vapi
2971-vapi_DATA = DbusmenuGtk$(VER)-0.2.vapi
2972+vapi_DATA = DbusmenuGtk$(VER)-0.4.vapi
2973
2974-DbusmenuGtk$(VER)-0.2.vapi: DbusmenuGtk$(VER)-0.2.tmp.gir Makefile.am
2975- $(VALA_API_GEN) --library=DbusmenuGtk$(VER)-0.2 \
2976+DbusmenuGtk$(VER)-0.4.vapi: DbusmenuGtk$(VER)-0.4.tmp.gir Makefile.am
2977+ $(VALA_API_GEN) --library=DbusmenuGtk$(VER)-0.4 \
2978 --pkg gdk-pixbuf-2.0 \
2979 --pkg $(GTKVALA) \
2980 --pkg atk \
2981- --pkg Dbusmenu-Glib-0.2 \
2982+ --pkg Dbusmenu-Glib-0.4 \
2983 --vapidir=$(top_builddir)/libdbusmenu-glib \
2984 $<
2985
2986-DbusmenuGtk$(VER)-0.2.tmp.gir: DbusmenuGtk$(VER)-0.2.gir
2987+DbusmenuGtk$(VER)-0.4.tmp.gir: DbusmenuGtk$(VER)-0.4.gir
2988 $(SED) \
2989 -e "s|GdkPixbuf.Pixbuf|Gdk.Pixbuf|g" \
2990 -e "s|Atk.ImplementorIface|Atk.Implementor|g" \
2991 $< > $@
2992
2993-CLEANFILES += $(vapi_DATA) DbusmenuGtk$(VER)-0.2.tmp.gir
2994+CLEANFILES += $(vapi_DATA) DbusmenuGtk$(VER)-0.4.tmp.gir
2995
2996 endif
2997
2998
2999=== modified file 'libdbusmenu-gtk/client.c'
3000--- libdbusmenu-gtk/client.c 2010-11-11 14:15:20 +0000
3001+++ libdbusmenu-gtk/client.c 2010-12-08 03:19:55 +0000
3002@@ -57,9 +57,9 @@
3003 static gboolean new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
3004 static gboolean new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
3005
3006-static void process_visible (DbusmenuMenuitem * mi, GtkMenuItem * gmi, const GValue * value);
3007-static void process_sensitive (DbusmenuMenuitem * mi, GtkMenuItem * gmi, const GValue * value);
3008-static void image_property_handle (DbusmenuMenuitem * item, const gchar * property, const GValue * invalue, gpointer userdata);
3009+static void process_visible (DbusmenuMenuitem * mi, GtkMenuItem * gmi, GVariant * value);
3010+static void process_sensitive (DbusmenuMenuitem * mi, GtkMenuItem * gmi, GVariant * value);
3011+static void image_property_handle (DbusmenuMenuitem * item, const gchar * property, GVariant * invalue, gpointer userdata);
3012
3013 /* GObject Stuff */
3014 G_DEFINE_TYPE (DbusmenuGtkClient, dbusmenu_gtkclient, DBUSMENU_TYPE_CLIENT);
3015@@ -283,10 +283,8 @@
3016 menu_pressed_cb (GtkMenuItem * gmi, DbusmenuMenuitem * mi)
3017 {
3018 if (gtk_menu_item_get_submenu(gmi) == NULL) {
3019- GValue value = {0};
3020- g_value_init(&value, G_TYPE_INT);
3021- g_value_set_int(&value, 0);
3022- dbusmenu_menuitem_handle_event(mi, "clicked", &value, gtk_get_current_event_time());
3023+ GVariant * variant = g_variant_new("i", 0);
3024+ dbusmenu_menuitem_handle_event(mi, "clicked", variant, gtk_get_current_event_time());
3025 } else {
3026 /* TODO: We need to stop the display of the submenu
3027 until this callback returns. */
3028@@ -297,7 +295,7 @@
3029
3030 /* Process the visible property */
3031 static void
3032-process_visible (DbusmenuMenuitem * mi, GtkMenuItem * gmi, const GValue * value)
3033+process_visible (DbusmenuMenuitem * mi, GtkMenuItem * gmi, GVariant * value)
3034 {
3035 gboolean val = TRUE;
3036 if (value != NULL) {
3037@@ -314,7 +312,7 @@
3038
3039 /* Process the sensitive property */
3040 static void
3041-process_sensitive (DbusmenuMenuitem * mi, GtkMenuItem * gmi, const GValue * value)
3042+process_sensitive (DbusmenuMenuitem * mi, GtkMenuItem * gmi, GVariant * value)
3043 {
3044 gboolean val = TRUE;
3045 if (value != NULL) {
3046@@ -326,26 +324,21 @@
3047
3048 /* Process the sensitive property */
3049 static void
3050-process_toggle_type (DbusmenuMenuitem * mi, GtkMenuItem * gmi, const GValue * value)
3051+process_toggle_type (DbusmenuMenuitem * mi, GtkMenuItem * gmi, GVariant * variant)
3052 {
3053 if (!IS_GENERICMENUITEM(gmi)) return;
3054- if (value == NULL) return;
3055+ if (variant == NULL) return;
3056
3057 GenericmenuitemCheckType type = GENERICMENUITEM_CHECK_TYPE_NONE;
3058
3059- GValue strvalue = {0};
3060- g_value_init(&strvalue, G_TYPE_STRING);
3061-
3062- if (value != NULL && g_value_transform(value, &strvalue)) {
3063- const gchar * strval = g_value_get_string(&strvalue);
3064+ if (variant != NULL) {
3065+ const gchar * strval = g_variant_get_string(variant, NULL);
3066
3067 if (!g_strcmp0(strval, DBUSMENU_MENUITEM_TOGGLE_CHECK)) {
3068 type = GENERICMENUITEM_CHECK_TYPE_CHECKBOX;
3069 } else if (!g_strcmp0(strval, DBUSMENU_MENUITEM_TOGGLE_RADIO)) {
3070 type = GENERICMENUITEM_CHECK_TYPE_RADIO;
3071 }
3072-
3073- g_value_unset(&strvalue);
3074 }
3075
3076 genericmenuitem_set_check_type(GENERICMENUITEM(gmi), type);
3077@@ -355,17 +348,14 @@
3078
3079 /* Process the sensitive property */
3080 static void
3081-process_toggle_state (DbusmenuMenuitem * mi, GtkMenuItem * gmi, const GValue * value)
3082+process_toggle_state (DbusmenuMenuitem * mi, GtkMenuItem * gmi, GVariant * variant)
3083 {
3084 if (!IS_GENERICMENUITEM(gmi)) return;
3085
3086 GenericmenuitemState state = GENERICMENUITEM_STATE_UNCHECKED;
3087
3088- GValue intvalue = {0};
3089- g_value_init(&intvalue, G_TYPE_INT);
3090-
3091- if (value != NULL && g_value_transform(value, &intvalue)) {
3092- int val = g_value_get_int(&intvalue);
3093+ if (variant != NULL) {
3094+ int val = g_variant_get_int32(variant);
3095
3096 if (val == DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED) {
3097 state = GENERICMENUITEM_STATE_CHECKED;
3098@@ -381,18 +371,18 @@
3099 /* Whenever we have a property change on a DbusmenuMenuitem
3100 we need to be responsive to that. */
3101 static void
3102-menu_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkMenuItem * gmi)
3103+menu_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant * variant, GtkMenuItem * gmi)
3104 {
3105 if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_LABEL)) {
3106- gtk_menu_item_set_label(gmi, g_value_get_string(value));
3107+ gtk_menu_item_set_label(gmi, variant == NULL ? NULL : g_variant_get_string(variant, NULL));
3108 } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_VISIBLE)) {
3109- process_visible(mi, gmi, value);
3110+ process_visible(mi, gmi, variant);
3111 } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_ENABLED)) {
3112- process_sensitive(mi, gmi, value);
3113+ process_sensitive(mi, gmi, variant);
3114 } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE)) {
3115- process_toggle_type(mi, gmi, value);
3116+ process_toggle_type(mi, gmi, variant);
3117 } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE)) {
3118- process_toggle_state(mi, gmi, value);
3119+ process_toggle_state(mi, gmi, variant);
3120 }
3121
3122 return;
3123@@ -401,7 +391,7 @@
3124 /* Special handler for the shortcut changing as we need to have the
3125 client for that one to get the accel group. */
3126 static void
3127-menu_shortcut_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, DbusmenuGtkClient * client)
3128+menu_shortcut_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant * value, DbusmenuGtkClient * client)
3129 {
3130 if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_SHORTCUT)) {
3131 refresh_shortcut(client, mi);
3132@@ -543,10 +533,10 @@
3133 g_object_weak_ref(G_OBJECT(item), destoryed_dbusmenuitem_cb, gmi);
3134
3135 /* Check our set of props to see if any are set already */
3136- process_visible(item, gmi, dbusmenu_menuitem_property_get_value(item, DBUSMENU_MENUITEM_PROP_VISIBLE));
3137- process_sensitive(item, gmi, dbusmenu_menuitem_property_get_value(item, DBUSMENU_MENUITEM_PROP_ENABLED));
3138- process_toggle_type(item, gmi, dbusmenu_menuitem_property_get_value(item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE));
3139- process_toggle_state(item, gmi, dbusmenu_menuitem_property_get_value(item, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE));
3140+ process_visible(item, gmi, dbusmenu_menuitem_property_get_variant(item, DBUSMENU_MENUITEM_PROP_VISIBLE));
3141+ process_sensitive(item, gmi, dbusmenu_menuitem_property_get_variant(item, DBUSMENU_MENUITEM_PROP_ENABLED));
3142+ process_toggle_type(item, gmi, dbusmenu_menuitem_property_get_variant(item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE));
3143+ process_toggle_state(item, gmi, dbusmenu_menuitem_property_get_variant(item, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE));
3144 refresh_shortcut(client, item);
3145
3146 /* Oh, we're a child, let's deal with that */
3147@@ -711,11 +701,11 @@
3148
3149 image_property_handle(newitem,
3150 DBUSMENU_MENUITEM_PROP_ICON_NAME,
3151- dbusmenu_menuitem_property_get_value(newitem, DBUSMENU_MENUITEM_PROP_ICON_NAME),
3152+ dbusmenu_menuitem_property_get_variant(newitem, DBUSMENU_MENUITEM_PROP_ICON_NAME),
3153 client);
3154 image_property_handle(newitem,
3155 DBUSMENU_MENUITEM_PROP_ICON_DATA,
3156- dbusmenu_menuitem_property_get_value(newitem, DBUSMENU_MENUITEM_PROP_ICON_DATA),
3157+ dbusmenu_menuitem_property_get_variant(newitem, DBUSMENU_MENUITEM_PROP_ICON_DATA),
3158 client);
3159 g_signal_connect(G_OBJECT(newitem),
3160 DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED,
3161@@ -749,7 +739,7 @@
3162 /* This handler looks at property changes for items that are
3163 image menu items. */
3164 static void
3165-image_property_handle (DbusmenuMenuitem * item, const gchar * property, const GValue * invalue, gpointer userdata)
3166+image_property_handle (DbusmenuMenuitem * item, const gchar * property, GVariant * variant, gpointer userdata)
3167 {
3168 /* We're only looking at these two properties here */
3169 if (g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON_NAME) != 0 &&
3170@@ -758,11 +748,10 @@
3171 }
3172
3173 const gchar * value = NULL;
3174+ if (variant != NULL) {
3175+ value = g_variant_get_string(variant, NULL);
3176+ }
3177
3178- if (invalue != NULL && G_VALUE_TYPE(invalue) == G_TYPE_STRING) {
3179- value = g_value_get_string(invalue);
3180- }
3181-
3182 if (value == NULL || value[0] == '\0') {
3183 /* This means that we're unsetting a value. */
3184 /* Try to use the other one */
3185
3186=== renamed file 'libdbusmenu-gtk/dbusmenu-gtk.pc.in' => 'libdbusmenu-gtk/dbusmenu-gtk-0.4.pc.in'
3187--- libdbusmenu-gtk/dbusmenu-gtk.pc.in 2009-03-25 20:09:14 +0000
3188+++ libdbusmenu-gtk/dbusmenu-gtk-0.4.pc.in 2010-12-08 03:19:55 +0000
3189@@ -4,7 +4,7 @@
3190 bindir=@bindir@
3191 includedir=@includedir@
3192
3193-Cflags: -I${includedir}/libdbusmenu-0.1
3194+Cflags: -I${includedir}/libdbusmenu-0.4
3195 Requires: dbus-glib-1 dbusmenu-glib
3196 Libs: -L${libdir} -ldbusmenu-gtk
3197
3198
3199=== renamed file 'libdbusmenu-gtk/dbusmenu-gtk3.pc.in' => 'libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc.in'
3200--- libdbusmenu-gtk/dbusmenu-gtk3.pc.in 2010-10-06 14:13:09 +0000
3201+++ libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc.in 2010-12-08 03:19:55 +0000
3202@@ -4,7 +4,7 @@
3203 bindir=@bindir@
3204 includedir=@includedir@
3205
3206-Cflags: -I${includedir}/libdbusmenu-0.1
3207+Cflags: -I${includedir}/libdbusmenu-0.4
3208 Requires: dbus-glib-1 dbusmenu-glib
3209 Libs: -L${libdir} -ldbusmenu-gtk3
3210
3211
3212=== modified file 'libdbusmenu-gtk/genericmenuitem.c'
3213--- libdbusmenu-gtk/genericmenuitem.c 2010-11-11 14:15:20 +0000
3214+++ libdbusmenu-gtk/genericmenuitem.c 2010-12-08 03:19:55 +0000
3215@@ -291,7 +291,6 @@
3216 }
3217
3218 item->priv->check_type = check_type;
3219- GValue value = {0};
3220
3221 switch (item->priv->check_type) {
3222 case GENERICMENUITEM_CHECK_TYPE_NONE:
3223@@ -300,14 +299,10 @@
3224 check on the item. */
3225 break;
3226 case GENERICMENUITEM_CHECK_TYPE_CHECKBOX:
3227- g_value_init(&value, G_TYPE_BOOLEAN);
3228- g_value_set_boolean(&value, FALSE);
3229- g_object_set_property(G_OBJECT(item), "draw-as-radio", &value);
3230+ gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(item), FALSE);
3231 break;
3232 case GENERICMENUITEM_CHECK_TYPE_RADIO:
3233- g_value_init(&value, G_TYPE_BOOLEAN);
3234- g_value_set_boolean(&value, TRUE);
3235- g_object_set_property(G_OBJECT(item), "draw-as-radio", &value);
3236+ gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(item), TRUE);
3237 break;
3238 default:
3239 g_warning("Generic Menuitem invalid check type: %d", check_type);
3240
3241=== modified file 'libdbusmenu-gtk/menuitem.c'
3242--- libdbusmenu-gtk/menuitem.c 2010-11-11 14:15:20 +0000
3243+++ libdbusmenu-gtk/menuitem.c 2010-12-08 03:19:55 +0000
3244@@ -29,7 +29,6 @@
3245 #include "menuitem.h"
3246 #include <gdk/gdk.h>
3247 #include <gtk/gtk.h>
3248-#include <dbus/dbus-gtype-specialized.h>
3249
3250 /**
3251 dbusmenu_menuitem_property_set_image:
3252@@ -178,50 +177,31 @@
3253 g_return_val_if_fail(DBUSMENU_IS_MENUITEM(menuitem), FALSE);
3254 g_return_val_if_fail(gtk_accelerator_valid(key, modifier), FALSE);
3255
3256- GArray * array = g_array_sized_new(TRUE, TRUE, sizeof(gchar *), 4); /* Four seems like the max we'd need, plus it's still small */
3257-
3258- const gchar * control_val = DBUSMENU_MENUITEM_SHORTCUT_CONTROL;
3259- const gchar * alt_val = DBUSMENU_MENUITEM_SHORTCUT_ALT;
3260- const gchar * shift_val = DBUSMENU_MENUITEM_SHORTCUT_SHIFT;
3261- const gchar * super_val = DBUSMENU_MENUITEM_SHORTCUT_SUPER;
3262+ GVariantBuilder builder;
3263+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
3264
3265 if (modifier & GDK_CONTROL_MASK) {
3266- g_array_append_val(array, control_val);
3267+ g_variant_builder_add(&builder, "s", DBUSMENU_MENUITEM_SHORTCUT_CONTROL);
3268 }
3269 if (modifier & GDK_MOD1_MASK) {
3270- g_array_append_val(array, alt_val);
3271+ g_variant_builder_add(&builder, "s", DBUSMENU_MENUITEM_SHORTCUT_ALT);
3272 }
3273 if (modifier & GDK_SHIFT_MASK) {
3274- g_array_append_val(array, shift_val);
3275+ g_variant_builder_add(&builder, "s", DBUSMENU_MENUITEM_SHORTCUT_SHIFT);
3276 }
3277 if (modifier & GDK_SUPER_MASK) {
3278- g_array_append_val(array, super_val);
3279+ g_variant_builder_add(&builder, "s", DBUSMENU_MENUITEM_SHORTCUT_SUPER);
3280 }
3281
3282 const gchar * keyname = gdk_keyval_name(key);
3283- g_array_append_val(array, keyname);
3284-
3285- GType type = dbus_g_type_get_collection("GPtrArray", G_TYPE_STRV);
3286- GPtrArray * wrapper = (GPtrArray *)dbus_g_type_specialized_construct(type);
3287-
3288- GValue value = {0,};
3289- g_value_init(&value, type);
3290- g_value_take_boxed(&value, wrapper);
3291-
3292- DBusGTypeSpecializedAppendContext ctx;
3293- dbus_g_type_specialized_init_append(&value, &ctx);
3294-
3295- GValue strval = {0,};
3296- g_value_init(&strval, G_TYPE_STRV);
3297- g_value_take_boxed(&strval, array->data);
3298- g_array_free(array, FALSE);
3299-
3300- dbus_g_type_specialized_collection_append(&ctx, &strval);
3301- dbus_g_type_specialized_collection_end_append(&ctx);
3302-
3303- dbusmenu_menuitem_property_set_value(menuitem, DBUSMENU_MENUITEM_PROP_SHORTCUT, &value);
3304-
3305- return TRUE;
3306+ g_variant_builder_add(&builder, "s", keyname);
3307+
3308+ GVariant * inside = g_variant_builder_end(&builder);
3309+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
3310+ g_variant_builder_add_value(&builder, inside);
3311+ GVariant * outsidevariant = g_variant_builder_end(&builder);
3312+
3313+ return dbusmenu_menuitem_property_set_variant(menuitem, DBUSMENU_MENUITEM_PROP_SHORTCUT, outsidevariant);
3314 }
3315
3316 /* Look at the closures in an accel group and find
3317@@ -279,68 +259,6 @@
3318 return dbusmenu_menuitem_property_set_shortcut(menuitem, key->accel_key, key->accel_mods);
3319 }
3320
3321-/* A set of typed data for the interator */
3322-typedef struct _iter_data_t iter_data_t;
3323-struct _iter_data_t {
3324- guint * key;
3325- GdkModifierType * modifier;
3326-};
3327-
3328-/* Goes through the wrapper items. In reality we only support one
3329- so it checks to see if a key is set first. But, we could possibly,
3330- support more in the future. */
3331-static void
3332-_wrapper_iterator (const GValue * value, gpointer user_data)
3333-{
3334- iter_data_t * iter_data = (iter_data_t *)user_data;
3335-
3336- if (*iter_data->key != 0) {
3337- g_warning("Shortcut is more than one entry. Which we don't currently support. Taking the first.");
3338- return;
3339- }
3340-
3341- if (!G_VALUE_HOLDS(value, G_TYPE_STRV)) {
3342- g_warning("Unexpected shortcut structure. Value array is: %s", G_VALUE_TYPE_NAME(value));
3343- return;
3344- }
3345-
3346- gchar ** stringarray = (gchar **)g_value_get_boxed(value);
3347- if (stringarray == NULL) {
3348- return;
3349- }
3350-
3351- const gchar * last_string = NULL;
3352- int i;
3353-
3354- for (i = 0; stringarray[i] != NULL; i++) {
3355- last_string = stringarray[i];
3356-
3357- if (g_strcmp0(last_string, DBUSMENU_MENUITEM_SHORTCUT_CONTROL) == 0) {
3358- *iter_data->modifier |= GDK_CONTROL_MASK;
3359- continue;
3360- }
3361- if (g_strcmp0(last_string, DBUSMENU_MENUITEM_SHORTCUT_ALT) == 0) {
3362- *iter_data->modifier |= GDK_MOD1_MASK;
3363- continue;
3364- }
3365- if (g_strcmp0(last_string, DBUSMENU_MENUITEM_SHORTCUT_SHIFT) == 0) {
3366- *iter_data->modifier |= GDK_SHIFT_MASK;
3367- continue;
3368- }
3369- if (g_strcmp0(last_string, DBUSMENU_MENUITEM_SHORTCUT_SUPER) == 0) {
3370- *iter_data->modifier |= GDK_SUPER_MASK;
3371- continue;
3372- }
3373- }
3374-
3375- if (last_string != NULL) {
3376- GdkModifierType tempmod;
3377- gtk_accelerator_parse(last_string, iter_data->key, &tempmod);
3378- }
3379-
3380- return;
3381-}
3382-
3383 /**
3384 dbusmenu_menuitem_property_get_shortcut:
3385 @menuitem: The #DbusmenuMenuitem to get the shortcut off
3386@@ -358,20 +276,37 @@
3387
3388 g_return_if_fail(DBUSMENU_IS_MENUITEM(menuitem));
3389
3390- const GValue * wrapper = dbusmenu_menuitem_property_get_value(menuitem, DBUSMENU_MENUITEM_PROP_SHORTCUT);
3391+ GVariant * wrapper = dbusmenu_menuitem_property_get_variant(menuitem, DBUSMENU_MENUITEM_PROP_SHORTCUT);
3392 if (wrapper == NULL) {
3393 return;
3394 }
3395- if (!dbus_g_type_is_collection(G_VALUE_TYPE(wrapper))) {
3396- g_warning("Unexpected shortcut structure. Wrapper is: %s", G_VALUE_TYPE_NAME(wrapper));
3397+
3398+ if (g_variant_n_children(wrapper) != 1) {
3399+ g_warning("Unable to parse shortcut, too many keys");
3400+ g_variant_unref(wrapper);
3401 return;
3402 }
3403
3404- iter_data_t iter_data;
3405- iter_data.key = key;
3406- iter_data.modifier = modifier;
3407-
3408- dbus_g_type_collection_value_iterate(wrapper, _wrapper_iterator, &iter_data);
3409+ GVariantIter iter;
3410+ g_variant_iter_init(&iter, g_variant_get_child_value(wrapper, 0));
3411+ gchar * string;
3412+
3413+ while(g_variant_iter_next(&iter, "s", &string)) {
3414+ if (g_strcmp0(string, DBUSMENU_MENUITEM_SHORTCUT_CONTROL) == 0) {
3415+ *modifier |= GDK_CONTROL_MASK;
3416+ } else if (g_strcmp0(string, DBUSMENU_MENUITEM_SHORTCUT_ALT) == 0) {
3417+ *modifier |= GDK_MOD1_MASK;
3418+ } else if (g_strcmp0(string, DBUSMENU_MENUITEM_SHORTCUT_SHIFT) == 0) {
3419+ *modifier |= GDK_SHIFT_MASK;
3420+ } else if (g_strcmp0(string, DBUSMENU_MENUITEM_SHORTCUT_SUPER) == 0) {
3421+ *modifier |= GDK_SUPER_MASK;
3422+ } else {
3423+ GdkModifierType tempmod;
3424+ gtk_accelerator_parse(string, key, &tempmod);
3425+ }
3426+
3427+ g_free(string);
3428+ }
3429
3430 return;
3431 }
3432
3433=== modified file 'tests/Makefile.am'
3434--- tests/Makefile.am 2010-08-27 19:31:44 +0000
3435+++ tests/Makefile.am 2010-12-08 03:19:55 +0000
3436@@ -52,7 +52,7 @@
3437
3438 lib_LTLIBRARIES = libdbusmenu-jsonloader.la
3439
3440-libdbusmenu_jsonloaderincludedir=$(includedir)/libdbusmenu-0.1/libdbusmenu-jsonloader/
3441+libdbusmenu_jsonloaderincludedir=$(includedir)/libdbusmenu-0.4/libdbusmenu-jsonloader/
3442
3443 libdbusmenu_jsonloaderinclude_HEADERS = \
3444 json-loader.h
3445@@ -80,7 +80,7 @@
3446 $(DBUSMENUGLIB_LIBS) \
3447 $(DBUSMENUTESTS_LIBS)
3448
3449-pkgconfig_DATA = dbusmenu-jsonloader.pc
3450+pkgconfig_DATA = dbusmenu-jsonloader-0.4.pc
3451 pkgconfigdir = $(libdir)/pkgconfig
3452
3453 ######################
3454
3455=== renamed file 'tests/dbusmenu-jsonloader.pc.in' => 'tests/dbusmenu-jsonloader-0.4.pc.in'
3456=== modified file 'tests/json-loader.c'
3457--- tests/json-loader.c 2010-06-29 03:39:59 +0000
3458+++ tests/json-loader.c 2010-12-08 03:19:55 +0000
3459@@ -20,115 +20,76 @@
3460 */
3461
3462 #include "json-loader.h"
3463-#include <dbus/dbus-gtype-specialized.h>
3464-
3465-static GValue *
3466-node2value (JsonNode * node)
3467+
3468+static GVariant * node2variant (JsonNode * node);
3469+
3470+static void
3471+array_foreach (JsonArray * array, guint index, JsonNode * node, gpointer user_data)
3472+{
3473+ GVariantBuilder * builder = (GVariantBuilder *)user_data;
3474+ GVariant * variant = node2variant(node);
3475+ if (variant != NULL) {
3476+ g_variant_builder_add_value(builder, variant);
3477+ }
3478+ return;
3479+}
3480+
3481+static void
3482+object_foreach (JsonObject * array, const gchar * member, JsonNode * node, gpointer user_data)
3483+{
3484+ GVariantBuilder * builder = (GVariantBuilder *)user_data;
3485+ GVariant * variant = node2variant(node);
3486+ if (variant != NULL) {
3487+ g_variant_builder_add(builder, "{sv}", member, variant);
3488+ }
3489+ return;
3490+}
3491+
3492+static GVariant *
3493+node2variant (JsonNode * node)
3494 {
3495 if (node == NULL) {
3496 return NULL;
3497 }
3498
3499- GValue * value = g_new0(GValue, 1);
3500-
3501 if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE) {
3502- json_node_get_value(node, value);
3503- return value;
3504+ switch (json_node_get_value_type(node)) {
3505+ case G_TYPE_INT:
3506+ case G_TYPE_INT64:
3507+ return g_variant_new_int32(json_node_get_int(node));
3508+ case G_TYPE_DOUBLE:
3509+ case G_TYPE_FLOAT:
3510+ return g_variant_new_double(json_node_get_double(node));
3511+ case G_TYPE_BOOLEAN:
3512+ return g_variant_new_boolean(json_node_get_boolean(node));
3513+ case G_TYPE_STRING:
3514+ return g_variant_new_string(json_node_get_string(node));
3515+ default:
3516+ g_assert_not_reached();
3517+ }
3518 }
3519
3520 if (JSON_NODE_TYPE(node) == JSON_NODE_ARRAY) {
3521+ GVariantBuilder builder;
3522+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
3523+
3524 JsonArray * array = json_node_get_array(node);
3525- JsonNode * first = json_array_get_element(array, 0);
3526-
3527- if (JSON_NODE_TYPE(first) == JSON_NODE_VALUE) {
3528- GValue subvalue = {0};
3529- json_node_get_value(first, &subvalue);
3530-
3531- if (G_VALUE_TYPE(&subvalue) == G_TYPE_STRING) {
3532- GArray * garray = g_array_sized_new(TRUE, TRUE, sizeof(gchar *), json_array_get_length(array));
3533- g_value_init(value, G_TYPE_STRV);
3534- g_value_take_boxed(value, garray->data);
3535-
3536- int i;
3537- for (i = 0; i < json_array_get_length(array); i++) {
3538- const gchar * str = json_node_get_string(json_array_get_element(array, i));
3539- gchar * dupstr = g_strdup(str);
3540- g_array_append_val(garray, dupstr);
3541- }
3542-
3543- g_array_free(garray, FALSE);
3544- } else {
3545- GValueArray * varray = g_value_array_new(json_array_get_length(array));
3546- g_value_init(value, G_TYPE_VALUE_ARRAY);
3547- g_value_take_boxed(value, varray);
3548-
3549- g_value_array_append(varray, &subvalue);
3550- g_value_unset(&subvalue);
3551-
3552- int i;
3553- for (i = 1; i < json_array_get_length(array); i++) {
3554- json_node_get_value(first, &subvalue);
3555- g_value_array_append(varray, &subvalue);
3556- g_value_unset(&subvalue);
3557- }
3558- }
3559-
3560- } else {
3561- GValue * subvalue = node2value(first);
3562- GType type = dbus_g_type_get_collection("GPtrArray", G_VALUE_TYPE(subvalue));
3563- gpointer * wrapper = dbus_g_type_specialized_construct(type);
3564-
3565- g_value_init(value, type);
3566- g_value_take_boxed(value, wrapper);
3567-
3568- DBusGTypeSpecializedAppendContext ctx;
3569- dbus_g_type_specialized_init_append(value, &ctx);
3570-
3571- dbus_g_type_specialized_collection_append(&ctx, subvalue);
3572- int i;
3573- for (i = 1; i < json_array_get_length(array); i++) {
3574- GValue * subvalue = node2value(node);
3575- dbus_g_type_specialized_collection_append(&ctx, subvalue);
3576- }
3577-
3578- dbus_g_type_specialized_collection_end_append(&ctx);
3579- }
3580+ json_array_foreach_element(array, array_foreach, &builder);
3581+
3582+ return g_variant_builder_end(&builder);
3583 }
3584
3585 if (JSON_NODE_TYPE(node) == JSON_NODE_OBJECT) {
3586- JsonObject * obj = json_node_get_object(node);
3587-
3588- GType type = dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE);
3589- GHashTable * hash = (GHashTable *)dbus_g_type_specialized_construct(type);
3590-
3591- g_value_init(value, type);
3592- g_value_take_boxed(value, hash);
3593-
3594- DBusGTypeSpecializedAppendContext ctx;
3595- dbus_g_type_specialized_init_append(value, &ctx);
3596-
3597- GList * members = NULL;
3598- for (members = json_object_get_members(obj); members != NULL; members = g_list_next(members)) {
3599- const gchar * member = members->data;
3600-
3601- JsonNode * lnode = json_object_get_member(obj, member);
3602- GValue * value = node2value(lnode);
3603-
3604- if (value != NULL) {
3605- GValue name = {0};
3606- g_value_init(&name, G_TYPE_STRING);
3607- g_value_set_static_string(&name, member);
3608-
3609- dbus_g_type_specialized_map_append(&ctx, &name, value);
3610-
3611- g_value_unset(&name);
3612- g_value_unset(value);
3613- g_free(value);
3614- }
3615- }
3616+ GVariantBuilder builder;
3617+ g_variant_builder_init(&builder, G_VARIANT_TYPE_DICTIONARY);
3618+
3619+ JsonObject * array = json_node_get_object(node);
3620+ json_object_foreach_member(array, object_foreach, &builder);
3621+
3622+ return g_variant_builder_end(&builder);
3623 }
3624
3625- return value;
3626+ return NULL;
3627 }
3628
3629 static void
3630@@ -144,12 +105,11 @@
3631 if (!g_strcmp0(member, "submenu")) { continue; }
3632
3633 JsonNode * lnode = json_object_get_member(node, member);
3634- GValue * value = node2value(lnode);
3635+ GVariant * variant = node2variant(lnode);
3636
3637- if (value != NULL) {
3638- dbusmenu_menuitem_property_set_value(mi, member, value);
3639- g_value_unset(value);
3640- g_free(value);
3641+ if (variant != NULL) {
3642+ dbusmenu_menuitem_property_set_variant(mi, member, variant);
3643+ g_variant_unref(variant);
3644 }
3645 }
3646
3647
3648=== modified file 'tests/test-glib-events-client.c'
3649--- tests/test-glib-events-client.c 2010-08-27 20:57:42 +0000
3650+++ tests/test-glib-events-client.c 2010-12-08 03:19:55 +0000
3651@@ -35,7 +35,7 @@
3652 static gboolean first = TRUE;
3653
3654 static void
3655-event_status (DbusmenuClient * client, DbusmenuMenuitem * item, gchar * name, GValue * data, guint timestamp, GError * error, gpointer user_data)
3656+event_status (DbusmenuClient * client, DbusmenuMenuitem * item, gchar * name, GVariant * data, guint timestamp, GError * error, gpointer user_data)
3657 {
3658 g_debug("Event status: %s", error == NULL ? "Sent" : "Error");
3659
3660@@ -46,8 +46,8 @@
3661 return;
3662 }
3663
3664- if (g_value_get_int(data) != DATA_VALUE) {
3665- g_debug("Data value pass fail got: %d", g_value_get_int(data));
3666+ if (g_variant_get_int32(data) != DATA_VALUE) {
3667+ g_debug("Data value pass fail got: %d", g_variant_get_int32(g_variant_get_child_value(data, 0)));
3668 passed = FALSE;
3669 g_main_loop_quit(mainloop);
3670 return;
3671@@ -96,11 +96,8 @@
3672 return;
3673 }
3674
3675- GValue data = {0};
3676- g_value_init(&data, G_TYPE_INT);
3677- g_value_set_int(&data, DATA_VALUE);
3678-
3679- dbusmenu_menuitem_handle_event(menuroot, "clicked", &data, TIMESTAMP_VALUE);
3680+ GVariant * data = g_variant_new_int32(DATA_VALUE);
3681+ dbusmenu_menuitem_handle_event(menuroot, "clicked", data, TIMESTAMP_VALUE);
3682
3683 return;
3684 }
3685@@ -128,6 +125,7 @@
3686 mainloop = g_main_loop_new(NULL, FALSE);
3687 g_main_loop_run(mainloop);
3688
3689+ g_debug("Main loop complete");
3690 g_object_unref(G_OBJECT(client));
3691
3692 if (passed) {
3693
3694=== modified file 'tests/test-glib-events-server.c'
3695--- tests/test-glib-events-server.c 2010-08-27 20:29:49 +0000
3696+++ tests/test-glib-events-server.c 2010-12-08 03:19:55 +0000
3697@@ -20,11 +20,7 @@
3698 */
3699
3700 #include <glib.h>
3701-
3702-#include <dbus/dbus.h>
3703-#include <dbus/dbus-glib.h>
3704-#include <dbus/dbus-glib-lowlevel.h>
3705-#include <dbus/dbus-glib-bindings.h>
3706+#include <gio/gio.h>
3707
3708 #include <libdbusmenu-glib/server.h>
3709 #include <libdbusmenu-glib/menuitem.h>
3710@@ -49,35 +45,40 @@
3711 return FALSE;
3712 }
3713
3714-int
3715-main (int argc, char ** argv)
3716+static void
3717+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
3718 {
3719- GError * error = NULL;
3720-
3721- g_type_init();
3722-
3723- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
3724- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
3725-
3726- DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
3727- guint nameret = 0;
3728-
3729- if (!org_freedesktop_DBus_request_name(bus_proxy, "org.dbusmenu.test", 0, &nameret, &error)) {
3730- g_error("Unable to call to request name");
3731- return 1;
3732- }
3733-
3734- if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
3735- g_error("Unable to get name");
3736- return 1;
3737- }
3738-
3739 server = dbusmenu_server_new("/org/test");
3740 DbusmenuMenuitem * menuitem = dbusmenu_menuitem_new();
3741 dbusmenu_server_set_root(server, menuitem);
3742
3743 g_signal_connect(G_OBJECT(menuitem), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(handle_event), NULL);
3744
3745+ return;
3746+}
3747+
3748+static void
3749+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
3750+{
3751+ g_error("Unable to get name '%s' on DBus", name);
3752+ g_main_loop_quit(mainloop);
3753+ return;
3754+}
3755+
3756+int
3757+main (int argc, char ** argv)
3758+{
3759+ g_type_init();
3760+
3761+ g_bus_own_name(G_BUS_TYPE_SESSION,
3762+ "org.dbusmenu.test",
3763+ G_BUS_NAME_OWNER_FLAGS_NONE,
3764+ on_bus,
3765+ NULL,
3766+ name_lost,
3767+ NULL,
3768+ NULL);
3769+
3770 g_timeout_add_seconds(3, timer_func, NULL);
3771
3772 mainloop = g_main_loop_new(NULL, FALSE);
3773
3774=== modified file 'tests/test-glib-layout-server.c'
3775--- tests/test-glib-layout-server.c 2010-08-02 22:03:59 +0000
3776+++ tests/test-glib-layout-server.c 2010-12-08 03:19:55 +0000
3777@@ -20,11 +20,7 @@
3778 */
3779
3780 #include <glib.h>
3781-
3782-#include <dbus/dbus.h>
3783-#include <dbus/dbus-glib.h>
3784-#include <dbus/dbus-glib-lowlevel.h>
3785-#include <dbus/dbus-glib-bindings.h>
3786+#include <gio/gio.h>
3787
3788 #include <libdbusmenu-glib/server.h>
3789 #include <libdbusmenu-glib/menuitem.h>
3790@@ -72,33 +68,38 @@
3791 return TRUE;
3792 }
3793
3794+static void
3795+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
3796+{
3797+ server = dbusmenu_server_new("/org/test");
3798+
3799+ timer_func(NULL);
3800+ g_timeout_add(2500, timer_func, NULL);
3801+
3802+ return;
3803+}
3804+
3805+static void
3806+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
3807+{
3808+ g_error("Unable to get name '%s' on DBus", name);
3809+ g_main_loop_quit(mainloop);
3810+ return;
3811+}
3812+
3813 int
3814 main (int argc, char ** argv)
3815 {
3816- GError * error = NULL;
3817-
3818 g_type_init();
3819
3820- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
3821- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
3822-
3823- DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
3824- guint nameret = 0;
3825-
3826- if (!org_freedesktop_DBus_request_name(bus_proxy, "org.dbusmenu.test", 0, &nameret, &error)) {
3827- g_error("Unable to call to request name");
3828- return 1;
3829- }
3830-
3831- if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
3832- g_error("Unable to get name");
3833- return 1;
3834- }
3835-
3836- server = dbusmenu_server_new("/org/test");
3837-
3838- timer_func(NULL);
3839- g_timeout_add(2500, timer_func, NULL);
3840+ g_bus_own_name(G_BUS_TYPE_SESSION,
3841+ "org.dbusmenu.test",
3842+ G_BUS_NAME_OWNER_FLAGS_NONE,
3843+ on_bus,
3844+ NULL,
3845+ name_lost,
3846+ NULL,
3847+ NULL);
3848
3849 mainloop = g_main_loop_new(NULL, FALSE);
3850 g_main_loop_run(mainloop);
3851
3852=== modified file 'tests/test-glib-objects.c'
3853--- tests/test-glib-objects.c 2010-02-05 05:40:32 +0000
3854+++ tests/test-glib-objects.c 2010-12-08 03:19:55 +0000
3855@@ -77,17 +77,17 @@
3856 {
3857 /* Build a menu item */
3858 DbusmenuMenuitem * item = dbusmenu_menuitem_new();
3859- const GValue * out = NULL;
3860+ GVariant * out = NULL;
3861
3862 /* Test to make sure it's a happy object */
3863 g_assert(item != NULL);
3864
3865 /* Setting a string */
3866 dbusmenu_menuitem_property_set(item, "string", "value");
3867- out = dbusmenu_menuitem_property_get_value(item, "string");
3868+ out = dbusmenu_menuitem_property_get_variant(item, "string");
3869 g_assert(out != NULL);
3870- g_assert(G_VALUE_TYPE(out) == G_TYPE_STRING);
3871- g_assert(!g_strcmp0(g_value_get_string(out), "value"));
3872+ g_assert(g_variant_type_equal(g_variant_get_type(out), G_VARIANT_TYPE_STRING));
3873+ g_assert(!g_strcmp0(g_variant_get_string(out, NULL), "value"));
3874 g_assert(!g_strcmp0(dbusmenu_menuitem_property_get(item, "string"), "value"));
3875
3876 g_object_unref(item);
3877@@ -101,17 +101,17 @@
3878 {
3879 /* Build a menu item */
3880 DbusmenuMenuitem * item = dbusmenu_menuitem_new();
3881- const GValue * out = NULL;
3882+ GVariant * out = NULL;
3883
3884 /* Test to make sure it's a happy object */
3885 g_assert(item != NULL);
3886
3887 /* Setting a string */
3888 dbusmenu_menuitem_property_set_int(item, "int", 12345);
3889- out = dbusmenu_menuitem_property_get_value(item, "int");
3890+ out = dbusmenu_menuitem_property_get_variant(item, "int");
3891 g_assert(out != NULL);
3892- g_assert(G_VALUE_TYPE(out) == G_TYPE_INT);
3893- g_assert(g_value_get_int(out) == 12345);
3894+ g_assert(g_variant_type_equal(g_variant_get_type(out), G_VARIANT_TYPE_INT32));
3895+ g_assert(g_variant_get_int32(out) == 12345);
3896 g_assert(dbusmenu_menuitem_property_get_int(item, "int") == 12345);
3897
3898 g_object_unref(item);
3899@@ -125,18 +125,18 @@
3900 {
3901 /* Build a menu item */
3902 DbusmenuMenuitem * item = dbusmenu_menuitem_new();
3903- const GValue * out = NULL;
3904+ GVariant * out = NULL;
3905
3906 /* Test to make sure it's a happy object */
3907 g_assert(item != NULL);
3908
3909 /* Setting a string */
3910 dbusmenu_menuitem_property_set_bool(item, "boolean", TRUE);
3911- out = dbusmenu_menuitem_property_get_value(item, "boolean");
3912+ out = dbusmenu_menuitem_property_get_variant(item, "boolean");
3913 g_assert(out != NULL);
3914- g_assert(G_VALUE_TYPE(out) == G_TYPE_BOOLEAN);
3915- g_assert(g_value_get_boolean(out));
3916- g_assert(dbusmenu_menuitem_property_get_int(item, "boolean"));
3917+ g_assert(g_variant_type_equal(g_variant_get_type(out), G_VARIANT_TYPE_BOOLEAN));
3918+ g_assert(g_variant_get_boolean(out));
3919+ /* g_assert(dbusmenu_menuitem_property_get_int(item, "boolean") == 0); */
3920
3921 g_object_unref(item);
3922
3923@@ -177,7 +177,7 @@
3924
3925 /* A helper to put a value into a pointer for eval. */
3926 static void
3927-test_object_menuitem_props_signals_helper (DbusmenuMenuitem * mi, gchar * property, GValue * value, GValue ** out)
3928+test_object_menuitem_props_signals_helper (DbusmenuMenuitem * mi, gchar * property, GVariant * value, GVariant ** out)
3929 {
3930 if (!g_strcmp0(property, "swapper")) {
3931 *out = value;
3932@@ -194,7 +194,7 @@
3933 {
3934 /* Build a menu item */
3935 DbusmenuMenuitem * item = dbusmenu_menuitem_new();
3936- GValue * out = NULL;
3937+ GVariant * out = NULL;
3938
3939 /* Test to make sure it's a happy object */
3940 g_assert(item != NULL);
3941@@ -205,25 +205,25 @@
3942 /* Setting a boolean */
3943 dbusmenu_menuitem_property_set_bool(item, "swapper", TRUE);
3944 g_assert(out != NULL);
3945- g_assert(g_value_get_boolean(out));
3946+ g_assert(g_variant_get_boolean(out));
3947 out = NULL;
3948
3949 /* Setting a int */
3950 dbusmenu_menuitem_property_set_int(item, "swapper", 5432);
3951 g_assert(out != NULL);
3952- g_assert(g_value_get_int(out) == 5432);
3953+ g_assert(g_variant_get_int32(out) == 5432);
3954 out = NULL;
3955
3956 /* Setting a string */
3957 dbusmenu_menuitem_property_set(item, "swapper", "mystring");
3958 g_assert(out != NULL);
3959- g_assert(!g_strcmp0(g_value_get_string(out), "mystring"));
3960+ g_assert(!g_strcmp0(g_variant_get_string(out, NULL), "mystring"));
3961 out = NULL;
3962
3963 /* Setting a boolean */
3964 dbusmenu_menuitem_property_set_bool(item, "swapper", FALSE);
3965 g_assert(out != NULL);
3966- g_assert(!g_value_get_boolean(out));
3967+ g_assert(!g_variant_get_boolean(out));
3968 out = NULL;
3969
3970 g_object_unref(item);
3971
3972=== modified file 'tests/test-glib-properties-server.c'
3973--- tests/test-glib-properties-server.c 2010-02-05 18:10:47 +0000
3974+++ tests/test-glib-properties-server.c 2010-12-08 03:19:55 +0000
3975@@ -20,10 +20,7 @@
3976 */
3977
3978 #include <glib.h>
3979-
3980-#include <dbus/dbus.h>
3981-#include <dbus/dbus-glib.h>
3982-#include <dbus/dbus-glib-lowlevel.h>
3983+#include <gio/gio.h>
3984
3985 #include <libdbusmenu-glib/menuitem.h>
3986 #include <libdbusmenu-glib/server.h>
3987@@ -91,8 +88,6 @@
3988 {
3989 g_type_init();
3990
3991- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
3992-
3993 server = dbusmenu_server_new("/org/test");
3994
3995 timer_func(NULL);
3996
3997=== modified file 'tests/test-glib-proxy-client.c'
3998--- tests/test-glib-proxy-client.c 2010-02-19 21:41:56 +0000
3999+++ tests/test-glib-proxy-client.c 2010-12-08 03:19:55 +0000
4000@@ -150,10 +150,9 @@
4001 g_main_loop_quit(mainloop);
4002 }
4003
4004- GValue value = {0};
4005- g_value_init(&value, G_TYPE_INT);
4006- g_value_set_int(&value, 0);
4007- dbusmenu_menuitem_handle_event(menuroot, "clicked", &value, layouton);
4008+ GVariant * value = g_variant_new("i", 0);
4009+ dbusmenu_menuitem_handle_event(menuroot, "clicked", value, layouton);
4010+ g_variant_unref(value);
4011
4012 return FALSE;
4013 }
4014
4015=== modified file 'tests/test-glib-proxy-proxy.c'
4016--- tests/test-glib-proxy-proxy.c 2010-02-25 03:58:50 +0000
4017+++ tests/test-glib-proxy-proxy.c 2010-12-08 03:19:55 +0000
4018@@ -1,9 +1,5 @@
4019 #include <glib.h>
4020-
4021-#include <dbus/dbus.h>
4022-#include <dbus/dbus-glib.h>
4023-#include <dbus/dbus-glib-lowlevel.h>
4024-#include <dbus/dbus-glib-bindings.h>
4025+#include <gio/gio.h>
4026
4027 #include <libdbusmenu-glib/menuitem.h>
4028 #include <libdbusmenu-glib/menuitem-proxy.h>
4029@@ -32,6 +28,24 @@
4030 return;
4031 }
4032
4033+static void
4034+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
4035+{
4036+ client = dbusmenu_client_new((gchar *)user_data, "/org/test");
4037+
4038+ g_signal_connect(client, DBUSMENU_CLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(root_changed), server);
4039+
4040+ return;
4041+}
4042+
4043+static void
4044+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
4045+{
4046+ g_error("Unable to get name '%s' on DBus", name);
4047+ g_main_loop_quit(mainloop);
4048+ return;
4049+}
4050+
4051 int
4052 main (int argc, char ** argv)
4053 {
4054@@ -47,28 +61,16 @@
4055
4056 g_debug("I am '%s' and I'm proxying '%s'", whoami, myproxy);
4057
4058- GError * error = NULL;
4059- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
4060-
4061- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(connection)));
4062-
4063- DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
4064- guint nameret = 0;
4065-
4066- if (!org_freedesktop_DBus_request_name(bus_proxy, whoami, 0, &nameret, &error)) {
4067- g_error("Unable to call to request name");
4068- return 1;
4069- }
4070-
4071- if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
4072- g_error("Unable to get name");
4073- return 1;
4074- }
4075-
4076 server = dbusmenu_server_new("/org/test");
4077- client = dbusmenu_client_new(myproxy, "/org/test");
4078
4079- g_signal_connect(client, DBUSMENU_CLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(root_changed), server);
4080+ g_bus_own_name(G_BUS_TYPE_SESSION,
4081+ whoami,
4082+ G_BUS_NAME_OWNER_FLAGS_NONE,
4083+ on_bus,
4084+ NULL,
4085+ name_lost,
4086+ myproxy,
4087+ NULL);
4088
4089 mainloop = g_main_loop_new(NULL, FALSE);
4090 g_main_loop_run(mainloop);
4091
4092=== modified file 'tests/test-glib-proxy-server.c'
4093--- tests/test-glib-proxy-server.c 2010-02-19 21:16:29 +0000
4094+++ tests/test-glib-proxy-server.c 2010-12-08 03:19:55 +0000
4095@@ -20,11 +20,7 @@
4096 */
4097
4098 #include <glib.h>
4099-
4100-#include <dbus/dbus.h>
4101-#include <dbus/dbus-glib.h>
4102-#include <dbus/dbus-glib-lowlevel.h>
4103-#include <dbus/dbus-glib-bindings.h>
4104+#include <gio/gio.h>
4105
4106 #include <libdbusmenu-glib/menuitem.h>
4107 #include <libdbusmenu-glib/server.h>
4108@@ -104,31 +100,36 @@
4109 return;
4110 }
4111
4112+static void
4113+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
4114+{
4115+ server = dbusmenu_server_new("/org/test");
4116+ layout_change(NULL, 0, NULL);
4117+
4118+ return;
4119+}
4120+
4121+static void
4122+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
4123+{
4124+ g_error("Unable to get name '%s' on DBus", name);
4125+ g_main_loop_quit(mainloop);
4126+ return;
4127+}
4128+
4129 int
4130 main (int argc, char ** argv)
4131 {
4132 g_type_init();
4133
4134- GError * error = NULL;
4135- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
4136-
4137- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(connection)));
4138-
4139- DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
4140- guint nameret = 0;
4141-
4142- if (!org_freedesktop_DBus_request_name(bus_proxy, "test.proxy.server", 0, &nameret, &error)) {
4143- g_error("Unable to call to request name");
4144- return 1;
4145- }
4146-
4147- if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
4148- g_error("Unable to get name");
4149- return 1;
4150- }
4151-
4152- server = dbusmenu_server_new("/org/test");
4153- layout_change(NULL, 0, NULL);
4154+ g_bus_own_name(G_BUS_TYPE_SESSION,
4155+ "test.proxy.server",
4156+ G_BUS_NAME_OWNER_FLAGS_NONE,
4157+ on_bus,
4158+ NULL,
4159+ name_lost,
4160+ NULL,
4161+ NULL);
4162
4163 mainloop = g_main_loop_new(NULL, FALSE);
4164 g_main_loop_run(mainloop);
4165
4166=== modified file 'tests/test-glib-simple-items.c'
4167--- tests/test-glib-simple-items.c 2009-09-30 19:58:04 +0000
4168+++ tests/test-glib-simple-items.c 2010-12-08 03:19:55 +0000
4169@@ -1,6 +1,3 @@
4170-#include <dbus/dbus-glib.h>
4171-#include <dbus/dbus-glib-bindings.h>
4172-
4173 #include <libdbusmenu-glib/server.h>
4174 #include <libdbusmenu-glib/menuitem.h>
4175
4176
4177=== modified file 'tests/test-glib-submenu-server.c'
4178--- tests/test-glib-submenu-server.c 2010-06-08 15:19:37 +0000
4179+++ tests/test-glib-submenu-server.c 2010-12-08 03:19:55 +0000
4180@@ -20,11 +20,7 @@
4181 */
4182
4183 #include <glib.h>
4184-
4185-#include <dbus/dbus.h>
4186-#include <dbus/dbus-glib.h>
4187-#include <dbus/dbus-glib-lowlevel.h>
4188-#include <dbus/dbus-glib-bindings.h>
4189+#include <gio/gio.h>
4190
4191 #include <libdbusmenu-glib/server.h>
4192 #include <libdbusmenu-glib/menuitem.h>
4193@@ -72,33 +68,38 @@
4194 return TRUE;
4195 }
4196
4197+static void
4198+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
4199+{
4200+ server = dbusmenu_server_new("/org/test");
4201+
4202+ timer_func(NULL);
4203+ g_timeout_add(2500, timer_func, NULL);
4204+
4205+ return;
4206+}
4207+
4208+static void
4209+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
4210+{
4211+ g_error("Unable to get name '%s' on DBus", name);
4212+ g_main_loop_quit(mainloop);
4213+ return;
4214+}
4215+
4216 int
4217 main (int argc, char ** argv)
4218 {
4219- GError * error = NULL;
4220-
4221 g_type_init();
4222
4223- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
4224- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
4225-
4226- DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
4227- guint nameret = 0;
4228-
4229- if (!org_freedesktop_DBus_request_name(bus_proxy, "org.dbusmenu.test", 0, &nameret, &error)) {
4230- g_error("Unable to call to request name");
4231- return 1;
4232- }
4233-
4234- if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
4235- g_error("Unable to get name");
4236- return 1;
4237- }
4238-
4239- server = dbusmenu_server_new("/org/test");
4240-
4241- timer_func(NULL);
4242- g_timeout_add(2500, timer_func, NULL);
4243+ g_bus_own_name(G_BUS_TYPE_SESSION,
4244+ "org.dbusmenu.test",
4245+ G_BUS_NAME_OWNER_FLAGS_NONE,
4246+ on_bus,
4247+ NULL,
4248+ name_lost,
4249+ NULL,
4250+ NULL);
4251
4252 mainloop = g_main_loop_new(NULL, FALSE);
4253 g_main_loop_run(mainloop);
4254
4255=== modified file 'tests/test-gtk-label-server.c'
4256--- tests/test-gtk-label-server.c 2010-06-28 20:55:53 +0000
4257+++ tests/test-gtk-label-server.c 2010-12-08 03:19:55 +0000
4258@@ -20,11 +20,7 @@
4259 */
4260
4261 #include <glib.h>
4262-
4263-#include <dbus/dbus.h>
4264-#include <dbus/dbus-glib.h>
4265-#include <dbus/dbus-glib-lowlevel.h>
4266-#include <dbus/dbus-glib-bindings.h>
4267+#include <gio/gio.h>
4268
4269 #include <libdbusmenu-glib/menuitem.h>
4270 #include <libdbusmenu-glib/server.h>
4271@@ -53,6 +49,25 @@
4272 return TRUE;
4273 }
4274
4275+static void
4276+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
4277+{
4278+ server = dbusmenu_server_new("/org/test");
4279+
4280+ timer_func(NULL);
4281+ g_timeout_add_seconds(5, timer_func, NULL);
4282+
4283+ return;
4284+}
4285+
4286+static void
4287+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
4288+{
4289+ g_error("Unable to get name '%s' on DBus", name);
4290+ g_main_loop_quit(mainloop);
4291+ return;
4292+}
4293+
4294 int
4295 main (int argc, char ** argv)
4296 {
4297@@ -73,26 +88,15 @@
4298 root_array = json_node_get_array(root_node);
4299 g_debug("%d layouts in test description '%s'", json_array_get_length(root_array), argv[1]);
4300
4301- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
4302- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
4303-
4304- DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
4305- guint nameret = 0;
4306-
4307- if (!org_freedesktop_DBus_request_name(bus_proxy, "glib.label.test", 0, &nameret, &error)) {
4308- g_error("Unable to call to request name");
4309- return 1;
4310- }
4311-
4312- if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
4313- g_error("Unable to get name");
4314- return 1;
4315- }
4316-
4317- server = dbusmenu_server_new("/org/test");
4318-
4319- timer_func(NULL);
4320- g_timeout_add_seconds(5, timer_func, NULL);
4321+
4322+ g_bus_own_name(G_BUS_TYPE_SESSION,
4323+ "glib.label.test",
4324+ G_BUS_NAME_OWNER_FLAGS_NONE,
4325+ on_bus,
4326+ NULL,
4327+ name_lost,
4328+ NULL,
4329+ NULL);
4330
4331 mainloop = g_main_loop_new(NULL, FALSE);
4332 g_main_loop_run(mainloop);
4333
4334=== modified file 'tests/test-gtk-objects.c'
4335--- tests/test-gtk-objects.c 2010-06-14 19:52:26 +0000
4336+++ tests/test-gtk-objects.c 2010-12-08 03:19:55 +0000
4337@@ -72,7 +72,7 @@
4338 g_object_unref(pixbuf);
4339
4340 /* Check to see if it's set */
4341- const GValue * val = dbusmenu_menuitem_property_get_value(item, prop_name);
4342+ GVariant * val = dbusmenu_menuitem_property_get_variant(item, prop_name);
4343 g_assert(val != NULL);
4344
4345 /* Get the pixbuf back! */
4346@@ -105,7 +105,7 @@
4347 g_assert(success);
4348
4349 /* Check for value */
4350- const GValue * val = dbusmenu_menuitem_property_get_value(item, DBUSMENU_MENUITEM_PROP_SHORTCUT);
4351+ GVariant * val = dbusmenu_menuitem_property_get_variant(item, DBUSMENU_MENUITEM_PROP_SHORTCUT);
4352 g_assert(val != NULL);
4353
4354 /* Check to see if we love it */
4355
4356=== modified file 'tests/test-gtk-reorder-server.c'
4357--- tests/test-gtk-reorder-server.c 2010-07-22 09:31:48 +0000
4358+++ tests/test-gtk-reorder-server.c 2010-12-08 03:19:55 +0000
4359@@ -20,11 +20,7 @@
4360 */
4361
4362 #include <glib.h>
4363-
4364-#include <dbus/dbus.h>
4365-#include <dbus/dbus-glib.h>
4366-#include <dbus/dbus-glib-lowlevel.h>
4367-#include <dbus/dbus-glib-bindings.h>
4368+#include <gio/gio.h>
4369
4370 #include <libdbusmenu-glib/menuitem.h>
4371 #include <libdbusmenu-glib/server.h>
4372@@ -73,29 +69,9 @@
4373 return TRUE;
4374 }
4375
4376-int
4377-main (int argc, char ** argv)
4378+static void
4379+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
4380 {
4381- GError * error = NULL;
4382-
4383- g_type_init();
4384-
4385- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
4386- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
4387-
4388- DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
4389- guint nameret = 0;
4390-
4391- if (!org_freedesktop_DBus_request_name(bus_proxy, "glib.label.test", 0, &nameret, &error)) {
4392- g_error("Unable to call to request name");
4393- return 1;
4394- }
4395-
4396- if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
4397- g_error("Unable to get name");
4398- return 1;
4399- }
4400-
4401 server = dbusmenu_server_new("/org/test");
4402 root = dbusmenu_menuitem_new();
4403 dbusmenu_server_set_root(server, root);
4404@@ -109,6 +85,31 @@
4405 timer_func(NULL);
4406 g_timeout_add_seconds(5, timer_func, NULL);
4407
4408+ return;
4409+}
4410+
4411+static void
4412+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
4413+{
4414+ g_error("Unable to get name '%s' on DBus", name);
4415+ g_main_loop_quit(mainloop);
4416+ return;
4417+}
4418+
4419+int
4420+main (int argc, char ** argv)
4421+{
4422+ g_type_init();
4423+
4424+ g_bus_own_name(G_BUS_TYPE_SESSION,
4425+ "glib.label.test",
4426+ G_BUS_NAME_OWNER_FLAGS_NONE,
4427+ on_bus,
4428+ NULL,
4429+ name_lost,
4430+ NULL,
4431+ NULL);
4432+
4433 mainloop = g_main_loop_new(NULL, FALSE);
4434 g_main_loop_run(mainloop);
4435
4436
4437=== modified file 'tests/test-gtk-shortcut-server.c'
4438--- tests/test-gtk-shortcut-server.c 2010-06-15 19:42:35 +0000
4439+++ tests/test-gtk-shortcut-server.c 2010-12-08 03:19:55 +0000
4440@@ -20,13 +20,9 @@
4441 */
4442
4443 #include <glib.h>
4444+#include <gio/gio.h>
4445 #include <gdk/gdkkeysyms.h>
4446
4447-#include <dbus/dbus.h>
4448-#include <dbus/dbus-glib.h>
4449-#include <dbus/dbus-glib-lowlevel.h>
4450-#include <dbus/dbus-glib-bindings.h>
4451-
4452 #include <libdbusmenu-glib/menuitem.h>
4453 #include <libdbusmenu-glib/server.h>
4454 #include <libdbusmenu-gtk/menuitem.h>
4455@@ -61,33 +57,38 @@
4456 return;
4457 }
4458
4459+static void
4460+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
4461+{
4462+ server = dbusmenu_server_new("/org/test");
4463+ build_menu();
4464+
4465+ g_timeout_add_seconds(10, timer_func, NULL);
4466+
4467+ return;
4468+}
4469+
4470+static void
4471+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
4472+{
4473+ g_error("Unable to get name '%s' on DBus", name);
4474+ g_main_loop_quit(mainloop);
4475+ return;
4476+}
4477+
4478 int
4479 main (int argc, char ** argv)
4480 {
4481- GError * error = NULL;
4482-
4483 g_type_init();
4484
4485- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
4486- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
4487-
4488- DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
4489- guint nameret = 0;
4490-
4491- if (!org_freedesktop_DBus_request_name(bus_proxy, "glib.label.test", 0, &nameret, &error)) {
4492- g_error("Unable to call to request name");
4493- return 1;
4494- }
4495-
4496- if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
4497- g_error("Unable to get name");
4498- return 1;
4499- }
4500-
4501- server = dbusmenu_server_new("/org/test");
4502- build_menu();
4503-
4504- g_timeout_add_seconds(10, timer_func, NULL);
4505+ g_bus_own_name(G_BUS_TYPE_SESSION,
4506+ "glib.label.test",
4507+ G_BUS_NAME_OWNER_FLAGS_NONE,
4508+ on_bus,
4509+ NULL,
4510+ name_lost,
4511+ NULL,
4512+ NULL);
4513
4514 mainloop = g_main_loop_new(NULL, FALSE);
4515 g_main_loop_run(mainloop);
4516
4517=== modified file 'tests/test-gtk-submenu-server.c'
4518--- tests/test-gtk-submenu-server.c 2010-08-20 21:52:02 +0000
4519+++ tests/test-gtk-submenu-server.c 2010-12-08 03:19:55 +0000
4520@@ -20,11 +20,7 @@
4521 */
4522
4523 #include <glib.h>
4524-
4525-#include <dbus/dbus.h>
4526-#include <dbus/dbus-glib.h>
4527-#include <dbus/dbus-glib-lowlevel.h>
4528-#include <dbus/dbus-glib-bindings.h>
4529+#include <gio/gio.h>
4530
4531 #include <libdbusmenu-glib/menuitem.h>
4532 #include <libdbusmenu-glib/server.h>
4533@@ -59,29 +55,9 @@
4534 return item;
4535 }
4536
4537-int
4538-main (int argc, char ** argv)
4539+static void
4540+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
4541 {
4542- GError * error = NULL;
4543-
4544- g_type_init();
4545-
4546- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
4547- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
4548-
4549- DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
4550- guint nameret = 0;
4551-
4552- if (!org_freedesktop_DBus_request_name(bus_proxy, "glib.label.test", 0, &nameret, &error)) {
4553- g_error("Unable to call to request name");
4554- return 1;
4555- }
4556-
4557- if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
4558- g_error("Unable to get name");
4559- return 1;
4560- }
4561-
4562 DbusmenuServer * server = dbusmenu_server_new("/org/test");
4563 DbusmenuMenuitem * root = dbusmenu_menuitem_new();
4564 dbusmenu_server_set_root(server, root);
4565@@ -101,6 +77,31 @@
4566
4567 g_timeout_add_seconds(4, show_item, item);
4568
4569+ return;
4570+}
4571+
4572+static void
4573+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
4574+{
4575+ g_error("Unable to get name '%s' on DBus", name);
4576+ g_main_loop_quit(mainloop);
4577+ return;
4578+}
4579+
4580+int
4581+main (int argc, char ** argv)
4582+{
4583+ g_type_init();
4584+
4585+ g_bus_own_name(G_BUS_TYPE_SESSION,
4586+ "glib.label.test",
4587+ G_BUS_NAME_OWNER_FLAGS_NONE,
4588+ on_bus,
4589+ NULL,
4590+ name_lost,
4591+ NULL,
4592+ NULL);
4593+
4594 g_timeout_add_seconds(6, timer_func, NULL);
4595
4596 mainloop = g_main_loop_new(NULL, FALSE);
4597
4598=== modified file 'tests/test-json-01.json'
4599--- tests/test-json-01.json 2010-08-12 16:11:13 +0000
4600+++ tests/test-json-01.json 2010-12-08 03:19:55 +0000
4601@@ -1,127 +1,127 @@
4602 {
4603 "id": 0,
4604- "children-display": "submenu",
4605+ "children-display": 'submenu',
4606 "submenu": [
4607 {
4608 "id": 5,
4609- "children-display": "submenu",
4610+ "children-display": 'submenu',
4611 "enabled": true,
4612- "label": "File",
4613+ "label": 'File',
4614 "visible": true,
4615 "submenu": [
4616 {
4617 "id": 6,
4618 "enabled": true,
4619- "label": "Quit",
4620- "shortcut": [["Control", "q"]],
4621+ "label": 'Quit',
4622+ "shortcut": [['Control', 'q']],
4623 "visible": true
4624 },
4625 {
4626 "id": 7,
4627 "enabled": true,
4628- "label": "Close all",
4629- "shortcut": [["Control", "Shift", "w"]],
4630+ "label": 'Close all',
4631+ "shortcut": [['Control', 'Shift', 'w']],
4632 "visible": true
4633 },
4634 {
4635 "id": 8,
4636 "enabled": true,
4637- "label": "Close",
4638- "shortcut": [["Control", "w"]],
4639+ "label": 'Close',
4640+ "shortcut": [['Control', 'w']],
4641 "visible": true
4642 },
4643 {
4644 "id": 9,
4645- "type": "separator"
4646+ "type": 'separator'
4647 },
4648 {
4649 "id": 10,
4650 "enabled": true,
4651- "label": "Send by Email...",
4652+ "label": 'Send by Email...',
4653 "visible": true
4654 },
4655 {
4656 "id": 11,
4657 "enabled": true,
4658- "label": "Print...",
4659- "shortcut": [["Control", "p"]],
4660+ "label": 'Print...',
4661+ "shortcut": [['Control', 'p']],
4662 "visible": true
4663 },
4664 {
4665 "id": 12,
4666 "enabled": true,
4667- "label": "Page Setup",
4668+ "label": 'Page Setup',
4669 "visible": true
4670 },
4671 {
4672 "id": 13,
4673- "type": "separator"
4674+ "type": 'separator'
4675 },
4676 {
4677 "id": 14,
4678 "enabled": true,
4679- "label": "Revert",
4680+ "label": 'Revert',
4681 "visible": true
4682 },
4683 {
4684 "id": 15,
4685 "enabled": true,
4686- "label": "Save as Template...",
4687+ "label": 'Save as Template...',
4688 "visible": true
4689 },
4690 {
4691 "id": 16,
4692 "enabled": true,
4693- "label": "Save a Copy...",
4694+ "label": 'Save a Copy...',
4695 "visible": true
4696 },
4697 {
4698 "id": 17,
4699 "enabled": true,
4700- "label": "Save As...",
4701- "shortcut": [["Control", "Shift", "s"]],
4702+ "label": 'Save As...',
4703+ "shortcut": [['Control', 'Shift', 's']],
4704 "visible": true
4705 },
4706 {
4707 "id": 18,
4708 "enabled": true,
4709- "label": "Save",
4710- "shortcut": [["Control", "s"]],
4711+ "label": 'Save',
4712+ "shortcut": [['Control', 's']],
4713 "visible": true
4714 },
4715 {
4716 "id": 19,
4717- "type": "separator"
4718+ "type": 'separator'
4719 },
4720 {
4721 "id": 20,
4722- "children-display": "submenu",
4723+ "children-display": 'submenu',
4724 "enabled": true,
4725- "label": "Open Recent",
4726+ "label": 'Open Recent',
4727 "visible": true,
4728 "submenu": [
4729 {
4730 "id": 21,
4731 "enabled": true,
4732- "label": "Document History",
4733+ "label": 'Document History',
4734 "visible": true
4735 },
4736 {
4737 "id": 22,
4738- "type": "separator"
4739+ "type": 'separator'
4740 },
4741 {
4742 "id": 23,
4743 "enabled": true,
4744- "label": "giggity.jpg",
4745- "shortcut": [["Control", "2"]],
4746+ "label": 'giggity.jpg',
4747+ "shortcut": [['Control', '2']],
4748 "visible": true
4749 },
4750 {
4751 "id": 24,
4752 "enabled": true,
4753- "label": "Icon Height.svg",
4754- "shortcut": [["Control", "1"]],
4755+ "label": 'Icon Height.svg',
4756+ "shortcut": [['Control', '1']],
4757 "visible": true
4758 }
4759 ]
4760@@ -129,150 +129,150 @@
4761 {
4762 "id": 25,
4763 "enabled": true,
4764- "label": "Open Location...",
4765+ "label": 'Open Location...',
4766 "visible": true
4767 },
4768 {
4769 "id": 26,
4770 "enabled": true,
4771- "label": "Open as Layers...",
4772- "shortcut": [["Control", "Alt", "o"]],
4773+ "label": 'Open as Layers...',
4774+ "shortcut": [['Control', 'Alt', 'o']],
4775 "visible": true
4776 },
4777 {
4778 "id": 27,
4779 "enabled": true,
4780- "label": "Open...",
4781- "shortcut": [["Control", "o"]],
4782+ "label": 'Open...',
4783+ "shortcut": [['Control', 'o']],
4784 "visible": true
4785 },
4786 {
4787 "id": 28,
4788- "children-display": "submenu",
4789+ "children-display": 'submenu',
4790 "enabled": true,
4791- "label": "Create",
4792+ "label": 'Create',
4793 "visible": true,
4794 "submenu": [
4795 {
4796 "id": 29,
4797- "children-display": "submenu",
4798+ "children-display": 'submenu',
4799 "enabled": true,
4800- "label": "Web Page Themes",
4801+ "label": 'Web Page Themes',
4802 "visible": true,
4803 "submenu": [
4804 {
4805 "id": 30,
4806- "children-display": "submenu",
4807+ "children-display": 'submenu',
4808 "enabled": true,
4809- "label": "Classic.Gimp.Org",
4810+ "label": 'Classic.Gimp.Org',
4811 "visible": true,
4812 "submenu": [
4813 {
4814 "id": 31,
4815 "enabled": true,
4816- "label": "Tube Sub-Sub-Button Label...",
4817+ "label": 'Tube Sub-Sub-Button Label...',
4818 "visible": true
4819 },
4820 {
4821 "id": 32,
4822 "enabled": true,
4823- "label": "Tube Sub-Button Label...",
4824+ "label": 'Tube Sub-Button Label...',
4825 "visible": true
4826 },
4827 {
4828 "id": 33,
4829 "enabled": true,
4830- "label": "Tube Button Label...",
4831+ "label": 'Tube Button Label...',
4832 "visible": true
4833 },
4834 {
4835 "id": 34,
4836 "enabled": true,
4837- "label": "Small Header...",
4838+ "label": 'Small Header...',
4839 "visible": true
4840 },
4841 {
4842 "id": 35,
4843 "enabled": true,
4844- "label": "General Tube Labels...",
4845+ "label": 'General Tube Labels...',
4846 "visible": true
4847 },
4848 {
4849 "id": 36,
4850 "enabled": true,
4851- "label": "Big Header...",
4852+ "label": 'Big Header...',
4853 "visible": true
4854 }
4855 ]
4856 },
4857 {
4858 "id": 37,
4859- "children-display": "submenu",
4860+ "children-display": 'submenu',
4861 "enabled": true,
4862- "label": "Beveled Pattern",
4863+ "label": 'Beveled Pattern',
4864 "visible": true,
4865 "submenu": [
4866 {
4867 "id": 38,
4868 "enabled": true,
4869- "label": "Hrule...",
4870+ "label": 'Hrule...',
4871 "visible": true
4872 },
4873 {
4874 "id": 39,
4875 "enabled": true,
4876- "label": "Heading...",
4877+ "label": 'Heading...',
4878 "visible": true
4879 },
4880 {
4881 "id": 40,
4882 "enabled": true,
4883- "label": "Button...",
4884+ "label": 'Button...',
4885 "visible": true
4886 },
4887 {
4888 "id": 41,
4889 "enabled": true,
4890- "label": "Bullet...",
4891+ "label": 'Bullet...',
4892 "visible": true
4893 },
4894 {
4895 "id": 42,
4896 "enabled": true,
4897- "label": "Arrow...",
4898+ "label": 'Arrow...',
4899 "visible": true
4900 }
4901 ]
4902 },
4903 {
4904 "id": 43,
4905- "children-display": "submenu",
4906+ "children-display": 'submenu',
4907 "enabled": true,
4908- "label": "Alien Glow",
4909+ "label": 'Alien Glow',
4910 "visible": true,
4911 "submenu": [
4912 {
4913 "id": 44,
4914 "enabled": true,
4915- "label": "Hrule...",
4916+ "label": 'Hrule...',
4917 "visible": true
4918 },
4919 {
4920 "id": 45,
4921 "enabled": true,
4922- "label": "Button...",
4923+ "label": 'Button...',
4924 "visible": true
4925 },
4926 {
4927 "id": 46,
4928 "enabled": true,
4929- "label": "Bullet...",
4930+ "label": 'Bullet...',
4931 "visible": true
4932 },
4933 {
4934 "id": 47,
4935 "enabled": true,
4936- "label": "Arrow...",
4937+ "label": 'Arrow...',
4938 "visible": true
4939 }
4940 ]
4941@@ -281,274 +281,274 @@
4942 },
4943 {
4944 "id": 48,
4945- "children-display": "submenu",
4946+ "children-display": 'submenu',
4947 "enabled": true,
4948- "label": "Patterns",
4949+ "label": 'Patterns',
4950 "visible": true,
4951 "submenu": [
4952 {
4953 "id": 49,
4954 "enabled": true,
4955- "label": "Truchet...",
4956+ "label": 'Truchet...',
4957 "visible": true
4958 },
4959 {
4960 "id": 50,
4961 "enabled": true,
4962- "label": "Swirly...",
4963+ "label": 'Swirly...',
4964 "visible": true
4965 },
4966 {
4967 "id": 51,
4968 "enabled": true,
4969- "label": "Swirl-Tile...",
4970+ "label": 'Swirl-Tile...',
4971 "visible": true
4972 },
4973 {
4974 "id": 52,
4975 "enabled": true,
4976- "label": "Render Map...",
4977+ "label": 'Render Map...',
4978 "visible": true
4979 },
4980 {
4981 "id": 53,
4982 "enabled": true,
4983- "label": "Land...",
4984+ "label": 'Land...',
4985 "visible": true
4986 },
4987 {
4988 "id": 54,
4989 "enabled": true,
4990- "label": "Flatland...",
4991+ "label": 'Flatland...',
4992 "visible": true
4993 },
4994 {
4995 "id": 55,
4996 "enabled": true,
4997- "label": "Camouflage...",
4998+ "label": 'Camouflage...',
4999 "visible": true
5000 },
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches