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: 2790 lines (+1346/-406)
26 files modified
.bzrignore (+1/-0)
configure.ac (+6/-5)
debian/changelog (+12/-0)
debian/libdbusmenu-tools.install (+1/-1)
libdbusmenu-glib/Doxyfile (+257/-0)
libdbusmenu-glib/Makefile.am (+2/-0)
libdbusmenu-glib/client-menuitem.c (+106/-0)
libdbusmenu-glib/client-menuitem.h (+61/-0)
libdbusmenu-glib/client.c (+28/-59)
libdbusmenu-glib/client.h (+7/-2)
libdbusmenu-glib/dbus-menu.xml (+231/-119)
libdbusmenu-glib/menuitem-marshal.list (+1/-0)
libdbusmenu-glib/menuitem-private.h (+1/-1)
libdbusmenu-glib/menuitem.c (+55/-26)
libdbusmenu-glib/menuitem.h (+16/-12)
libdbusmenu-glib/server-marshal.list (+1/-1)
libdbusmenu-glib/server.c (+30/-30)
libdbusmenu-glib/server.h (+6/-5)
libdbusmenu-gtk/client.c (+36/-21)
tests/test-gtk-label-server.c (+6/-3)
tests/test-gtk-label.json (+121/-121)
tools/Makefile.am (+5/-0)
tools/dbusmenu-bench (+157/-0)
tools/testapp/CMakeLists.txt (+29/-0)
tools/testapp/Makefile.am (+17/-0)
tools/testapp/main.c (+153/-0)
To merge this branch: bzr merge lp:~dbusmenu-team/libdbusmenu/ubuntu
Reviewer Review Type Date Requested Status
Sebastien Bacher Pending
Review via email: mp+18630@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Ted Gould (ted) wrote :

0.2.2

lp:~dbusmenu-team/libdbusmenu/ubuntu updated
60. By Sebastien Bacher

releasing version 0.2.2-0ubuntu1

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-21 22:17:02 +0000
3+++ .bzrignore 2010-02-04 20:30:33 +0000
4@@ -58,3 +58,4 @@
5 tests/test-glib-objects
6 tests/test-glib-objects-test
7 tests/test-glib-objects.xml
8+tools/testapp/dbusmenu-testapp
9
10=== modified file 'configure.ac'
11--- configure.ac 2010-01-20 02:07:35 +0000
12+++ configure.ac 2010-02-04 20:30:33 +0000
13@@ -1,11 +1,11 @@
14
15-AC_INIT(libdbusmenu, 0.2.1, ted@canonical.com)
16-AC_COPYRIGHT([Copyright 2009 Canonical])
17+AC_INIT(libdbusmenu, 0.2.2, ted@canonical.com)
18+AC_COPYRIGHT([Copyright 2009,2010 Canonical])
19
20 AC_PREREQ(2.53)
21
22 AM_CONFIG_HEADER(config.h)
23-AM_INIT_AUTOMAKE(libdbusmenu, 0.2.1)
24+AM_INIT_AUTOMAKE(libdbusmenu, 0.2.2)
25
26 AM_MAINTAINER_MODE
27
28@@ -65,8 +65,8 @@
29 # Lib versioning
30 ###########################
31
32-LIBDBUSMENU_CURRENT=0
33-LIBDBUSMENU_REVISION=11
34+LIBDBUSMENU_CURRENT=1
35+LIBDBUSMENU_REVISION=0
36 LIBDBUSMENU_AGE=0
37
38 AC_SUBST(LIBDBUSMENU_CURRENT)
39@@ -105,6 +105,7 @@
40 libdbusmenu-gtk/Makefile
41 libdbusmenu-gtk/dbusmenu-gtk.pc
42 tools/Makefile
43+tools/testapp/Makefile
44 tests/Makefile
45 ])
46
47
48=== modified file 'debian/changelog'
49--- debian/changelog 2010-01-20 02:07:35 +0000
50+++ debian/changelog 2010-02-04 20:30:33 +0000
51@@ -1,3 +1,15 @@
52+libdbusmenu (0.2.2-0ubuntu1~ppa1) lucid; urgency=low
53+
54+ * Upstream Release 0.2.2
55+ * Interoperability fixes
56+ * Adding timestamps to events
57+ * Better handling of XML
58+ * Adding tools for timing dbusmenu
59+ * debian/libdbusmenu-tools.install: Adding a wildcard to get
60+ all of the tools in libexec
61+
62+ -- Ted Gould <ted@ubuntu.com> Thu, 04 Feb 2010 12:18:26 -0800
63+
64 libdbusmenu (0.2.1-0ubuntu1) lucid; urgency=low
65
66 * Upstream release 0.2.1
67
68=== modified file 'debian/libdbusmenu-tools.install'
69--- debian/libdbusmenu-tools.install 2010-01-09 14:09:31 +0000
70+++ debian/libdbusmenu-tools.install 2010-02-04 20:30:33 +0000
71@@ -1,1 +1,1 @@
72-debian/tmp/usr/lib/libdbusmenu/dbusmenu-dumper
73+debian/tmp/usr/lib/libdbusmenu/dbusmenu-*
74
75=== added file 'libdbusmenu-glib/Doxyfile'
76--- libdbusmenu-glib/Doxyfile 1970-01-01 00:00:00 +0000
77+++ libdbusmenu-glib/Doxyfile 2010-02-04 20:30:33 +0000
78@@ -0,0 +1,257 @@
79+# Doxyfile 1.6.1
80+
81+#---------------------------------------------------------------------------
82+# Project related configuration options
83+#---------------------------------------------------------------------------
84+DOXYFILE_ENCODING = UTF-8
85+PROJECT_NAME = DBusMenu
86+PROJECT_NUMBER =
87+OUTPUT_DIRECTORY =
88+CREATE_SUBDIRS = NO
89+OUTPUT_LANGUAGE = English
90+BRIEF_MEMBER_DESC = YES
91+REPEAT_BRIEF = YES
92+ABBREVIATE_BRIEF =
93+ALWAYS_DETAILED_SEC = NO
94+INLINE_INHERITED_MEMB = NO
95+FULL_PATH_NAMES = YES
96+STRIP_FROM_PATH =
97+STRIP_FROM_INC_PATH =
98+SHORT_NAMES = NO
99+JAVADOC_AUTOBRIEF = NO
100+QT_AUTOBRIEF = NO
101+MULTILINE_CPP_IS_BRIEF = NO
102+INHERIT_DOCS = YES
103+SEPARATE_MEMBER_PAGES = NO
104+TAB_SIZE = 8
105+ALIASES =
106+OPTIMIZE_OUTPUT_FOR_C = NO
107+OPTIMIZE_OUTPUT_JAVA = NO
108+OPTIMIZE_FOR_FORTRAN = NO
109+OPTIMIZE_OUTPUT_VHDL = NO
110+EXTENSION_MAPPING =
111+BUILTIN_STL_SUPPORT = NO
112+CPP_CLI_SUPPORT = NO
113+SIP_SUPPORT = NO
114+IDL_PROPERTY_SUPPORT = YES
115+DISTRIBUTE_GROUP_DOC = NO
116+SUBGROUPING = YES
117+TYPEDEF_HIDES_STRUCT = NO
118+SYMBOL_CACHE_SIZE = 0
119+#---------------------------------------------------------------------------
120+# Build related configuration options
121+#---------------------------------------------------------------------------
122+EXTRACT_ALL = NO
123+EXTRACT_PRIVATE = NO
124+EXTRACT_STATIC = NO
125+EXTRACT_LOCAL_CLASSES = YES
126+EXTRACT_LOCAL_METHODS = NO
127+EXTRACT_ANON_NSPACES = NO
128+HIDE_UNDOC_MEMBERS = NO
129+HIDE_UNDOC_CLASSES = NO
130+HIDE_FRIEND_COMPOUNDS = NO
131+HIDE_IN_BODY_DOCS = NO
132+INTERNAL_DOCS = NO
133+CASE_SENSE_NAMES = YES
134+HIDE_SCOPE_NAMES = NO
135+SHOW_INCLUDE_FILES = YES
136+INLINE_INFO = YES
137+SORT_MEMBER_DOCS = YES
138+SORT_BRIEF_DOCS = NO
139+SORT_MEMBERS_CTORS_1ST = NO
140+SORT_GROUP_NAMES = NO
141+SORT_BY_SCOPE_NAME = NO
142+GENERATE_TODOLIST = YES
143+GENERATE_TESTLIST = YES
144+GENERATE_BUGLIST = YES
145+GENERATE_DEPRECATEDLIST= YES
146+ENABLED_SECTIONS =
147+MAX_INITIALIZER_LINES = 30
148+SHOW_USED_FILES = YES
149+SHOW_DIRECTORIES = NO
150+SHOW_FILES = YES
151+SHOW_NAMESPACES = YES
152+FILE_VERSION_FILTER =
153+LAYOUT_FILE =
154+#---------------------------------------------------------------------------
155+# configuration options related to warning and progress messages
156+#---------------------------------------------------------------------------
157+QUIET = NO
158+WARNINGS = YES
159+WARN_IF_UNDOCUMENTED = YES
160+WARN_IF_DOC_ERROR = YES
161+WARN_NO_PARAMDOC = NO
162+WARN_FORMAT = "$file:$line: $text"
163+WARN_LOGFILE =
164+#---------------------------------------------------------------------------
165+# configuration options related to the input files
166+#---------------------------------------------------------------------------
167+INPUT = .
168+INPUT_ENCODING = UTF-8
169+FILE_PATTERNS = *.xml
170+RECURSIVE = NO
171+EXCLUDE =
172+EXCLUDE_SYMLINKS = NO
173+EXCLUDE_PATTERNS =
174+EXCLUDE_SYMBOLS =
175+EXAMPLE_PATH =
176+EXAMPLE_PATTERNS =
177+EXAMPLE_RECURSIVE = NO
178+IMAGE_PATH =
179+INPUT_FILTER = doxymel
180+FILTER_PATTERNS = *.xml=doxymel
181+FILTER_SOURCE_FILES = NO
182+#---------------------------------------------------------------------------
183+# configuration options related to source browsing
184+#---------------------------------------------------------------------------
185+SOURCE_BROWSER = NO
186+INLINE_SOURCES = NO
187+STRIP_CODE_COMMENTS = YES
188+REFERENCED_BY_RELATION = NO
189+REFERENCES_RELATION = NO
190+REFERENCES_LINK_SOURCE = YES
191+USE_HTAGS = NO
192+VERBATIM_HEADERS = YES
193+#---------------------------------------------------------------------------
194+# configuration options related to the alphabetical class index
195+#---------------------------------------------------------------------------
196+ALPHABETICAL_INDEX = NO
197+COLS_IN_ALPHA_INDEX = 5
198+IGNORE_PREFIX =
199+#---------------------------------------------------------------------------
200+# configuration options related to the HTML output
201+#---------------------------------------------------------------------------
202+GENERATE_HTML = YES
203+HTML_OUTPUT = html
204+HTML_FILE_EXTENSION = .html
205+HTML_HEADER =
206+HTML_FOOTER =
207+HTML_STYLESHEET =
208+HTML_ALIGN_MEMBERS = YES
209+HTML_DYNAMIC_SECTIONS = NO
210+GENERATE_DOCSET = NO
211+DOCSET_FEEDNAME = "Doxygen generated docs"
212+DOCSET_BUNDLE_ID = org.doxygen.Project
213+GENERATE_HTMLHELP = NO
214+CHM_FILE =
215+HHC_LOCATION =
216+GENERATE_CHI = NO
217+CHM_INDEX_ENCODING =
218+BINARY_TOC = NO
219+TOC_EXPAND = NO
220+GENERATE_QHP = NO
221+QCH_FILE =
222+QHP_NAMESPACE =
223+QHP_VIRTUAL_FOLDER = doc
224+QHP_CUST_FILTER_NAME =
225+QHP_CUST_FILTER_ATTRS =
226+QHP_SECT_FILTER_ATTRS =
227+QHG_LOCATION =
228+DISABLE_INDEX = NO
229+ENUM_VALUES_PER_LINE = 4
230+GENERATE_TREEVIEW = NO
231+USE_INLINE_TREES = NO
232+TREEVIEW_WIDTH = 250
233+FORMULA_FONTSIZE = 10
234+SEARCHENGINE = YES
235+#---------------------------------------------------------------------------
236+# configuration options related to the LaTeX output
237+#---------------------------------------------------------------------------
238+GENERATE_LATEX = NO
239+LATEX_OUTPUT = latex
240+LATEX_CMD_NAME = latex
241+MAKEINDEX_CMD_NAME = makeindex
242+COMPACT_LATEX = NO
243+PAPER_TYPE = a4wide
244+EXTRA_PACKAGES =
245+LATEX_HEADER =
246+PDF_HYPERLINKS = YES
247+USE_PDFLATEX = YES
248+LATEX_BATCHMODE = NO
249+LATEX_HIDE_INDICES = NO
250+LATEX_SOURCE_CODE = NO
251+#---------------------------------------------------------------------------
252+# configuration options related to the RTF output
253+#---------------------------------------------------------------------------
254+GENERATE_RTF = NO
255+RTF_OUTPUT = rtf
256+COMPACT_RTF = NO
257+RTF_HYPERLINKS = NO
258+RTF_STYLESHEET_FILE =
259+RTF_EXTENSIONS_FILE =
260+#---------------------------------------------------------------------------
261+# configuration options related to the man page output
262+#---------------------------------------------------------------------------
263+GENERATE_MAN = NO
264+MAN_OUTPUT = man
265+MAN_EXTENSION = .3
266+MAN_LINKS = NO
267+#---------------------------------------------------------------------------
268+# configuration options related to the XML output
269+#---------------------------------------------------------------------------
270+GENERATE_XML = NO
271+XML_OUTPUT = xml
272+XML_SCHEMA =
273+XML_DTD =
274+XML_PROGRAMLISTING = YES
275+#---------------------------------------------------------------------------
276+# configuration options for the AutoGen Definitions output
277+#---------------------------------------------------------------------------
278+GENERATE_AUTOGEN_DEF = NO
279+#---------------------------------------------------------------------------
280+# configuration options related to the Perl module output
281+#---------------------------------------------------------------------------
282+GENERATE_PERLMOD = NO
283+PERLMOD_LATEX = NO
284+PERLMOD_PRETTY = YES
285+PERLMOD_MAKEVAR_PREFIX =
286+#---------------------------------------------------------------------------
287+# Configuration options related to the preprocessor
288+#---------------------------------------------------------------------------
289+ENABLE_PREPROCESSING = YES
290+MACRO_EXPANSION = NO
291+EXPAND_ONLY_PREDEF = NO
292+SEARCH_INCLUDES = YES
293+INCLUDE_PATH =
294+INCLUDE_FILE_PATTERNS =
295+PREDEFINED =
296+EXPAND_AS_DEFINED =
297+SKIP_FUNCTION_MACROS = YES
298+#---------------------------------------------------------------------------
299+# Configuration::additions related to external references
300+#---------------------------------------------------------------------------
301+TAGFILES =
302+GENERATE_TAGFILE =
303+ALLEXTERNALS = NO
304+EXTERNAL_GROUPS = YES
305+PERL_PATH = /usr/bin/perl
306+#---------------------------------------------------------------------------
307+# Configuration options related to the dot tool
308+#---------------------------------------------------------------------------
309+CLASS_DIAGRAMS = YES
310+MSCGEN_PATH =
311+HIDE_UNDOC_RELATIONS = YES
312+HAVE_DOT = NO
313+DOT_FONTNAME = FreeSans
314+DOT_FONTSIZE = 10
315+DOT_FONTPATH =
316+CLASS_GRAPH = YES
317+COLLABORATION_GRAPH = YES
318+GROUP_GRAPHS = YES
319+UML_LOOK = NO
320+TEMPLATE_RELATIONS = NO
321+INCLUDE_GRAPH = YES
322+INCLUDED_BY_GRAPH = YES
323+CALL_GRAPH = NO
324+CALLER_GRAPH = NO
325+GRAPHICAL_HIERARCHY = YES
326+DIRECTORY_GRAPH = YES
327+DOT_IMAGE_FORMAT = png
328+DOT_PATH =
329+DOTFILE_DIRS =
330+DOT_GRAPH_MAX_NODES = 50
331+MAX_DOT_GRAPH_DEPTH = 0
332+DOT_TRANSPARENT = NO
333+DOT_MULTI_TARGETS = YES
334+GENERATE_LEGEND = YES
335+DOT_CLEANUP = YES
336
337=== modified file 'libdbusmenu-glib/Makefile.am'
338--- libdbusmenu-glib/Makefile.am 2009-11-13 18:02:08 +0000
339+++ libdbusmenu-glib/Makefile.am 2010-02-04 20:30:33 +0000
340@@ -27,6 +27,8 @@
341 server.c \
342 server-marshal.h \
343 server-marshal.c \
344+ client-menuitem.h \
345+ client-menuitem.c \
346 client.h \
347 client.c
348
349
350=== added file 'libdbusmenu-glib/client-menuitem.c'
351--- libdbusmenu-glib/client-menuitem.c 1970-01-01 00:00:00 +0000
352+++ libdbusmenu-glib/client-menuitem.c 2010-02-04 20:30:33 +0000
353@@ -0,0 +1,106 @@
354+/*
355+A small subclass of the menuitem for using clients.
356+
357+Copyright 2010 Canonical Ltd.
358+
359+Authors:
360+ Ted Gould <ted@canonical.com>
361+
362+This program is free software: you can redistribute it and/or modify it
363+under the terms of either or both of the following licenses:
364+
365+1) the GNU Lesser General Public License version 3, as published by the
366+Free Software Foundation; and/or
367+2) the GNU Lesser General Public License version 2.1, as published by
368+the Free Software Foundation.
369+
370+This program is distributed in the hope that it will be useful, but
371+WITHOUT ANY WARRANTY; without even the implied warranties of
372+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
373+PURPOSE. See the applicable version of the GNU Lesser General Public
374+License for more details.
375+
376+You should have received a copy of both the GNU Lesser General Public
377+License version 3 and version 2.1 along with this program. If not, see
378+<http://www.gnu.org/licenses/>
379+*/
380+
381+#ifdef HAVE_CONFIG_H
382+#include "config.h"
383+#endif
384+
385+#include "client-menuitem.h"
386+
387+typedef struct _DbusmenuClientMenuitemPrivate DbusmenuClientMenuitemPrivate;
388+
389+struct _DbusmenuClientMenuitemPrivate
390+{
391+ DbusmenuClient * client;
392+};
393+
394+#define DBUSMENU_CLIENT_MENUITEM_GET_PRIVATE(o) \
395+(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_CLIENT_MENUITEM_TYPE, DbusmenuClientMenuitemPrivate))
396+
397+static void dbusmenu_client_menuitem_class_init (DbusmenuClientMenuitemClass *klass);
398+static void dbusmenu_client_menuitem_init (DbusmenuClientMenuitem *self);
399+static void dbusmenu_client_menuitem_dispose (GObject *object);
400+static void dbusmenu_client_menuitem_finalize (GObject *object);
401+static void handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp);
402+
403+G_DEFINE_TYPE (DbusmenuClientMenuitem, dbusmenu_client_menuitem, DBUSMENU_TYPE_MENUITEM);
404+
405+static void
406+dbusmenu_client_menuitem_class_init (DbusmenuClientMenuitemClass *klass)
407+{
408+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
409+
410+ g_type_class_add_private (klass, sizeof (DbusmenuClientMenuitemPrivate));
411+
412+ object_class->dispose = dbusmenu_client_menuitem_dispose;
413+ object_class->finalize = dbusmenu_client_menuitem_finalize;
414+
415+ DbusmenuMenuitemClass * mclass = DBUSMENU_MENUITEM_CLASS(klass);
416+ mclass->handle_event = handle_event;
417+
418+ return;
419+}
420+
421+static void
422+dbusmenu_client_menuitem_init (DbusmenuClientMenuitem *self)
423+{
424+
425+ return;
426+}
427+
428+static void
429+dbusmenu_client_menuitem_dispose (GObject *object)
430+{
431+
432+ G_OBJECT_CLASS (dbusmenu_client_menuitem_parent_class)->dispose (object);
433+ return;
434+}
435+
436+static void
437+dbusmenu_client_menuitem_finalize (GObject *object)
438+{
439+
440+ G_OBJECT_CLASS (dbusmenu_client_menuitem_parent_class)->finalize (object);
441+ return;
442+}
443+
444+DbusmenuClientMenuitem *
445+dbusmenu_client_menuitem_new (gint id, DbusmenuClient * client)
446+{
447+ DbusmenuClientMenuitem * mi = g_object_new(DBUSMENU_CLIENT_MENUITEM_TYPE, "id", id, NULL);
448+ DbusmenuClientMenuitemPrivate * priv = DBUSMENU_CLIENT_MENUITEM_GET_PRIVATE(mi);
449+ priv->client = client;
450+ return mi;
451+}
452+
453+static void
454+handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp)
455+{
456+ DbusmenuClientMenuitemPrivate * priv = DBUSMENU_CLIENT_MENUITEM_GET_PRIVATE(mi);
457+ dbusmenu_client_send_event(priv->client, dbusmenu_menuitem_get_id(mi), name, value, timestamp);
458+ return;
459+}
460
461=== added file 'libdbusmenu-glib/client-menuitem.h'
462--- libdbusmenu-glib/client-menuitem.h 1970-01-01 00:00:00 +0000
463+++ libdbusmenu-glib/client-menuitem.h 2010-02-04 20:30:33 +0000
464@@ -0,0 +1,61 @@
465+/*
466+A small subclass of the menuitem for using clients.
467+
468+Copyright 2010 Canonical Ltd.
469+
470+Authors:
471+ Ted Gould <ted@canonical.com>
472+
473+This program is free software: you can redistribute it and/or modify it
474+under the terms of either or both of the following licenses:
475+
476+1) the GNU Lesser General Public License version 3, as published by the
477+Free Software Foundation; and/or
478+2) the GNU Lesser General Public License version 2.1, as published by
479+the Free Software Foundation.
480+
481+This program is distributed in the hope that it will be useful, but
482+WITHOUT ANY WARRANTY; without even the implied warranties of
483+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
484+PURPOSE. See the applicable version of the GNU Lesser General Public
485+License for more details.
486+
487+You should have received a copy of both the GNU Lesser General Public
488+License version 3 and version 2.1 along with this program. If not, see
489+<http://www.gnu.org/licenses/>
490+*/
491+
492+#ifndef __DBUSMENU_CLIENT_MENUITEM_H__
493+#define __DBUSMENU_CLIENT_MENUITEM_H__
494+
495+#include <glib.h>
496+#include <glib-object.h>
497+#include "menuitem.h"
498+#include "client.h"
499+
500+G_BEGIN_DECLS
501+
502+#define DBUSMENU_CLIENT_MENUITEM_TYPE (dbusmenu_client_menuitem_get_type ())
503+#define DBUSMENU_CLIENT_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DBUSMENU_CLIENT_MENUITEM_TYPE, DbusmenuClientMenuitem))
504+#define DBUSMENU_CLIENT_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DBUSMENU_CLIENT_MENUITEM_TYPE, DbusmenuClientMenuitemClass))
505+#define DBUSMENU_IS_CLIENT_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DBUSMENU_CLIENT_MENUITEM_TYPE))
506+#define DBUSMENU_IS_CLIENT_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_CLIENT_MENUITEM_TYPE))
507+#define DBUSMENU_CLIENT_MENUITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_CLIENT_MENUITEM_TYPE, DbusmenuClientMenuitemClass))
508+
509+typedef struct _DbusmenuClientMenuitem DbusmenuClientMenuitem;
510+typedef struct _DbusmenuClientMenuitemClass DbusmenuClientMenuitemClass;
511+
512+struct _DbusmenuClientMenuitemClass {
513+ DbusmenuMenuitemClass parent_class;
514+};
515+
516+struct _DbusmenuClientMenuitem {
517+ DbusmenuMenuitem parent;
518+};
519+
520+GType dbusmenu_client_menuitem_get_type (void);
521+DbusmenuClientMenuitem * dbusmenu_client_menuitem_new (gint id, DbusmenuClient * client);
522+
523+G_END_DECLS
524+
525+#endif
526
527=== modified file 'libdbusmenu-glib/client.c'
528--- libdbusmenu-glib/client.c 2010-01-07 05:27:49 +0000
529+++ libdbusmenu-glib/client.c 2010-02-04 20:30:33 +0000
530@@ -35,6 +35,7 @@
531
532 #include "client.h"
533 #include "menuitem.h"
534+#include "client-menuitem.h"
535 #include "dbusmenu-client.h"
536 #include "server-marshal.h"
537
538@@ -96,10 +97,10 @@
539 static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec);
540 /* Private Funcs */
541 static void layout_update (DBusGProxy * proxy, gint revision, guint parent, DbusmenuClient * client);
542-static void id_prop_update (DBusGProxy * proxy, guint id, gchar * property, GValue * value, DbusmenuClient * client);
543-static void id_update (DBusGProxy * proxy, guint id, DbusmenuClient * client);
544+static void id_prop_update (DBusGProxy * proxy, gint id, gchar * property, GValue * value, DbusmenuClient * client);
545+static void id_update (DBusGProxy * proxy, gint id, DbusmenuClient * client);
546 static void build_proxies (DbusmenuClient * client);
547-static guint parse_node_get_id (xmlNodePtr node);
548+static gint parse_node_get_id (xmlNodePtr node);
549 static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, DBusGProxy * proxy);
550 static gint parse_layout (DbusmenuClient * client, const gchar * layout);
551 static void update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError * in_error, void * data);
552@@ -321,7 +322,7 @@
553 /* Signal from the server that a property has changed
554 on one of our menuitems */
555 static void
556-id_prop_update (DBusGProxy * proxy, guint id, gchar * property, GValue * value, DbusmenuClient * client)
557+id_prop_update (DBusGProxy * proxy, gint id, gchar * property, GValue * value, DbusmenuClient * client)
558 {
559 #ifdef MASSIVEDEBUGGING
560 GValue valstr = {0};
561@@ -344,7 +345,7 @@
562 /* Oh, lots of updates now. That silly server, they want
563 to change all kinds of stuff! */
564 static void
565-id_update (DBusGProxy * proxy, guint id, DbusmenuClient * client)
566+id_update (DBusGProxy * proxy, gint id, DbusmenuClient * client)
567 {
568 #ifdef MASSIVEDEBUGGING
569 g_debug("Client side ID update: %d", id);
570@@ -498,15 +499,15 @@
571 priv->dbusproxy = NULL;
572 }
573
574- dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__INT_UINT, G_TYPE_NONE, G_TYPE_INT, G_TYPE_UINT, G_TYPE_INVALID);
575- dbus_g_proxy_add_signal(priv->menuproxy, "LayoutUpdate", G_TYPE_INT, G_TYPE_UINT, G_TYPE_INVALID);
576- dbus_g_proxy_connect_signal(priv->menuproxy, "LayoutUpdate", G_CALLBACK(layout_update), client, NULL);
577+ dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__UINT_INT, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_INT, G_TYPE_INVALID);
578+ dbus_g_proxy_add_signal(priv->menuproxy, "LayoutUpdated", G_TYPE_UINT, G_TYPE_INT, G_TYPE_INVALID);
579+ dbus_g_proxy_connect_signal(priv->menuproxy, "LayoutUpdated", G_CALLBACK(layout_update), client, NULL);
580
581 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);
582 dbus_g_proxy_add_signal(priv->menuproxy, "ItemPropertyUpdated", G_TYPE_UINT, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
583 dbus_g_proxy_connect_signal(priv->menuproxy, "ItemPropertyUpdated", G_CALLBACK(id_prop_update), client, NULL);
584
585- dbus_g_proxy_add_signal(priv->menuproxy, "ItemUpdated", G_TYPE_UINT, G_TYPE_INVALID);
586+ dbus_g_proxy_add_signal(priv->menuproxy, "ItemUpdated", G_TYPE_INT, G_TYPE_INVALID);
587 dbus_g_proxy_connect_signal(priv->menuproxy, "ItemUpdated", G_CALLBACK(id_update), client, NULL);
588
589 update_layout(client);
590@@ -514,51 +515,23 @@
591 return;
592 }
593
594-/* Get the "revision" attribute of the node, parse it and
595- return it. Also we're checking to ensure the node
596- is a 'menu' here. */
597-static gint
598-parse_node_get_revision (xmlNodePtr node)
599-{
600- if (g_strcmp0((gchar *)node->name, "menu") != 0) {
601- /* This kills some nodes early */
602- g_warning("XML Node is not 'menu' it is '%s'", node->name);
603- return 0;
604- }
605-
606- xmlAttrPtr attrib;
607- for (attrib = node->properties; attrib != NULL; attrib = attrib->next) {
608- if (g_strcmp0((gchar *)attrib->name, "revision") == 0) {
609- if (attrib->children != NULL) {
610- guint revision = (guint)g_ascii_strtoull((gchar *)attrib->children->content, NULL, 10);
611- /* g_debug ("Found ID: %d", id); */
612- return revision;
613- }
614- break;
615- }
616- }
617-
618- g_warning("Unable to find a revision on the node");
619- return 0;
620-}
621-
622 /* Get the ID attribute of the node, parse it and
623 return it. Also we're checking to ensure the node
624 is a 'menu' here. */
625-static guint
626+static gint
627 parse_node_get_id (xmlNodePtr node)
628 {
629 if (g_strcmp0((gchar *)node->name, "menu") != 0) {
630 /* This kills some nodes early */
631 g_warning("XML Node is not 'menu' it is '%s'", node->name);
632- return 0;
633+ return -1;
634 }
635
636 xmlAttrPtr attrib;
637 for (attrib = node->properties; attrib != NULL; attrib = attrib->next) {
638 if (g_strcmp0((gchar *)attrib->name, "id") == 0) {
639 if (attrib->children != NULL) {
640- guint id = (guint)g_ascii_strtoull((gchar *)attrib->children->content, NULL, 10);
641+ gint id = (guint)g_ascii_strtoll((gchar *)attrib->children->content, NULL, 10);
642 /* g_debug ("Found ID: %d", id); */
643 return id;
644 }
645@@ -567,7 +540,7 @@
646 }
647
648 g_warning("Unable to find an ID on the node");
649- return 0;
650+ return -1;
651 }
652
653 /* A small helper that calls _property_set on each hash table
654@@ -654,14 +627,11 @@
655 return;
656 }
657
658-static void
659-menuitem_activate (DbusmenuMenuitem * mi, DbusmenuClient * client)
660+void
661+dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name, const GValue * value, guint timestamp)
662 {
663 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
664- GValue value = {0};
665- g_value_init(&value, G_TYPE_INT);
666- g_value_set_int(&value, 0);
667- org_ayatana_dbusmenu_event_async (priv->menuproxy, dbusmenu_menuitem_get_id(mi), "clicked", &value, menuitem_call_cb, mi);
668+ org_ayatana_dbusmenu_event_async (priv->menuproxy, id, name, value, timestamp, menuitem_call_cb, GINT_TO_POINTER(id));
669 return;
670 }
671
672@@ -670,11 +640,14 @@
673 static DbusmenuMenuitem *
674 parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, DBusGProxy * proxy)
675 {
676- guint id = parse_node_get_id(node);
677+ gint id = parse_node_get_id(node);
678+ if (id < 0) {
679+ return NULL;
680+ }
681 #ifdef MASSIVEDEBUGGING
682 g_debug("Client looking at node with id: %d", id);
683 #endif
684- if (item == NULL || dbusmenu_menuitem_get_id(item) != id || id == 0) {
685+ if (item == NULL || dbusmenu_menuitem_get_id(item) != id) {
686 if (item != NULL) {
687 if (parent != NULL) {
688 dbusmenu_menuitem_child_delete(parent, item);
689@@ -683,17 +656,11 @@
690 item = NULL;
691 }
692
693- if (id == 0) {
694- g_warning("ID from XML file is zero");
695- return NULL;
696- }
697-
698 /* Build a new item */
699- item = dbusmenu_menuitem_new_with_id(id);
700+ item = DBUSMENU_MENUITEM(dbusmenu_client_menuitem_new(id, client));
701 if (parent == NULL) {
702 dbusmenu_menuitem_set_root(item, TRUE);
703 }
704- g_signal_connect(G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(menuitem_activate), client);
705
706 /* Get the properties queued up for this item */
707 /* Not happy about this, but I need these :( */
708@@ -717,7 +684,10 @@
709
710 for (children = node->children, position = 0; children != NULL; children = children->next, position++) {
711 /* g_debug("Looking at child: %d", position); */
712- guint childid = parse_node_get_id(children);
713+ gint childid = parse_node_get_id(children);
714+ if (childid < 0) {
715+ continue;
716+ }
717 DbusmenuMenuitem * childmi = NULL;
718
719 GList * childsearch = NULL;
720@@ -764,7 +734,6 @@
721 xmldoc = xmlReadMemory(layout, g_utf8_strlen(layout, 16*1024), "dbusmenu.xml", NULL, 0);
722
723 xmlNodePtr root = xmlDocGetRootElement(xmldoc);
724- gint revision = parse_node_get_revision(root);
725
726 DbusmenuMenuitem * oldroot = priv->root;
727 priv->root = parse_layout_xml(client, root, priv->root, NULL, priv->menuproxy);
728@@ -781,7 +750,7 @@
729 g_signal_emit(G_OBJECT(client), signals[ROOT_CHANGED], 0, priv->root, TRUE);
730 }
731
732- return revision;
733+ return 1;
734 }
735
736 /* When the layout property returns, here's where we take care of that. */
737
738=== modified file 'libdbusmenu-glib/client.h'
739--- libdbusmenu-glib/client.h 2009-12-10 04:57:31 +0000
740+++ libdbusmenu-glib/client.h 2010-02-04 20:30:33 +0000
741@@ -50,9 +50,9 @@
742 #define DBUSMENU_CLIENT_PROP_DBUS_NAME "dbus-name"
743 #define DBUSMENU_CLIENT_PROP_DBUS_OBJECT "dbus-object"
744
745-#define DBUSMENU_CLIENT_TYPES_DEFAULT "menuitem"
746+#define DBUSMENU_CLIENT_TYPES_DEFAULT "standard"
747 #define DBUSMENU_CLIENT_TYPES_SEPARATOR "separator"
748-#define DBUSMENU_CLIENT_TYPES_IMAGE "menuitem"
749+#define DBUSMENU_CLIENT_TYPES_IMAGE "standard"
750
751 /**
752 DbusmenuClientClass:
753@@ -104,6 +104,11 @@
754 gboolean dbusmenu_client_add_type_handler (DbusmenuClient * client,
755 const gchar * type,
756 DbusmenuClientTypeHandler newfunc);
757+void dbusmenu_client_send_event (DbusmenuClient * client,
758+ gint id,
759+ const gchar * name,
760+ const GValue * value,
761+ guint timestamp);
762
763 /**
764 SECTION:client
765
766=== modified file 'libdbusmenu-glib/dbus-menu.xml'
767--- libdbusmenu-glib/dbus-menu.xml 2009-12-24 10:31:16 +0000
768+++ libdbusmenu-glib/dbus-menu.xml 2010-02-04 20:30:33 +0000
769@@ -8,6 +8,7 @@
770
771 Authors:
772 Ted Gould <ted@canonical.com>
773+ Aurelien Gateau <ted@canonical.com>
774
775 This program is free software: you can redistribute it and/or modify it
776 under the terms of either or both of the following licenses:
777@@ -27,164 +28,275 @@
778 License version 3 and version 2.1 along with this program. If not, see
779 <http://www.gnu.org/licenses/>
780 -->
781-<node name="/">
782+<node name="/" xmlns:dox="http://www.ayatana.org/dbus/dox.dtd">
783 <interface name="org.ayatana.dbusmenu">
784+ <dox:d><![CDATA[
785+ The goal of this DBus interface is to be able to pass menu items
786+ through DBus.
787+
788+ Items are represented with a unique numeric id and a dictionary of
789+ properties.
790+
791+ Available properties are:
792+
793+ <table>
794+ <tr>
795+ <th>Name</th>
796+ <th>Type</th>
797+ <th>Description</th>
798+ <th>Default Value</th>
799+ </tr>
800+ <tr>
801+ <td>type</td>
802+ <td>String</td>
803+ <td>Can be one of:
804+ - "standard": an item which can be clicked to trigger an action or
805+ show another menu
806+ - "separator": a separator
807+
808+ Vendor specific types can be added by prefixing them with
809+ "x-<vendor>-".
810+ </td>
811+ <td>"standard"</td>
812+ </tr>
813+ <tr>
814+ <td>label</td>
815+ <td>string</td>
816+ <td>Text of the item, except that:
817+ -# two consecutive underscore characters "__" are displayed as a
818+ single underscore,
819+ -# any remaining underscore characters are not displayed at all,
820+ -# the first of those remaining underscore characters (unless it is
821+ the last character in the string) indicates that the following
822+ character is the access key.
823+ </td>
824+ <td>""</td>
825+ </tr>
826+ <tr>
827+ <td>enabled</td>
828+ <td>boolean</td>
829+ <td>Whether the item can be activated or not.</td>
830+ <td>true</td>
831+ </tr>
832+ <tr>
833+ <td>icon-name</td>
834+ <td>string</td>
835+ <td>Icon name of the item, following the freedesktop.org icon spec.</td>
836+ <td>""</td>
837+ </tr>
838+ <tr>
839+ <td>icon-data</td>
840+ <td>binary</td>
841+ <td>PNG data of the icon.</td>
842+ <td>Empty</td>
843+ </tr>
844+ <tr>
845+ <td>toggle-type</td>
846+ <td>string</td>
847+ <td>
848+ If the item can be toggled, this property should be set to:
849+ - "checkmark": Item is an independent togglable item
850+ - "radio": Item is part of a group where only one item can be
851+ toggled at a time
852+ - "": Item cannot be toggled
853+ </td>
854+ <td>""</td>
855+ </tr>
856+ <tr>
857+ <td>toggle-state</td>
858+ <td>int</td>
859+ <td>
860+ Describe the current state of a "togglable" item. Can be one of:
861+ - 0 = off
862+ - 1 = on
863+ - anything else = indeterminate
864+
865+ Note:
866+ The implementation does not itself handle ensuring that only one
867+ item in a radio group is set to "on", or that a group does not have
868+ "on" and "indeterminate" items simultaneously; maintaining this
869+ policy is up to the toolkit wrappers.
870+ </td>
871+ <td>0</td>
872+ </tr>
873+ <tr>
874+ <td>children-display</td>
875+ <td>string</td>
876+ <td>
877+ If the menu item has children this property should be set to
878+ "submenu".
879+ </td>
880+ <td>""</td>
881+ </tr>
882+ </table>
883+
884+ Vendor specific properties can be added by prefixing them with
885+ "x-<vendor>-".
886+ ]]></dox:d>
887
888 <!-- Properties -->
889-<!--
890-Provides the version of the DBusmenu API that this API is
891-implementing.
892--->
893- <property name="version" type="u" access="read"/>
894+ <property name="version" type="u" access="read">
895+ <dox:d>
896+ Provides the version of the DBusmenu API that this API is
897+ implementing.
898+ </dox:d>
899+ </property>
900
901 <!-- Functions -->
902
903-<!--
904-Provides an XML representation of the menu hierarchy
905-
906-@param parentId The ID of the parent node for the layout. For
907- grabbing the layout from the root node use zero.
908-@param revision The revision number of the layout. For matching
909- with layoutUpdated signals.
910-@param layout The layout as an XML string of IDs.
911-
912-XML syntax:
913-
914+ <method name="GetLayout">
915+ <dox:d><![CDATA[
916+ Provides an XML representation of the menu hierarchy
917+
918+ XML syntax:
919+
920+ @verbatim
921 <menu id="1" revision="2"> # Root container
922- <menu id="2" revision="2"> # First level menu, for example "File"
923- <menu id="3" revision="2"/> ~ Second level menu, for example "Open"
924- <menu id="4" revision="3"/>
925- ...
926- </menu>
927- <menu id="5" revision="2"> # Another first level menu, say "Edit"
928- ...
929- </menu>
930- ...
931+ <menu id="2" revision="2"> # First level menu, for example "File"
932+ <menu id="3" revision="2"/> ~ Second level menu, for example "Open"
933+ <menu id="4" revision="3"/>
934+ ...
935+ </menu>
936+ <menu id="5" revision="2"> # Another first level menu, say "Edit"
937+ ...
938+ </menu>
939+ ...
940 </menu>
941--->
942- <method name="GetLayout">
943- <arg type="u" name="parentId" direction="in" />
944- <arg type="u" name="revision" direction="out" />
945- <arg type="s" name="layout" direction="out" />
946+ @endverbatim
947+ ]]></dox:d>
948+ <arg type="i" name="parentId" direction="in">
949+ <dox:d>The ID of the parent node for the layout. For
950+ grabbing the layout from the root node use zero.</dox:d>
951+ </arg>
952+ <arg type="u" name="revision" direction="out">
953+ <dox:d>The revision number of the layout. For matching
954+ with layoutUpdated signals.</dox:d>
955+ </arg>
956+ <arg type="s" name="layout" direction="out">
957+ <dox:d>The layout as an XML string of IDs.</dox:d>
958+ </arg>
959 </method>
960
961-<!--
962-Returns the list of items which are children of @a parentId.
963-
964-@param Ids A list of ids that we should be finding the properties
965- on. If the list is empty, all menu items should be sent.
966-@param propertyNames list of string the list of item properties we
967- are interested in. If there are no entries in the list all of
968- the properties will be sent.
969-
970-An item is represented as a struct following this format:
971-@li id unsigned the item id
972-@li properties map(string => variant) the requested item properties
973-
974--->
975 <method name="GetGroupProperties">
976- <arg type="au" name="Ids" direction="in" />
977- <arg type="as" name="propertyNames" direction="in" />
978- <arg type="a(ua{sv})" name="properties" direction="out" />
979+ <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="QVariantList"/>
980+ <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="DBusMenuItemList"/>
981+ <dox:d>
982+ Returns the list of items which are children of @a parentId.
983+ </dox:d>
984+ <arg type="ai" name="ids" direction="in" >
985+ <dox:d>
986+ A list of ids that we should be finding the properties
987+ on. If the list is empty, all menu items should be sent.
988+ </dox:d>
989+ </arg>
990+ <arg type="as" name="propertyNames" direction="in" >
991+ <dox:d>
992+ The list of item properties we are
993+ interested in. If there are no entries in the list all of
994+ the properties will be sent.
995+ </dox:d>
996+ </arg>
997+ <arg type="a(ia{sv})" name="properties" direction="out" >
998+ <dox:d>
999+ An array of property values.
1000+ An item in this area is represented as a struct following
1001+ this format:
1002+ @li id unsigned the item id
1003+ @li properties map(string => variant) the requested item properties
1004+ </dox:d>
1005+ </arg>
1006 </method>
1007
1008 <method name="GetChildren">
1009- <arg type="u" name="id" direction="in" />
1010+ <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="DBusMenuItemList"/>
1011+ <arg type="i" name="id" direction="in" />
1012 <arg type="as" name="propertyNames" direction="in" />
1013- <arg type="a(ua{sv})" name="properties" direction="out" />
1014+ <arg type="a(ia{sv})" name="properties" direction="out" />
1015 </method>
1016
1017-<!--
1018-Each menu item has a set of properties. Property keys are in menuitem.h:
1019-
1020-@li type string Type of the item (see below)
1021-@li label string Text of the item
1022-@li icon-data binary Raw data of the icon (TODO: define format)
1023-@li icon string Icon name of the item, following icon spec
1024-@li sensitive boolean Whether the item can be activated or not
1025-@li visible boolean Whether the item is visible or not (XXX: Is this necessary?)
1026-@li checked boolean Whether a checkbox or radio item is checked
1027-@li shortcut string The keyboard shortcut
1028-
1029-@c type property is an enum which can take the following values (client.h):
1030-
1031-@li action An item which can be clicked to trigger an action
1032-@li checkbox An item which can be checked or unchecked
1033-@li radio An item which can be checked or unchecked as part of a group
1034-@li separator A separator
1035-@li menu An item which contains more items
1036--->
1037 <method name="GetProperty">
1038- <arg type="u" name="id" direction="in" />
1039+ <arg type="i" name="id" direction="in" />
1040 <arg type="s" name="name" direction="in" />
1041 <arg type="v" name="value" direction="out" />
1042 </method>
1043
1044-<!--
1045-Returns multiple properties in one call. This is more efficient than
1046-GetProperty.
1047-
1048-@param id unsigned the item whose properties we want to retrieve.
1049-@param propertyNames list of string name of the properties we want. If the list contains no entries, all properties are sent.
1050--->
1051 <method name="GetProperties">
1052+ <dox:d>
1053+ Returns multiple properties in one call. This is more efficient than
1054+ GetProperty.
1055+
1056+ </dox:d>
1057 <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
1058- <arg type="u" name="id" direction="in" />
1059- <arg type="as" name="propertyNames" direction="in" />
1060+ <arg type="i" name="id" direction="in" >
1061+ <dox:d>The item whose properties we want to retrieve.</dox:d>
1062+ </arg>
1063+ <arg type="as" name="propertyNames" direction="in" >
1064+ <dox:d>List of string name of the properties we want. If the list contains no entries, all properties are sent.</dox:d>
1065+ </arg>
1066 <arg type="a{sv}" name="properties" direction="out" />
1067 </method>
1068
1069-<!--
1070-This is called by the applet to notify the application an event happened on a
1071-menu item.
1072-
1073-@param id the id of the item which received the event
1074-@param type the type of event
1075-@param data event-specific data
1076-
1077-@a type can be one of the following:
1078-
1079-@li "clicked"
1080-@li "hovered"
1081-
1082-Vendor specific events can be added by prefixing them with "x-<vendor>-"
1083--->
1084 <method name="Event">
1085- <arg type="u" name="id" direction="in" />
1086- <arg type="s" name="eventId" direction="in" />
1087- <arg type="v" name="data" direction="in" />
1088+ <dox:d><![CDATA[
1089+ This is called by the applet to notify the application an event happened on a
1090+ menu item.
1091+
1092+ @a type can be one of the following:
1093+
1094+ @li "clicked"
1095+ @li "hovered"
1096+
1097+ Vendor specific events can be added by prefixing them with "x-<vendor>-"
1098+ ]]></dox:d>
1099+ <arg type="i" name="id" direction="in" >
1100+ <dox:d>the id of the item which received the event</dox:d>
1101+ </arg>
1102+ <arg type="s" name="eventId" direction="in" >
1103+ <dox:d>the type of event</dox:d>
1104+ </arg>
1105+ <arg type="v" name="data" direction="in" >
1106+ <dox:d>event-specific data</dox:d>
1107+ </arg>
1108+ <arg type="u" name="timestamp" direction="in" >
1109+ <dox:d>The time that the event occured if available or the time the message was sent if not</dox:d>
1110+ </arg>
1111 </method>
1112
1113 <!-- Signals -->
1114-<!--
1115-Triggered by the application to notify the applet that the property @a property
1116-from item @a id has changed to @a value.
1117--->
1118 <signal name="ItemPropertyUpdated">
1119- <arg type="u" name="id" direction="out" />
1120+ <dox:d>
1121+ Triggered by the application to notify the applet that the property @a property
1122+ from item @a id has changed to @a value.
1123+ </dox:d>
1124+ <arg type="i" name="id" direction="out" />
1125 <arg type="s" name="prop" direction="out" />
1126 <arg type="v" name="value" direction="out" />
1127 </signal>
1128
1129-<!--
1130-Triggered by the application to notify the applet that all properties of item
1131-@a id should be considered outdated
1132--->
1133 <signal name="ItemUpdated">
1134- <arg type="u" name="id" direction="out" />
1135+ <dox:d>
1136+ Triggered by the application to notify the applet that all properties of item
1137+ </dox:d>
1138+ <arg type="i" name="id" direction="out" >
1139+ <dox:d>id which should be considered outdated</dox:d>
1140+ </arg>
1141 </signal>
1142
1143-<!--
1144-Triggered by the application to notify display of a layout update, up to
1145-revision
1146-@param revsion The revision of the layout that we're currently on
1147-@param parent If the layout update is only of a subtree, this is the parent
1148- item for the entries that have changed. It is zero if the
1149- whole layout should be considered invalid.
1150--->
1151- <signal name="LayoutUpdate">
1152- <arg type="i" name="revision" direction="out" />
1153- <arg type="u" name="parent" direction="out" />
1154+ <signal name="LayoutUpdated">
1155+ <dox:d>
1156+ Triggered by the application to notify display of a layout update, up to
1157+ revision
1158+ </dox:d>
1159+ <arg type="u" name="revision" direction="out" >
1160+ <dox:d>The revision of the layout that we're currently on</dox:d>
1161+ </arg>
1162+ <arg type="i" name="parent" direction="out" >
1163+ <dox:d>
1164+ If the layout update is only of a subtree, this is the
1165+ parent item for the entries that have changed. It is zero if
1166+ the whole layout should be considered invalid.
1167+ </dox:d>
1168+ </arg>
1169 </signal>
1170
1171 <!-- End of interesting stuff -->
1172
1173=== modified file 'libdbusmenu-glib/menuitem-marshal.list'
1174--- libdbusmenu-glib/menuitem-marshal.list 2009-12-19 03:58:26 +0000
1175+++ libdbusmenu-glib/menuitem-marshal.list 2010-02-04 20:30:33 +0000
1176@@ -3,3 +3,4 @@
1177 VOID: OBJECT, UINT
1178 VOID: OBJECT
1179 VOID: VOID
1180+VOID: UINT
1181
1182=== modified file 'libdbusmenu-glib/menuitem-private.h'
1183--- libdbusmenu-glib/menuitem-private.h 2009-11-13 18:02:08 +0000
1184+++ libdbusmenu-glib/menuitem-private.h 2010-02-04 20:30:33 +0000
1185@@ -33,7 +33,7 @@
1186
1187 G_BEGIN_DECLS
1188
1189-void dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array, gint revision);
1190+void dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array);
1191
1192 G_END_DECLS
1193
1194
1195=== modified file 'libdbusmenu-glib/menuitem.c'
1196--- libdbusmenu-glib/menuitem.c 2009-12-21 22:15:45 +0000
1197+++ libdbusmenu-glib/menuitem.c 2010-02-04 20:30:33 +0000
1198@@ -55,7 +55,7 @@
1199 typedef struct _DbusmenuMenuitemPrivate DbusmenuMenuitemPrivate;
1200 struct _DbusmenuMenuitemPrivate
1201 {
1202- guint id;
1203+ gint id;
1204 GList * children;
1205 GHashTable * properties;
1206 gboolean root;
1207@@ -92,6 +92,7 @@
1208 static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec);
1209 static void g_value_transform_STRING_BOOLEAN (const GValue * in, GValue * out);
1210 static void g_value_transform_STRING_INT (const GValue * in, GValue * out);
1211+static void handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp);
1212
1213 /* GObject stuff */
1214 G_DEFINE_TYPE (DbusmenuMenuitem, dbusmenu_menuitem, G_TYPE_OBJECT);
1215@@ -108,6 +109,8 @@
1216 object_class->set_property = set_property;
1217 object_class->get_property = get_property;
1218
1219+ klass->handle_event = handle_event;
1220+
1221 /**
1222 DbusmenuMenuitem::property-changed:
1223 @arg0: The #DbusmenuMenuitem object.
1224@@ -127,6 +130,7 @@
1225 /**
1226 DbusmenuMenuitem::item-activated:
1227 @arg0: The #DbusmenuMenuitem object.
1228+ @arg1: The timestamp of when it was activated
1229
1230 Emitted on the objects on the server side when
1231 they are signaled on the client side.
1232@@ -136,8 +140,8 @@
1233 G_SIGNAL_RUN_LAST,
1234 G_STRUCT_OFFSET(DbusmenuMenuitemClass, item_activated),
1235 NULL, NULL,
1236- _dbusmenu_menuitem_marshal_VOID__VOID,
1237- G_TYPE_NONE, 0, G_TYPE_NONE);
1238+ _dbusmenu_menuitem_marshal_VOID__UINT,
1239+ G_TYPE_NONE, 1, G_TYPE_UINT, G_TYPE_NONE);
1240 /**
1241 DbusmenuMenuitem::child-added:
1242 @arg0: The #DbusmenuMenuitem which is the parent.
1243@@ -206,7 +210,7 @@
1244 G_TYPE_NONE, 0, G_TYPE_NONE);
1245
1246 g_object_class_install_property (object_class, PROP_ID,
1247- g_param_spec_uint("id", "ID for the menu item",
1248+ g_param_spec_int("id", "ID for the menu item",
1249 "This is a unique indentifier for the menu item.",
1250 0, 30000, 0,
1251 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
1252@@ -245,7 +249,7 @@
1253 return;
1254 }
1255
1256-static guint menuitem_next_id = 1;
1257+static gint menuitem_next_id = 0;
1258
1259 /* A small little function to both clear the insides of a
1260 value as well as the memory it itself uses. */
1261@@ -314,9 +318,9 @@
1262
1263 switch (id) {
1264 case PROP_ID:
1265- priv->id = g_value_get_uint(value);
1266+ priv->id = g_value_get_int(value);
1267 if (priv->id > menuitem_next_id) {
1268- menuitem_next_id = priv->id;
1269+ menuitem_next_id = priv->id + 1;
1270 }
1271 break;
1272 }
1273@@ -331,16 +335,23 @@
1274
1275 switch (id) {
1276 case PROP_ID:
1277- if (priv->id == 0) {
1278- priv->id = menuitem_next_id++;
1279- }
1280- g_value_set_uint(value, priv->id);
1281+ g_value_set_int(value, priv->id);
1282 break;
1283 }
1284
1285 return;
1286 }
1287
1288+/* Handles the activate event if it is sent. */
1289+static void
1290+handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp)
1291+{
1292+ if (g_strcmp0(name, "clicked") == 0) {
1293+ g_signal_emit(G_OBJECT(mi), signals[ITEM_ACTIVATED], 0, timestamp, TRUE);
1294+ }
1295+
1296+ return;
1297+}
1298
1299 /* Public interface */
1300
1301@@ -354,7 +365,7 @@
1302 DbusmenuMenuitem *
1303 dbusmenu_menuitem_new (void)
1304 {
1305- return g_object_new(DBUSMENU_TYPE_MENUITEM, NULL);
1306+ return g_object_new(DBUSMENU_TYPE_MENUITEM, "id", menuitem_next_id++, NULL);
1307 }
1308
1309 /**
1310@@ -366,7 +377,7 @@
1311 Return value: A newly allocated #DbusmenuMenuitem.
1312 */
1313 DbusmenuMenuitem *
1314-dbusmenu_menuitem_new_with_id (guint id)
1315+dbusmenu_menuitem_new_with_id (gint id)
1316 {
1317 DbusmenuMenuitem * mi = g_object_new(DBUSMENU_TYPE_MENUITEM, "id", id, NULL);
1318 /* g_debug("New Menuitem id %d goal id %d", dbusmenu_menuitem_get_id(mi), id); */
1319@@ -641,7 +652,7 @@
1320 can't be found.
1321 */
1322 DbusmenuMenuitem *
1323-dbusmenu_menuitem_child_find (DbusmenuMenuitem * mi, guint id)
1324+dbusmenu_menuitem_child_find (DbusmenuMenuitem * mi, gint id)
1325 {
1326 g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), NULL);
1327
1328@@ -660,7 +671,7 @@
1329
1330 typedef struct {
1331 DbusmenuMenuitem * mi;
1332- guint id;
1333+ gint id;
1334 } find_id_t;
1335
1336 /* Basically the heart of the find_id that matches the
1337@@ -696,7 +707,7 @@
1338 represented by @mi.
1339 */
1340 DbusmenuMenuitem *
1341-dbusmenu_menuitem_find_id (DbusmenuMenuitem * mi, guint id)
1342+dbusmenu_menuitem_find_id (DbusmenuMenuitem * mi, gint id)
1343 {
1344 g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), NULL);
1345 find_id_t find_id = {mi: NULL, id: id};
1346@@ -1047,7 +1058,6 @@
1347 dbusmenu_menuitem_buildxml:
1348 @mi: #DbusmenuMenuitem to represent in XML
1349 @array: A list of string that will be turned into an XML file
1350- @revision: The revision of the layout to embed in the XML
1351
1352 This function will add strings to the array @array. It will put
1353 at least one entry if this menu item has no children. If it has
1354@@ -1056,18 +1066,22 @@
1355 children to place their own tags in the array in between those two.
1356 */
1357 void
1358-dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array, gint revision)
1359+dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array)
1360 {
1361 g_return_if_fail(DBUSMENU_IS_MENUITEM(mi));
1362
1363+ gint id = 0;
1364+ if (!dbusmenu_menuitem_get_root(mi)) {
1365+ id = dbusmenu_menuitem_get_id(mi);
1366+ }
1367+
1368 GList * children = dbusmenu_menuitem_get_children(mi);
1369- /* TODO: Only put revision info in the root node. Save some bandwidth. */
1370 if (children == NULL) {
1371- g_ptr_array_add(array, g_strdup_printf("<menu id=\"%d\" revision=\"%d\" />", dbusmenu_menuitem_get_id(mi), revision));
1372+ g_ptr_array_add(array, g_strdup_printf("<menu id=\"%d\"/>", id));
1373 } else {
1374- g_ptr_array_add(array, g_strdup_printf("<menu id=\"%d\" revision=\"%d\">", dbusmenu_menuitem_get_id(mi), revision));
1375+ g_ptr_array_add(array, g_strdup_printf("<menu id=\"%d\">", id));
1376 for ( ; children != NULL; children = children->next) {
1377- dbusmenu_menuitem_buildxml(DBUSMENU_MENUITEM(children->data), array, revision);
1378+ dbusmenu_menuitem_buildxml(DBUSMENU_MENUITEM(children->data), array);
1379 }
1380 g_ptr_array_add(array, g_strdup("</menu>"));
1381 }
1382@@ -1112,20 +1126,35 @@
1383 }
1384
1385 /**
1386- dbusmenu_menuitem_activate:
1387+ dbusmenu_menuitem_handle_event:
1388 @mi: The #DbusmenuMenuitem to send the signal on.
1389+ @name: The name of the signal
1390+ @value: A value that could be set for the event
1391+ @timestamp: The timestamp of when the event happened
1392+
1393+ This function is called to create an event. It is likely
1394+ to be overrided by subclasses. The default menu item
1395+ will respond to the activate signal and do:
1396
1397 Emits the #DbusmenuMenuitem::item-activate signal on this
1398 menu item. Called by server objects when they get the
1399 appropriate DBus signals from the client.
1400+
1401+ If you subclass this function you should really think
1402+ about calling the parent function unless you have a good
1403+ reason not to.
1404 */
1405 void
1406-dbusmenu_menuitem_activate (DbusmenuMenuitem * mi)
1407+dbusmenu_menuitem_handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp)
1408 {
1409 g_return_if_fail(DBUSMENU_IS_MENUITEM(mi));
1410 #ifdef MASSIVEDEBUGGING
1411- g_debug("Menuitem %d (%s) activated", ID(mi), LABEL(mi));
1412+ g_debug("Menuitem %d (%s) is getting event '%s'", ID(mi), LABEL(mi), name);
1413 #endif
1414- g_signal_emit(G_OBJECT(mi), signals[ITEM_ACTIVATED], 0, TRUE);
1415+ DbusmenuMenuitemClass * class = DBUSMENU_MENUITEM_GET_CLASS(mi);
1416+
1417+ if (class->handle_event != NULL) {
1418+ return class->handle_event(mi, name, value, timestamp);
1419+ }
1420 return;
1421 }
1422
1423=== modified file 'libdbusmenu-glib/menuitem.h'
1424--- libdbusmenu-glib/menuitem.h 2010-01-07 16:49:35 +0000
1425+++ libdbusmenu-glib/menuitem.h 2010-02-04 20:30:33 +0000
1426@@ -52,19 +52,19 @@
1427
1428 #define DBUSMENU_MENUITEM_PROP_TYPE "type"
1429 #define DBUSMENU_MENUITEM_PROP_VISIBLE "visible"
1430-#define DBUSMENU_MENUITEM_PROP_SENSITIVE "sensitive"
1431+#define DBUSMENU_MENUITEM_PROP_ENABLED "enabled"
1432 #define DBUSMENU_MENUITEM_PROP_LABEL "label"
1433-#define DBUSMENU_MENUITEM_PROP_ICON "icon"
1434+#define DBUSMENU_MENUITEM_PROP_ICON_NAME "icon-name"
1435 #define DBUSMENU_MENUITEM_PROP_ICON_DATA "icon-data"
1436 #define DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE "toggle-type"
1437-#define DBUSMENU_MENUITEM_PROP_TOGGLE_CHECKED "toggle-checked"
1438+#define DBUSMENU_MENUITEM_PROP_TOGGLE_STATE "toggle-state"
1439
1440 #define DBUSMENU_MENUITEM_TOGGLE_CHECK "checkmark"
1441 #define DBUSMENU_MENUITEM_TOGGLE_RADIO "radio"
1442
1443-#define DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED "unchecked"
1444-#define DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED "checked"
1445-#define DBUSMENU_MENUITEM_TOGGLE_STATE_UNKNOWN "indeterminate"
1446+#define DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED 0
1447+#define DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED 1
1448+#define DBUSMENU_MENUITEM_TOGGLE_STATE_UNKNOWN -1
1449
1450 /**
1451 DbusmenuMenuitem:
1452@@ -92,6 +92,9 @@
1453 @realized: Slot for #DbusmenuMenuitem::realized.
1454 @buildxml: Virtual function that appends the strings required
1455 to represent this menu item in the menu XML file.
1456+ @handle_event: This function is to override how events are handled
1457+ by subclasses. Look at #dbusmenu_menuitem_handle_event for
1458+ lots of good information.
1459 @reserved1: Reserved for future use.
1460 @reserved2: Reserved for future use.
1461 @reserved3: Reserved for future use.
1462@@ -104,7 +107,7 @@
1463
1464 /* Signals */
1465 void (*property_changed) (gchar * property, GValue * value);
1466- void (*item_activated) (void);
1467+ void (*item_activated) (guint timestamp);
1468 void (*child_added) (DbusmenuMenuitem * child, guint position);
1469 void (*child_removed) (DbusmenuMenuitem * child);
1470 void (*child_moved) (DbusmenuMenuitem * child, guint newpos, guint oldpos);
1471@@ -112,17 +115,18 @@
1472
1473 /* Virtual functions */
1474 void (*buildxml) (GPtrArray * stringarray);
1475+ void (*handle_event) (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp);
1476
1477 void (*reserved1) (void);
1478 void (*reserved2) (void);
1479- void (*reserved3) (void);
1480+ /* void (*reserved3) (void); */
1481 /* void (*reserved4) (void); -- realized, realloc when bumping lib version */
1482 };
1483
1484 GType dbusmenu_menuitem_get_type (void);
1485
1486 DbusmenuMenuitem * dbusmenu_menuitem_new (void) G_GNUC_WARN_UNUSED_RESULT;
1487-DbusmenuMenuitem * dbusmenu_menuitem_new_with_id (guint id) G_GNUC_WARN_UNUSED_RESULT;
1488+DbusmenuMenuitem * dbusmenu_menuitem_new_with_id (gint id) G_GNUC_WARN_UNUSED_RESULT;
1489 guint dbusmenu_menuitem_get_id (DbusmenuMenuitem * mi);
1490
1491 GList * dbusmenu_menuitem_get_children (DbusmenuMenuitem * mi);
1492@@ -134,8 +138,8 @@
1493 gboolean dbusmenu_menuitem_child_delete (DbusmenuMenuitem * mi, DbusmenuMenuitem * child);
1494 gboolean dbusmenu_menuitem_child_add_position (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position);
1495 gboolean dbusmenu_menuitem_child_reorder (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position);
1496-DbusmenuMenuitem * dbusmenu_menuitem_child_find (DbusmenuMenuitem * mi, guint id);
1497-DbusmenuMenuitem * dbusmenu_menuitem_find_id (DbusmenuMenuitem * mi, guint id);
1498+DbusmenuMenuitem * dbusmenu_menuitem_child_find (DbusmenuMenuitem * mi, gint id);
1499+DbusmenuMenuitem * dbusmenu_menuitem_find_id (DbusmenuMenuitem * mi, gint id);
1500
1501 gboolean dbusmenu_menuitem_property_set (DbusmenuMenuitem * mi, const gchar * property, const gchar * value);
1502 gboolean dbusmenu_menuitem_property_set_value (DbusmenuMenuitem * mi, const gchar * property, const GValue * value);
1503@@ -153,7 +157,7 @@
1504 gboolean dbusmenu_menuitem_get_root (DbusmenuMenuitem * mi);
1505
1506 void dbusmenu_menuitem_foreach (DbusmenuMenuitem * mi, void (*func) (DbusmenuMenuitem * mi, gpointer data), gpointer data);
1507-void dbusmenu_menuitem_activate (DbusmenuMenuitem * mi);
1508+void dbusmenu_menuitem_handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp);
1509
1510 /**
1511 SECTION:menuitem
1512
1513=== modified file 'libdbusmenu-glib/server-marshal.list'
1514--- libdbusmenu-glib/server-marshal.list 2009-12-09 17:17:32 +0000
1515+++ libdbusmenu-glib/server-marshal.list 2010-02-04 20:30:33 +0000
1516@@ -1,2 +1,2 @@
1517 VOID: UINT, STRING, POINTER
1518-VOID: INT, UINT
1519+VOID: UINT, INT
1520
1521=== modified file 'libdbusmenu-glib/server.c'
1522--- libdbusmenu-glib/server.c 2009-12-24 10:31:16 +0000
1523+++ libdbusmenu-glib/server.c 2010-02-04 20:30:33 +0000
1524@@ -35,16 +35,16 @@
1525 #include "server-marshal.h"
1526
1527 /* DBus Prototypes */
1528-static gboolean _dbusmenu_server_get_layout (DbusmenuServer * server, guint parent, guint * revision, gchar ** layout, GError ** error);
1529-static gboolean _dbusmenu_server_get_property (DbusmenuServer * server, guint id, gchar * property, gchar ** value, GError ** error);
1530-static gboolean _dbusmenu_server_get_properties (DbusmenuServer * server, guint id, GPtrArray * properties, GHashTable ** dict, GError ** error);
1531+static gboolean _dbusmenu_server_get_layout (DbusmenuServer * server, gint parent, guint * revision, gchar ** layout, GError ** error);
1532+static gboolean _dbusmenu_server_get_property (DbusmenuServer * server, gint id, gchar * property, gchar ** value, GError ** error);
1533+static gboolean _dbusmenu_server_get_properties (DbusmenuServer * server, gint id, GPtrArray * properties, GHashTable ** dict, GError ** error);
1534 static gboolean _dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, GArray * properties, GHashTable ** values, GError ** error);
1535-static gboolean _dbusmenu_server_event (DbusmenuServer * server, guint id, gchar * eventid, GValue * data, GError ** error);
1536-static gboolean _dbusmenu_server_get_children (DbusmenuServer * server, guint id, GPtrArray * properties, GPtrArray ** output, GError ** error);
1537+static gboolean _dbusmenu_server_event (DbusmenuServer * server, gint id, gchar * eventid, GValue * data, guint timestamp, GError ** error);
1538+static gboolean _dbusmenu_server_get_children (DbusmenuServer * server, gint id, GPtrArray * properties, GPtrArray ** output, GError ** error);
1539
1540 #include "dbusmenu-server.h"
1541
1542-#define DBUSMENU_VERSION_NUMBER 1
1543+#define DBUSMENU_VERSION_NUMBER 2
1544
1545 /* Privates, I'll show you mine... */
1546 typedef struct _DbusmenuServerPrivate DbusmenuServerPrivate;
1547@@ -63,7 +63,7 @@
1548 enum {
1549 ID_PROP_UPDATE,
1550 ID_UPDATE,
1551- LAYOUT_UPDATE,
1552+ LAYOUT_UPDATED,
1553 LAST_SIGNAL
1554 };
1555
1556@@ -148,7 +148,7 @@
1557 g_cclosure_marshal_VOID__UINT,
1558 G_TYPE_NONE, 1, G_TYPE_UINT);
1559 /**
1560- DbusmenuServer::layout-update:
1561+ DbusmenuServer::layout-updated:
1562 @arg0: The #DbusmenuServer emitting the signal.
1563 @arg1: A revision number representing which revision the update
1564 represents itself as.
1565@@ -157,13 +157,13 @@
1566 This signal is emitted any time the layout of the
1567 menuitems under this server is changed.
1568 */
1569- signals[LAYOUT_UPDATE] = g_signal_new(DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATE,
1570+ signals[LAYOUT_UPDATED] = g_signal_new(DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATED,
1571 G_TYPE_FROM_CLASS(class),
1572 G_SIGNAL_RUN_LAST,
1573- G_STRUCT_OFFSET(DbusmenuServerClass, layout_update),
1574+ G_STRUCT_OFFSET(DbusmenuServerClass, layout_updated),
1575 NULL, NULL,
1576- _dbusmenu_server_marshal_VOID__INT_UINT,
1577- G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_UINT);
1578+ _dbusmenu_server_marshal_VOID__UINT_INT,
1579+ G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_INT);
1580
1581
1582 g_object_class_install_property (object_class, PROP_DBUS_OBJECT,
1583@@ -248,7 +248,7 @@
1584 g_debug("Setting root node to NULL");
1585 }
1586 priv->layout_revision++;
1587- g_signal_emit(obj, signals[LAYOUT_UPDATE], 0, priv->layout_revision, 0, TRUE);
1588+ g_signal_emit(obj, signals[LAYOUT_UPDATED], 0, priv->layout_revision, 0, TRUE);
1589 break;
1590 default:
1591 g_return_if_reached();
1592@@ -306,7 +306,7 @@
1593 /* TODO: We probably need to group the layout update signals to make the number more reasonble. */
1594 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
1595 priv->layout_revision++;
1596- g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, 0, TRUE);
1597+ g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATED], 0, priv->layout_revision, 0, TRUE);
1598 return;
1599 }
1600
1601@@ -317,7 +317,7 @@
1602 /* TODO: We probably need to group the layout update signals to make the number more reasonble. */
1603 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
1604 priv->layout_revision++;
1605- g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, 0, TRUE);
1606+ g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATED], 0, priv->layout_revision, 0, TRUE);
1607 return;
1608 }
1609
1610@@ -326,7 +326,7 @@
1611 {
1612 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
1613 priv->layout_revision++;
1614- g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, 0, TRUE);
1615+ g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATED], 0, priv->layout_revision, 0, TRUE);
1616 return;
1617 }
1618
1619@@ -366,7 +366,7 @@
1620
1621 /* DBus interface */
1622 static gboolean
1623-_dbusmenu_server_get_layout (DbusmenuServer * server, guint parent, guint * revision, gchar ** layout, GError ** error)
1624+_dbusmenu_server_get_layout (DbusmenuServer * server, gint parent, guint * revision, gchar ** layout, GError ** error)
1625 {
1626 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
1627
1628@@ -376,13 +376,13 @@
1629 if (parent == 0) {
1630 if (priv->root == NULL) {
1631 /* g_debug("Getting layout without root node!"); */
1632- g_ptr_array_add(xmlarray, g_strdup_printf("<menu revision=\"%d\" />", priv->layout_revision));
1633+ g_ptr_array_add(xmlarray, g_strdup("<menu/>"));
1634 } else {
1635- dbusmenu_menuitem_buildxml(priv->root, xmlarray, priv->layout_revision);
1636+ dbusmenu_menuitem_buildxml(priv->root, xmlarray);
1637 }
1638 } else {
1639 DbusmenuMenuitem * item = dbusmenu_menuitem_find_id(priv->root, parent);
1640- dbusmenu_menuitem_buildxml(item, xmlarray, priv->layout_revision);
1641+ dbusmenu_menuitem_buildxml(item, xmlarray);
1642 }
1643 g_ptr_array_add(xmlarray, NULL);
1644
1645@@ -396,7 +396,7 @@
1646 }
1647
1648 static gboolean
1649-_dbusmenu_server_get_property (DbusmenuServer * server, guint id, gchar * property, gchar ** value, GError ** error)
1650+_dbusmenu_server_get_property (DbusmenuServer * server, gint id, gchar * property, gchar ** value, GError ** error)
1651 {
1652 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
1653 DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id);
1654@@ -441,7 +441,7 @@
1655 }
1656
1657 static gboolean
1658-_dbusmenu_server_get_properties (DbusmenuServer * server, guint id, GPtrArray * properties, GHashTable ** dict, GError ** error)
1659+_dbusmenu_server_get_properties (DbusmenuServer * server, gint id, GPtrArray * properties, GHashTable ** dict, GError ** error)
1660 {
1661 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
1662 DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id);
1663@@ -475,12 +475,12 @@
1664 }
1665
1666 static void
1667-_gvalue_array_append_uint(GValueArray *array, guint i)
1668+_gvalue_array_append_int(GValueArray *array, gint i)
1669 {
1670 GValue value = {0};
1671
1672- g_value_init(&value, G_TYPE_UINT);
1673- g_value_set_uint(&value, i);
1674+ g_value_init(&value, G_TYPE_INT);
1675+ g_value_set_int(&value, i);
1676 g_value_array_append(array, &value);
1677 g_value_unset(&value);
1678 }
1679@@ -502,18 +502,18 @@
1680 DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(data);
1681 GPtrArray * output = (GPtrArray *)(user_data);
1682
1683- guint id = dbusmenu_menuitem_get_id(mi);
1684+ gint id = dbusmenu_menuitem_get_id(mi);
1685 GHashTable * dict = dbusmenu_menuitem_properties_copy(mi);
1686
1687 GValueArray * item = g_value_array_new(1);
1688- _gvalue_array_append_uint(item, id);
1689+ _gvalue_array_append_int(item, id);
1690 _gvalue_array_append_hashtable(item, dict);
1691
1692 g_ptr_array_add(output, item);
1693 }
1694
1695 static gboolean
1696-_dbusmenu_server_get_children (DbusmenuServer * server, guint id, GPtrArray * properties, GPtrArray ** output, GError ** error)
1697+_dbusmenu_server_get_children (DbusmenuServer * server, gint id, GPtrArray * properties, GPtrArray ** output, GError ** error)
1698 {
1699 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
1700 DbusmenuMenuitem * mi = id == 0 ? priv->root : dbusmenu_menuitem_find_id(priv->root, id);
1701@@ -537,7 +537,7 @@
1702 }
1703
1704 static gboolean
1705-_dbusmenu_server_event (DbusmenuServer * server, guint id, gchar * eventid, GValue * data, GError ** error)
1706+_dbusmenu_server_event (DbusmenuServer * server, gint id, gchar * eventid, GValue * data, guint timestamp, GError ** error)
1707 {
1708 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
1709 DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id);
1710@@ -553,7 +553,7 @@
1711 return FALSE;
1712 }
1713
1714- dbusmenu_menuitem_activate(mi);
1715+ dbusmenu_menuitem_handle_event(mi, eventid, data, timestamp);
1716 return TRUE;
1717 }
1718
1719
1720=== modified file 'libdbusmenu-glib/server.h'
1721--- libdbusmenu-glib/server.h 2009-12-09 19:58:32 +0000
1722+++ libdbusmenu-glib/server.h 2010-02-04 20:30:33 +0000
1723@@ -45,7 +45,8 @@
1724
1725 #define DBUSMENU_SERVER_SIGNAL_ID_PROP_UPDATE "item-property-updated"
1726 #define DBUSMENU_SERVER_SIGNAL_ID_UPDATE "item-updated"
1727-#define DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATE "layout-update"
1728+#define DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATED "layout-updated"
1729+#define DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATE DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATED
1730
1731 #define DBUSMENU_SERVER_PROP_DBUS_OBJECT "dbus-object"
1732 #define DBUSMENU_SERVER_PROP_ROOT_NODE "root-node"
1733@@ -56,7 +57,7 @@
1734 @parent_class: #GObjectClass
1735 @id_prop_update: Slot for #DbusmenuServer::id-prop-update.
1736 @id_update: Slot for #DbusmenuServer::id-update.
1737- @layout_update: Slot for #DbusmenuServer::layout-update.
1738+ @layout_updated: Slot for #DbusmenuServer::layout-update.
1739 @dbusmenu_server_reserved1: Reserved for future use.
1740 @dbusmenu_server_reserved2: Reserved for future use.
1741 @dbusmenu_server_reserved3: Reserved for future use.
1742@@ -69,9 +70,9 @@
1743 GObjectClass parent_class;
1744
1745 /* Signals */
1746- void (*id_prop_update)(guint id, gchar * property, gchar * value);
1747- void (*id_update)(guint id);
1748- void (*layout_update)(gint revision);
1749+ void (*id_prop_update)(gint id, gchar * property, gchar * value);
1750+ void (*id_update)(gint id);
1751+ void (*layout_updated)(gint revision);
1752
1753 /* Reserved */
1754 void (*dbusmenu_server_reserved1)(void);
1755
1756=== modified file 'libdbusmenu-gtk/client.c'
1757--- libdbusmenu-gtk/client.c 2010-01-11 18:42:55 +0000
1758+++ libdbusmenu-gtk/client.c 2010-02-04 20:30:33 +0000
1759@@ -109,7 +109,10 @@
1760 static gboolean
1761 menu_pressed_cb (GtkMenuItem * gmi, DbusmenuMenuitem * mi)
1762 {
1763- dbusmenu_menuitem_activate(mi);
1764+ GValue value = {0};
1765+ g_value_init(&value, G_TYPE_INT);
1766+ g_value_set_int(&value, 0);
1767+ dbusmenu_menuitem_handle_event(mi, "clicked", &value, gtk_get_current_event_time());
1768 return TRUE;
1769 }
1770
1771@@ -136,7 +139,7 @@
1772 {
1773 gboolean val = TRUE;
1774 if (value != NULL) {
1775- val = dbusmenu_menuitem_property_get_bool(mi, DBUSMENU_MENUITEM_PROP_SENSITIVE);
1776+ val = dbusmenu_menuitem_property_get_bool(mi, DBUSMENU_MENUITEM_PROP_ENABLED);
1777 }
1778 gtk_widget_set_sensitive(GTK_WIDGET(gmi), val);
1779 return;
1780@@ -147,17 +150,23 @@
1781 process_toggle_type (DbusmenuMenuitem * mi, GtkMenuItem * gmi, const GValue * value)
1782 {
1783 if (!IS_GENERICMENUITEM(gmi)) return;
1784+ if (value == NULL) return;
1785
1786 GenericmenuitemCheckType type = GENERICMENUITEM_CHECK_TYPE_NONE;
1787
1788- if (value != NULL && G_VALUE_TYPE(value) == G_TYPE_STRING) {
1789- const gchar * strval = g_value_get_string(value);
1790+ GValue strvalue = {0};
1791+ g_value_init(&strvalue, G_TYPE_STRING);
1792+
1793+ if (value != NULL && g_value_transform(value, &strvalue)) {
1794+ const gchar * strval = g_value_get_string(&strvalue);
1795
1796 if (!g_strcmp0(strval, DBUSMENU_MENUITEM_TOGGLE_CHECK)) {
1797 type = GENERICMENUITEM_CHECK_TYPE_CHECKBOX;
1798 } else if (!g_strcmp0(strval, DBUSMENU_MENUITEM_TOGGLE_RADIO)) {
1799 type = GENERICMENUITEM_CHECK_TYPE_RADIO;
1800 }
1801+
1802+ g_value_unset(&strvalue);
1803 }
1804
1805 genericmenuitem_set_check_type(GENERICMENUITEM(gmi), type);
1806@@ -167,18 +176,21 @@
1807
1808 /* Process the sensitive property */
1809 static void
1810-process_toggle_checked (DbusmenuMenuitem * mi, GtkMenuItem * gmi, const GValue * value)
1811+process_toggle_state (DbusmenuMenuitem * mi, GtkMenuItem * gmi, const GValue * value)
1812 {
1813 if (!IS_GENERICMENUITEM(gmi)) return;
1814
1815 GenericmenuitemState state = GENERICMENUITEM_STATE_UNCHECKED;
1816
1817- if (value != NULL && G_VALUE_TYPE(value) == G_TYPE_STRING) {
1818- const gchar * strval = g_value_get_string(value);
1819-
1820- if (!g_strcmp0(strval, DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED)) {
1821+ GValue intvalue = {0};
1822+ g_value_init(&intvalue, G_TYPE_INT);
1823+
1824+ if (value != NULL && g_value_transform(value, &intvalue)) {
1825+ int val = g_value_get_int(&intvalue);
1826+
1827+ if (val == DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED) {
1828 state = GENERICMENUITEM_STATE_CHECKED;
1829- } else if (!g_strcmp0(strval, DBUSMENU_MENUITEM_TOGGLE_STATE_UNKNOWN)) {
1830+ } else if (val == DBUSMENU_MENUITEM_TOGGLE_STATE_UNKNOWN) {
1831 state = GENERICMENUITEM_STATE_INDETERMINATE;
1832 }
1833 }
1834@@ -196,12 +208,12 @@
1835 gtk_menu_item_set_label(gmi, g_value_get_string(value));
1836 } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_VISIBLE)) {
1837 process_visible(mi, gmi, value);
1838- } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_SENSITIVE)) {
1839+ } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_ENABLED)) {
1840 process_sensitive(mi, gmi, value);
1841 } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE)) {
1842 process_toggle_type(mi, gmi, value);
1843- } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_TOGGLE_CHECKED)) {
1844- process_toggle_checked(mi, gmi, value);
1845+ } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE)) {
1846+ process_toggle_state(mi, gmi, value);
1847 }
1848
1849 return;
1850@@ -284,9 +296,9 @@
1851
1852 /* Check our set of props to see if any are set already */
1853 process_visible(item, gmi, dbusmenu_menuitem_property_get_value(item, DBUSMENU_MENUITEM_PROP_VISIBLE));
1854- process_sensitive(item, gmi, dbusmenu_menuitem_property_get_value(item, DBUSMENU_MENUITEM_PROP_SENSITIVE));
1855+ process_sensitive(item, gmi, dbusmenu_menuitem_property_get_value(item, DBUSMENU_MENUITEM_PROP_ENABLED));
1856 process_toggle_type(item, gmi, dbusmenu_menuitem_property_get_value(item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE));
1857- process_toggle_checked(item, gmi, dbusmenu_menuitem_property_get_value(item, DBUSMENU_MENUITEM_PROP_TOGGLE_CHECKED));
1858+ process_toggle_state(item, gmi, dbusmenu_menuitem_property_get_value(item, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE));
1859
1860 /* Oh, we're a child, let's deal with that */
1861 if (parent != NULL) {
1862@@ -426,8 +438,8 @@
1863 }
1864
1865 image_property_handle(newitem,
1866- DBUSMENU_MENUITEM_PROP_ICON,
1867- dbusmenu_menuitem_property_get_value(newitem, DBUSMENU_MENUITEM_PROP_ICON),
1868+ DBUSMENU_MENUITEM_PROP_ICON_NAME,
1869+ dbusmenu_menuitem_property_get_value(newitem, DBUSMENU_MENUITEM_PROP_ICON_NAME),
1870 client);
1871 image_property_handle(newitem,
1872 DBUSMENU_MENUITEM_PROP_ICON_DATA,
1873@@ -468,7 +480,10 @@
1874 image_property_handle (DbusmenuMenuitem * item, const gchar * property, const GValue * invalue, gpointer userdata)
1875 {
1876 /* We're only looking at these two properties here */
1877- g_return_if_fail(!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON) || !g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON_DATA));
1878+ if (g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON_NAME) != 0 &&
1879+ g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON_DATA) != 0) {
1880+ return;
1881+ }
1882
1883 const gchar * value = NULL;
1884
1885@@ -479,10 +494,10 @@
1886 if (value == NULL || value[0] == '\0') {
1887 /* This means that we're unsetting a value. */
1888 /* Try to use the other one */
1889- if (g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON)) {
1890+ if (g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON_NAME)) {
1891 property = DBUSMENU_MENUITEM_PROP_ICON_DATA;
1892 } else {
1893- property = DBUSMENU_MENUITEM_PROP_ICON;
1894+ property = DBUSMENU_MENUITEM_PROP_ICON_NAME;
1895 }
1896 }
1897
1898@@ -504,7 +519,7 @@
1899 }
1900
1901 /* Now figure out what to change */
1902- if (!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON)) {
1903+ if (!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON_NAME)) {
1904 const gchar * iconname = dbusmenu_menuitem_property_get(item, property);
1905 if (iconname == NULL) {
1906 /* If there is no name, by golly we want no
1907
1908=== modified file 'tests/test-gtk-label-server.c'
1909--- tests/test-gtk-label-server.c 2009-09-02 20:13:15 +0000
1910+++ tests/test-gtk-label-server.c 2010-02-04 20:30:33 +0000
1911@@ -32,9 +32,9 @@
1912 #include <json-glib/json-glib.h>
1913
1914 static void
1915-menuitem_click(DbusmenuMenuitem * mi, gpointer user_data)
1916+menuitem_click(DbusmenuMenuitem * mi, guint32 time, gpointer user_data)
1917 {
1918- g_debug("Clicked on: %d", dbusmenu_menuitem_get_id(mi));
1919+ g_debug("Clicked on: %d @ %d", dbusmenu_menuitem_get_id(mi), time);
1920 return;
1921 }
1922
1923@@ -53,7 +53,10 @@
1924 JsonNode * lnode = json_object_get_member(node, member);
1925 if (JSON_NODE_TYPE(lnode) != JSON_NODE_VALUE) { continue; }
1926
1927- dbusmenu_menuitem_property_set(mi, member, json_node_get_string(lnode));
1928+ GValue value = {0};
1929+ json_node_get_value(lnode, &value);
1930+ dbusmenu_menuitem_property_set_value(mi, member, &value);
1931+ g_value_unset(&value);
1932 }
1933
1934 return;
1935
1936=== modified file 'tests/test-gtk-label.json'
1937--- tests/test-gtk-label.json 2010-01-07 16:40:45 +0000
1938+++ tests/test-gtk-label.json 2010-02-04 20:30:33 +0000
1939@@ -1,256 +1,256 @@
1940 [
1941- {"id": 1, "type": "menuitem",
1942+ {"id": 1, "type": "standard",
1943 "label": "value1",
1944 "submenu": [
1945- {"id": 30, "type": "menuitem",
1946+ {"id": 30, "type": "standard",
1947 "label": "value30"},
1948- {"id": 31, "type": "menuitem",
1949+ {"id": 31, "type": "standard",
1950 "label": "value31"},
1951- {"id": 32, "type": "menuitem",
1952+ {"id": 32, "type": "standard",
1953 "label": "value32"},
1954- {"id": 33, "type": "menuitem",
1955+ {"id": 33, "type": "standard",
1956 "label": "value33"},
1957- {"id": 34, "type": "menuitem",
1958+ {"id": 34, "type": "standard",
1959 "label": "value34"},
1960- {"id": 35, "type": "menuitem",
1961+ {"id": 35, "type": "standard",
1962 "label": "value35"},
1963- {"id": 36, "type": "menuitem",
1964+ {"id": 36, "type": "standard",
1965 "label": "value36"},
1966- {"id": 37, "type": "menuitem",
1967+ {"id": 37, "type": "standard",
1968 "label": "value37"},
1969- {"id": 38, "type": "menuitem",
1970+ {"id": 38, "type": "standard",
1971 "label": "value38"},
1972- {"id": 39, "type": "menuitem",
1973+ {"id": 39, "type": "standard",
1974 "label": "value39"}
1975 ]
1976 },
1977- {"id": 2, "type": "menuitem",
1978+ {"id": 2, "type": "standard",
1979 "label": "value2",
1980 "submenu": [
1981- {"id": 20, "type": "menuitem",
1982+ {"id": 20, "type": "standard",
1983 "label": "value20"},
1984 {"id": 21, "type": "separator",
1985 "label": "value21"},
1986- {"id": 22, "type": "menuitem",
1987+ {"id": 22, "type": "standard",
1988 "label": "value22"},
1989 {"id": 23, "type": "separator",
1990 "label": "value23"},
1991- {"id": 24, "type": "menuitem",
1992+ {"id": 24, "type": "standard",
1993 "label": "value24"},
1994 {"id": 25, "type": "separator",
1995 "label": "value25"},
1996- {"id": 26, "type": "menuitem",
1997+ {"id": 26, "type": "standard",
1998 "label": "value26"},
1999 {"id": 27, "type": "separator",
2000 "label": "value27"},
2001- {"id": 28, "type": "menuitem",
2002+ {"id": 28, "type": "standard",
2003 "label": "value28"},
2004- {"id": 29, "type": "menuitem", "visible": "false",
2005+ {"id": 29, "type": "standard", "visible": "false",
2006 "label": "value29"}
2007 ]
2008 },
2009- {"id": 4, "type": "menuitem",
2010+ {"id": 4, "type": "standard",
2011 "label": "value4",
2012 "submenu": [
2013 {"id": 40,
2014- "type": "menuitem",
2015- "sensitive": "true",
2016+ "type": "standard",
2017+ "enabled": "true",
2018 "label": "value40"},
2019 {"id": 41,
2020- "type": "menuitem",
2021- "sensitive": "false",
2022+ "type": "standard",
2023+ "enabled": "false",
2024 "label": "value41"},
2025 {"id": 42,
2026- "type": "menuitem",
2027- "sensitive": "true",
2028+ "type": "standard",
2029+ "enabled": "true",
2030 "label": "value42"},
2031 {"id": 43,
2032- "type": "menuitem",
2033- "sensitive": "false",
2034+ "type": "standard",
2035+ "enabled": "false",
2036 "label": "value43"},
2037 {"id": 44,
2038- "type": "menuitem",
2039- "sensitive": "true",
2040+ "type": "standard",
2041+ "enabled": "true",
2042 "label": "value44"},
2043 {"id": 45,
2044- "type": "menuitem",
2045- "sensitive": "false",
2046+ "type": "standard",
2047+ "enabled": "false",
2048 "label": "value45"},
2049 {"id": 46,
2050- "type": "menuitem",
2051- "sensitive": "true",
2052+ "type": "standard",
2053+ "enabled": "true",
2054 "label": "value46"},
2055 {"id": 47,
2056- "type": "menuitem",
2057- "sensitive": "false",
2058+ "type": "standard",
2059+ "enabled": "false",
2060 "label": "value47"},
2061 {"id": 48,
2062- "type": "menuitem",
2063- "sensitive": "true",
2064+ "type": "standard",
2065+ "enabled": "true",
2066 "label": "value48"},
2067 {"id": 49,
2068- "type": "menuitem",
2069+ "type": "standard",
2070 "visible": "false",
2071- "sensitive": "false",
2072+ "enabled": "false",
2073 "label": "value49"}
2074 ]
2075 },
2076- {"id": 3, "type": "menuitem",
2077+ {"id": 3, "type": "standard",
2078 "label": "a super long label that is really of unreasonable length but we should make sure it makes it across the bus",
2079 "not.a.value": "A useless value",
2080 "submenu": [
2081- {"id": 10, "type": "menuitem",
2082+ {"id": 10, "type": "standard",
2083 "label": "value10"},
2084- {"id": 11, "type": "menuitem",
2085+ {"id": 11, "type": "standard",
2086 "label": "value11"},
2087- {"id": 12, "type": "menuitem",
2088+ {"id": 12, "type": "standard",
2089 "label": "value12"},
2090- {"id": 13, "type": "menuitem",
2091+ {"id": 13, "type": "standard",
2092 "label": "value13"},
2093- {"id": 14, "type": "menuitem",
2094+ {"id": 14, "type": "standard",
2095 "label": "value14"},
2096- {"id": 15, "type": "menuitem",
2097+ {"id": 15, "type": "standard",
2098 "label": "value15"},
2099- {"id": 16, "type": "menuitem",
2100+ {"id": 16, "type": "standard",
2101 "label": "value16"},
2102- {"id": 17, "type": "menuitem",
2103+ {"id": 17, "type": "standard",
2104 "label": "value17"},
2105- {"id": 18, "type": "menuitem",
2106+ {"id": 18, "type": "standard",
2107 "label": "value18"},
2108- {"id": 19, "type": "menuitem",
2109+ {"id": 19, "type": "standard",
2110 "label": "value19"}
2111 ]
2112 },
2113- {"id": 4, "type": "menuitem",
2114+ {"id": 4, "type": "standard",
2115 "label": "value2",
2116 "submenu": [
2117- {"id": 5, "type": "menuitem",
2118+ {"id": 5, "type": "standard",
2119 "label": "value5",
2120 "submenu": [
2121- {"id": 10, "type": "menuitem",
2122+ {"id": 10, "type": "standard",
2123 "label": "value10"},
2124- {"id": 11, "type": "menuitem",
2125+ {"id": 11, "type": "standard",
2126 "label": "value11"},
2127- {"id": 12, "type": "menuitem",
2128+ {"id": 12, "type": "standard",
2129 "label": "value12"},
2130- {"id": 13, "type": "menuitem",
2131+ {"id": 13, "type": "standard",
2132 "label": "value13"},
2133- {"id": 14, "type": "menuitem",
2134+ {"id": 14, "type": "standard",
2135 "label": "value14"},
2136- {"id": 15, "type": "menuitem",
2137+ {"id": 15, "type": "standard",
2138 "label": "value15"},
2139- {"id": 16, "type": "menuitem",
2140+ {"id": 16, "type": "standard",
2141 "label": "value16"},
2142- {"id": 17, "type": "menuitem",
2143+ {"id": 17, "type": "standard",
2144 "label": "value17"},
2145- {"id": 18, "type": "menuitem",
2146+ {"id": 18, "type": "standard",
2147 "label": "value18"},
2148- {"id": 19, "type": "menuitem",
2149+ {"id": 19, "type": "standard",
2150 "label": "value19"}
2151 ]
2152 },
2153- {"id": 6, "type": "menuitem",
2154+ {"id": 6, "type": "standard",
2155 "label": "value6",
2156 "submenu": [
2157- {"id": 20, "type": "menuitem",
2158+ {"id": 20, "type": "standard",
2159 "label": "value20"},
2160- {"id": 21, "type": "menuitem",
2161+ {"id": 21, "type": "standard",
2162 "label": "value21"},
2163- {"id": 22, "type": "menuitem",
2164+ {"id": 22, "type": "standard",
2165 "label": "value22"},
2166- {"id": 23, "type": "menuitem",
2167+ {"id": 23, "type": "standard",
2168 "label": "value23"},
2169- {"id": 24, "type": "menuitem",
2170+ {"id": 24, "type": "standard",
2171 "label": "value24"},
2172- {"id": 25, "type": "menuitem",
2173+ {"id": 25, "type": "standard",
2174 "label": "value25"},
2175- {"id": 26, "type": "menuitem",
2176+ {"id": 26, "type": "standard",
2177 "label": "value26"},
2178- {"id": 27, "type": "menuitem",
2179+ {"id": 27, "type": "standard",
2180 "label": "value27"},
2181- {"id": 28, "type": "menuitem",
2182+ {"id": 28, "type": "standard",
2183 "label": "value28"},
2184- {"id": 29, "type": "menuitem",
2185+ {"id": 29, "type": "standard",
2186 "label": "value29"}
2187 ]
2188 },
2189- {"id": 7, "type": "menuitem",
2190+ {"id": 7, "type": "standard",
2191 "label": "value7",
2192 "submenu": [
2193- {"id": 30, "type": "menuitem",
2194+ {"id": 30, "type": "standard",
2195 "label": "value30"},
2196- {"id": 31, "type": "menuitem",
2197+ {"id": 31, "type": "standard",
2198 "label": "value31"},
2199- {"id": 32, "type": "menuitem",
2200+ {"id": 32, "type": "standard",
2201 "label": "value32"},
2202- {"id": 33, "type": "menuitem",
2203+ {"id": 33, "type": "standard",
2204 "label": "value33"},
2205- {"id": 34, "type": "menuitem",
2206+ {"id": 34, "type": "standard",
2207 "label": "value34"},
2208- {"id": 35, "type": "menuitem",
2209+ {"id": 35, "type": "standard",
2210 "label": "value35"},
2211- {"id": 36, "type": "menuitem",
2212+ {"id": 36, "type": "standard",
2213 "label": "value36"},
2214- {"id": 37, "type": "menuitem",
2215+ {"id": 37, "type": "standard",
2216 "label": "value37"},
2217- {"id": 38, "type": "menuitem",
2218+ {"id": 38, "type": "standard",
2219 "label": "value38"},
2220- {"id": 39, "type": "menuitem",
2221+ {"id": 39, "type": "standard",
2222 "label": "value39"}
2223 ]
2224 },
2225 ]
2226 },
2227- {"id": 8, "type": "menuitem",
2228+ {"id": 8, "type": "standard",
2229 "label": "value1",
2230 "submenu": [
2231 {"id": 80,
2232- "type": "menuitem",
2233- "icon": "face-angel",
2234+ "type": "standard",
2235+ "icon-name": "face-angel",
2236 "label": "angel"},
2237 {"id": 81,
2238- "type": "menuitem",
2239- "icon": "face-angry",
2240+ "type": "standard",
2241+ "icon-name": "face-angry",
2242 "label": "angry"},
2243 {"id": 82,
2244- "type": "menuitem",
2245- "icon": "face-cool",
2246+ "type": "standard",
2247+ "icon-name": "face-cool",
2248 "label": "cool"},
2249 {"id": 83,
2250- "type":"menuitem",
2251- "icon": "face-devilish",
2252+ "type":"standard",
2253+ "icon-name": "face-devilish",
2254 "label": "devilish"},
2255 {"id": 84,
2256- "type": "menuitem",
2257- "icon": "face-embarrassed",
2258+ "type": "standard",
2259+ "icon-name": "face-embarrassed",
2260 "label": "embarrassed"},
2261 {"id": 85,
2262- "type": "menuitem",
2263- "icon": "face-kiss",
2264+ "type": "standard",
2265+ "icon-name": "face-kiss",
2266 "label": "kiss"},
2267 {"id": 86,
2268- "type": "menuitem",
2269- "icon": "face-laugh",
2270+ "type": "standard",
2271+ "icon-name": "face-laugh",
2272 "label": "laugh"},
2273 {"id": 87,
2274- "type": "menuitem",
2275- "icon": "face-monkey",
2276+ "type": "standard",
2277+ "icon-name": "face-monkey",
2278 "label": "monkey"},
2279 {"id": 88,
2280- "type": "menuitem",
2281- "icon": "face-sad",
2282+ "type": "standard",
2283+ "icon-name": "face-sad",
2284 "label": "sad"},
2285 {"id": 89,
2286- "type": "menuitem",
2287- "icon": "face-sick",
2288+ "type": "standard",
2289+ "icon-name": "face-sick",
2290 "label": "sick"}
2291 ]
2292 },
2293- {"id": 9, "type": "menuitem",
2294+ {"id": 9, "type": "standard",
2295 "label": "value1",
2296 "submenu": [
2297 {"id": 90,
2298- "type": "menuitem",
2299+ "type": "standard",
2300 "icon-data":
2301 "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACPUlEQVR4nGJgoBAAAAAA///Ch1gW
2302 BzK0LQ5iaGNgYGDBpQgAAAD//8KpeY4/Q9+DCV7/H/S4/p8byDABlyEAAAAA///CqnluAMOEx5O8
2303@@ -266,7 +266,7 @@
2304 QmCC",
2305 "label": "up"},
2306 {"id": 91,
2307- "type": "menuitem",
2308+ "type": "standard",
2309 "icon-data":
2310 "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACl0lEQVR4nGJgoBAAAAAA//9ixCLG
2311 sSWS4bs0B1QWip/+YGDwWcLAycDA8ANZMQAAAP//YsFigIA0JwODdvIsBob/fxgY/vxk+P/7OwPD
2312@@ -283,8 +283,8 @@
2313 +ys2zQwMDAwAAAAA//8DAAF5nhyE7tENAAAAAElFTkSuQmCC",
2314 "label": "down"},
2315 {"id": 92,
2316- "type": "menuitem",
2317- "icon": "up",
2318+ "type": "standard",
2319+ "icon-name": "up",
2320 "icon-data":
2321 "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACl0lEQVR4nGJgoBAAAAAA//9ixCLG
2322 sSWS4bs0B1QWip/+YGDwWcLAycDA8ANZMQAAAP//YsFigIA0JwODdvIsBob/fxgY/vxk+P/7OwPD
2323@@ -301,8 +301,8 @@
2324 +ys2zQwMDAwAAAAA//8DAAF5nhyE7tENAAAAAElFTkSuQmCC",
2325 "label": "up"},
2326 {"id": 93,
2327- "type": "menuitem",
2328- "icon": "down",
2329+ "type": "standard",
2330+ "icon-name": "down",
2331 "icon-data":
2332 "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACPUlEQVR4nGJgoBAAAAAA///Ch1gW
2333 BzK0LQ5iaGNgYGDBpQgAAAD//8KpeY4/Q9+DCV7/H/S4/p8byDABlyEAAAAA///CqnluAMOEx5O8
2334@@ -319,7 +319,7 @@
2335 "label": "down"}
2336 ]
2337 },
2338- {"id": 1, "type": "menuitem",
2339+ {"id": 1, "type": "standard",
2340 "label": "value1",
2341 "submenu": [
2342 {"id": 30,
2343@@ -329,42 +329,42 @@
2344 {"id": 31,
2345 "label": "No check (checked)",
2346 "toggle-type": "none",
2347- "toggle-checked": "checked"
2348+ "toggle-state": 1
2349 },
2350 {"id": 32,
2351 "label": "No check (????)",
2352 "toggle-type": "none",
2353- "toggle-checked": "indeterminate"
2354+ "toggle-state": -1
2355 },
2356 {"id": 33,
2357 "label": "Check (empty)",
2358 "toggle-type": "checkmark",
2359- "toggle-checked": "unchecked"
2360+ "toggle-state": 0
2361 },
2362 {"id": 34,
2363 "label": "Check (checked)",
2364 "toggle-type": "checkmark",
2365- "toggle-checked": "checked"
2366+ "toggle-state": 1
2367 },
2368 {"id": 35,
2369 "label": "Check (?????)",
2370 "toggle-type": "checkmark",
2371- "toggle-checked": "indeterminate"
2372+ "toggle-state": -1
2373 },
2374 {"id": 36,
2375 "label": "Radio (empty)",
2376 "toggle-type": "radio",
2377- "toggle-checked": "unchecked"
2378+ "toggle-state": 0
2379 },
2380 {"id": 37,
2381 "label": "Radio (checked)",
2382 "toggle-type": "radio",
2383- "toggle-checked": "checked"
2384+ "toggle-state": 1
2385 },
2386 {"id": 38,
2387 "label": "Radio (?????)",
2388 "toggle-type": "radio",
2389- "toggle-checked": "indeterminate"
2390+ "toggle-state": -1
2391 }
2392 ]
2393 },
2394
2395=== modified file 'tools/Makefile.am'
2396--- tools/Makefile.am 2009-10-05 14:12:45 +0000
2397+++ tools/Makefile.am 2010-02-04 20:30:33 +0000
2398@@ -1,6 +1,10 @@
2399
2400+SUBDIRS = testapp
2401+
2402 libexec_PROGRAMS = dbusmenu-dumper
2403
2404+libexec_SCRIPTS = dbusmenu-bench
2405+
2406 dbusmenu_dumper_SOURCES = \
2407 dbusmenu-dumper.c
2408
2409@@ -12,3 +16,4 @@
2410 ../libdbusmenu-glib/libdbusmenu-glib.la \
2411 $(DBUSMENUGLIB_LIBS)
2412
2413+EXTRA_DIST = dbusmenu-bench
2414
2415=== added file 'tools/dbusmenu-bench'
2416--- tools/dbusmenu-bench 1970-01-01 00:00:00 +0000
2417+++ tools/dbusmenu-bench 2010-02-04 20:30:33 +0000
2418@@ -0,0 +1,157 @@
2419+#!/usr/bin/env python
2420+# encoding: utf-8
2421+"""
2422+A library to communicate a menu object set accross DBus and
2423+track updates and maintain consistency.
2424+
2425+Copyright 2010 Canonical Ltd.
2426+
2427+Authors:
2428+ Aurélien Gâteau <aurelien.gateau@canonical.com>
2429+
2430+This program is free software: you can redistribute it and/or modify it
2431+under the terms of either or both of the following licenses:
2432+
2433+1) the GNU Lesser General Public License version 3, as published by the
2434+Free Software Foundation; and/or
2435+2) the GNU Lesser General Public License version 2.1, as published by
2436+the Free Software Foundation.
2437+
2438+This program is distributed in the hope that it will be useful, but
2439+WITHOUT ANY WARRANTY; without even the implied warranties of
2440+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
2441+PURPOSE. See the applicable version of the GNU Lesser General Public
2442+License for more details.
2443+
2444+You should have received a copy of both the GNU Lesser General Public
2445+License version 3 and version 2.1 along with this program. If not, see
2446+<http://www.gnu.org/licenses/>
2447+"""
2448+import itertools
2449+import time
2450+import sys
2451+from optparse import OptionParser
2452+from xml.etree import ElementTree as ET
2453+
2454+import dbus
2455+
2456+DBUS_INTERFACE = "org.ayatana.dbusmenu"
2457+DBUS_SERVICE = "org.dbusmenu.test"
2458+DBUS_PATH = "/MenuBar"
2459+
2460+PROBE_GET_LAYOUT = "GetLayout"
2461+PROBE_GET_PROPERTIES = "GetProperties"
2462+PROBE_GET_CHILDREN = "GetChildren"
2463+PROBES = PROBE_GET_LAYOUT, PROBE_GET_PROPERTIES, PROBE_GET_CHILDREN
2464+
2465+class Chrono(object):
2466+ def __init__(self):
2467+ self._time = 0
2468+ self.restart()
2469+
2470+ def restart(self):
2471+ new_time = time.time()
2472+ delta = new_time - self._time
2473+ self._time = new_time
2474+ return delta
2475+
2476+ def elapsed(self):
2477+ return time.time() - self._time
2478+
2479+
2480+def dump_properties(properties, prepend=""):
2481+ for key, value in properties.items():
2482+ print "%s- %s: %s" % (prepend, key, value)
2483+
2484+
2485+def run_test_sequence(menu, dump=False):
2486+ """
2487+ Runs the test sequence and returns a dict of method_name: seconds
2488+ """
2489+ property_names = ["type", "label", "enabled", "icon-name"]
2490+ times = dict()
2491+ chrono = Chrono()
2492+ revision, layout = menu.GetLayout(dbus.Int32(0))
2493+ times["GetLayout"] = chrono.elapsed()
2494+ if dump:
2495+ print "revision:", revision
2496+ print "layout:"
2497+ print layout
2498+
2499+ # Get ids
2500+ tree = ET.fromstring(layout)
2501+ root_id = int(tree.attrib["id"])
2502+ child_element = tree.find("menu")
2503+ assert child_element is not None
2504+ child_id = int(child_element.attrib["id"])
2505+
2506+ chrono.restart()
2507+ children = menu.GetChildren(dbus.Int32(root_id), property_names)
2508+ times["GetChildren"] = chrono.elapsed()
2509+ if dump:
2510+ print "children:"
2511+ for child in children:
2512+ id, properties = child
2513+ print "- %d:" % id
2514+ dump_properties(properties, prepend=" ")
2515+
2516+ chrono.restart()
2517+ properties = menu.GetProperties(dbus.Int32(child_id), property_names)
2518+ times["GetProperties"] = chrono.elapsed()
2519+ if dump:
2520+ print "properties:"
2521+ dump_properties(properties)
2522+
2523+ return times
2524+
2525+def create_timing_dict():
2526+ return dict(zip(PROBES, itertools.repeat(0)))
2527+
2528+def print_probe(prefix, name, value, timestamp):
2529+ value = int(value * 1000000)
2530+ print "%(prefix)s.%(name)s:%(value)d@%(timestamp)d" % locals()
2531+
2532+def main():
2533+ parser = OptionParser(usage = "%prog [options]")
2534+
2535+ parser.add_option("-c", "--count", dest="count", type=int, default=1,
2536+ help="repeat calls COUNT times", metavar="COUNT")
2537+ parser.add_option("-d", "--dump", dest="dump", action="store_true", default=False,
2538+ help="dump call output to stdout")
2539+
2540+ (options, args) = parser.parse_args()
2541+
2542+ bus = dbus.SessionBus()
2543+ proxy = bus.get_object(DBUS_SERVICE, DBUS_PATH)
2544+ menu = dbus.Interface(proxy, dbus_interface=DBUS_INTERFACE)
2545+
2546+ if options.dump:
2547+ run_test_sequence(menu, dump=True)
2548+ return
2549+
2550+ cumulated_timings = create_timing_dict()
2551+ min_timings = create_timing_dict()
2552+ max_timings = create_timing_dict()
2553+ for x in range(options.count):
2554+ timings = run_test_sequence(menu)
2555+ for name, timing in timings.items():
2556+ cumulated_timings[name] += timing
2557+ if min_timings[name] == 0 or min_timings[name] > timing:
2558+ min_timings[name] = timing
2559+ if max_timings[name] < timing:
2560+ max_timings[name] = timing
2561+
2562+ timestamp = int(time.time())
2563+ for name, timing in cumulated_timings.items():
2564+ print_probe("average", name, timing / options.count, timestamp)
2565+ for name, timing in min_timings.items():
2566+ print_probe("min", name, timing, timestamp)
2567+ for name, timing in max_timings.items():
2568+ print_probe("max", name, timing, timestamp)
2569+
2570+ return 0
2571+
2572+
2573+if __name__=="__main__":
2574+ sys.exit(main())
2575+# vi: ts=4 sw=4 et tw=0
2576
2577=== added directory 'tools/testapp'
2578=== added file 'tools/testapp/CMakeLists.txt'
2579--- tools/testapp/CMakeLists.txt 1970-01-01 00:00:00 +0000
2580+++ tools/testapp/CMakeLists.txt 2010-02-04 20:30:33 +0000
2581@@ -0,0 +1,29 @@
2582+find_package(PkgConfig REQUIRED)
2583+
2584+pkg_check_modules(DBUSMENUGLIB REQUIRED dbusmenu-glib)
2585+pkg_check_modules(GLIB REQUIRED glib-2.0)
2586+pkg_check_modules(JSONGLIB REQUIRED json-glib-1.0)
2587+
2588+set(glibapp_SRCS
2589+ main.c
2590+ )
2591+
2592+include_directories(
2593+ ${DBUSMENUGLIB_INCLUDE_DIRS}
2594+ ${GLIB_INCLUDE_DIRS}
2595+ ${JSONGLIB_INCLUDE_DIRS}
2596+ )
2597+
2598+link_directories(
2599+ ${DBUSMENUGLIB_LIBRARY_DIRS}
2600+ ${GLIB_LIBRARY_DIRS}
2601+ ${JSONGLIB_LIBRARY_DIRS}
2602+ )
2603+
2604+add_executable(dbusmenubench-glibapp ${glibapp_SRCS})
2605+
2606+target_link_libraries(dbusmenubench-glibapp
2607+ ${DBUSMENUGLIB_LIBRARIES}
2608+ ${GLIB_LIBARIES}
2609+ ${JSONGLIB_LIBRARIES}
2610+ )
2611
2612=== added file 'tools/testapp/Makefile.am'
2613--- tools/testapp/Makefile.am 1970-01-01 00:00:00 +0000
2614+++ tools/testapp/Makefile.am 2010-02-04 20:30:33 +0000
2615@@ -0,0 +1,17 @@
2616+
2617+libexec_PROGRAMS = dbusmenu-testapp
2618+
2619+dbusmenu_testapp_SOURCES = \
2620+ main.c
2621+
2622+dbusmenu_testapp_CFLAGS = \
2623+ -I $(srcdir)/../.. \
2624+ $(DBUSMENUTESTS_CFLAGS) \
2625+ $(DBUSMENUGLIB_CFLAGS) \
2626+ -Wall -Werror
2627+
2628+dbusmenu_testapp_LDADD = \
2629+ $(builddir)/../../libdbusmenu-glib/libdbusmenu-glib.la \
2630+ $(builddir)/../../libdbusmenu-gtk/libdbusmenu-gtk.la \
2631+ $(DBUSMENUGTK_LIBS) \
2632+ $(DBUSMENUTESTS_LIBS)
2633
2634=== added file 'tools/testapp/main.c'
2635--- tools/testapp/main.c 1970-01-01 00:00:00 +0000
2636+++ tools/testapp/main.c 2010-02-04 20:30:33 +0000
2637@@ -0,0 +1,153 @@
2638+/*
2639+A library to communicate a menu object set accross DBus and
2640+track updates and maintain consistency.
2641+
2642+Copyright 2010 Canonical Ltd.
2643+
2644+Authors:
2645+ Aurélien Gâteau <aurelien.gateau@canonical.com>
2646+
2647+This program is free software: you can redistribute it and/or modify it
2648+under the terms of either or both of the following licenses:
2649+
2650+1) the GNU Lesser General Public License version 3, as published by the
2651+Free Software Foundation; and/or
2652+2) the GNU Lesser General Public License version 2.1, as published by
2653+the Free Software Foundation.
2654+
2655+This program is distributed in the hope that it will be useful, but
2656+WITHOUT ANY WARRANTY; without even the implied warranties of
2657+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
2658+PURPOSE. See the applicable version of the GNU Lesser General Public
2659+License for more details.
2660+
2661+You should have received a copy of both the GNU Lesser General Public
2662+License version 3 and version 2.1 along with this program. If not, see
2663+<http://www.gnu.org/licenses/>
2664+*/
2665+#include <glib.h>
2666+
2667+#include <dbus/dbus-glib.h>
2668+#include <dbus/dbus-glib-bindings.h>
2669+
2670+#include <json-glib/json-glib.h>
2671+
2672+#include <libdbusmenu-glib/server.h>
2673+#include <libdbusmenu-glib/menuitem.h>
2674+
2675+#define USAGE "dbusmenubench-glibapp <path/to/menu.json>"
2676+
2677+static void
2678+set_props (DbusmenuMenuitem * mi, JsonObject * node)
2679+{
2680+ if (node == NULL) return;
2681+
2682+ GList * members = NULL;
2683+ for (members = json_object_get_members(node); members != NULL; members = g_list_next(members)) {
2684+ const gchar * member = members->data;
2685+
2686+ if (!g_strcmp0(member, "id")) { continue; }
2687+ if (!g_strcmp0(member, "submenu")) { continue; }
2688+
2689+ JsonNode * lnode = json_object_get_member(node, member);
2690+ if (JSON_NODE_TYPE(lnode) != JSON_NODE_VALUE) { continue; }
2691+
2692+ dbusmenu_menuitem_property_set(mi, member, json_node_get_string(lnode));
2693+ }
2694+
2695+ return;
2696+}
2697+
2698+static DbusmenuMenuitem *
2699+layout2menuitem (JsonNode * inlayout)
2700+{
2701+ if (inlayout == NULL) return NULL;
2702+ if (JSON_NODE_TYPE(inlayout) != JSON_NODE_OBJECT) return NULL;
2703+
2704+ JsonObject * layout = json_node_get_object(inlayout);
2705+
2706+ DbusmenuMenuitem * local = NULL;
2707+ if (json_object_has_member(layout, "id")) {
2708+ JsonNode * node = json_object_get_member(layout, "id");
2709+ g_return_val_if_fail(JSON_NODE_TYPE(node) == JSON_NODE_VALUE, NULL);
2710+ local = dbusmenu_menuitem_new_with_id(json_node_get_int(node));
2711+ } else {
2712+ local = dbusmenu_menuitem_new();
2713+ }
2714+
2715+ set_props(local, layout);
2716+
2717+ if (json_object_has_member(layout, "submenu")) {
2718+ JsonNode * node = json_object_get_member(layout, "submenu");
2719+ g_return_val_if_fail(JSON_NODE_TYPE(node) == JSON_NODE_ARRAY, local);
2720+ JsonArray * array = json_node_get_array(node);
2721+ guint count;
2722+ for (count = 0; count < json_array_get_length(array); count++) {
2723+ DbusmenuMenuitem * child = layout2menuitem(json_array_get_element(array, count));
2724+ if (child != NULL) {
2725+ dbusmenu_menuitem_child_append(local, child);
2726+ }
2727+ }
2728+ }
2729+
2730+ /* g_debug("Layout to menu return: 0x%X", (unsigned int)local); */
2731+ return local;
2732+}
2733+
2734+void init_menu(DbusmenuMenuitem *root, const char *filename)
2735+{
2736+ JsonParser * parser = json_parser_new();
2737+ GError * error = NULL;
2738+ if (!json_parser_load_from_file(parser, filename, &error)) {
2739+ g_debug("Failed parsing file %s because: %s", filename, error->message);
2740+ return;
2741+ }
2742+ JsonNode * root_node = json_parser_get_root(parser);
2743+ if (JSON_NODE_TYPE(root_node) != JSON_NODE_ARRAY) {
2744+ g_debug("Root node is not an array, fail. It's an: %s", json_node_type_name(root_node));
2745+ return;
2746+ }
2747+
2748+ JsonArray * root_array = json_node_get_array(root_node);
2749+ int pos;
2750+ int count = json_array_get_length(root_array);
2751+ for (pos=0; pos < count; ++pos) {
2752+ DbusmenuMenuitem *child = layout2menuitem(json_array_get_element(root_array, pos));
2753+ dbusmenu_menuitem_child_append(root, child);
2754+ }
2755+}
2756+
2757+int main (int argc, char ** argv)
2758+{
2759+ g_type_init();
2760+
2761+ if (argc != 2) {
2762+ g_warning(USAGE);
2763+ return 1;
2764+ }
2765+ const char *filename = argv[1];
2766+
2767+ GError * error = NULL;
2768+ DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
2769+ DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
2770+ guint nameret = 0;
2771+
2772+ if (!org_freedesktop_DBus_request_name(bus_proxy, "org.dbusmenu.test", 0, &nameret, &error)) {
2773+ g_error("Unable to call to request name");
2774+ return 1;
2775+ }
2776+
2777+ if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
2778+ g_error("Unable to get name");
2779+ return 1;
2780+ }
2781+
2782+ DbusmenuServer *server = dbusmenu_server_new("/MenuBar");
2783+ DbusmenuMenuitem *root = dbusmenu_menuitem_new_with_id(0);
2784+ init_menu(root, filename);
2785+ dbusmenu_server_set_root(server, root);
2786+
2787+ g_main_loop_run(g_main_loop_new(NULL, FALSE));
2788+
2789+ return 0;
2790+}

Subscribers

People subscribed via source and target branches

to all changes: