Merge lp:~dbusmenu-team/libdbusmenu/ubuntu into lp:~ubuntu-desktop/libdbusmenu/ubuntu

Proposed by Ted Gould
Status: Merged
Merged at revision: not available
Proposed branch: lp:~dbusmenu-team/libdbusmenu/ubuntu
Merge into: lp:~ubuntu-desktop/libdbusmenu/ubuntu
Diff against target: 3422 lines (+1971/-343)
39 files modified
.bzrignore (+7/-0)
Makefile.am (+1/-1)
configure.ac (+4/-6)
debian/changelog (+82/-0)
debian/control (+10/-0)
libdbusmenu-glib/Makefile.am (+1/-0)
libdbusmenu-glib/client.c (+45/-42)
libdbusmenu-glib/client.h (+1/-1)
libdbusmenu-glib/dbus-menu.xml (+99/-29)
libdbusmenu-glib/menuitem-marshal.list (+1/-1)
libdbusmenu-glib/menuitem-private.h (+40/-0)
libdbusmenu-glib/menuitem.c (+216/-10)
libdbusmenu-glib/menuitem.h (+17/-2)
libdbusmenu-glib/server-marshal.list (+2/-1)
libdbusmenu-glib/server.c (+133/-40)
libdbusmenu-glib/server.h (+3/-3)
libdbusmenu-gtk/Makefile.am (+2/-0)
libdbusmenu-gtk/client.c (+102/-59)
libdbusmenu-gtk/genericmenuitem.c (+444/-0)
libdbusmenu-gtk/genericmenuitem.h (+91/-0)
libdbusmenu-qt/Makefile.am (+0/-29)
libdbusmenu-qt/dbusmenu-qt.pc.in (+0/-14)
libdbusmenu-qt/test.c (+0/-4)
libdbusmenu-qt/test.h (+0/-2)
tests/Makefile.am (+94/-21)
tests/dbusmenu-gtk/Makefile.am (+0/-43)
tests/dbusmenu-gtk/dbusMenuTest (+1/-1)
tests/dbusmenu-gtk/mago_tests/dbusmenu.py (+2/-2)
tests/dbusmenu-gtk/mago_tests/dbusmenu.xml (+10/-10)
tests/run-xvfb.sh (+7/-0)
tests/test-glib-layout-client.c (+2/-4)
tests/test-glib-layout-server.c (+17/-0)
tests/test-glib-objects.c (+278/-0)
tests/test-glib-properties-client.c (+1/-1)
tests/test-gtk-label-client.c (+5/-2)
tests/test-gtk-label.json (+63/-14)
tests/test-gtk-reorder-server.c (+1/-1)
tools/Makefile.am (+14/-0)
tools/dbusmenu-dumper.c (+175/-0)
To merge this branch: bzr merge lp:~dbusmenu-team/libdbusmenu/ubuntu
Reviewer Review Type Date Requested Status
DBus Menu Team Pending
Review via email: mp+17017@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Ted Gould (ted) wrote :

Official 0.2.0

lp:~dbusmenu-team/libdbusmenu/ubuntu updated
53. By Ken VanDine

* Upstream release 0.2.0
  - Remove unused libdbusmenu-qt
  - Changing API to be V0.2 for reals
  - Adding underline support
  - Test suite fixes and automation support
  - dbus-dumper tool
  - Switch to org.ayatana
  - Fixing the handling of typed properties, especially bools.
  - Adding GetChildren function for getting a single submenu
  - Starting to watch DBus if the proxy builds fail.
  - Test suite fixes
  - Fixing the consistency between the #defines and what
    was used in the code.
* debian/control, debian/libdbusmenu-tools.install: Setting
  up a package for the new dbusmenu-dumper tool.
* debian/control: Mentioning nicely that this will cause
  indicator-messages << 0.3 and indicator-session << 0.2 to
  break.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2009-12-10 18:53:54 +0000
3+++ .bzrignore 2010-01-08 14:45:24 +0000
4@@ -49,5 +49,12 @@
5 tests/test-gtk-reorder-server.c
6 tests/test-gtk-reorder-server
7 tests/test-gtk-reorder
8+tools/dbusmenu-dumper
9 libdbusmenu-[0-9].[0-9].[0-9].tar.gz
10 libdbusmenu-[0-9].[0-9].[0-9].tar.gz.asc
11+tests/test-mago
12+tests/*.bustle
13+libdbusmenu-gtk/libdbusmenu_gtk_la-genericmenuitem.lo
14+tests/test-glib-objects
15+tests/test-glib-objects-test
16+tests/test-glib-objects.xml
17
18=== modified file 'Makefile.am'
19--- Makefile.am 2009-12-10 18:39:41 +0000
20+++ Makefile.am 2010-01-08 14:45:24 +0000
21@@ -1,3 +1,3 @@
22
23-SUBDIRS = libdbusmenu-glib libdbusmenu-gtk libdbusmenu-qt tests po
24+SUBDIRS = libdbusmenu-glib libdbusmenu-gtk tools tests po
25
26
27=== modified file 'configure.ac'
28--- configure.ac 2009-12-10 18:48:47 +0000
29+++ configure.ac 2010-01-08 14:45:24 +0000
30@@ -1,11 +1,11 @@
31
32-AC_INIT(libdbusmenu, 0.1.8, ted@canonical.com)
33+AC_INIT(libdbusmenu, 0.2.0, ted@canonical.com)
34 AC_COPYRIGHT([Copyright 2009 Canonical])
35
36 AC_PREREQ(2.53)
37
38 AM_CONFIG_HEADER(config.h)
39-AM_INIT_AUTOMAKE(libdbusmenu, 0.1.8)
40+AM_INIT_AUTOMAKE(libdbusmenu, 0.2.0)
41
42 AM_MAINTAINER_MODE
43
44@@ -66,7 +66,7 @@
45 ###########################
46
47 LIBDBUSMENU_CURRENT=0
48-LIBDBUSMENU_REVISION=8
49+LIBDBUSMENU_REVISION=10
50 LIBDBUSMENU_AGE=0
51
52 AC_SUBST(LIBDBUSMENU_CURRENT)
53@@ -104,10 +104,8 @@
54 libdbusmenu-glib/dbusmenu-glib.pc
55 libdbusmenu-gtk/Makefile
56 libdbusmenu-gtk/dbusmenu-gtk.pc
57-libdbusmenu-qt/Makefile
58-libdbusmenu-qt/dbusmenu-qt.pc
59+tools/Makefile
60 tests/Makefile
61-tests/dbusmenu-gtk/Makefile
62 ])
63
64 ###########################
65
66=== modified file 'debian/changelog'
67--- debian/changelog 2009-12-10 19:23:37 +0000
68+++ debian/changelog 2010-01-08 14:45:24 +0000
69@@ -1,4 +1,86 @@
70+<<<<<<< TREE
71 libdbusmenu (0.1.8-0ubuntu1) lucid; urgency=low
72+=======
73+libdbusmenu (0.2.0-0ubuntu1~ppa1) karmic; urgency=low
74+
75+ * Upstream official 0.2.0
76+ * Remove unused libdbusmenu-qt
77+
78+ -- Ted Gould <ted@ubuntu.com> Fri, 08 Jan 2010 08:42:59 -0600
79+
80+libdbusmenu (0.2.0~dev-0ubuntu1~ppa9) karmic; urgency=low
81+
82+ * Upstream update:
83+ * Fixing the consistency between the #defines and what
84+ was used in the code.
85+
86+ -- Ted Gould <ted@ubuntu.com> Thu, 07 Jan 2010 11:03:16 -0600
87+
88+libdbusmenu (0.2.0~dev-0ubuntu1~ppa8) karmic; urgency=low
89+
90+ * Upstream update:
91+ * Starting to watch DBus if the proxy builds fail.
92+
93+ -- Ted Gould <ted@ubuntu.com> Thu, 07 Jan 2010 10:54:21 -0600
94+
95+libdbusmenu (0.2.0~dev-0ubuntu1~ppa7) karmic; urgency=low
96+
97+ * Upstream update:
98+ * Adding GetChildren function for getting a single submenu
99+ * Test suite fixes
100+
101+ -- Ted Gould <ted@ubuntu.com> Wed, 06 Jan 2010 22:17:16 -0600
102+
103+libdbusmenu (0.2.0~dev-0ubuntu1~ppa6) karmic; urgency=low
104+
105+ * Fixing the handling of typed properties, especially bools.
106+
107+ -- Ted Gould <ted@ubuntu.com> Tue, 22 Dec 2009 14:40:21 -0600
108+
109+libdbusmenu (0.2.0~dev-0ubuntu1~ppa5) karmic; urgency=low
110+
111+ * debian/control: Switching the breaks to be ~dev as those
112+ versions are not yet released.
113+
114+ -- Ted Gould <ted@ubuntu.com> Fri, 18 Dec 2009 21:21:12 -0600
115+
116+libdbusmenu (0.2.0~dev-0ubuntu1~ppa4) karmic; urgency=low
117+
118+ * Updating trunk
119+ * Setting version numbers
120+
121+ -- Ted Gould <ted@ubuntu.com> Fri, 18 Dec 2009 15:31:08 -0600
122+
123+libdbusmenu (0.2.0~dev-0ubuntu1~ppa3) karmic; urgency=low
124+
125+ * Updating trunk
126+ * Changing API to be V0.2 for reals
127+ * debian/control: Mentioning nicely that this will cause
128+ indicator-messages << 0.3 and indicator-session << 0.2 to
129+ break.
130+
131+ -- Ted Gould <ted@ubuntu.com> Fri, 18 Dec 2009 14:31:45 -0600
132+
133+libdbusmenu (0.2.0~dev-0ubuntu1~ppa2) karmic; urgency=low
134+
135+ * Updating to trunk
136+ * Adding underline support
137+
138+ -- Ted Gould <ted@ubuntu.com> Thu, 10 Dec 2009 13:03:41 -0600
139+
140+libdbusmenu (0.2.0~dev-0ubuntu1~ppa1) karmic; urgency=low
141+
142+ * Updating to trunk
143+ * Test suite fixes and automation support
144+ * dbus-dumper tool
145+ * Switch to org.ayatana
146+ * debian/control, debian/libdbusmenu-tools.install: Setting
147+ up a package for the new dbusmenu-dumper tool.
148+
149+ -- Ted Gould <ted@ubuntu.com> Tue, 08 Dec 2009 14:16:37 -0600
150+
151+libdbusmenu (0.1.8-0ubuntu1) karmic; urgency=low
152+>>>>>>> MERGE-SOURCE
153
154 * Upstream release 0.1.8
155 * Changing the name to org.ayatana
156
157=== modified file 'debian/control'
158--- debian/control 2009-08-27 18:55:42 +0000
159+++ debian/control 2010-01-08 14:45:24 +0000
160@@ -21,6 +21,8 @@
161 Architecture: any
162 Depends: ${shlibs:Depends},
163 ${misc:Depends}
164+Breaks: indicator-messages (<< 0.3.0~dev),
165+ indicator-session (<< 0.2.0~dev)
166 Description: Menus over DBus shared library for glib
167 This package contains shared libraries to be used by applications.
168
169@@ -58,3 +60,11 @@
170 This package contains files that are needed to build applications.
171 .
172 This package provides the development files.
173+
174+Package: libdbusmenu-tools
175+Section: devel
176+Architecture: any
177+Depends: ${shlibs:Depends},
178+ ${misc:Depends},
179+ libdbusmenu-glib0 (= ${binary:Version})
180+Description: Need a better description.
181
182=== modified file 'libdbusmenu-glib/Makefile.am'
183--- libdbusmenu-glib/Makefile.am 2009-05-15 20:27:40 +0000
184+++ libdbusmenu-glib/Makefile.am 2010-01-08 14:45:24 +0000
185@@ -22,6 +22,7 @@
186 menuitem.c \
187 menuitem-marshal.h \
188 menuitem-marshal.c \
189+ menuitem-private.h \
190 server.h \
191 server.c \
192 server-marshal.h \
193
194=== modified file 'libdbusmenu-glib/client.c'
195--- libdbusmenu-glib/client.c 2009-10-28 16:58:38 +0000
196+++ libdbusmenu-glib/client.c 2010-01-08 14:45:24 +0000
197@@ -34,6 +34,7 @@
198 #include <libxml/tree.h>
199
200 #include "client.h"
201+#include "menuitem.h"
202 #include "dbusmenu-client.h"
203 #include "server-marshal.h"
204
205@@ -94,14 +95,14 @@
206 static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec);
207 static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec);
208 /* Private Funcs */
209-static void layout_update (DBusGProxy * proxy, gint revision, DbusmenuClient * client);
210-static void id_prop_update (DBusGProxy * proxy, guint id, gchar * property, gchar * value, DbusmenuClient * client);
211+static void layout_update (DBusGProxy * proxy, gint revision, guint parent, DbusmenuClient * client);
212+static void id_prop_update (DBusGProxy * proxy, guint id, gchar * property, GValue * value, DbusmenuClient * client);
213 static void id_update (DBusGProxy * proxy, guint id, DbusmenuClient * client);
214 static void build_proxies (DbusmenuClient * client);
215 static guint parse_node_get_id (xmlNodePtr node);
216 static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, DBusGProxy * proxy);
217 static gint parse_layout (DbusmenuClient * client, const gchar * layout);
218-static void update_layout_cb (DBusGProxy * proxy, DBusGProxyCall * call, void * data);
219+static void update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError * in_error, void * data);
220 static void update_layout (DbusmenuClient * client);
221 static void menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data);
222
223@@ -215,7 +216,7 @@
224 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(object);
225
226 if (priv->layoutcall != NULL) {
227- dbus_g_proxy_cancel_call(priv->propproxy, priv->layoutcall);
228+ dbus_g_proxy_cancel_call(priv->menuproxy, priv->layoutcall);
229 priv->layoutcall = NULL;
230 }
231 if (priv->menuproxy != NULL) {
232@@ -307,7 +308,7 @@
233
234 /* Annoying little wrapper to make the right function update */
235 static void
236-layout_update (DBusGProxy * proxy, gint revision, DbusmenuClient * client)
237+layout_update (DBusGProxy * proxy, gint revision, guint parent, DbusmenuClient * client)
238 {
239 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
240 priv->current_revision = revision;
241@@ -320,10 +321,14 @@
242 /* Signal from the server that a property has changed
243 on one of our menuitems */
244 static void
245-id_prop_update (DBusGProxy * proxy, guint id, gchar * property, gchar * value, DbusmenuClient * client)
246+id_prop_update (DBusGProxy * proxy, guint id, gchar * property, GValue * value, DbusmenuClient * client)
247 {
248 #ifdef MASSIVEDEBUGGING
249- g_debug("Property change sent to client for item %d property %s value %s", id, property, g_utf8_strlen(value, 50) < 25 ? value : "<too long>");
250+ GValue valstr = {0};
251+ g_value_init(&valstr, G_TYPE_STRING);
252+ g_value_transform(value, &valstr);
253+ 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>");
254+ g_value_unset(&valstr);
255 #endif
256
257 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
258@@ -332,7 +337,7 @@
259 DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id);
260 g_return_if_fail(menuitem != NULL);
261
262- dbusmenu_menuitem_property_set(menuitem, property, value);
263+ dbusmenu_menuitem_property_set_value(menuitem, property, value);
264 return;
265 }
266
267@@ -351,7 +356,9 @@
268 DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id);
269 g_return_if_fail(menuitem != NULL);
270
271- org_ayatana_dbusmenu_get_properties_async(proxy, id, menuitem_get_properties_cb, menuitem);
272+ gchar * properties[1] = {NULL}; /* This gets them all */
273+ g_debug("Getting properties");
274+ org_ayatana_dbusmenu_get_properties_async(proxy, id, (const gchar **)properties, menuitem_get_properties_cb, menuitem);
275 return;
276 }
277
278@@ -360,8 +367,9 @@
279 dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, DbusmenuClient * client)
280 {
281 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
282+ /* g_debug("Owner change: %s %s %s", name, prev, new); */
283
284- if (!(new != NULL && prev == NULL)) {
285+ if (!(new[0] != '\0' && prev[0] == '\0')) {
286 /* If it's not someone new getting on the bus, sorry we
287 simply just don't care. It's not that your service isn't
288 important to someone, just not us. You'll find the right
289@@ -369,7 +377,7 @@
290 return;
291 }
292
293- if (g_strcmp0(new, priv->dbus_name)) {
294+ if (g_strcmp0(name, priv->dbus_name)) {
295 /* Again, someone else's service. */
296 return;
297 }
298@@ -464,6 +472,7 @@
299 if (error != NULL) {
300 g_warning("Unable to get property proxy for %s on %s: %s", priv->dbus_name, priv->dbus_object, error->message);
301 g_error_free(error);
302+ build_dbus_proxy(client);
303 return;
304 }
305 g_object_add_weak_pointer(G_OBJECT(priv->propproxy), (gpointer *)&priv->propproxy);
306@@ -477,6 +486,7 @@
307 if (error != NULL) {
308 g_warning("Unable to get dbusmenu proxy for %s on %s: %s", priv->dbus_name, priv->dbus_object, error->message);
309 g_error_free(error);
310+ build_dbus_proxy(client);
311 return;
312 }
313 g_object_add_weak_pointer(G_OBJECT(priv->menuproxy), (gpointer *)&priv->menuproxy);
314@@ -488,15 +498,16 @@
315 priv->dbusproxy = NULL;
316 }
317
318- dbus_g_proxy_add_signal(priv->menuproxy, "LayoutUpdate", G_TYPE_INT, G_TYPE_INVALID);
319+ dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__INT_UINT, G_TYPE_NONE, G_TYPE_INT, G_TYPE_UINT, G_TYPE_INVALID);
320+ dbus_g_proxy_add_signal(priv->menuproxy, "LayoutUpdate", G_TYPE_INT, G_TYPE_UINT, G_TYPE_INVALID);
321 dbus_g_proxy_connect_signal(priv->menuproxy, "LayoutUpdate", G_CALLBACK(layout_update), client, NULL);
322
323- dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__UINT_STRING_STRING, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
324- dbus_g_proxy_add_signal(priv->menuproxy, "IdPropUpdate", G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
325- dbus_g_proxy_connect_signal(priv->menuproxy, "IdPropUpdate", G_CALLBACK(id_prop_update), client, NULL);
326+ dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__UINT_STRING_POINTER, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
327+ dbus_g_proxy_add_signal(priv->menuproxy, "ItemPropertyUpdated", G_TYPE_UINT, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
328+ dbus_g_proxy_connect_signal(priv->menuproxy, "ItemPropertyUpdated", G_CALLBACK(id_prop_update), client, NULL);
329
330- dbus_g_proxy_add_signal(priv->menuproxy, "IdUpdate", G_TYPE_UINT, G_TYPE_INVALID);
331- dbus_g_proxy_connect_signal(priv->menuproxy, "IdUpdate", G_CALLBACK(id_update), client, NULL);
332+ dbus_g_proxy_add_signal(priv->menuproxy, "ItemUpdated", G_TYPE_UINT, G_TYPE_INVALID);
333+ dbus_g_proxy_connect_signal(priv->menuproxy, "ItemUpdated", G_CALLBACK(id_update), client, NULL);
334
335 update_layout(client);
336
337@@ -564,7 +575,7 @@
338 static void
339 get_properties_helper (gpointer key, gpointer value, gpointer data)
340 {
341- dbusmenu_menuitem_property_set((DbusmenuMenuitem *)data, (gchar *)key, (gchar *)value);
342+ dbusmenu_menuitem_property_set_value((DbusmenuMenuitem *)data, (gchar *)key, (GValue *)value);
343 return;
344 }
345
346@@ -606,7 +617,7 @@
347 const gchar * type;
348 DbusmenuClientTypeHandler newfunc = NULL;
349
350- type = dbusmenu_menuitem_property_get(propdata->item, "type");
351+ type = dbusmenu_menuitem_property_get(propdata->item, DBUSMENU_MENUITEM_PROP_TYPE);
352 if (type != NULL) {
353 newfunc = g_hash_table_lookup(priv->type_handlers, type);
354 } else {
355@@ -647,7 +658,10 @@
356 menuitem_activate (DbusmenuMenuitem * mi, DbusmenuClient * client)
357 {
358 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
359- org_ayatana_dbusmenu_call_async (priv->menuproxy, dbusmenu_menuitem_get_id(mi), menuitem_call_cb, mi);
360+ GValue value = {0};
361+ g_value_init(&value, G_TYPE_INT);
362+ g_value_set_int(&value, 0);
363+ org_ayatana_dbusmenu_event_async (priv->menuproxy, dbusmenu_menuitem_get_id(mi), "clicked", &value, menuitem_call_cb, mi);
364 return;
365 }
366
367@@ -689,7 +703,8 @@
368 propdata->item = item;
369 propdata->parent = parent;
370
371- org_ayatana_dbusmenu_get_properties_async(proxy, id, menuitem_get_properties_new_cb, propdata);
372+ gchar * properties[1] = {NULL}; /* This gets them all */
373+ org_ayatana_dbusmenu_get_properties_async(proxy, id, (const gchar **)properties, menuitem_get_properties_new_cb, propdata);
374 } else {
375 g_warning("Unable to allocate memory to get properties for menuitem. This menuitem will never be realized.");
376 }
377@@ -771,32 +786,24 @@
378
379 /* When the layout property returns, here's where we take care of that. */
380 static void
381-update_layout_cb (DBusGProxy * proxy, DBusGProxyCall * call, void * data)
382+update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError * error, void * data)
383 {
384 DbusmenuClient * client = DBUSMENU_CLIENT(data);
385 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
386
387- GError * error = NULL;
388- GValue value = {0};
389-
390- priv->layoutcall = NULL;
391- if (!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_VALUE, &value, G_TYPE_INVALID)) {
392+ if (error != NULL) {
393 g_warning("Getting layout failed on client %s object %s: %s", priv->dbus_name, priv->dbus_object, error->message);
394- g_error_free(error);
395 return;
396 }
397
398- const gchar * xml = g_value_get_string(&value);
399- /* g_debug("Got layout string: %s", xml); */
400- gint rev = parse_layout(client, xml);
401-
402- if (rev == 0) {
403+ if (!parse_layout(client, xml)) {
404 g_warning("Unable to parse layout!");
405 return;
406 }
407
408 priv->my_revision = rev;
409 /* g_debug("Root is now: 0x%X", (unsigned int)priv->root); */
410+ priv->layoutcall = NULL;
411 #ifdef MASSIVEDEBUGGING
412 g_debug("Client signaling layout has changed.");
413 #endif
414@@ -816,7 +823,7 @@
415 {
416 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
417
418- if (priv->propproxy == NULL) {
419+ if (priv->menuproxy == NULL) {
420 return;
421 }
422
423@@ -824,14 +831,10 @@
424 return;
425 }
426
427- priv->layoutcall = dbus_g_proxy_begin_call (priv->propproxy,
428- "Get",
429- update_layout_cb,
430- client,
431- NULL,
432- G_TYPE_STRING, "org.ayatana.dbusmenu",
433- G_TYPE_STRING, "layout",
434- G_TYPE_INVALID, G_TYPE_VALUE, G_TYPE_INVALID);
435+ priv->layoutcall = org_ayatana_dbusmenu_get_layout_async(priv->menuproxy,
436+ 0, /* Parent is the root */
437+ update_layout_cb,
438+ client);
439
440 return;
441 }
442
443=== modified file 'libdbusmenu-glib/client.h'
444--- libdbusmenu-glib/client.h 2009-08-26 20:15:13 +0000
445+++ libdbusmenu-glib/client.h 2010-01-08 14:45:24 +0000
446@@ -52,7 +52,7 @@
447
448 #define DBUSMENU_CLIENT_TYPES_DEFAULT "menuitem"
449 #define DBUSMENU_CLIENT_TYPES_SEPARATOR "separator"
450-#define DBUSMENU_CLIENT_TYPES_IMAGE "imageitem"
451+#define DBUSMENU_CLIENT_TYPES_IMAGE "menuitem"
452
453 /**
454 DbusmenuClientClass:
455
456=== modified file 'libdbusmenu-glib/dbus-menu.xml'
457--- libdbusmenu-glib/dbus-menu.xml 2009-11-20 18:01:22 +0000
458+++ libdbusmenu-glib/dbus-menu.xml 2010-01-08 14:45:24 +0000
459@@ -32,8 +32,22 @@
460
461 <!-- Properties -->
462 <!--
463+Provides the version of the DBusmenu API that this API is
464+implementing.
465+-->
466+ <property name="version" type="u" access="read"/>
467+
468+<!-- Functions -->
469+
470+<!--
471 Provides an XML representation of the menu hierarchy
472
473+@param parentId The ID of the parent node for the layout. For
474+ grabbing the layout from the root node use zero.
475+@param revision The revision number of the layout. For matching
476+ with layoutUpdated signals.
477+@param layout The layout as an XML string of IDs.
478+
479 XML syntax:
480
481 <menu id="1" revision="2"> # Root container
482@@ -48,73 +62,129 @@
483 ...
484 </menu>
485 -->
486- <property name="layout" type="s" access="read"/>
487-
488-<!-- Functions -->
489+ <method name="GetLayout">
490+ <arg type="u" name="parentId" direction="in" />
491+ <arg type="u" name="revision" direction="out" />
492+ <arg type="s" name="layout" direction="out" />
493+ </method>
494+
495+<!--
496+Returns the list of items which are children of @a parentId.
497+
498+@param Ids A list of ids that we should be finding the properties
499+ on. If the list is empty, all menu items should be sent.
500+@param propertyNames list of string the list of item properties we
501+ are interested in. If there are no entries in the list all of
502+ the properties will be sent.
503+
504+An item is represented as a struct following this format:
505+@li id unsigned the item id
506+@li properties map(string => variant) the requested item properties
507+
508+-->
509+ <method name="GetGroupProperties">
510+ <arg type="au" name="Ids" direction="in" />
511+ <arg type="as" name="propertyNames" direction="in" />
512+ <arg type="a(ua{sv})" name="properties" direction="out" />
513+ </method>
514+
515+ <method name="GetChildren">
516+ <arg type="u" name="id" direction="in" />
517+ <arg type="as" name="propertyNames" direction="in" />
518+ <arg type="a(ua{sv})" name="properties" direction="out" />
519+ </method>
520
521 <!--
522 Each menu item has a set of properties. Property keys are in menuitem.h:
523
524-- visible
525-- sensitive
526-- label
527-- icon
528-- icon-data
529-- type
530-
531-"type" property is an enum which can take the following values (client.h):
532-
533-- menuitem
534-- separator
535-- imageitem
536+@li type string Type of the item (see below)
537+@li label string Text of the item
538+@li icon-data binary Raw data of the icon (TODO: define format)
539+@li icon string Icon name of the item, following icon spec
540+@li sensitive boolean Whether the item can be activated or not
541+@li visible boolean Whether the item is visible or not (XXX: Is this necessary?)
542+@li checked boolean Whether a checkbox or radio item is checked
543+@li shortcut string The keyboard shortcut
544+
545+@c type property is an enum which can take the following values (client.h):
546+
547+@li action An item which can be clicked to trigger an action
548+@li checkbox An item which can be checked or unchecked
549+@li radio An item which can be checked or unchecked as part of a group
550+@li separator A separator
551+@li menu An item which contains more items
552 -->
553 <method name="GetProperty">
554 <arg type="u" name="id" direction="in" />
555- <arg type="s" name="property" direction="in" />
556- <arg type="s" name="value" direction="out" />
557+ <arg type="s" name="name" direction="in" />
558+ <arg type="v" name="value" direction="out" />
559 </method>
560
561 <!--
562-Convenience method to retrieve all properties in one call (more efficient)
563+Returns multiple properties in one call. This is more efficient than
564+GetProperty.
565+
566+@param id unsigned the item whose properties we want to retrieve.
567+@param propertyNames list of string name of the properties we want. If the list contains no entries, all properties are sent.
568 -->
569 <method name="GetProperties">
570+ <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
571 <arg type="u" name="id" direction="in" />
572- <arg type="a{ss}" name="properties" direction="out" />
573+ <arg type="as" name="propertyNames" direction="in" />
574+ <arg type="a{sv}" name="properties" direction="out" />
575 </method>
576
577 <!--
578-This is called by the display to notify the application it should trigger
579-the action associated with a specific menu id
580+This is called by the applet to notify the application an event happened on a
581+menu item.
582+
583+@param id the id of the item which received the event
584+@param type the type of event
585+@param data event-specific data
586+
587+@a type can be one of the following:
588+
589+@li "clicked"
590+@li "hovered"
591+
592+Vendor specific events can be added by prefixing them with "x-<vendor>-"
593 -->
594- <method name="Call">
595+ <method name="Event">
596 <arg type="u" name="id" direction="in" />
597+ <arg type="s" name="eventId" direction="in" />
598+ <arg type="v" name="data" direction="in" />
599 </method>
600
601 <!-- Signals -->
602 <!--
603-Triggered by the application to notify display that the property prop from menu id
604-as changed to value.
605+Triggered by the application to notify the applet that the property @a property
606+from item @a id has changed to @a value.
607 -->
608- <signal name="IdPropUpdate">
609+ <signal name="ItemPropertyUpdated">
610 <arg type="u" name="id" direction="out" />
611 <arg type="s" name="prop" direction="out" />
612- <arg type="s" name="value" direction="out" />
613+ <arg type="v" name="value" direction="out" />
614 </signal>
615
616 <!--
617-Triggered by the application to notify display that all properties of menu id
618-should be considered outdated
619+Triggered by the application to notify the applet that all properties of item
620+@a id should be considered outdated
621 -->
622- <signal name="IdUpdate">
623+ <signal name="ItemUpdated">
624 <arg type="u" name="id" direction="out" />
625 </signal>
626
627 <!--
628 Triggered by the application to notify display of a layout update, up to
629 revision
630+@param revsion The revision of the layout that we're currently on
631+@param parent If the layout update is only of a subtree, this is the parent
632+ item for the entries that have changed. It is zero if the
633+ whole layout should be considered invalid.
634 -->
635 <signal name="LayoutUpdate">
636 <arg type="i" name="revision" direction="out" />
637+ <arg type="u" name="parent" direction="out" />
638 </signal>
639
640 <!-- End of interesting stuff -->
641
642=== modified file 'libdbusmenu-glib/menuitem-marshal.list'
643--- libdbusmenu-glib/menuitem-marshal.list 2009-06-23 19:38:58 +0000
644+++ libdbusmenu-glib/menuitem-marshal.list 2010-01-08 14:45:24 +0000
645@@ -1,4 +1,4 @@
646-VOID: STRING, STRING
647+VOID: STRING, POINTER
648 VOID: OBJECT, UINT, UINT
649 VOID: OBJECT, UINT
650 VOID: OBJECT
651
652=== added file 'libdbusmenu-glib/menuitem-private.h'
653--- libdbusmenu-glib/menuitem-private.h 1970-01-01 00:00:00 +0000
654+++ libdbusmenu-glib/menuitem-private.h 2010-01-08 14:45:24 +0000
655@@ -0,0 +1,40 @@
656+/*
657+A library to communicate a menu object set accross DBus and
658+track updates and maintain consistency.
659+
660+Copyright 2009 Canonical Ltd.
661+
662+Authors:
663+ Ted Gould <ted@canonical.com>
664+
665+This program is free software: you can redistribute it and/or modify it
666+under the terms of either or both of the following licenses:
667+
668+1) the GNU Lesser General Public License version 3, as published by the
669+Free Software Foundation; and/or
670+2) the GNU Lesser General Public License version 2.1, as published by
671+the Free Software Foundation.
672+
673+This program is distributed in the hope that it will be useful, but
674+WITHOUT ANY WARRANTY; without even the implied warranties of
675+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
676+PURPOSE. See the applicable version of the GNU Lesser General Public
677+License for more details.
678+
679+You should have received a copy of both the GNU Lesser General Public
680+License version 3 and version 2.1 along with this program. If not, see
681+<http://www.gnu.org/licenses/>
682+*/
683+
684+#ifndef __DBUSMENU_MENUITEM_PRIVATE_H__
685+#define __DBUSMENU_MENUITEM_PRIVATE_H__
686+
687+#include "menuitem.h"
688+
689+G_BEGIN_DECLS
690+
691+void dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array, gint revision);
692+
693+G_END_DECLS
694+
695+#endif
696
697=== modified file 'libdbusmenu-glib/menuitem.c'
698--- libdbusmenu-glib/menuitem.c 2009-10-01 19:23:35 +0000
699+++ libdbusmenu-glib/menuitem.c 2010-01-08 14:45:24 +0000
700@@ -26,11 +26,13 @@
701 <http://www.gnu.org/licenses/>
702 */
703
704+#include <stdlib.h>
705 #ifdef HAVE_CONFIG_H
706 #include "config.h"
707 #endif
708 #include "menuitem.h"
709 #include "menuitem-marshal.h"
710+#include "menuitem-private.h"
711
712 #ifdef MASSIVEDEBUGGING
713 #define LABEL(x) dbusmenu_menuitem_property_get(DBUSMENU_MENUITEM(x), DBUSMENU_MENUITEM_PROP_LABEL)
714@@ -88,6 +90,8 @@
715 static void dbusmenu_menuitem_finalize (GObject *object);
716 static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec);
717 static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec);
718+static void g_value_transform_STRING_BOOLEAN (const GValue * in, GValue * out);
719+static void g_value_transform_STRING_INT (const GValue * in, GValue * out);
720
721 /* GObject stuff */
722 G_DEFINE_TYPE (DbusmenuMenuitem, dbusmenu_menuitem, G_TYPE_OBJECT);
723@@ -118,8 +122,8 @@
724 G_SIGNAL_RUN_LAST,
725 G_STRUCT_OFFSET(DbusmenuMenuitemClass, property_changed),
726 NULL, NULL,
727- _dbusmenu_menuitem_marshal_VOID__STRING_STRING,
728- G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
729+ _dbusmenu_menuitem_marshal_VOID__STRING_POINTER,
730+ G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_POINTER);
731 /**
732 DbusmenuMenuitem::item-activated:
733 @arg0: The #DbusmenuMenuitem object.
734@@ -207,11 +211,56 @@
735 0, 30000, 0,
736 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
737
738+ /* Check transfer functions for GValue */
739+ if (!g_value_type_transformable(G_TYPE_STRING, G_TYPE_BOOLEAN)) {
740+ g_value_register_transform_func(G_TYPE_STRING, G_TYPE_BOOLEAN, g_value_transform_STRING_BOOLEAN);
741+ }
742+ if (!g_value_type_transformable(G_TYPE_STRING, G_TYPE_INT)) {
743+ g_value_register_transform_func(G_TYPE_STRING, G_TYPE_INT, g_value_transform_STRING_INT);
744+ }
745+
746+ return;
747+}
748+
749+/* A little helper function to translate a string into
750+ a boolean value */
751+static void
752+g_value_transform_STRING_BOOLEAN (const GValue * in, GValue * out)
753+{
754+ const gchar * string = g_value_get_string(in);
755+ if (!g_strcmp0(string, "TRUE") || !g_strcmp0(string, "true") || !g_strcmp0(string, "True")) {
756+ g_value_set_boolean(out, TRUE);
757+ } else {
758+ g_value_set_boolean(out, FALSE);
759+ }
760+ return;
761+}
762+
763+/* A little helper function to translate a string into
764+ a integer value */
765+static void
766+g_value_transform_STRING_INT (const GValue * in, GValue * out)
767+{
768+ g_value_set_int(out, atoi(g_value_get_string(in)));
769 return;
770 }
771
772 static guint menuitem_next_id = 1;
773
774+/* A small little function to both clear the insides of a
775+ value as well as the memory it itself uses. */
776+static void
777+_g_value_free (gpointer data)
778+{
779+ if (data == NULL) return;
780+ GValue * value = (GValue*)data;
781+ g_value_unset(value);
782+ g_free(data);
783+ return;
784+}
785+
786+/* Initialize the values of the in the object, and build the
787+ properties hash table. */
788 static void
789 dbusmenu_menuitem_init (DbusmenuMenuitem *self)
790 {
791@@ -220,7 +269,7 @@
792 priv->id = 0;
793 priv->children = NULL;
794
795- priv->properties = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
796+ priv->properties = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, _g_value_free);
797
798 priv->root = FALSE;
799
800@@ -673,27 +722,107 @@
801 gboolean
802 dbusmenu_menuitem_property_set (DbusmenuMenuitem * mi, const gchar * property, const gchar * value)
803 {
804+ GValue val = {0};
805+ g_value_init(&val, G_TYPE_STRING);
806+ g_value_set_static_string(&val, value);
807+ return dbusmenu_menuitem_property_set_value(mi, property, &val);
808+}
809+
810+/**
811+ dbusmenu_menuitem_property_set_bool:
812+ @mi: The #DbusmenuMenuitem to set the property on.
813+ @property: Name of the property to set.
814+ @value: The value of the property.
815+
816+ Takes a boolean @value and sets it on @property as a
817+ property on @mi. If a property already exists by that name,
818+ then the value is set to the new value. If not, the property
819+ is added. If the value is changed or the property was previously
820+ unset then the signal #DbusmenuMenuitem::prop-changed will be
821+ emitted by this function.
822+
823+ Return value: A boolean representing if the property value was set.
824+*/
825+gboolean
826+dbusmenu_menuitem_property_set_bool (DbusmenuMenuitem * mi, const gchar * property, const gboolean value)
827+{
828+ GValue val = {0};
829+ g_value_init(&val, G_TYPE_BOOLEAN);
830+ g_value_set_boolean(&val, value);
831+ return dbusmenu_menuitem_property_set_value(mi, property, &val);
832+}
833+
834+/**
835+ dbusmenu_menuitem_property_set_int:
836+ @mi: The #DbusmenuMenuitem to set the property on.
837+ @property: Name of the property to set.
838+ @value: The value of the property.
839+
840+ Takes a boolean @value and sets it on @property as a
841+ property on @mi. If a property already exists by that name,
842+ then the value is set to the new value. If not, the property
843+ is added. If the value is changed or the property was previously
844+ unset then the signal #DbusmenuMenuitem::prop-changed will be
845+ emitted by this function.
846+
847+ Return value: A boolean representing if the property value was set.
848+*/
849+gboolean
850+dbusmenu_menuitem_property_set_int (DbusmenuMenuitem * mi, const gchar * property, const gint value)
851+{
852+ GValue val = {0};
853+ g_value_init(&val, G_TYPE_INT);
854+ g_value_set_int(&val, value);
855+ return dbusmenu_menuitem_property_set_value(mi, property, &val);
856+}
857+
858+/**
859+ dbusmenu_menuitem_property_set:
860+ @mi: The #DbusmenuMenuitem to set the property on.
861+ @property: Name of the property to set.
862+ @value: The value of the property.
863+
864+ Takes the pair of @property and @value and places them as a
865+ property on @mi. If a property already exists by that name,
866+ then the value is set to the new value. If not, the property
867+ is added. If the value is changed or the property was previously
868+ unset then the signal #DbusmenuMenuitem::prop-changed will be
869+ emitted by this function.
870+
871+ Return value: A boolean representing if the property value was set.
872+*/
873+gboolean
874+dbusmenu_menuitem_property_set_value (DbusmenuMenuitem * mi, const gchar * property, const GValue * value)
875+{
876 g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
877 g_return_val_if_fail(property != NULL, FALSE);
878+ g_return_val_if_fail(G_IS_VALUE(value), FALSE);
879
880 DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
881 /* g_debug("Setting a property. ID: %d Prop: %s Value: %s", priv->id, property, value); */
882
883+ #if 0
884 gpointer lookup = g_hash_table_lookup(priv->properties, property);
885 if (g_strcmp0((gchar *)lookup, value) == 0) {
886 /* The value is the same as the value currently in the
887 table so we don't really care. Just say everything's okay */
888 return TRUE;
889 }
890+ #endif
891
892 gchar * lprop = g_strdup(property);
893- gchar * lval = g_strdup(value);
894+ GValue * lval = g_new0(GValue, 1);
895+ g_value_init(lval, G_VALUE_TYPE(value));
896+ g_value_copy(value, lval);
897
898- g_hash_table_insert(priv->properties, lprop, lval);
899+ g_hash_table_replace(priv->properties, lprop, lval);
900 #ifdef MASSIVEDEBUGGING
901- g_debug("Menuitem %d (%s) signalling property '%s' changed to '%s'", ID(mi), LABEL(mi), property, g_utf8_strlen(value, 50) < 25 ? value : "<too long>");
902+ gchar * valstr = g_strdup_value_contents(lval);
903+ 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>");
904+ g_free(valstr);
905 #endif
906- g_signal_emit(G_OBJECT(mi), signals[PROPERTY_CHANGED], 0, property, value, TRUE);
907+
908+ g_signal_emit(G_OBJECT(mi), signals[PROPERTY_CHANGED], 0, lprop, lval, TRUE);
909
910 return TRUE;
911 }
912@@ -709,18 +838,95 @@
913
914 Return value: A string with the value of the property
915 that shouldn't be free'd. Or #NULL if the property
916- is not set.
917+ is not set or is not a string.
918 */
919 const gchar *
920 dbusmenu_menuitem_property_get (DbusmenuMenuitem * mi, const gchar * property)
921 {
922+ const GValue * value = dbusmenu_menuitem_property_get_value(mi, property);
923+ if (value == NULL) return NULL;
924+ if (G_VALUE_TYPE(value) != G_TYPE_STRING) return NULL;
925+ return g_value_get_string(value);
926+}
927+
928+/**
929+ dbusmenu_menuitem_property_get_value:
930+ @mi: The #DbusmenuMenuitem to look for the property on.
931+ @property: The property to grab.
932+
933+ Look up a property on @mi and return the value of it if
934+ it exits. #NULL will be returned if the property doesn't
935+ exist.
936+
937+ Return value: A GValue for the property.
938+*/
939+const GValue *
940+dbusmenu_menuitem_property_get_value (DbusmenuMenuitem * mi, const gchar * property)
941+{
942 g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), NULL);
943 g_return_val_if_fail(property != NULL, NULL);
944
945 DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
946
947- return (const gchar *)g_hash_table_lookup(priv->properties, property);
948-}
949+ return (const GValue *)g_hash_table_lookup(priv->properties, property);
950+}
951+
952+/**
953+ dbusmenu_menuitem_property_get_bool:
954+ @mi: The #DbusmenuMenuitem to look for the property on.
955+ @property: The property to grab.
956+
957+ Look up a property on @mi and return the value of it if
958+ it exits. Returns #FALSE if the property doesn't exist.
959+
960+ Return value: The value of the property or #FALSE.
961+*/
962+gboolean
963+dbusmenu_menuitem_property_get_bool (DbusmenuMenuitem * mi, const gchar * property)
964+{
965+ const GValue * value = dbusmenu_menuitem_property_get_value(mi, property);
966+ if (value == NULL) return FALSE;
967+ if (G_VALUE_TYPE(value) != G_TYPE_BOOLEAN) {
968+ if (g_value_type_transformable(G_VALUE_TYPE(value), G_TYPE_BOOLEAN)) {
969+ GValue boolval = {0};
970+ g_value_init(&boolval, G_TYPE_BOOLEAN);
971+ g_value_transform(value, &boolval);
972+ return g_value_get_boolean(&boolval);
973+ } else {
974+ return FALSE;
975+ }
976+ }
977+ return g_value_get_boolean(value);
978+}
979+
980+/**
981+ dbusmenu_menuitem_property_get_int:
982+ @mi: The #DbusmenuMenuitem to look for the property on.
983+ @property: The property to grab.
984+
985+ Look up a property on @mi and return the value of it if
986+ it exits. Returns zero if the property doesn't exist.
987+
988+ Return value: The value of the property or zero.
989+*/
990+gint
991+dbusmenu_menuitem_property_get_int (DbusmenuMenuitem * mi, const gchar * property)
992+{
993+ const GValue * value = dbusmenu_menuitem_property_get_value(mi, property);
994+ if (value == NULL) return 0;
995+ if (G_VALUE_TYPE(value) != G_TYPE_INT) {
996+ if (g_value_type_transformable(G_VALUE_TYPE(value), G_TYPE_INT)) {
997+ GValue intval = {0};
998+ g_value_init(&intval, G_TYPE_INT);
999+ g_value_transform(value, &intval);
1000+ return g_value_get_int(&intval);
1001+ } else {
1002+ return 0;
1003+ }
1004+ }
1005+ return g_value_get_int(value);
1006+}
1007+
1008
1009 /**
1010 dbusmenu_menuitem_property_exit:
1011
1012=== modified file 'libdbusmenu-glib/menuitem.h'
1013--- libdbusmenu-glib/menuitem.h 2009-09-21 20:01:40 +0000
1014+++ libdbusmenu-glib/menuitem.h 2010-01-08 14:45:24 +0000
1015@@ -50,11 +50,21 @@
1016 #define DBUSMENU_MENUITEM_SIGNAL_REALIZED "realized"
1017 #define DBUSMENU_MENUITEM_SIGNAL_REALIZED_ID (g_signal_lookup(DBUSMENU_MENUITEM_SIGNAL_REALIZED, DBUSMENU_TYPE_MENUITEM))
1018
1019+#define DBUSMENU_MENUITEM_PROP_TYPE "type"
1020 #define DBUSMENU_MENUITEM_PROP_VISIBLE "visible"
1021 #define DBUSMENU_MENUITEM_PROP_SENSITIVE "sensitive"
1022 #define DBUSMENU_MENUITEM_PROP_LABEL "label"
1023 #define DBUSMENU_MENUITEM_PROP_ICON "icon"
1024 #define DBUSMENU_MENUITEM_PROP_ICON_DATA "icon-data"
1025+#define DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE "toggle-type"
1026+#define DBUSMENU_MENUITEM_PROP_TOGGLE_CHECKED "toggle-checked"
1027+
1028+#define DBUSMENU_MENUITEM_TOGGLE_CHECK "checkmark"
1029+#define DBUSMENU_MENUITEM_TOGGLE_RADIO "radio"
1030+
1031+#define DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED "unchecked"
1032+#define DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED "checked"
1033+#define DBUSMENU_MENUITEM_TOGGLE_STATE_UNKNOWN "indeterminate"
1034
1035 /**
1036 DbusmenuMenuitem:
1037@@ -93,7 +103,7 @@
1038 GObjectClass parent_class;
1039
1040 /* Signals */
1041- void (*property_changed) (gchar * property, gchar * value);
1042+ void (*property_changed) (gchar * property, GValue * value);
1043 void (*item_activated) (void);
1044 void (*child_added) (DbusmenuMenuitem * child, guint position);
1045 void (*child_removed) (DbusmenuMenuitem * child);
1046@@ -128,7 +138,13 @@
1047 DbusmenuMenuitem * dbusmenu_menuitem_find_id (DbusmenuMenuitem * mi, guint id);
1048
1049 gboolean dbusmenu_menuitem_property_set (DbusmenuMenuitem * mi, const gchar * property, const gchar * value);
1050+gboolean dbusmenu_menuitem_property_set_value (DbusmenuMenuitem * mi, const gchar * property, const GValue * value);
1051+gboolean dbusmenu_menuitem_property_set_bool (DbusmenuMenuitem * mi, const gchar * property, const gboolean value);
1052+gboolean dbusmenu_menuitem_property_set_int (DbusmenuMenuitem * mi, const gchar * property, const gint value);
1053 const gchar * dbusmenu_menuitem_property_get (DbusmenuMenuitem * mi, const gchar * property);
1054+const GValue * dbusmenu_menuitem_property_get_value (DbusmenuMenuitem * mi, const gchar * property);
1055+gboolean dbusmenu_menuitem_property_get_bool (DbusmenuMenuitem * mi, const gchar * property);
1056+gint dbusmenu_menuitem_property_get_int (DbusmenuMenuitem * mi, const gchar * property);
1057 gboolean dbusmenu_menuitem_property_exist (DbusmenuMenuitem * mi, const gchar * property);
1058 GList * dbusmenu_menuitem_properties_list (DbusmenuMenuitem * mi) G_GNUC_WARN_UNUSED_RESULT;
1059 GHashTable * dbusmenu_menuitem_properties_copy (DbusmenuMenuitem * mi);
1060@@ -136,7 +152,6 @@
1061 void dbusmenu_menuitem_set_root (DbusmenuMenuitem * mi, gboolean root);
1062 gboolean dbusmenu_menuitem_get_root (DbusmenuMenuitem * mi);
1063
1064-void dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array, gint revision);
1065 void dbusmenu_menuitem_foreach (DbusmenuMenuitem * mi, void (*func) (DbusmenuMenuitem * mi, gpointer data), gpointer data);
1066 void dbusmenu_menuitem_activate (DbusmenuMenuitem * mi);
1067
1068
1069=== modified file 'libdbusmenu-glib/server-marshal.list'
1070--- libdbusmenu-glib/server-marshal.list 2009-04-16 16:26:18 +0000
1071+++ libdbusmenu-glib/server-marshal.list 2010-01-08 14:45:24 +0000
1072@@ -1,1 +1,2 @@
1073-VOID: UINT, STRING, STRING
1074+VOID: UINT, STRING, POINTER
1075+VOID: INT, UINT
1076
1077=== modified file 'libdbusmenu-glib/server.c'
1078--- libdbusmenu-glib/server.c 2009-10-28 16:58:24 +0000
1079+++ libdbusmenu-glib/server.c 2010-01-08 14:45:24 +0000
1080@@ -30,16 +30,22 @@
1081 #include "config.h"
1082 #endif
1083
1084+#include "menuitem-private.h"
1085 #include "server.h"
1086 #include "server-marshal.h"
1087
1088 /* DBus Prototypes */
1089+static gboolean _dbusmenu_server_get_layout (DbusmenuServer * server, guint parent, guint * revision, gchar ** layout, GError ** error);
1090 static gboolean _dbusmenu_server_get_property (DbusmenuServer * server, guint id, gchar * property, gchar ** value, GError ** error);
1091-static gboolean _dbusmenu_server_get_properties (DbusmenuServer * server, guint id, GHashTable ** dict, GError ** error);
1092-static gboolean _dbusmenu_server_call (DbusmenuServer * server, guint id, GError ** error);
1093+static gboolean _dbusmenu_server_get_properties (DbusmenuServer * server, guint id, GPtrArray * properties, GHashTable ** dict, GError ** error);
1094+static gboolean _dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, GArray * properties, GHashTable ** values, GError ** error);
1095+static gboolean _dbusmenu_server_event (DbusmenuServer * server, guint id, gchar * eventid, GValue * data, GError ** error);
1096+static gboolean _dbusmenu_server_get_children (DbusmenuServer * server, guint id, GPtrArray * properties, GPtrArray ** output, GError ** error);
1097
1098 #include "dbusmenu-server.h"
1099
1100+#define DBUSMENU_VERSION_NUMBER 1
1101+
1102 /* Privates, I'll show you mine... */
1103 typedef struct _DbusmenuServerPrivate DbusmenuServerPrivate;
1104
1105@@ -68,7 +74,7 @@
1106 PROP_0,
1107 PROP_DBUS_OBJECT,
1108 PROP_ROOT_NODE,
1109- PROP_LAYOUT
1110+ PROP_VERSION
1111 };
1112
1113 /* Errors */
1114@@ -76,6 +82,7 @@
1115 INVALID_MENUITEM_ID,
1116 INVALID_PROPERTY_NAME,
1117 UNKNOWN_DBUS_ERROR,
1118+ NOT_IMPLEMENTED,
1119 LAST_ERROR
1120 };
1121
1122@@ -86,7 +93,7 @@
1123 static void dbusmenu_server_finalize (GObject *object);
1124 static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec);
1125 static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec);
1126-static void menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, gchar * value, DbusmenuServer * server);
1127+static void menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GValue * value, DbusmenuServer * server);
1128 static void menuitem_child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint pos, DbusmenuServer * server);
1129 static void menuitem_child_removed (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, DbusmenuServer * server);
1130 static void menuitem_signals_create (DbusmenuMenuitem * mi, gpointer data);
1131@@ -122,8 +129,8 @@
1132 G_SIGNAL_RUN_LAST,
1133 G_STRUCT_OFFSET(DbusmenuServerClass, id_prop_update),
1134 NULL, NULL,
1135- _dbusmenu_server_marshal_VOID__UINT_STRING_STRING,
1136- G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
1137+ _dbusmenu_server_marshal_VOID__UINT_STRING_POINTER,
1138+ G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_VALUE);
1139 /**
1140 DbusmenuServer::id-update:
1141 @arg0: The #DbusmenuServer emitting the signal.
1142@@ -145,6 +152,7 @@
1143 @arg0: The #DbusmenuServer emitting the signal.
1144 @arg1: A revision number representing which revision the update
1145 represents itself as.
1146+ @arg2: The ID of the parent for this update.
1147
1148 This signal is emitted any time the layout of the
1149 menuitems under this server is changed.
1150@@ -154,8 +162,8 @@
1151 G_SIGNAL_RUN_LAST,
1152 G_STRUCT_OFFSET(DbusmenuServerClass, layout_update),
1153 NULL, NULL,
1154- g_cclosure_marshal_VOID__INT,
1155- G_TYPE_NONE, 1, G_TYPE_INT);
1156+ _dbusmenu_server_marshal_VOID__INT_UINT,
1157+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_UINT);
1158
1159
1160 g_object_class_install_property (object_class, PROP_DBUS_OBJECT,
1161@@ -168,10 +176,10 @@
1162 "The base object of the menus that are served",
1163 DBUSMENU_TYPE_MENUITEM,
1164 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1165- g_object_class_install_property (object_class, PROP_LAYOUT,
1166- g_param_spec_string(DBUSMENU_SERVER_PROP_LAYOUT, "XML Layout of the menus",
1167- "A simple XML string that describes the layout of the menus",
1168- "<menu />",
1169+ g_object_class_install_property (object_class, PROP_VERSION,
1170+ g_param_spec_uint(DBUSMENU_SERVER_PROP_VERSION, "Dbusmenu API version",
1171+ "The version of the DBusmenu API that we're implementing.",
1172+ DBUSMENU_VERSION_NUMBER, DBUSMENU_VERSION_NUMBER, DBUSMENU_VERSION_NUMBER,
1173 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
1174
1175 dbus_g_object_type_install_info(DBUSMENU_TYPE_SERVER, &dbus_glib__dbusmenu_server_object_info);
1176@@ -240,11 +248,8 @@
1177 g_debug("Setting root node to NULL");
1178 }
1179 priv->layout_revision++;
1180- g_signal_emit(obj, signals[LAYOUT_UPDATE], 0, priv->layout_revision, TRUE);
1181+ g_signal_emit(obj, signals[LAYOUT_UPDATE], 0, priv->layout_revision, 0, TRUE);
1182 break;
1183- case PROP_LAYOUT:
1184- /* Can't set this, fall through to error */
1185- g_warning("Can not set property: layout");
1186 default:
1187 g_return_if_reached();
1188 break;
1189@@ -276,25 +281,9 @@
1190 case PROP_ROOT_NODE:
1191 g_value_set_object(value, priv->root);
1192 break;
1193- case PROP_LAYOUT: {
1194- GPtrArray * xmlarray = g_ptr_array_new();
1195- if (priv->root == NULL) {
1196- /* g_debug("Getting layout without root node!"); */
1197- g_ptr_array_add(xmlarray, g_strdup_printf("<menu revision=\"%d\" />", priv->layout_revision));
1198- } else {
1199- dbusmenu_menuitem_buildxml(priv->root, xmlarray, priv->layout_revision);
1200- }
1201- g_ptr_array_add(xmlarray, NULL);
1202-
1203- /* build string */
1204- gchar * finalstring = g_strjoinv("", (gchar **)xmlarray->pdata);
1205- g_value_take_string(value, finalstring);
1206- /* g_debug("Final string: %s", finalstring); */
1207-
1208- g_ptr_array_foreach(xmlarray, xmlarray_foreach_free, NULL);
1209- g_ptr_array_free(xmlarray, TRUE);
1210+ case PROP_VERSION:
1211+ g_value_set_uint(value, DBUSMENU_VERSION_NUMBER);
1212 break;
1213- }
1214 default:
1215 g_return_if_reached();
1216 break;
1217@@ -304,7 +293,7 @@
1218 }
1219
1220 static void
1221-menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, gchar * value, DbusmenuServer * server)
1222+menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GValue * value, DbusmenuServer * server)
1223 {
1224 g_signal_emit(G_OBJECT(server), signals[ID_PROP_UPDATE], 0, dbusmenu_menuitem_get_id(mi), property, value, TRUE);
1225 return;
1226@@ -317,7 +306,7 @@
1227 /* TODO: We probably need to group the layout update signals to make the number more reasonble. */
1228 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
1229 priv->layout_revision++;
1230- g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, TRUE);
1231+ g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, 0, TRUE);
1232 return;
1233 }
1234
1235@@ -328,7 +317,7 @@
1236 /* TODO: We probably need to group the layout update signals to make the number more reasonble. */
1237 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
1238 priv->layout_revision++;
1239- g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, TRUE);
1240+ g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, 0, TRUE);
1241 return;
1242 }
1243
1244@@ -337,7 +326,7 @@
1245 {
1246 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
1247 priv->layout_revision++;
1248- g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, TRUE);
1249+ g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, 0, TRUE);
1250 return;
1251 }
1252
1253@@ -376,6 +365,36 @@
1254 }
1255
1256 /* DBus interface */
1257+static gboolean
1258+_dbusmenu_server_get_layout (DbusmenuServer * server, guint parent, guint * revision, gchar ** layout, GError ** error)
1259+{
1260+ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
1261+
1262+ *revision = priv->layout_revision;
1263+ GPtrArray * xmlarray = g_ptr_array_new();
1264+
1265+ if (parent == 0) {
1266+ if (priv->root == NULL) {
1267+ /* g_debug("Getting layout without root node!"); */
1268+ g_ptr_array_add(xmlarray, g_strdup_printf("<menu revision=\"%d\" />", priv->layout_revision));
1269+ } else {
1270+ dbusmenu_menuitem_buildxml(priv->root, xmlarray, priv->layout_revision);
1271+ }
1272+ } else {
1273+ DbusmenuMenuitem * item = dbusmenu_menuitem_find_id(priv->root, parent);
1274+ dbusmenu_menuitem_buildxml(item, xmlarray, priv->layout_revision);
1275+ }
1276+ g_ptr_array_add(xmlarray, NULL);
1277+
1278+ /* build string */
1279+ *layout = g_strjoinv("", (gchar **)xmlarray->pdata);
1280+
1281+ g_ptr_array_foreach(xmlarray, xmlarray_foreach_free, NULL);
1282+ g_ptr_array_free(xmlarray, TRUE);
1283+
1284+ return TRUE;
1285+}
1286+
1287 static gboolean
1288 _dbusmenu_server_get_property (DbusmenuServer * server, guint id, gchar * property, gchar ** value, GError ** error)
1289 {
1290@@ -422,7 +441,7 @@
1291 }
1292
1293 static gboolean
1294-_dbusmenu_server_get_properties (DbusmenuServer * server, guint id, GHashTable ** dict, GError ** error)
1295+_dbusmenu_server_get_properties (DbusmenuServer * server, guint id, GPtrArray * properties, GHashTable ** dict, GError ** error)
1296 {
1297 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
1298 DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id);
1299@@ -444,7 +463,81 @@
1300 }
1301
1302 static gboolean
1303-_dbusmenu_server_call (DbusmenuServer * server, guint id, GError ** error)
1304+_dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, GArray * properties, GHashTable ** values, GError ** error)
1305+{
1306+ if (error != NULL) {
1307+ g_set_error(error,
1308+ error_quark(),
1309+ NOT_IMPLEMENTED,
1310+ "The GetGroupProperties function is not implemented, sorry.");
1311+ }
1312+ return FALSE;
1313+}
1314+
1315+static void
1316+_gvalue_array_append_uint(GValueArray *array, guint i)
1317+{
1318+ GValue value = {0};
1319+
1320+ g_value_init(&value, G_TYPE_UINT);
1321+ g_value_set_uint(&value, i);
1322+ g_value_array_append(array, &value);
1323+ g_value_unset(&value);
1324+}
1325+
1326+static void
1327+_gvalue_array_append_hashtable(GValueArray *array, GHashTable * dict)
1328+{
1329+ GValue value = {0};
1330+
1331+ g_value_init(&value, dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE));
1332+ g_value_set_boxed(&value, dict);
1333+ g_value_array_append(array, &value);
1334+ g_value_unset(&value);
1335+}
1336+
1337+static void
1338+serialize_menuitem(gpointer data, gpointer user_data)
1339+{
1340+ DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(data);
1341+ GPtrArray * output = (GPtrArray *)(user_data);
1342+
1343+ guint id = dbusmenu_menuitem_get_id(mi);
1344+ GHashTable * dict = dbusmenu_menuitem_properties_copy(mi);
1345+
1346+ GValueArray * item = g_value_array_new(1);
1347+ _gvalue_array_append_uint(item, id);
1348+ _gvalue_array_append_hashtable(item, dict);
1349+
1350+ g_ptr_array_add(output, item);
1351+}
1352+
1353+static gboolean
1354+_dbusmenu_server_get_children (DbusmenuServer * server, guint id, GPtrArray * properties, GPtrArray ** output, GError ** error)
1355+{
1356+ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
1357+ DbusmenuMenuitem * mi = id == 0 ? priv->root : dbusmenu_menuitem_find_id(priv->root, id);
1358+
1359+ if (mi == NULL) {
1360+ if (error != NULL) {
1361+ g_set_error(error,
1362+ error_quark(),
1363+ INVALID_MENUITEM_ID,
1364+ "The ID supplied %d does not refer to a menu item we have",
1365+ id);
1366+ }
1367+ return FALSE;
1368+ }
1369+
1370+ *output = g_ptr_array_new();
1371+ GList * children = dbusmenu_menuitem_get_children(mi);
1372+ g_list_foreach(children, serialize_menuitem, *output);
1373+
1374+ return TRUE;
1375+}
1376+
1377+static gboolean
1378+_dbusmenu_server_event (DbusmenuServer * server, guint id, gchar * eventid, GValue * data, GError ** error)
1379 {
1380 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
1381 DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id);
1382
1383=== modified file 'libdbusmenu-glib/server.h'
1384--- libdbusmenu-glib/server.h 2009-09-21 19:55:10 +0000
1385+++ libdbusmenu-glib/server.h 2010-01-08 14:45:24 +0000
1386@@ -43,13 +43,13 @@
1387 #define DBUSMENU_IS_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_TYPE_SERVER))
1388 #define DBUSMENU_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_TYPE_SERVER, DbusmenuServerClass))
1389
1390-#define DBUSMENU_SERVER_SIGNAL_ID_PROP_UPDATE "id-prop-update"
1391-#define DBUSMENU_SERVER_SIGNAL_ID_UPDATE "id-update"
1392+#define DBUSMENU_SERVER_SIGNAL_ID_PROP_UPDATE "item-property-updated"
1393+#define DBUSMENU_SERVER_SIGNAL_ID_UPDATE "item-updated"
1394 #define DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATE "layout-update"
1395
1396 #define DBUSMENU_SERVER_PROP_DBUS_OBJECT "dbus-object"
1397 #define DBUSMENU_SERVER_PROP_ROOT_NODE "root-node"
1398-#define DBUSMENU_SERVER_PROP_LAYOUT "layout"
1399+#define DBUSMENU_SERVER_PROP_VERSION "version"
1400
1401 /**
1402 DbusmenuServerClass:
1403
1404=== modified file 'libdbusmenu-gtk/Makefile.am'
1405--- libdbusmenu-gtk/Makefile.am 2009-10-01 19:22:18 +0000
1406+++ libdbusmenu-gtk/Makefile.am 2010-01-08 14:45:24 +0000
1407@@ -15,6 +15,8 @@
1408 libdbusmenu_gtk_la_SOURCES = \
1409 client.h \
1410 client.c \
1411+ genericmenuitem.h \
1412+ genericmenuitem.c \
1413 menu.h \
1414 menu.c \
1415 menuitem.h \
1416
1417=== modified file 'libdbusmenu-gtk/client.c'
1418--- libdbusmenu-gtk/client.c 2009-12-10 16:30:09 +0000
1419+++ libdbusmenu-gtk/client.c 2010-01-08 14:45:24 +0000
1420@@ -34,6 +34,7 @@
1421
1422 #include "client.h"
1423 #include "menuitem.h"
1424+#include "genericmenuitem.h"
1425
1426 /* Prototypes */
1427 static void dbusmenu_gtkclient_class_init (DbusmenuGtkClientClass *klass);
1428@@ -47,10 +48,10 @@
1429
1430 static gboolean new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
1431 static gboolean new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
1432-static gboolean new_item_image (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
1433
1434-static void process_visible (GtkMenuItem * gmi, const gchar * value);
1435-static void process_sensitive (GtkMenuItem * gmi, const gchar * value);
1436+static void process_visible (DbusmenuMenuitem * mi, GtkMenuItem * gmi, const GValue * value);
1437+static void process_sensitive (DbusmenuMenuitem * mi, GtkMenuItem * gmi, const GValue * value);
1438+static void image_property_handle (DbusmenuMenuitem * item, const gchar * property, const GValue * invalue, gpointer userdata);
1439
1440 /* GObject Stuff */
1441 G_DEFINE_TYPE (DbusmenuGtkClient, dbusmenu_gtkclient, DBUSMENU_TYPE_CLIENT);
1442@@ -74,7 +75,6 @@
1443 {
1444 dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(self), DBUSMENU_CLIENT_TYPES_DEFAULT, new_item_normal);
1445 dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(self), DBUSMENU_CLIENT_TYPES_SEPARATOR, new_item_seperator);
1446- dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(self), DBUSMENU_CLIENT_TYPES_IMAGE, new_item_image);
1447
1448 g_signal_connect(G_OBJECT(self), DBUSMENU_CLIENT_SIGNAL_NEW_MENUITEM, G_CALLBACK(new_menuitem), NULL);
1449
1450@@ -115,9 +115,14 @@
1451
1452 /* Process the visible property */
1453 static void
1454-process_visible (GtkMenuItem * gmi, const gchar * value)
1455+process_visible (DbusmenuMenuitem * mi, GtkMenuItem * gmi, const GValue * value)
1456 {
1457- if (value == NULL || !g_strcmp0(value, "true")) {
1458+ gboolean val = TRUE;
1459+ if (value != NULL) {
1460+ val = dbusmenu_menuitem_property_get_bool(mi, DBUSMENU_MENUITEM_PROP_VISIBLE);
1461+ }
1462+
1463+ if (val) {
1464 gtk_widget_show(GTK_WIDGET(gmi));
1465 } else {
1466 gtk_widget_hide(GTK_WIDGET(gmi));
1467@@ -127,27 +132,76 @@
1468
1469 /* Process the sensitive property */
1470 static void
1471-process_sensitive (GtkMenuItem * gmi, const gchar * value)
1472-{
1473- if (value == NULL || !g_strcmp0(value, "true")) {
1474- gtk_widget_set_sensitive(GTK_WIDGET(gmi), TRUE);
1475- } else {
1476- gtk_widget_set_sensitive(GTK_WIDGET(gmi), FALSE);
1477- }
1478+process_sensitive (DbusmenuMenuitem * mi, GtkMenuItem * gmi, const GValue * value)
1479+{
1480+ gboolean val = TRUE;
1481+ if (value != NULL) {
1482+ val = dbusmenu_menuitem_property_get_bool(mi, DBUSMENU_MENUITEM_PROP_SENSITIVE);
1483+ }
1484+ gtk_widget_set_sensitive(GTK_WIDGET(gmi), val);
1485+ return;
1486+}
1487+
1488+/* Process the sensitive property */
1489+static void
1490+process_toggle_type (DbusmenuMenuitem * mi, GtkMenuItem * gmi, const GValue * value)
1491+{
1492+ if (!IS_GENERICMENUITEM(gmi)) return;
1493+
1494+ GenericmenuitemCheckType type = GENERICMENUITEM_CHECK_TYPE_NONE;
1495+
1496+ if (value != NULL && G_VALUE_TYPE(value) == G_TYPE_STRING) {
1497+ const gchar * strval = g_value_get_string(value);
1498+
1499+ if (!g_strcmp0(strval, DBUSMENU_MENUITEM_TOGGLE_CHECK)) {
1500+ type = GENERICMENUITEM_CHECK_TYPE_CHECKBOX;
1501+ } else if (!g_strcmp0(strval, DBUSMENU_MENUITEM_TOGGLE_RADIO)) {
1502+ type = GENERICMENUITEM_CHECK_TYPE_RADIO;
1503+ }
1504+ }
1505+
1506+ genericmenuitem_set_check_type(GENERICMENUITEM(gmi), type);
1507+
1508+ return;
1509+}
1510+
1511+/* Process the sensitive property */
1512+static void
1513+process_toggle_checked (DbusmenuMenuitem * mi, GtkMenuItem * gmi, const GValue * value)
1514+{
1515+ if (!IS_GENERICMENUITEM(gmi)) return;
1516+
1517+ GenericmenuitemState state = GENERICMENUITEM_STATE_UNCHECKED;
1518+
1519+ if (value != NULL && G_VALUE_TYPE(value) == G_TYPE_STRING) {
1520+ const gchar * strval = g_value_get_string(value);
1521+
1522+ if (!g_strcmp0(strval, DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED)) {
1523+ state = GENERICMENUITEM_STATE_CHECKED;
1524+ } else if (!g_strcmp0(strval, DBUSMENU_MENUITEM_TOGGLE_STATE_UNKNOWN)) {
1525+ state = GENERICMENUITEM_STATE_INDETERMINATE;
1526+ }
1527+ }
1528+
1529+ genericmenuitem_set_state(GENERICMENUITEM(gmi), state);
1530 return;
1531 }
1532
1533 /* Whenever we have a property change on a DbusmenuMenuitem
1534 we need to be responsive to that. */
1535 static void
1536-menu_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, gchar * value, GtkMenuItem * gmi)
1537+menu_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkMenuItem * gmi)
1538 {
1539 if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_LABEL)) {
1540- gtk_menu_item_set_label(gmi, value);
1541+ gtk_menu_item_set_label(gmi, g_value_get_string(value));
1542 } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_VISIBLE)) {
1543- process_visible(gmi, value);
1544+ process_visible(mi, gmi, value);
1545 } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_SENSITIVE)) {
1546- process_sensitive(gmi, value);
1547+ process_sensitive(mi, gmi, value);
1548+ } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE)) {
1549+ process_toggle_type(mi, gmi, value);
1550+ } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_TOGGLE_CHECKED)) {
1551+ process_toggle_checked(mi, gmi, value);
1552 }
1553
1554 return;
1555@@ -228,9 +282,13 @@
1556 /* Life insurance */
1557 g_object_weak_ref(G_OBJECT(item), destoryed_dbusmenuitem_cb, gmi);
1558
1559- process_visible(gmi, dbusmenu_menuitem_property_get(item, DBUSMENU_MENUITEM_PROP_VISIBLE));
1560- process_sensitive(gmi, dbusmenu_menuitem_property_get(item, DBUSMENU_MENUITEM_PROP_SENSITIVE));
1561+ /* Check our set of props to see if any are set already */
1562+ process_visible(item, gmi, dbusmenu_menuitem_property_get_value(item, DBUSMENU_MENUITEM_PROP_VISIBLE));
1563+ process_sensitive(item, gmi, dbusmenu_menuitem_property_get_value(item, DBUSMENU_MENUITEM_PROP_SENSITIVE));
1564+ process_toggle_type(item, gmi, dbusmenu_menuitem_property_get_value(item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE));
1565+ process_toggle_checked(item, gmi, dbusmenu_menuitem_property_get_value(item, DBUSMENU_MENUITEM_PROP_TOGGLE_CHECKED));
1566
1567+ /* Oh, we're a child, let's deal with that */
1568 if (parent != NULL) {
1569 new_child(parent, item, dbusmenu_menuitem_get_position(item, parent), DBUSMENU_GTKCLIENT(client));
1570 }
1571@@ -358,8 +416,8 @@
1572 /* Note: not checking parent, it's reasonable for it to be NULL */
1573
1574 GtkMenuItem * gmi;
1575- gmi = GTK_MENU_ITEM(gtk_menu_item_new_with_label(dbusmenu_menuitem_property_get(newitem, DBUSMENU_MENUITEM_PROP_LABEL)));
1576- gtk_menu_item_set_use_underline (gmi, TRUE);
1577+ gmi = GTK_MENU_ITEM(g_object_new(GENERICMENUITEM_TYPE, NULL));
1578+ gtk_menu_item_set_label(gmi, dbusmenu_menuitem_property_get(newitem, DBUSMENU_MENUITEM_PROP_LABEL));
1579
1580 if (gmi != NULL) {
1581 dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent);
1582@@ -367,6 +425,19 @@
1583 return FALSE;
1584 }
1585
1586+ image_property_handle(newitem,
1587+ DBUSMENU_MENUITEM_PROP_ICON,
1588+ dbusmenu_menuitem_property_get_value(newitem, DBUSMENU_MENUITEM_PROP_ICON),
1589+ client);
1590+ image_property_handle(newitem,
1591+ DBUSMENU_MENUITEM_PROP_ICON_DATA,
1592+ dbusmenu_menuitem_property_get_value(newitem, DBUSMENU_MENUITEM_PROP_ICON_DATA),
1593+ client);
1594+ g_signal_connect(G_OBJECT(newitem),
1595+ DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED,
1596+ G_CALLBACK(image_property_handle),
1597+ client);
1598+
1599 return TRUE;
1600 }
1601
1602@@ -394,11 +465,17 @@
1603 /* This handler looks at property changes for items that are
1604 image menu items. */
1605 static void
1606-image_property_handle (DbusmenuMenuitem * item, const gchar * property, const gchar * value, gpointer userdata)
1607+image_property_handle (DbusmenuMenuitem * item, const gchar * property, const GValue * invalue, gpointer userdata)
1608 {
1609 /* We're only looking at these two properties here */
1610 g_return_if_fail(!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON) || !g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON_DATA));
1611
1612+ const gchar * value = NULL;
1613+
1614+ if (invalue != NULL && G_VALUE_TYPE(invalue) == G_TYPE_STRING) {
1615+ value = g_value_get_string(invalue);
1616+ }
1617+
1618 if (value == NULL || value[0] == '\0') {
1619 /* This means that we're unsetting a value. */
1620 /* Try to use the other one */
1621@@ -416,12 +493,12 @@
1622 g_warning("Oddly we're handling image properties on a menuitem that doesn't have any GTK structures associated with it.");
1623 return;
1624 }
1625- GtkWidget * gtkimage = gtk_image_menu_item_get_image(GTK_IMAGE_MENU_ITEM(gimi));
1626+ GtkWidget * gtkimage = genericmenuitem_get_image(GENERICMENUITEM(gimi));
1627
1628 if (!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON_DATA)) {
1629 /* If we have an image already built from a name that is
1630 way better than a pixbuf. Keep it. */
1631- if (gtk_image_get_storage_type(GTK_IMAGE(gtkimage)) == GTK_IMAGE_ICON_NAME) {
1632+ if (gtkimage != NULL && gtk_image_get_storage_type(GTK_IMAGE(gtkimage)) == GTK_IMAGE_ICON_NAME) {
1633 return;
1634 }
1635 }
1636@@ -474,42 +551,8 @@
1637
1638 }
1639
1640- gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(gimi), gtkimage);
1641+ genericmenuitem_set_image(GENERICMENUITEM(gimi), gtkimage);
1642
1643 return;
1644 }
1645
1646-/* This is a type call back for the image type where
1647- it uses the GtkImageMenuitem to create the menu item. */
1648-static gboolean
1649-new_item_image (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
1650-{
1651- g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
1652- g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
1653- /* Note: not checking parent, it's reasonable for it to be NULL */
1654-
1655- GtkMenuItem * gmi;
1656- gmi = GTK_MENU_ITEM(gtk_image_menu_item_new_with_label(dbusmenu_menuitem_property_get(newitem, DBUSMENU_MENUITEM_PROP_LABEL)));
1657- gtk_menu_item_set_use_underline (gmi, TRUE);
1658-
1659- if (gmi != NULL) {
1660- dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent);
1661- } else {
1662- return FALSE;
1663- }
1664-
1665- image_property_handle(newitem,
1666- DBUSMENU_MENUITEM_PROP_ICON,
1667- dbusmenu_menuitem_property_get(newitem, DBUSMENU_MENUITEM_PROP_ICON),
1668- client);
1669- image_property_handle(newitem,
1670- DBUSMENU_MENUITEM_PROP_ICON_DATA,
1671- dbusmenu_menuitem_property_get(newitem, DBUSMENU_MENUITEM_PROP_ICON_DATA),
1672- client);
1673- g_signal_connect(G_OBJECT(newitem),
1674- DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED,
1675- G_CALLBACK(image_property_handle),
1676- client);
1677-
1678- return TRUE;
1679-}
1680
1681=== added file 'libdbusmenu-gtk/genericmenuitem.c'
1682--- libdbusmenu-gtk/genericmenuitem.c 1970-01-01 00:00:00 +0000
1683+++ libdbusmenu-gtk/genericmenuitem.c 2010-01-08 14:45:24 +0000
1684@@ -0,0 +1,444 @@
1685+/*
1686+A menuitem subclass that has the ability to do lots of different
1687+things depending on it's settings.
1688+
1689+Copyright 2009 Canonical Ltd.
1690+
1691+Authors:
1692+ Ted Gould <ted@canonical.com>
1693+
1694+This program is free software: you can redistribute it and/or modify it
1695+under the terms of either or both of the following licenses:
1696+
1697+1) the GNU Lesser General Public License version 3, as published by the
1698+Free Software Foundation; and/or
1699+2) the GNU Lesser General Public License version 2.1, as published by
1700+the Free Software Foundation.
1701+
1702+This program is distributed in the hope that it will be useful, but
1703+WITHOUT ANY WARRANTY; without even the implied warranties of
1704+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
1705+PURPOSE. See the applicable version of the GNU Lesser General Public
1706+License for more details.
1707+
1708+You should have received a copy of both the GNU Lesser General Public
1709+License version 3 and version 2.1 along with this program. If not, see
1710+<http://www.gnu.org/licenses/>
1711+*/
1712+
1713+#ifdef HAVE_CONFIG_H
1714+#include "config.h"
1715+#endif
1716+
1717+#include "genericmenuitem.h"
1718+
1719+/**
1720+ GenericmenuitemPrivate:
1721+ @check_type: What type of check we have, or none at all.
1722+ @state: What the state of our check is.
1723+*/
1724+struct _GenericmenuitemPrivate {
1725+ GenericmenuitemCheckType check_type;
1726+ GenericmenuitemState state;
1727+};
1728+
1729+/* Private macro */
1730+#define GENERICMENUITEM_GET_PRIVATE(o) \
1731+(G_TYPE_INSTANCE_GET_PRIVATE ((o), GENERICMENUITEM_TYPE, GenericmenuitemPrivate))
1732+
1733+/* Prototypes */
1734+static void genericmenuitem_class_init (GenericmenuitemClass *klass);
1735+static void genericmenuitem_init (Genericmenuitem *self);
1736+static void genericmenuitem_dispose (GObject *object);
1737+static void genericmenuitem_finalize (GObject *object);
1738+static void draw_indicator (GtkCheckMenuItem *check_menu_item, GdkRectangle *area);
1739+static void set_label (GtkMenuItem * menu_item, const gchar * label);
1740+static const gchar * get_label (GtkMenuItem * menu_item);
1741+static void activate (GtkMenuItem * menu_item);
1742+
1743+/* GObject stuff */
1744+G_DEFINE_TYPE (Genericmenuitem, genericmenuitem, GTK_TYPE_CHECK_MENU_ITEM);
1745+
1746+/* Globals */
1747+static void (*parent_draw_indicator) (GtkCheckMenuItem *check_menu_item, GdkRectangle *area) = NULL;
1748+
1749+/* Initializing all of the classes. Most notably we're
1750+ disabling the drawing of the check early. */
1751+static void
1752+genericmenuitem_class_init (GenericmenuitemClass *klass)
1753+{
1754+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
1755+
1756+ g_type_class_add_private (klass, sizeof (GenericmenuitemPrivate));
1757+
1758+ object_class->dispose = genericmenuitem_dispose;
1759+ object_class->finalize = genericmenuitem_finalize;
1760+
1761+ GtkCheckMenuItemClass * check_class = GTK_CHECK_MENU_ITEM_CLASS (klass);
1762+
1763+ parent_draw_indicator = check_class->draw_indicator;
1764+ check_class->draw_indicator = draw_indicator;
1765+
1766+ GtkMenuItemClass * menuitem_class = GTK_MENU_ITEM_CLASS (klass);
1767+ menuitem_class->set_label = set_label;
1768+ menuitem_class->get_label = get_label;
1769+ menuitem_class->activate = activate;
1770+
1771+ return;
1772+}
1773+
1774+/* Sets default values for all the class variables. Mostly,
1775+ this puts us in a default state. */
1776+static void
1777+genericmenuitem_init (Genericmenuitem *self)
1778+{
1779+ self->priv = GENERICMENUITEM_GET_PRIVATE(self);
1780+
1781+ self->priv->check_type = GENERICMENUITEM_CHECK_TYPE_NONE;
1782+ self->priv->state = GENERICMENUITEM_STATE_UNCHECKED;
1783+
1784+ return;
1785+}
1786+
1787+/* Clean everything up. Whew, that can be work. */
1788+static void
1789+genericmenuitem_dispose (GObject *object)
1790+{
1791+
1792+ G_OBJECT_CLASS (genericmenuitem_parent_class)->dispose (object);
1793+ return;
1794+}
1795+
1796+/* Now free memory, we no longer need it. */
1797+static void
1798+genericmenuitem_finalize (GObject *object)
1799+{
1800+
1801+ G_OBJECT_CLASS (genericmenuitem_parent_class)->finalize (object);
1802+ return;
1803+}
1804+
1805+/* Checks to see if we should be drawing a little box at
1806+ all. If we should be, let's do that, otherwise we're
1807+ going suppress the box drawing. */
1808+static void
1809+draw_indicator (GtkCheckMenuItem *check_menu_item, GdkRectangle *area)
1810+{
1811+ Genericmenuitem * self = GENERICMENUITEM(check_menu_item);
1812+ if (self->priv->check_type != GENERICMENUITEM_CHECK_TYPE_NONE) {
1813+ parent_draw_indicator(check_menu_item, area);
1814+ }
1815+ return;
1816+}
1817+
1818+/* A small helper to look through the widgets in the
1819+ box and find the one that is the label. */
1820+static void
1821+set_label_helper (GtkWidget * widget, gpointer data)
1822+{
1823+ GtkWidget ** labelval = (GtkWidget **)data;
1824+ if (GTK_IS_LABEL(widget)) {
1825+ *labelval = widget;
1826+ }
1827+ return;
1828+}
1829+
1830+/* Set the label on the item */
1831+static void
1832+set_label (GtkMenuItem * menu_item, const gchar * label)
1833+{
1834+ GtkWidget * child = gtk_bin_get_child(GTK_BIN(menu_item));
1835+ GtkLabel * labelw = NULL;
1836+ gboolean suppress_update = FALSE;
1837+
1838+ /* Try to find if we have a label already */
1839+ if (child != NULL) {
1840+ if (GTK_IS_LABEL(child)) {
1841+ /* We've got a label, let's update it. */
1842+ labelw = GTK_LABEL(child);
1843+ } else if (GTK_IS_BOX(child)) {
1844+ /* Look for the label in the box */
1845+ gtk_container_foreach(GTK_CONTAINER(child), set_label_helper, &labelw);
1846+ } else {
1847+ /* We need to put the child into a new box and
1848+ make the box the child of the menu item. Basically
1849+ we're inserting a box in the middle. */
1850+ GtkWidget * hbox = gtk_hbox_new(FALSE, 0);
1851+ g_object_ref(child);
1852+ gtk_container_remove(GTK_CONTAINER(menu_item), child);
1853+ gtk_box_pack_start(GTK_BOX(hbox), child, FALSE, FALSE, 0);
1854+ gtk_container_add(GTK_CONTAINER(menu_item), hbox);
1855+ gtk_widget_show(hbox);
1856+ g_object_unref(child);
1857+ child = hbox;
1858+ /* It's important to notice that labelw is not set
1859+ by this condition. There was no label to find. */
1860+ }
1861+ }
1862+
1863+ /* No we can see if we need to ethier build a label or just
1864+ update the one that we already have. */
1865+ if (labelw == NULL) {
1866+ /* Build it */
1867+ labelw = GTK_LABEL(gtk_label_new(label));
1868+ gtk_label_set_use_underline(GTK_LABEL(labelw), TRUE);
1869+ gtk_misc_set_alignment(GTK_MISC(labelw), 0.0, 0.5);
1870+ gtk_widget_show(GTK_WIDGET(labelw));
1871+
1872+ /* Check to see if it needs to be in the bin for this
1873+ menu item or whether it gets packed in a box. */
1874+ if (child == NULL) {
1875+ gtk_container_add(GTK_CONTAINER(menu_item), GTK_WIDGET(labelw));
1876+ } else {
1877+ gtk_box_pack_end(GTK_BOX(child), GTK_WIDGET(labelw), TRUE, TRUE, 0);
1878+ }
1879+ } else {
1880+ /* Oh, just an update. No biggie. */
1881+ if (!g_strcmp0(label, gtk_label_get_label(labelw))) {
1882+ /* The only reason to suppress the update is if we had
1883+ a label and the value was the same as the one we're
1884+ getting in. */
1885+ suppress_update = TRUE;
1886+ } else {
1887+ gtk_label_set_label(labelw, label);
1888+ }
1889+ }
1890+
1891+ /* If we changed the value, tell folks. */
1892+ if (!suppress_update) {
1893+ g_object_notify(G_OBJECT(menu_item), "label");
1894+ }
1895+
1896+ return;
1897+}
1898+
1899+/* Get the text of the label for the item */
1900+static const gchar *
1901+get_label (GtkMenuItem * menu_item)
1902+{
1903+ GtkWidget * child = gtk_bin_get_child(GTK_BIN(menu_item));
1904+ GtkLabel * labelw = NULL;
1905+
1906+ /* Try to find if we have a label already */
1907+ if (child != NULL) {
1908+ if (GTK_IS_LABEL(child)) {
1909+ /* We've got a label, let's update it. */
1910+ labelw = GTK_LABEL(child);
1911+ } else if (GTK_IS_BOX(child)) {
1912+ /* Look for the label in the box */
1913+ gtk_container_foreach(GTK_CONTAINER(child), set_label_helper, &labelw);
1914+ }
1915+ }
1916+
1917+ if (labelw != NULL) {
1918+ return gtk_label_get_label(labelw);
1919+ }
1920+
1921+ return NULL;
1922+}
1923+
1924+/* Make sure we don't toggle when there is an
1925+ activate like a normal check menu item. */
1926+static void
1927+activate (GtkMenuItem * menu_item)
1928+{
1929+ return;
1930+}
1931+
1932+/**
1933+ genericmenuitem_set_check_type:
1934+ @item: #Genericmenuitem to set the type on
1935+ @check_type: Which type of check should be displayed
1936+
1937+ This function changes the type of the checkmark that
1938+ appears in the left hand gutter for the menuitem.
1939+*/
1940+void
1941+genericmenuitem_set_check_type (Genericmenuitem * item, GenericmenuitemCheckType check_type)
1942+{
1943+ if (item->priv->check_type == check_type) {
1944+ return;
1945+ }
1946+
1947+ item->priv->check_type = check_type;
1948+ GValue value = {0};
1949+
1950+ switch (item->priv->check_type) {
1951+ case GENERICMENUITEM_CHECK_TYPE_NONE:
1952+ /* We don't need to do anything here as we're queuing the
1953+ draw and then when it draws it'll avoid drawing the
1954+ check on the item. */
1955+ break;
1956+ case GENERICMENUITEM_CHECK_TYPE_CHECKBOX:
1957+ g_value_init(&value, G_TYPE_BOOLEAN);
1958+ g_value_set_boolean(&value, FALSE);
1959+ g_object_set_property(G_OBJECT(item), "draw-as-radio", &value);
1960+ break;
1961+ case GENERICMENUITEM_CHECK_TYPE_RADIO:
1962+ g_value_init(&value, G_TYPE_BOOLEAN);
1963+ g_value_set_boolean(&value, TRUE);
1964+ g_object_set_property(G_OBJECT(item), "draw-as-radio", &value);
1965+ break;
1966+ default:
1967+ g_warning("Generic Menuitem invalid check type: %d", check_type);
1968+ return;
1969+ }
1970+
1971+ gtk_widget_queue_draw(GTK_WIDGET(item));
1972+
1973+ return;
1974+}
1975+
1976+/**
1977+ genericmenuitem_set_state:
1978+ @item: #Genericmenuitem to set the type on
1979+ @check_type: What is the state of the check
1980+
1981+ Sets the state of the check in the menu item. It does
1982+ not require, but isn't really useful if the type of
1983+ check that the menuitem is set to #GENERICMENUITEM_CHECK_TYPE_NONE.
1984+*/
1985+void
1986+genericmenuitem_set_state (Genericmenuitem * item, GenericmenuitemState state)
1987+{
1988+ if (item->priv->state == state) {
1989+ return;
1990+ }
1991+
1992+ item->priv->state = state;
1993+
1994+ GtkCheckMenuItem * check = GTK_CHECK_MENU_ITEM(item);
1995+
1996+ gboolean old_active = check->active;
1997+ gboolean old_inconsist = check->inconsistent;
1998+
1999+ switch (item->priv->state) {
2000+ case GENERICMENUITEM_STATE_UNCHECKED:
2001+ check->active = FALSE;
2002+ check->inconsistent = FALSE;
2003+ break;
2004+ case GENERICMENUITEM_STATE_CHECKED:
2005+ check->active = TRUE;
2006+ check->inconsistent = FALSE;
2007+ break;
2008+ case GENERICMENUITEM_STATE_INDETERMINATE:
2009+ check->active = TRUE;
2010+ check->inconsistent = TRUE;
2011+ break;
2012+ default:
2013+ g_warning("Generic Menuitem invalid check state: %d", state);
2014+ return;
2015+ }
2016+
2017+ if (old_active != check->active) {
2018+ g_object_notify(G_OBJECT(item), "active");
2019+ }
2020+
2021+ if (old_inconsist != check->inconsistent) {
2022+ g_object_notify(G_OBJECT(item), "inconsistent");
2023+ }
2024+
2025+ gtk_widget_queue_draw(GTK_WIDGET(item));
2026+
2027+ return;
2028+}
2029+
2030+/* A small helper to look through the widgets in the
2031+ box and find the one that is the image. */
2032+static void
2033+set_image_helper (GtkWidget * widget, gpointer data)
2034+{
2035+ GtkWidget ** labelval = (GtkWidget **)data;
2036+ if (GTK_IS_IMAGE(widget)) {
2037+ *labelval = widget;
2038+ }
2039+ return;
2040+}
2041+
2042+/**
2043+ genericmenuitem_set_image:
2044+ @item: A #Genericmenuitem
2045+ @image: The image to set as the image of @item
2046+
2047+ Sets the image of the menu item.
2048+*/
2049+void
2050+genericmenuitem_set_image (Genericmenuitem * menu_item, GtkWidget * image)
2051+{
2052+ GtkWidget * child = gtk_bin_get_child(GTK_BIN(menu_item));
2053+ GtkImage * imagew = NULL;
2054+
2055+ /* Try to find if we have a label already */
2056+ if (child != NULL) {
2057+ if (GTK_IS_IMAGE(child)) {
2058+ /* We've got a label, let's update it. */
2059+ imagew = GTK_IMAGE(child);
2060+ } else if (GTK_IS_BOX(child)) {
2061+ /* Look for the label in the box */
2062+ gtk_container_foreach(GTK_CONTAINER(child), set_image_helper, &imagew);
2063+ } else if (image != NULL) {
2064+ /* We need to put the child into a new box and
2065+ make the box the child of the menu item. Basically
2066+ we're inserting a box in the middle. */
2067+ GtkWidget * hbox = gtk_hbox_new(FALSE, 0);
2068+ g_object_ref(child);
2069+ gtk_container_remove(GTK_CONTAINER(menu_item), child);
2070+ gtk_box_pack_end(GTK_BOX(hbox), child, TRUE, TRUE, 0);
2071+ gtk_container_add(GTK_CONTAINER(menu_item), hbox);
2072+ gtk_widget_show(hbox);
2073+ g_object_unref(child);
2074+ child = hbox;
2075+ /* It's important to notice that imagew is not set
2076+ by this condition. There was no label to find. */
2077+ }
2078+ }
2079+
2080+ /* No we can see if we need to ethier replace and image or
2081+ just put ourselves into the structures */
2082+ if (imagew != NULL) {
2083+ gtk_widget_destroy(GTK_WIDGET(imagew));
2084+ }
2085+
2086+ /* Check to see if it needs to be in the bin for this
2087+ menu item or whether it gets packed in a box. */
2088+ if (image != NULL) {
2089+ if (child == NULL) {
2090+ gtk_container_add(GTK_CONTAINER(menu_item), GTK_WIDGET(image));
2091+ } else {
2092+ gtk_box_pack_start(GTK_BOX(child), GTK_WIDGET(image), FALSE, FALSE, 0);
2093+ }
2094+
2095+ gtk_widget_show(image);
2096+ }
2097+
2098+ return;
2099+}
2100+
2101+/**
2102+ genericmenuitem_get_image:
2103+ @item: A #Genericmenuitem
2104+
2105+ Returns the image if there is one.
2106+
2107+ Return value: A pointer to the image of the item or #NULL
2108+ if there isn't one.
2109+*/
2110+GtkWidget *
2111+genericmenuitem_get_image (Genericmenuitem * menu_item)
2112+{
2113+ GtkWidget * child = gtk_bin_get_child(GTK_BIN(menu_item));
2114+ GtkWidget * imagew = NULL;
2115+
2116+ /* Try to find if we have a label already */
2117+ if (child != NULL) {
2118+ if (GTK_IS_IMAGE(child)) {
2119+ /* We've got a label, let's update it. */
2120+ imagew = child;
2121+ } else if (GTK_IS_BOX(child)) {
2122+ /* Look for the label in the box */
2123+ gtk_container_foreach(GTK_CONTAINER(child), set_image_helper, &imagew);
2124+ }
2125+ }
2126+
2127+ return imagew;
2128+}
2129
2130=== added file 'libdbusmenu-gtk/genericmenuitem.h'
2131--- libdbusmenu-gtk/genericmenuitem.h 1970-01-01 00:00:00 +0000
2132+++ libdbusmenu-gtk/genericmenuitem.h 2010-01-08 14:45:24 +0000
2133@@ -0,0 +1,91 @@
2134+/*
2135+A menuitem subclass that has the ability to do lots of different
2136+things depending on it's settings.
2137+
2138+Copyright 2009 Canonical Ltd.
2139+
2140+Authors:
2141+ Ted Gould <ted@canonical.com>
2142+
2143+This program is free software: you can redistribute it and/or modify it
2144+under the terms of either or both of the following licenses:
2145+
2146+1) the GNU Lesser General Public License version 3, as published by the
2147+Free Software Foundation; and/or
2148+2) the GNU Lesser General Public License version 2.1, as published by
2149+the Free Software Foundation.
2150+
2151+This program is distributed in the hope that it will be useful, but
2152+WITHOUT ANY WARRANTY; without even the implied warranties of
2153+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
2154+PURPOSE. See the applicable version of the GNU Lesser General Public
2155+License for more details.
2156+
2157+You should have received a copy of both the GNU Lesser General Public
2158+License version 3 and version 2.1 along with this program. If not, see
2159+<http://www.gnu.org/licenses/>
2160+*/
2161+
2162+#ifndef __GENERICMENUITEM_H__
2163+#define __GENERICMENUITEM_H__
2164+
2165+#include <glib.h>
2166+#include <glib-object.h>
2167+#include <gtk/gtk.h>
2168+
2169+G_BEGIN_DECLS
2170+
2171+#define GENERICMENUITEM_TYPE (genericmenuitem_get_type ())
2172+#define GENERICMENUITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GENERICMENUITEM_TYPE, Genericmenuitem))
2173+#define GENERICMENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GENERICMENUITEM_TYPE, GenericmenuitemClass))
2174+#define IS_GENERICMENUITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GENERICMENUITEM_TYPE))
2175+#define IS_GENERICMENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GENERICMENUITEM_TYPE))
2176+#define GENERICMENUITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GENERICMENUITEM_TYPE, GenericmenuitemClass))
2177+
2178+typedef struct _Genericmenuitem Genericmenuitem;
2179+typedef struct _GenericmenuitemClass GenericmenuitemClass;
2180+typedef struct _GenericmenuitemPrivate GenericmenuitemPrivate;
2181+typedef enum _GenericmenuitemCheckType GenericmenuitemCheckType;
2182+typedef enum _GenericmenuitemState GenericmenuitemState;
2183+
2184+/**
2185+ GenericmenuitemClass:
2186+ @parent_class: Our parent #GtkCheckMenuItemClass
2187+*/
2188+struct _GenericmenuitemClass {
2189+ GtkCheckMenuItemClass parent_class;
2190+};
2191+
2192+/**
2193+ Genericmenuitem:
2194+ @parent: Our parent #GtkCheckMenuItem
2195+*/
2196+struct _Genericmenuitem {
2197+ GtkCheckMenuItem parent;
2198+ GenericmenuitemPrivate * priv;
2199+};
2200+
2201+enum _GenericmenuitemCheckType {
2202+ GENERICMENUITEM_CHECK_TYPE_NONE,
2203+ GENERICMENUITEM_CHECK_TYPE_CHECKBOX,
2204+ GENERICMENUITEM_CHECK_TYPE_RADIO
2205+};
2206+
2207+enum _GenericmenuitemState {
2208+ GENERICMENUITEM_STATE_UNCHECKED,
2209+ GENERICMENUITEM_STATE_CHECKED,
2210+ GENERICMENUITEM_STATE_INDETERMINATE
2211+};
2212+
2213+GType genericmenuitem_get_type (void);
2214+void genericmenuitem_set_check_type (Genericmenuitem * item,
2215+ GenericmenuitemCheckType check_type);
2216+void genericmenuitem_set_state (Genericmenuitem * item,
2217+ GenericmenuitemState state);
2218+void genericmenuitem_set_image (Genericmenuitem * item,
2219+ GtkWidget * image);
2220+GtkWidget * genericmenuitem_get_image (Genericmenuitem * item);
2221+
2222+G_END_DECLS
2223+
2224+#endif
2225
2226=== removed directory 'libdbusmenu-qt'
2227=== removed file 'libdbusmenu-qt/Makefile.am'
2228--- libdbusmenu-qt/Makefile.am 2009-03-25 20:09:14 +0000
2229+++ libdbusmenu-qt/Makefile.am 1970-01-01 00:00:00 +0000
2230@@ -1,29 +0,0 @@
2231-
2232-EXTRA_DIST = \
2233- dbusmenu-qt.pc.in
2234-
2235-lib_LTLIBRARIES = \
2236- libdbusmenu-qt.la
2237-
2238-libdbusmenu_qtincludedir=$(includedir)/libdbusmenu-0.1/libdbusmenu-qt/
2239-
2240-libdbusmenu_qtinclude_HEADERS = \
2241- test.h
2242-
2243-libdbusmenu_qt_la_SOURCES = \
2244- test.c
2245-
2246-libdbusmenu_qt_la_LDFLAGS = \
2247- -version-info $(LIBDBUSMENU_CURRENT):$(LIBDBUSMENU_REVISION):$(LIBDBUSMENU_AGE) \
2248- -no-undefined \
2249- -export-symbols-regex "^[^_].*"
2250-
2251-libdbusmenu_qt_la_CFLAGS = \
2252- $(LIBDBUSMENU_QT_CFLAGS)
2253-
2254-libdbusmenu_qt_la_LIBADD = \
2255- $(LIBDBUSMENU_QT_LIBS)
2256-
2257-pkgconfig_DATA = dbusmenu-qt.pc
2258-pkgconfigdir = $(libdir)/pkgconfig
2259-
2260
2261=== removed file 'libdbusmenu-qt/dbusmenu-qt.pc.in'
2262--- libdbusmenu-qt/dbusmenu-qt.pc.in 2009-03-25 20:09:14 +0000
2263+++ libdbusmenu-qt/dbusmenu-qt.pc.in 1970-01-01 00:00:00 +0000
2264@@ -1,14 +0,0 @@
2265-prefix=@prefix@
2266-exec_prefix=@exec_prefix@
2267-libdir=@libdir@
2268-bindir=@bindir@
2269-includedir=@includedir@
2270-
2271-Cflags: -I${includedir}/libdbusmenu-0.1
2272-Requires: dbus-glib-1 dbusmenu-glib
2273-Libs: -L${libdir} -ldbusmenu-qt
2274-
2275-Name: libdbusmenu-qt
2276-Description: libdbusmenu-qt.
2277-Version: @VERSION@
2278-
2279
2280=== removed file 'libdbusmenu-qt/test.c'
2281--- libdbusmenu-qt/test.c 2009-03-25 20:09:14 +0000
2282+++ libdbusmenu-qt/test.c 1970-01-01 00:00:00 +0000
2283@@ -1,4 +0,0 @@
2284-
2285-void mysymbol (void) {
2286- return;
2287-}
2288
2289=== removed file 'libdbusmenu-qt/test.h'
2290--- libdbusmenu-qt/test.h 2009-03-25 20:09:14 +0000
2291+++ libdbusmenu-qt/test.h 1970-01-01 00:00:00 +0000
2292@@ -1,2 +0,0 @@
2293-
2294-void mysymbol (void);
2295
2296=== modified file 'tests/Makefile.am'
2297--- tests/Makefile.am 2009-12-10 18:39:41 +0000
2298+++ tests/Makefile.am 2010-01-08 14:45:24 +0000
2299@@ -1,16 +1,17 @@
2300-SUBDIRS = dbusmenu-gtk
2301
2302-DBUS_RUNNER=dbus-test-runner --dbus-config /usr/share/dbus-test-runner/session.conf
2303+DBUS_RUNNER=dbus-test-runner
2304
2305 TESTS = \
2306+ test-glib-objects-test \
2307 test-glib-layout \
2308 test-glib-properties \
2309+ test-glib-simple-items \
2310 test-gtk-label \
2311- test-glib-simple-items \
2312 test-gtk-reorder
2313
2314 check_PROGRAMS = \
2315 glib-server-nomenu \
2316+ test-glib-objects \
2317 test-glib-layout-client \
2318 test-glib-layout-server \
2319 test-glib-properties-client \
2320@@ -20,6 +21,12 @@
2321 test-glib-simple-items \
2322 test-gtk-reorder-server
2323
2324+XVFB_RUN=". $(srcdir)/run-xvfb.sh"
2325+
2326+######################
2327+# Test GLib server
2328+######################
2329+
2330 glib_server_nomenu_SOURCES = \
2331 glib-server-nomenu.c
2332
2333@@ -35,10 +42,10 @@
2334 # Test Glib Layout
2335 ######################
2336
2337-test-glib-layout: test-glib-layout-client test-glib-layout-server
2338- @echo "#!/bin/sh" > test-glib-layout
2339- @echo $(DBUS_RUNNER) --task ./test-glib-layout-client --task-name Client --task ./test-glib-layout-server --task-name Server --ignore-return >> test-glib-layout
2340- @chmod +x test-glib-layout
2341+test-glib-layout: test-glib-layout-client test-glib-layout-server Makefile.am
2342+ @echo "#!/bin/bash" > $@
2343+ @echo $(DBUS_RUNNER) --task ./test-glib-layout-client --task-name Client --task ./test-glib-layout-server --task-name Server --ignore-return >> $@
2344+ @chmod +x $@
2345
2346 test_glib_layout_server_SOURCES = \
2347 test-glib-layout.h \
2348@@ -66,13 +73,35 @@
2349
2350
2351 ######################
2352+# Test Glib Object
2353+######################
2354+
2355+OBJECT_XML_REPORT = test-glib-objects.xml
2356+
2357+test-glib-objects-test: test-glib-objects Makefile.am
2358+ @echo "#!/bin/bash" > $@
2359+ @echo $(DBUS_RUNNER) --task gtester --parameter --verbose --parameter -k --parameter -o --parameter $(OBJECT_XML_REPORT) --parameter ./test-glib-objects >> $@
2360+ @chmod +x $@
2361+
2362+test_glib_objects_SOURCES = \
2363+ test-glib-objects.c
2364+
2365+test_glib_objects_CFLAGS = \
2366+ -I $(srcdir)/.. \
2367+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
2368+
2369+test_glib_objects_LDADD = \
2370+ ../libdbusmenu-glib/libdbusmenu-glib.la \
2371+ $(DBUSMENUGLIB_LIBS)
2372+
2373+######################
2374 # Test Glib Properties
2375 ######################
2376
2377-test-glib-properties: test-glib-properties-client test-glib-properties-server
2378- @echo "#!/bin/sh" > test-glib-properties
2379- @echo $(DBUS_RUNNER) --task ./test-glib-properties-client --task-name Client --task ./test-glib-properties-server --task-name Server --ignore-return >> test-glib-properties
2380- @chmod +x test-glib-properties
2381+test-glib-properties: test-glib-properties-client test-glib-properties-server Makefile.am
2382+ @echo "#!/bin/bash" > $@
2383+ @echo $(DBUS_RUNNER) --task ./test-glib-properties-client --task-name Client --task ./test-glib-properties-server --task-name Server --ignore-return >> $@
2384+ @chmod +x $@
2385
2386 test_glib_properties_server_SOURCES = \
2387 test-glib-properties.h \
2388@@ -117,10 +146,11 @@
2389 # Test GTK Label
2390 #########################
2391
2392-test-gtk-label: test-gtk-label-client test-gtk-label-server test-gtk-label.json
2393- @echo "#!/bin/sh" > test-gtk-label
2394- @echo $(DBUS_RUNNER) --task ./test-gtk-label-client --task-name Client --task ./test-gtk-label-server --parameter $(srcdir)/test-gtk-label.json --task-name Server --ignore-return >> test-gtk-label
2395- @chmod +x test-gtk-label
2396+test-gtk-label: test-gtk-label-client test-gtk-label-server test-gtk-label.json Makefile.am
2397+ @echo "#!/bin/bash" > $@
2398+ @echo $(XVFB_RUN) >> $@
2399+ @echo $(DBUS_RUNNER) --task ./test-gtk-label-client --task-name Client --task ./test-gtk-label-server --parameter $(srcdir)/test-gtk-label.json --task-name Server --ignore-return >> $@
2400+ @chmod +x $@
2401
2402 test_gtk_label_server_SOURCES = \
2403 test-gtk-label-server.c
2404@@ -156,10 +186,11 @@
2405 # Test GTK Reorder
2406 #########################
2407
2408-test-gtk-reorder: test-gtk-label-client test-gtk-reorder-server
2409- @echo "#!/bin/sh" > test-gtk-reorder
2410- @echo $(DBUS_RUNNER) --task ./test-gtk-label-client --task-name Client --task ./test-gtk-reorder-server --parameter $(srcdir)/test-gtk-label.json --task-name Server --ignore-return >> test-gtk-reorder
2411- @chmod +x test-gtk-reorder
2412+test-gtk-reorder: test-gtk-label-client test-gtk-reorder-server Makefile.am
2413+ @echo "#!/bin/bash" > $@
2414+ @echo $(XVFB_RUN) >> $@
2415+ @echo $(DBUS_RUNNER) --task ./test-gtk-label-client --task-name Client --task ./test-gtk-reorder-server --parameter $(srcdir)/test-gtk-label.json --task-name Server --ignore-return >> $@
2416+ @chmod +x $@
2417
2418 test_gtk_reorder_server_SOURCES = \
2419 test-gtk-reorder-server.c
2420@@ -176,6 +207,20 @@
2421 $(DBUSMENUGTK_LIBS) \
2422 $(DBUSMENUTESTS_LIBS)
2423
2424+#########################
2425+# Test Mago
2426+#########################
2427+
2428+test-mago: test-gtk-label-client test-gtk-label-server $(srcdir)/dbusmenu-gtk/mago_tests/dbusmenu.xml Makefile.am
2429+ @echo "#!/bin/bash" > $@
2430+ @echo $(XVFB_RUN) >> $@
2431+ @echo cd $(srcdir)/dbusmenu-gtk >> $@
2432+ @echo /usr/lib/at-spi/at-spi-registryd \& >> $@
2433+ @echo echo Mago Results dir: $(abs_builddir)/mago.results >> $@
2434+ @echo echo PYTHONPATH=$(abs_srcdir)/dbusmenu-gtk/mago_tests >> $@
2435+ @echo export INDICATOR_BUILD_DIR=$(abs_builddir) >> $@
2436+ @echo PYTHONPATH=$(abs_srcdir)/dbusmenu-gtk/mago_tests mago -f dbusmenu.xml -t $(abs_builddir)/mago.results --log-level=debug >> $@
2437+ @chmod +x $@
2438
2439 #########################
2440 # Other
2441@@ -188,7 +233,35 @@
2442
2443 EXTRA_DIST = \
2444 $(examples_DATA) \
2445- test-gtk-label.json
2446+ run-xvfb.sh \
2447+ test-gtk-label.json \
2448+ dbusmenu-gtk/dbusMenuTest \
2449+ dbusmenu-gtk/mago_tests/dbusmenu.xml \
2450+ dbusmenu-gtk/mago_tests/dbusmenu.py \
2451+ dbusmenu-gtk/mago_tests/data/blank_label_2levels.json \
2452+ dbusmenu-gtk/mago_tests/data/blank_label.json \
2453+ dbusmenu-gtk/mago_tests/data/blank_submenus.json \
2454+ dbusmenu-gtk/mago_tests/data/dynamic.json \
2455+ dbusmenu-gtk/mago_tests/data/long_label.json \
2456+ dbusmenu-gtk/mago_tests/data/no_id.json \
2457+ dbusmenu-gtk/mago_tests/data/no_label.json \
2458+ dbusmenu-gtk/mago_tests/data/sameid_submenus_diff_sizes.json \
2459+ dbusmenu-gtk/mago_tests/data/sameid_submenus.json \
2460+ dbusmenu-gtk/mago_tests/data/sameid_top_and_submenus.json \
2461+ dbusmenu-gtk/mago_tests/data/sameid_topmenu.json \
2462+ dbusmenu-gtk/mago_tests/data/several_submenus.json \
2463+ dbusmenu-gtk/mago_tests/data/several_submenus_recursive.json \
2464+ dbusmenu-gtk/mago_tests/data/several_submenus_utf8.json \
2465+ dbusmenu-gtk/mago_tests/data/static.json \
2466+ dbusmenu-gtk/mago_tests/data/test-gtk-label.json
2467+
2468+CLEANFILES = \
2469+ dbusmenu-gtk/mago_tests/dbusmenu.pyc
2470+
2471+distclean-local:
2472+ -rm -rf $(builddir)/mago.results
2473
2474 DISTCLEANFILES = \
2475- $(TESTS)
2476+ $(TESTS) \
2477+ $(OBJECT_XML_REPORT)
2478+
2479
2480=== removed file 'tests/dbusmenu-gtk/Makefile.am'
2481--- tests/dbusmenu-gtk/Makefile.am 2009-06-25 15:40:26 +0000
2482+++ tests/dbusmenu-gtk/Makefile.am 1970-01-01 00:00:00 +0000
2483@@ -1,43 +0,0 @@
2484-
2485-check: tests
2486-
2487-tests: mago
2488-
2489-mago: dbusmenu.xml dbusmenu.py
2490- PYTHONPATH=$(builddir) mago -f $(builddir)/dbusmenu.xml -t $(builddir)/mago.results
2491-
2492-dbusmenu.xml: dbusmenu.xml.in
2493- sed -e "s|\@srcdir\@|$(srcdir)|" $< > $@
2494-
2495-dbusmenu.py: dbusmenu.py.in
2496- sed -e "s|\@srcdir\@|$(srcdir)|" $< > $@
2497-
2498-EXTRA_DIST = \
2499- dbusmenu.xml.in \
2500- dbusmenu.py.in \
2501- dbusMenuTest \
2502- data/blank_label_2levels.json \
2503- data/blank_label.json \
2504- data/blank_submenus.json \
2505- data/dynamic.json \
2506- data/long_label.json \
2507- data/no_id.json \
2508- data/no_label.json \
2509- data/sameid_submenus_diff_sizes.json \
2510- data/sameid_submenus.json \
2511- data/sameid_top_and_submenus.json \
2512- data/sameid_topmenu.json \
2513- data/several_submenus.json \
2514- data/several_submenus_recursive.json \
2515- data/several_submenus_utf8.json \
2516- data/static.json \
2517- data/test-gtk-label.json
2518-
2519-CLEANFILES = \
2520- dbusmenu.xml \
2521- dbusmenu.pyc \
2522- dbusmenu.py
2523-
2524-distclean-local:
2525- -rm -rf $(builddir)/mago.results
2526-
2527
2528=== modified file 'tests/dbusmenu-gtk/dbusMenuTest'
2529--- tests/dbusmenu-gtk/dbusMenuTest 2009-12-10 18:39:41 +0000
2530+++ tests/dbusmenu-gtk/dbusMenuTest 2010-01-08 14:45:24 +0000
2531@@ -3,6 +3,6 @@
2532 export NO_GAIL=0
2533 export NO_AT_BRIDGE=0
2534
2535-dbus-test-runner --dbus-config /usr/share/dbus-test-runner/session.conf --task ../test-gtk-label-client --task-name Client --task ../test-gtk-label-server --parameter ./$1 --task-name Server --ignore-return
2536+dbus-test-runner --dbus-config /usr/share/dbus-test-runner/session.conf --task $INDICATOR_BUILD_DIR/test-gtk-label-client --task-name Client --task $INDICATOR_BUILD_DIR/test-gtk-label-server --parameter ./mago_tests/$1 --task-name Server --ignore-return
2537
2538
2539
2540=== added directory 'tests/dbusmenu-gtk/mago_tests'
2541=== renamed directory 'tests/dbusmenu-gtk/data' => 'tests/dbusmenu-gtk/mago_tests/data'
2542=== renamed file 'tests/dbusmenu-gtk/dbusmenu.py.in' => 'tests/dbusmenu-gtk/mago_tests/dbusmenu.py'
2543--- tests/dbusmenu-gtk/dbusmenu.py.in 2009-12-10 18:39:41 +0000
2544+++ tests/dbusmenu-gtk/mago_tests/dbusmenu.py 2010-01-08 14:45:24 +0000
2545@@ -1,10 +1,10 @@
2546 from mago.test_suite.main import SingleApplicationTestSuite
2547 from mago.application.main import Application
2548
2549-import ldtp, ooldtp, ldtputils
2550+import ldtp, ooldtp, ldtputils, os.path
2551
2552 class DbusMenuGtkApp():
2553- LAUNCHER = "@srcdir@/dbusMenuTest"
2554+ LAUNCHER = os.path.join(os.path.dirname(__file__), "..", "dbusMenuTest")
2555 WINDOW = "frmlibdbusmenu-gtktest"
2556
2557 def open(self, menu_schema=''):
2558
2559=== renamed file 'tests/dbusmenu-gtk/dbusmenu.xml.in' => 'tests/dbusmenu-gtk/mago_tests/dbusmenu.xml'
2560--- tests/dbusmenu-gtk/dbusmenu.xml.in 2009-12-10 18:39:41 +0000
2561+++ tests/dbusmenu-gtk/mago_tests/dbusmenu.xml 2010-01-08 14:45:24 +0000
2562@@ -8,7 +8,7 @@
2563 <method>testStaticMenu</method>
2564 <description>Simple check for a menu </description>
2565 <args>
2566- <menu_schema>@srcdir@/data/static.json</menu_schema>
2567+ <menu_schema>data/static.json</menu_schema>
2568 <menu_item>value39</menu_item>
2569 </args>
2570 </case>
2571@@ -16,7 +16,7 @@
2572 <method>testStaticMenu</method>
2573 <description>Blank Label</description>
2574 <args>
2575- <menu_schema>@srcdir@/data/blank_label.json</menu_schema>
2576+ <menu_schema>data/blank_label.json</menu_schema>
2577 <menu_item></menu_item>
2578 </args>
2579 </case>
2580@@ -24,7 +24,7 @@
2581 <method>testSubmenus</method>
2582 <description>Blank Submenus</description>
2583 <args>
2584- <menu_schema>@srcdir@/data/blank_submenus.json</menu_schema>
2585+ <menu_schema>data/blank_submenus.json</menu_schema>
2586 <menu_item>value6</menu_item>
2587 <submenus></submenus>
2588 </args>
2589@@ -33,7 +33,7 @@
2590 <method>testStaticMenu</method>
2591 <description>Really Long Label (1000 chars)</description>
2592 <args>
2593- <menu_schema>@srcdir@/data/long_label.json</menu_schema>
2594+ <menu_schema>data/long_label.json</menu_schema>
2595 <menu_item>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</menu_item>
2596 </args>
2597 </case>
2598@@ -41,7 +41,7 @@
2599 <method>testStaticMenu</method>
2600 <description>Search for a submenu that comes from a menu without ID</description>
2601 <args>
2602- <menu_schema>@srcdir@/data/no_id.json</menu_schema>
2603+ <menu_schema>data/no_id.json</menu_schema>
2604 <menu_item>submenu_from_no_id</menu_item>
2605 </args>
2606 </case>
2607@@ -49,7 +49,7 @@
2608 <method>testStaticMenu</method>
2609 <description>Search for a submenu that comes from a menu with a blank label</description>
2610 <args>
2611- <menu_schema>@srcdir@/data/blank_label_2levels.json</menu_schema>
2612+ <menu_schema>data/blank_label_2levels.json</menu_schema>
2613 <menu_item>value10</menu_item>
2614 </args>
2615 </case>
2616@@ -57,7 +57,7 @@
2617 <method>testStaticMenu</method>
2618 <description>Be sure that a submenu from a menu without label does not exist</description>
2619 <args>
2620- <menu_schema>@srcdir@/data/no_label.json</menu_schema>
2621+ <menu_schema>data/no_label.json</menu_schema>
2622 <menu_item>submenu_from_no_label</menu_item>
2623 <notexists>True</notexists>
2624 </args>
2625@@ -66,7 +66,7 @@
2626 <method>testStaticMenu</method>
2627 <description>Check that a submenu is shown</description>
2628 <args>
2629- <menu_schema>@srcdir@/data/several_submenus.json</menu_schema>
2630+ <menu_schema>data/several_submenus.json</menu_schema>
2631 <menu_item>value10</menu_item>
2632 </args>
2633 </case>
2634@@ -74,7 +74,7 @@
2635 <method>testStaticMenu</method>
2636 <description>Be sure that a submenu from a 4th level depth, is shown</description>
2637 <args>
2638- <menu_schema>@srcdir@/data/several_submenus_recursive.json</menu_schema>
2639+ <menu_schema>data/several_submenus_recursive.json</menu_schema>
2640 <menu_item>value7001</menu_item>
2641 </args>
2642 </case>
2643@@ -82,7 +82,7 @@
2644 <method>testStaticMenu</method>
2645 <description>Be sure that a submenu, with a UTF-8 label, is shown</description>
2646 <args>
2647- <menu_schema>@srcdir@/data/several_submenus_utf8.json</menu_schema>
2648+ <menu_schema>data/several_submenus_utf8.json</menu_schema>
2649 <menu_item>value5ス</menu_item>
2650 </args>
2651 </case>
2652
2653=== added file 'tests/run-xvfb.sh'
2654--- tests/run-xvfb.sh 1970-01-01 00:00:00 +0000
2655+++ tests/run-xvfb.sh 2010-01-08 14:45:24 +0000
2656@@ -0,0 +1,7 @@
2657+if [ "$DISPLAY" == "" ]; then
2658+Xvfb -ac -noreset -screen 0 800x600x16 -help 2>/dev/null 1>&2
2659+XID=`for id in 101 102 103 104 105 106 107 197 199 211 223 227 293 307 308 309 310 311 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 4703 4721 4723 4729 4733 4751 9973 9974 9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990 9991 9992 9993 9994 9995 9996 9997 9998 9999 ; do test -e /tmp/.X$id-lock || { echo $id; exit 0; }; done; exit 1`
2660+{ Xvfb -ac -noreset -screen 0 800x600x16 :$XID -screen 0 800x600x16 -nolisten tcp -auth /dev/null >/dev/null 2>&1 & trap "kill -15 $! " 0 HUP INT QUIT TRAP USR1 PIPE TERM ; } || { echo "Gtk+Tests:ERROR: Failed to start Xvfb environment for X11 target tests."; exit 1; }
2661+DISPLAY=:$XID
2662+export DISPLAY
2663+fi
2664
2665=== modified file 'tests/test-glib-layout-client.c'
2666--- tests/test-glib-layout-client.c 2009-12-10 18:39:41 +0000
2667+++ tests/test-glib-layout-client.c 2010-01-08 14:45:24 +0000
2668@@ -109,9 +109,7 @@
2669 {
2670 g_type_init();
2671
2672- g_usleep(500000);
2673-
2674- DbusmenuClient * client = dbusmenu_client_new(":1.0", "/org/test");
2675+ DbusmenuClient * client = dbusmenu_client_new("org.dbusmenu.test", "/org/test");
2676 g_signal_connect(G_OBJECT(client), DBUSMENU_CLIENT_SIGNAL_LAYOUT_UPDATED, G_CALLBACK(layout_updated), NULL);
2677
2678 g_timeout_add_seconds(10, timer_func, client);
2679@@ -126,6 +124,6 @@
2680 return 0;
2681 } else {
2682 g_debug("Quiting as we're a failure");
2683- return 0;
2684+ return 1;
2685 }
2686 }
2687
2688=== modified file 'tests/test-glib-layout-server.c'
2689--- tests/test-glib-layout-server.c 2009-05-27 08:11:12 +0000
2690+++ tests/test-glib-layout-server.c 2010-01-08 14:45:24 +0000
2691@@ -24,6 +24,7 @@
2692 #include <dbus/dbus.h>
2693 #include <dbus/dbus-glib.h>
2694 #include <dbus/dbus-glib-lowlevel.h>
2695+#include <dbus/dbus-glib-bindings.h>
2696
2697 #include <libdbusmenu-glib/server.h>
2698 #include <libdbusmenu-glib/menuitem.h>
2699@@ -74,10 +75,26 @@
2700 int
2701 main (int argc, char ** argv)
2702 {
2703+ GError * error = NULL;
2704+
2705 g_type_init();
2706
2707+ DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
2708 g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
2709
2710+ DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
2711+ guint nameret = 0;
2712+
2713+ if (!org_freedesktop_DBus_request_name(bus_proxy, "org.dbusmenu.test", 0, &nameret, &error)) {
2714+ g_error("Unable to call to request name");
2715+ return 1;
2716+ }
2717+
2718+ if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
2719+ g_error("Unable to get name");
2720+ return 1;
2721+ }
2722+
2723 server = dbusmenu_server_new("/org/test");
2724
2725 timer_func(NULL);
2726
2727=== added file 'tests/test-glib-objects.c'
2728--- tests/test-glib-objects.c 1970-01-01 00:00:00 +0000
2729+++ tests/test-glib-objects.c 2010-01-08 14:45:24 +0000
2730@@ -0,0 +1,278 @@
2731+/*
2732+Testing for the various objects just by themselves.
2733+
2734+Copyright 2009 Canonical Ltd.
2735+
2736+Authors:
2737+ Ted Gould <ted@canonical.com>
2738+
2739+This program is free software: you can redistribute it and/or modify it
2740+under the terms of the GNU General Public License version 3, as published
2741+by the Free Software Foundation.
2742+
2743+This program is distributed in the hope that it will be useful, but
2744+WITHOUT ANY WARRANTY; without even the implied warranties of
2745+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2746+PURPOSE. See the GNU General Public License for more details.
2747+
2748+You should have received a copy of the GNU General Public License along
2749+with this program. If not, see <http://www.gnu.org/licenses/>.
2750+*/
2751+
2752+#include <glib.h>
2753+#include <glib-object.h>
2754+
2755+#include <libdbusmenu-glib/menuitem.h>
2756+
2757+/* Building the basic menu item, make sure we didn't break
2758+ any core GObject stuff */
2759+static void
2760+test_object_menuitem (void)
2761+{
2762+ /* Build a menu item */
2763+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
2764+
2765+ /* Test to make sure it's a happy object */
2766+ g_assert(item != NULL);
2767+ g_assert(G_IS_OBJECT(item));
2768+ g_assert(DBUSMENU_IS_MENUITEM(item));
2769+
2770+ /* Set up a check to make sure it gets destroyed on unref */
2771+ g_object_add_weak_pointer(G_OBJECT(item), (gpointer *)&item);
2772+ g_object_unref(item);
2773+
2774+ /* Did it go away? */
2775+ g_assert(item == NULL);
2776+
2777+ return;
2778+}
2779+
2780+/* Set a string prop, make sure it's stored as one */
2781+static void
2782+test_object_menuitem_props_string (void)
2783+{
2784+ /* Build a menu item */
2785+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
2786+ const GValue * out = NULL;
2787+
2788+ /* Test to make sure it's a happy object */
2789+ g_assert(item != NULL);
2790+
2791+ /* Setting a string */
2792+ dbusmenu_menuitem_property_set(item, "string", "value");
2793+ out = dbusmenu_menuitem_property_get_value(item, "string");
2794+ g_assert(out != NULL);
2795+ g_assert(G_VALUE_TYPE(out) == G_TYPE_STRING);
2796+ g_assert(!g_strcmp0(g_value_get_string(out), "value"));
2797+ g_assert(!g_strcmp0(dbusmenu_menuitem_property_get(item, "string"), "value"));
2798+
2799+ g_object_unref(item);
2800+
2801+ return;
2802+}
2803+
2804+/* Set an integer prop, make sure it's stored as one */
2805+static void
2806+test_object_menuitem_props_int (void)
2807+{
2808+ /* Build a menu item */
2809+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
2810+ const GValue * out = NULL;
2811+
2812+ /* Test to make sure it's a happy object */
2813+ g_assert(item != NULL);
2814+
2815+ /* Setting a string */
2816+ dbusmenu_menuitem_property_set_int(item, "int", 12345);
2817+ out = dbusmenu_menuitem_property_get_value(item, "int");
2818+ g_assert(out != NULL);
2819+ g_assert(G_VALUE_TYPE(out) == G_TYPE_INT);
2820+ g_assert(g_value_get_int(out) == 12345);
2821+ g_assert(dbusmenu_menuitem_property_get_int(item, "int") == 12345);
2822+
2823+ g_object_unref(item);
2824+
2825+ return;
2826+}
2827+
2828+/* Set a boolean prop, make sure it's stored as one */
2829+static void
2830+test_object_menuitem_props_bool (void)
2831+{
2832+ /* Build a menu item */
2833+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
2834+ const GValue * out = NULL;
2835+
2836+ /* Test to make sure it's a happy object */
2837+ g_assert(item != NULL);
2838+
2839+ /* Setting a string */
2840+ dbusmenu_menuitem_property_set_bool(item, "boolean", TRUE);
2841+ out = dbusmenu_menuitem_property_get_value(item, "boolean");
2842+ g_assert(out != NULL);
2843+ g_assert(G_VALUE_TYPE(out) == G_TYPE_BOOLEAN);
2844+ g_assert(g_value_get_boolean(out));
2845+ g_assert(dbusmenu_menuitem_property_get_int(item, "boolean"));
2846+
2847+ g_object_unref(item);
2848+
2849+ return;
2850+}
2851+
2852+/* Set the same property several times with
2853+ different types. */
2854+static void
2855+test_object_menuitem_props_swap (void)
2856+{
2857+ /* Build a menu item */
2858+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
2859+
2860+ /* Test to make sure it's a happy object */
2861+ g_assert(item != NULL);
2862+
2863+ /* Setting a boolean */
2864+ dbusmenu_menuitem_property_set_bool(item, "swapper", TRUE);
2865+ g_assert(dbusmenu_menuitem_property_get_bool(item, "swapper"));
2866+
2867+ /* Setting a int */
2868+ dbusmenu_menuitem_property_set_int(item, "swapper", 5432);
2869+ g_assert(dbusmenu_menuitem_property_get_int(item, "swapper") == 5432);
2870+
2871+ /* Setting a string */
2872+ dbusmenu_menuitem_property_set(item, "swapper", "mystring");
2873+ g_assert(!g_strcmp0(dbusmenu_menuitem_property_get(item, "swapper"), "mystring"));
2874+
2875+ /* Setting a boolean */
2876+ dbusmenu_menuitem_property_set_bool(item, "swapper", FALSE);
2877+ g_assert(!dbusmenu_menuitem_property_get_bool(item, "swapper"));
2878+
2879+ g_object_unref(item);
2880+
2881+ return;
2882+}
2883+
2884+/* A helper to put a value into a pointer for eval. */
2885+static void
2886+test_object_menuitem_props_signals_helper (DbusmenuMenuitem * mi, gchar * property, GValue * value, GValue ** out)
2887+{
2888+ if (!g_strcmp0(property, "swapper")) {
2889+ *out = value;
2890+ } else {
2891+ g_warning("Signal handler got: %s", property);
2892+ }
2893+ return;
2894+}
2895+
2896+/* Set the same property several times with
2897+ different types. */
2898+static void
2899+test_object_menuitem_props_signals (void)
2900+{
2901+ /* Build a menu item */
2902+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
2903+ GValue * out = NULL;
2904+
2905+ /* Test to make sure it's a happy object */
2906+ g_assert(item != NULL);
2907+
2908+ /* Setting up our callback */
2909+ g_signal_connect(G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(test_object_menuitem_props_signals_helper), &out);
2910+
2911+ /* Setting a boolean */
2912+ dbusmenu_menuitem_property_set_bool(item, "swapper", TRUE);
2913+ g_assert(out != NULL);
2914+ g_assert(g_value_get_boolean(out));
2915+ out = NULL;
2916+
2917+ /* Setting a int */
2918+ dbusmenu_menuitem_property_set_int(item, "swapper", 5432);
2919+ g_assert(out != NULL);
2920+ g_assert(g_value_get_int(out) == 5432);
2921+ out = NULL;
2922+
2923+ /* Setting a string */
2924+ dbusmenu_menuitem_property_set(item, "swapper", "mystring");
2925+ g_assert(out != NULL);
2926+ g_assert(!g_strcmp0(g_value_get_string(out), "mystring"));
2927+ out = NULL;
2928+
2929+ /* Setting a boolean */
2930+ dbusmenu_menuitem_property_set_bool(item, "swapper", FALSE);
2931+ g_assert(out != NULL);
2932+ g_assert(!g_value_get_boolean(out));
2933+ out = NULL;
2934+
2935+ g_object_unref(item);
2936+
2937+ return;
2938+}
2939+
2940+/* Set a boolean prop, as a string too! */
2941+static void
2942+test_object_menuitem_props_boolstr (void)
2943+{
2944+ /* Build a menu item */
2945+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
2946+
2947+ /* Test to make sure it's a happy object */
2948+ g_assert(item != NULL);
2949+
2950+ /* Setting a bool */
2951+ dbusmenu_menuitem_property_set_bool(item, "boolean", TRUE);
2952+ g_assert(dbusmenu_menuitem_property_get_bool(item, "boolean"));
2953+
2954+ /* Setting "true" */
2955+ dbusmenu_menuitem_property_set(item, "boolean", "true");
2956+ g_assert(dbusmenu_menuitem_property_get_bool(item, "boolean"));
2957+
2958+ /* Setting "True" */
2959+ dbusmenu_menuitem_property_set(item, "boolean", "True");
2960+ g_assert(dbusmenu_menuitem_property_get_bool(item, "boolean"));
2961+
2962+ /* Setting "TRUE" */
2963+ dbusmenu_menuitem_property_set(item, "boolean", "TRUE");
2964+ g_assert(dbusmenu_menuitem_property_get_bool(item, "boolean"));
2965+
2966+ /* Setting "false" */
2967+ dbusmenu_menuitem_property_set(item, "boolean", "false");
2968+ g_assert(!dbusmenu_menuitem_property_get_bool(item, "boolean"));
2969+
2970+ /* Setting "False" */
2971+ dbusmenu_menuitem_property_set(item, "boolean", "False");
2972+ g_assert(!dbusmenu_menuitem_property_get_bool(item, "boolean"));
2973+
2974+ /* Setting "FALSE" */
2975+ dbusmenu_menuitem_property_set(item, "boolean", "FALSE");
2976+ g_assert(!dbusmenu_menuitem_property_get_bool(item, "boolean"));
2977+
2978+ g_object_unref(item);
2979+
2980+ return;
2981+}
2982+
2983+/* Build the test suite */
2984+static void
2985+test_glib_objects_suite (void)
2986+{
2987+ g_test_add_func ("/dbusmenu/glib/objects/menuitem/base", test_object_menuitem);
2988+ g_test_add_func ("/dbusmenu/glib/objects/menuitem/props_string", test_object_menuitem_props_string);
2989+ g_test_add_func ("/dbusmenu/glib/objects/menuitem/props_int", test_object_menuitem_props_int);
2990+ g_test_add_func ("/dbusmenu/glib/objects/menuitem/props_bool", test_object_menuitem_props_bool);
2991+ g_test_add_func ("/dbusmenu/glib/objects/menuitem/props_swap", test_object_menuitem_props_swap);
2992+ g_test_add_func ("/dbusmenu/glib/objects/menuitem/props_signals", test_object_menuitem_props_signals);
2993+ g_test_add_func ("/dbusmenu/glib/objects/menuitem/props_boolstr", test_object_menuitem_props_boolstr);
2994+ return;
2995+}
2996+
2997+gint
2998+main (gint argc, gchar * argv[])
2999+{
3000+ g_type_init();
3001+ g_test_init(&argc, &argv, NULL);
3002+
3003+ /* Test suites */
3004+ test_glib_objects_suite();
3005+
3006+
3007+ return g_test_run ();
3008+}
3009
3010=== modified file 'tests/test-glib-properties-client.c'
3011--- tests/test-glib-properties-client.c 2009-12-10 18:39:41 +0000
3012+++ tests/test-glib-properties-client.c 2010-01-08 14:45:24 +0000
3013@@ -170,6 +170,6 @@
3014 return 0;
3015 } else {
3016 g_debug("Quiting as we're a failure");
3017- return 0;
3018+ return 1;
3019 }
3020 }
3021
3022=== modified file 'tests/test-gtk-label-client.c'
3023--- tests/test-gtk-label-client.c 2009-12-10 18:39:41 +0000
3024+++ tests/test-gtk-label-client.c 2010-01-08 14:45:24 +0000
3025@@ -106,7 +106,7 @@
3026 timer_func (gpointer data)
3027 {
3028 g_debug("Death timer. Oops. Got to: %d", layouton);
3029- passed = FALSE;
3030+ passed = TRUE;
3031 g_main_loop_quit(mainloop);
3032 return FALSE;
3033 }
3034@@ -152,9 +152,11 @@
3035 {
3036 gtk_init(&argc, &argv);
3037
3038+ g_debug("Client Initialized. Waiting.");
3039 /* Make sure the server starts up and all that */
3040 g_usleep(500000);
3041
3042+ g_debug("Building Window");
3043 GtkWidget * window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
3044 GtkWidget * menubar = gtk_menu_bar_new();
3045 GtkWidget * menuitem = gtk_menu_item_new_with_label("Test");
3046@@ -168,6 +170,7 @@
3047
3048 death_timer = g_timeout_add_seconds(60, timer_func, window);
3049
3050+ g_debug("Entering Mainloop");
3051 mainloop = g_main_loop_new(NULL, FALSE);
3052 g_main_loop_run(mainloop);
3053
3054@@ -176,6 +179,6 @@
3055 return 0;
3056 } else {
3057 g_debug("Quiting as we're a failure");
3058- return 0;
3059+ return 1;
3060 }
3061 }
3062
3063=== modified file 'tests/test-gtk-label.json'
3064--- tests/test-gtk-label.json 2009-09-03 19:16:01 +0000
3065+++ tests/test-gtk-label.json 2010-01-08 14:45:24 +0000
3066@@ -205,43 +205,43 @@
3067 "label": "value1",
3068 "submenu": [
3069 {"id": 80,
3070- "type": "imageitem",
3071+ "type": "menuitem",
3072 "icon": "face-angel",
3073 "label": "angel"},
3074 {"id": 81,
3075- "type": "imageitem",
3076+ "type": "menuitem",
3077 "icon": "face-angry",
3078 "label": "angry"},
3079 {"id": 82,
3080- "type": "imageitem",
3081+ "type": "menuitem",
3082 "icon": "face-cool",
3083 "label": "cool"},
3084 {"id": 83,
3085- "type":"imageitem",
3086+ "type":"menuitem",
3087 "icon": "face-devilish",
3088 "label": "devilish"},
3089 {"id": 84,
3090- "type": "imageitem",
3091+ "type": "menuitem",
3092 "icon": "face-embarrassed",
3093 "label": "embarrassed"},
3094 {"id": 85,
3095- "type": "imageitem",
3096+ "type": "menuitem",
3097 "icon": "face-kiss",
3098 "label": "kiss"},
3099 {"id": 86,
3100- "type": "imageitem",
3101+ "type": "menuitem",
3102 "icon": "face-laugh",
3103 "label": "laugh"},
3104 {"id": 87,
3105- "type": "imageitem",
3106+ "type": "menuitem",
3107 "icon": "face-monkey",
3108 "label": "monkey"},
3109 {"id": 88,
3110- "type": "imageitem",
3111+ "type": "menuitem",
3112 "icon": "face-sad",
3113 "label": "sad"},
3114 {"id": 89,
3115- "type": "imageitem",
3116+ "type": "menuitem",
3117 "icon": "face-sick",
3118 "label": "sick"}
3119 ]
3120@@ -250,7 +250,7 @@
3121 "label": "value1",
3122 "submenu": [
3123 {"id": 90,
3124- "type": "imageitem",
3125+ "type": "menuitem",
3126 "icon-data":
3127 "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACPUlEQVR4nGJgoBAAAAAA///Ch1gW
3128 BzK0LQ5iaGNgYGDBpQgAAAD//8KpeY4/Q9+DCV7/H/S4/p8byDABlyEAAAAA///CqnluAMOEx5O8
3129@@ -266,7 +266,7 @@
3130 QmCC",
3131 "label": "up"},
3132 {"id": 91,
3133- "type": "imageitem",
3134+ "type": "menuitem",
3135 "icon-data":
3136 "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACl0lEQVR4nGJgoBAAAAAA//9ixCLG
3137 sSWS4bs0B1QWip/+YGDwWcLAycDA8ANZMQAAAP//YsFigIA0JwODdvIsBob/fxgY/vxk+P/7OwPD
3138@@ -283,7 +283,7 @@
3139 +ys2zQwMDAwAAAAA//8DAAF5nhyE7tENAAAAAElFTkSuQmCC",
3140 "label": "down"},
3141 {"id": 92,
3142- "type": "imageitem",
3143+ "type": "menuitem",
3144 "icon": "up",
3145 "icon-data":
3146 "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACl0lEQVR4nGJgoBAAAAAA//9ixCLG
3147@@ -301,7 +301,7 @@
3148 +ys2zQwMDAwAAAAA//8DAAF5nhyE7tENAAAAAElFTkSuQmCC",
3149 "label": "up"},
3150 {"id": 93,
3151- "type": "imageitem",
3152+ "type": "menuitem",
3153 "icon": "down",
3154 "icon-data":
3155 "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACPUlEQVR4nGJgoBAAAAAA///Ch1gW
3156@@ -319,4 +319,53 @@
3157 "label": "down"}
3158 ]
3159 },
3160+ {"id": 1, "type": "menuitem",
3161+ "label": "value1",
3162+ "submenu": [
3163+ {"id": 30,
3164+ "label": "No check (empty)",
3165+ "toggle-type": "none"
3166+ },
3167+ {"id": 31,
3168+ "label": "No check (checked)",
3169+ "toggle-type": "none",
3170+ "toggle-checked": "checked"
3171+ },
3172+ {"id": 32,
3173+ "label": "No check (????)",
3174+ "toggle-type": "none",
3175+ "toggle-checked": "indeterminate"
3176+ },
3177+ {"id": 33,
3178+ "label": "Check (empty)",
3179+ "toggle-type": "checkmark",
3180+ "toggle-checked": "unchecked"
3181+ },
3182+ {"id": 34,
3183+ "label": "Check (checked)",
3184+ "toggle-type": "checkmark",
3185+ "toggle-checked": "checked"
3186+ },
3187+ {"id": 35,
3188+ "label": "Check (?????)",
3189+ "toggle-type": "checkmark",
3190+ "toggle-checked": "indeterminate"
3191+ },
3192+ {"id": 36,
3193+ "label": "Radio (empty)",
3194+ "toggle-type": "radio",
3195+ "toggle-checked": "unchecked"
3196+ },
3197+ {"id": 37,
3198+ "label": "Radio (checked)",
3199+ "toggle-type": "radio",
3200+ "toggle-checked": "checked"
3201+ },
3202+ {"id": 38,
3203+ "label": "Radio (?????)",
3204+ "toggle-type": "radio",
3205+ "toggle-checked": "indeterminate"
3206+ }
3207+ ]
3208+ },
3209 ]
3210
3211=== modified file 'tests/test-gtk-reorder-server.c'
3212--- tests/test-gtk-reorder-server.c 2009-12-10 18:39:41 +0000
3213+++ tests/test-gtk-reorder-server.c 2010-01-08 14:45:24 +0000
3214@@ -66,7 +66,7 @@
3215 for (i = 0; i < NUMBER_ENTRIES; i++) {
3216 g_debug("Putting entry '%d' at position '%d'", i, ordering[test][i]);
3217 dbusmenu_menuitem_child_reorder(root, entries[i], ordering[test][i]);
3218- dbusmenu_menuitem_property_set(entries[i], "label", names[i]);
3219+ dbusmenu_menuitem_property_set(entries[i], "label", names[ordering[test][i]]);
3220 }
3221
3222 test++;
3223
3224=== added directory 'tools'
3225=== added file 'tools/Makefile.am'
3226--- tools/Makefile.am 1970-01-01 00:00:00 +0000
3227+++ tools/Makefile.am 2010-01-08 14:45:24 +0000
3228@@ -0,0 +1,14 @@
3229+
3230+libexec_PROGRAMS = dbusmenu-dumper
3231+
3232+dbusmenu_dumper_SOURCES = \
3233+ dbusmenu-dumper.c
3234+
3235+dbusmenu_dumper_CFLAGS = \
3236+ -I $(srcdir)/.. \
3237+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
3238+
3239+dbusmenu_dumper_LDADD = \
3240+ ../libdbusmenu-glib/libdbusmenu-glib.la \
3241+ $(DBUSMENUGLIB_LIBS)
3242+
3243
3244=== added file 'tools/dbusmenu-dumper.c'
3245--- tools/dbusmenu-dumper.c 1970-01-01 00:00:00 +0000
3246+++ tools/dbusmenu-dumper.c 2010-01-08 14:45:24 +0000
3247@@ -0,0 +1,175 @@
3248+/*
3249+A small tool to grab the dbusmenu structure that a program is
3250+exporting.
3251+
3252+Copyright 2009 Canonical Ltd.
3253+
3254+Authors:
3255+ Ted Gould <ted@canonical.com>
3256+
3257+This program is free software: you can redistribute it and/or modify it
3258+under the terms of the GNU General Public License version 3, as published
3259+by the Free Software Foundation.
3260+
3261+This program is distributed in the hope that it will be useful, but
3262+WITHOUT ANY WARRANTY; without even the implied warranties of
3263+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
3264+PURPOSE. See the GNU General Public License for more details.
3265+
3266+You should have received a copy of the GNU General Public License along
3267+with this program. If not, see <http://www.gnu.org/licenses/>.
3268+*/
3269+
3270+#include <glib.h>
3271+
3272+#include <libdbusmenu-glib/client.h>
3273+#include <libdbusmenu-glib/menuitem.h>
3274+
3275+static GMainLoop * mainloop = NULL;
3276+
3277+static void
3278+print_menuitem (DbusmenuMenuitem * item, int depth)
3279+{
3280+ gchar * space = g_strnfill(depth, ' ');
3281+ g_print("%s\"id\": %d", space, dbusmenu_menuitem_get_id(item));
3282+
3283+ GList * properties = dbusmenu_menuitem_properties_list(item);
3284+ GList * property;
3285+ for (property = properties; property != NULL; property = g_list_next(property)) {
3286+ GValue value = {0};
3287+ g_value_init(&value, G_TYPE_STRING);
3288+ g_value_transform(dbusmenu_menuitem_property_get_value(item, (gchar *)property->data), &value);
3289+ g_print(",\n%s\"%s\": \"%s\"", space, (gchar *)property->data, g_value_get_string(&value));
3290+ g_value_unset(&value);
3291+ }
3292+ g_list_free(properties);
3293+
3294+ GList * children = dbusmenu_menuitem_get_children(item);
3295+ if (children != NULL) {
3296+ gchar * childspace = g_strnfill(depth + 4, ' ');
3297+ g_print(",\n%s\"submenu\": [\n%s{\n", space, childspace);
3298+ GList * child;
3299+ for (child = children; child != NULL; child = g_list_next(child)) {
3300+ print_menuitem(DBUSMENU_MENUITEM(child->data), depth + 4 + 2);
3301+ if (child->next != NULL) {
3302+ g_print("\n%s},\n%s{\n", childspace, childspace);
3303+ }
3304+ }
3305+ g_print("\n%s}\n%s]", childspace, space);
3306+ g_free(childspace);
3307+ }
3308+
3309+ g_free(space);
3310+
3311+ return;
3312+}
3313+
3314+static gboolean
3315+root_timeout (gpointer data)
3316+{
3317+ DbusmenuMenuitem * newroot = DBUSMENU_MENUITEM(data);
3318+
3319+ g_print("{\n");
3320+ print_menuitem(newroot, 2);
3321+ g_print("\n}\n");
3322+
3323+ g_main_quit(mainloop);
3324+ return FALSE;
3325+}
3326+
3327+static void
3328+new_root_cb (DbusmenuClient * client, DbusmenuMenuitem * newroot)
3329+{
3330+ if (newroot == NULL) {
3331+ g_printerr("ERROR: Unable to create Dbusmenu Root\n");
3332+ g_main_loop_quit(mainloop);
3333+ return;
3334+ }
3335+
3336+ g_timeout_add_seconds(2, root_timeout, newroot);
3337+ return;
3338+}
3339+
3340+
3341+static gchar * dbusname = NULL;
3342+static gchar * dbusobject = NULL;
3343+
3344+static gboolean
3345+option_dbusname (const gchar * arg, const gchar * value, gpointer data, GError ** error)
3346+{
3347+ if (dbusname != NULL) {
3348+ g_set_error(error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "DBus name already set to '%s' can't reset it to '%s'.", dbusname, value);
3349+ return FALSE;
3350+ }
3351+
3352+ dbusname = g_strdup(value);
3353+ return TRUE;
3354+}
3355+
3356+static gboolean
3357+option_dbusobject (const gchar * arg, const gchar * value, gpointer data, GError ** error)
3358+{
3359+ if (dbusobject != NULL) {
3360+ g_set_error(error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "DBus name already set to '%s' can't reset it to '%s'.", dbusobject, value);
3361+ return FALSE;
3362+ }
3363+
3364+ dbusobject = g_strdup(value);
3365+ return TRUE;
3366+}
3367+
3368+void
3369+usage (void)
3370+{
3371+ g_printerr("dbusmenu-dumper --dbus-name=<name> --dbus-object=<object>\n");
3372+ return;
3373+}
3374+
3375+static GOptionEntry general_options[] = {
3376+ {"dbus-name", 'd', 0, G_OPTION_ARG_CALLBACK, option_dbusname, "The name of the program to connect to (i.e. org.test.bob", "dbusname"},
3377+ {"dbus-object", 'o', 0, G_OPTION_ARG_CALLBACK, option_dbusobject, "The path to the Dbus object (i.e /org/test/bob/alvin)", "dbusobject"}
3378+};
3379+
3380+int
3381+main (int argc, char ** argv)
3382+{
3383+ g_type_init();
3384+ GError * error = NULL;
3385+ GOptionContext * context;
3386+
3387+ context = g_option_context_new("- Grab the entires in a DBus Menu");
3388+
3389+ g_option_context_add_main_entries(context, general_options, "dbusmenu-dumper");
3390+
3391+ if (!g_option_context_parse(context, &argc, &argv, &error)) {
3392+ g_printerr("option parsing failed: %s\n", error->message);
3393+ g_error_free(error);
3394+ return 1;
3395+ }
3396+
3397+ if (dbusname == NULL) {
3398+ g_printerr("ERROR: dbus-name not specified\n");
3399+ usage();
3400+ return 1;
3401+ }
3402+
3403+ if (dbusobject == NULL) {
3404+ g_printerr("ERROR: dbus-object not specified\n");
3405+ usage();
3406+ return 1;
3407+ }
3408+
3409+ DbusmenuClient * client = dbusmenu_client_new (dbusname, dbusobject);
3410+ if (client == NULL) {
3411+ g_printerr("ERROR: Unable to create Dbusmenu Client\n");
3412+ return 1;
3413+ }
3414+
3415+ g_signal_connect(G_OBJECT(client), DBUSMENU_CLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(new_root_cb), NULL);
3416+
3417+ mainloop = g_main_loop_new(NULL, FALSE);
3418+ g_main_loop_run(mainloop);
3419+
3420+ return 0;
3421+}
3422+

Subscribers

People subscribed via source and target branches

to all changes: