aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am249
-rw-r--r--tests/dbusmenu-jsonloader.pc.in14
-rw-r--r--tests/json-loader.c220
-rw-r--r--tests/json-loader.h31
-rw-r--r--tests/run-xvfb.sh2
-rw-r--r--tests/test-glib-events-client.c140
-rw-r--r--tests/test-glib-events-server.c102
-rw-r--r--tests/test-glib-properties-client.c2
-rw-r--r--tests/test-gtk-label-client.c2
-rw-r--r--tests/test-gtk-label-server.c71
-rw-r--r--tests/test-gtk-objects.c145
-rw-r--r--tests/test-gtk-objects.jpgbin0 -> 14376 bytes
-rw-r--r--tests/test-gtk-shortcut-client.c76
-rw-r--r--tests/test-gtk-shortcut-server.c99
-rw-r--r--tests/test-gtk-submenu-client.c150
-rw-r--r--tests/test-gtk-submenu-server.c113
-rw-r--r--tests/test-json-01.json4023
-rw-r--r--tests/test-json-client.c75
-rw-r--r--tests/test-json-server.c81
19 files changed, 5516 insertions, 79 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f1b50bc..aa79c8f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,19 +1,28 @@
DBUS_RUNNER=dbus-test-runner
+CLEANFILES=
+
TESTS = \
test-glib-objects-test \
+ test-glib-events \
test-glib-layout \
test-glib-properties \
test-glib-proxy \
test-glib-simple-items \
test-glib-submenu \
+ test-json \
+ test-gtk-objects-test \
test-gtk-label \
- test-gtk-reorder
+ test-gtk-shortcut \
+ test-gtk-reorder \
+ test-gtk-submenu
check_PROGRAMS = \
glib-server-nomenu \
test-glib-objects \
+ test-glib-events-client \
+ test-glib-events-server \
test-glib-layout-client \
test-glib-layout-server \
test-glib-properties-client \
@@ -21,16 +30,60 @@ check_PROGRAMS = \
test-glib-proxy-client \
test-glib-proxy-server \
test-glib-proxy-proxy \
+ test-gtk-objects \
test-glib-submenu-client \
test-glib-submenu-server \
test-gtk-label-client \
test-gtk-label-server \
+ test-gtk-shortcut-client \
+ test-gtk-shortcut-server \
test-glib-simple-items \
- test-gtk-reorder-server
+ test-gtk-reorder-server \
+ test-json-client \
+ test-json-server \
+ test-gtk-submenu-server \
+ test-gtk-submenu-client
XVFB_RUN=". $(srcdir)/run-xvfb.sh"
######################
+# JSON Loader lib
+######################
+
+lib_LTLIBRARIES = libdbusmenu-jsonloader.la
+
+libdbusmenu_jsonloaderincludedir=$(includedir)/libdbusmenu-0.1/libdbusmenu-jsonloader/
+
+libdbusmenu_jsonloaderinclude_HEADERS = \
+ json-loader.h
+
+libdbusmenu_jsonloader_la_SOURCES = \
+ json-loader.h \
+ json-loader.c
+
+libdbusmenu_jsonloader_la_LDFLAGS = \
+ -version-info $(LIBDBUSMENU_CURRENT):$(LIBDBUSMENU_REVISION):$(LIBDBUSMENU_AGE) \
+ -no-undefined \
+ -export-symbols-regex "^[^_].*"
+
+libdbusmenu_jsonloader_la_CFLAGS = \
+ $(DBUSMENUGLIB_CFLAGS) \
+ $(DBUSMENUTESTS_CFLAGS) \
+ -I $(srcdir)/.. \
+ -Wall \
+ -Werror \
+ -DG_DISABLE_DEPRECATED \
+ -DG_LOG_DOMAIN="\"LIBDBUSMENU-JSONLOADER\""
+
+libdbusmenu_jsonloader_la_LIBADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ $(DBUSMENUGLIB_LIBS) \
+ $(DBUSMENUTESTS_LIBS)
+
+pkgconfig_DATA = dbusmenu-jsonloader.pc
+pkgconfigdir = $(libdir)/pkgconfig
+
+######################
# Test GLib server
######################
@@ -79,6 +132,78 @@ test_glib_layout_client_LDADD = \
$(DBUSMENUGLIB_LIBS)
######################
+# Test Glib Events
+######################
+
+test-glib-events: test-glib-events-client test-glib-events-server Makefile.am
+ @echo "#!/bin/bash" > $@
+ @echo $(DBUS_RUNNER) --task ./test-glib-events-client --task-name Client --task ./test-glib-events-server --task-name Server --ignore-return >> $@
+ @chmod +x $@
+
+test_glib_events_server_SOURCES = \
+ test-glib-events-server.c
+
+test_glib_events_server_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
+
+test_glib_events_server_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ $(DBUSMENUGLIB_LIBS)
+
+test_glib_events_client_SOURCES = \
+ test-glib-events-client.c
+
+test_glib_events_client_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
+
+test_glib_events_client_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ $(DBUSMENUGLIB_LIBS)
+
+######################
+# Test JSON
+######################
+
+test-json: test-json-client test-json-server Makefile.am
+ @echo "#!/bin/bash" > $@
+ @echo $(XVFB_RUN) >> $@
+ @echo $(DBUS_RUNNER) --task ./test-json-client --task-name Client --parameter $(top_builddir)/tools/dbusmenu-dumper --parameter test-json-01.output.json --ignore-return --task ./test-json-server --task-name Server --parameter $(srcdir)/test-json-01.json --ignore-return >> $@
+ @echo diff $(srcdir)/test-json-01.json test-json-01.output.json \> /dev/null >> $@
+ @chmod +x $@
+
+CLEANFILES += test-json-01.output.json
+
+test_json_server_SOURCES = \
+ test-json-server.c
+
+test_json_server_CFLAGS = \
+ -I $(srcdir)/.. \
+ -I $(srcdir) \
+ $(DBUSMENUGLIB_CFLAGS) \
+ $(DBUSMENUTESTS_CFLAGS) \
+ -Wall -Werror
+
+test_json_server_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ libdbusmenu-jsonloader.la \
+ $(DBUSMENUTESTS_LIBS) \
+ $(DBUSMENUGLIB_LIBS)
+
+test_json_client_SOURCES = \
+ test-json-client.c
+
+test_json_client_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
+
+test_json_client_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ $(DBUSMENUTESTS_LIBS) \
+ $(DBUSMENUGLIB_LIBS)
+
+######################
# Test Glib Submenu
######################
@@ -119,7 +244,7 @@ OBJECT_XML_REPORT = test-glib-objects.xml
test-glib-objects-test: test-glib-objects Makefile.am
@echo "#!/bin/bash" > $@
- @echo $(DBUS_RUNNER) --task gtester --parameter --verbose --parameter -k --parameter -o --parameter $(OBJECT_XML_REPORT) --parameter ./test-glib-objects >> $@
+ @echo $(DBUS_RUNNER) --task gtester --task-name test --parameter --verbose --parameter -k --parameter -o --parameter $(OBJECT_XML_REPORT) --parameter ./test-glib-objects >> $@
@chmod +x $@
test_glib_objects_SOURCES = \
@@ -231,6 +356,34 @@ test_glib_simple_items_LDADD = \
../libdbusmenu-glib/libdbusmenu-glib.la \
$(DBUSMENUGLIB_LIBS)
+######################
+# Test GTK Object
+######################
+
+GTK_OBJECT_XML_REPORT = test-gtk-objects.xml
+
+test-gtk-objects-test: test-gtk-objects Makefile.am
+ @echo "#!/bin/bash" > $@
+ @echo $(XVFB_RUN) >> $@
+ @echo $(DBUS_RUNNER) --task gtester --task-name test --parameter --verbose --parameter -k --parameter -o --parameter $(GTK_OBJECT_XML_REPORT) --parameter ./test-gtk-objects >> $@
+ @chmod +x $@
+
+test_gtk_objects_SOURCES = \
+ test-gtk-objects.c
+
+test_gtk_objects_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGLIB_CFLAGS) \
+ $(DBUSMENUGTK_CFLAGS) \
+ -DSRCDIR="\"$(srcdir)\"" \
+ -Wall -Werror
+
+test_gtk_objects_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ ../libdbusmenu-gtk/libdbusmenu-gtk.la \
+ $(DBUSMENUGLIB_LIBS) \
+ $(DBUSMENUGTK_LIBS)
+
#########################
# Test GTK Label
#########################
@@ -253,6 +406,7 @@ test_gtk_label_server_CFLAGS = \
test_gtk_label_server_LDADD = \
../libdbusmenu-glib/libdbusmenu-glib.la \
../libdbusmenu-gtk/libdbusmenu-gtk.la \
+ libdbusmenu-jsonloader.la \
$(DBUSMENUGTK_LIBS) \
$(DBUSMENUTESTS_LIBS)
@@ -272,6 +426,46 @@ test_gtk_label_client_LDADD = \
$(DBUSMENUTESTS_LIBS)
#########################
+# Test GTK Shortcut
+#########################
+
+test-gtk-shortcut: test-gtk-shortcut-client test-gtk-shortcut-server Makefile.am
+ @echo "#!/bin/bash" > $@
+ @echo $(XVFB_RUN) >> $@
+ @echo $(DBUS_RUNNER) --task ./test-gtk-shortcut-client --task-name Client --task ./test-gtk-shortcut-server --task-name Server --ignore-return >> $@
+ @chmod +x $@
+
+test_gtk_shortcut_server_SOURCES = \
+ test-gtk-shortcut-server.c
+
+test_gtk_shortcut_server_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGTK_CFLAGS) \
+ $(DBUSMENUTESTS_CFLAGS) \
+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
+
+test_gtk_shortcut_server_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ ../libdbusmenu-gtk/libdbusmenu-gtk.la \
+ $(DBUSMENUGTK_LIBS) \
+ $(DBUSMENUTESTS_LIBS)
+
+test_gtk_shortcut_client_SOURCES = \
+ test-gtk-shortcut-client.c
+
+test_gtk_shortcut_client_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGTK_CFLAGS) \
+ $(DBUSMENUTESTS_CFLAGS) \
+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
+
+test_gtk_shortcut_client_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ ../libdbusmenu-gtk/libdbusmenu-gtk.la \
+ $(DBUSMENUGTK_LIBS) \
+ $(DBUSMENUTESTS_LIBS)
+
+#########################
# Test GTK Reorder
#########################
@@ -297,6 +491,46 @@ test_gtk_reorder_server_LDADD = \
$(DBUSMENUTESTS_LIBS)
#########################
+# Test GTK Submenu
+#########################
+
+test-gtk-submenu: test-gtk-submenu-client test-gtk-submenu-server Makefile.am
+ @echo "#!/bin/bash" > $@
+ @echo $(XVFB_RUN) >> $@
+ @echo $(DBUS_RUNNER) --task ./test-gtk-submenu-client --task-name Client --task ./test-gtk-submenu-server --task-name Server --ignore-return >> $@
+ @chmod +x $@
+
+test_gtk_submenu_server_SOURCES = \
+ test-gtk-submenu-server.c
+
+test_gtk_submenu_server_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGTK_CFLAGS) \
+ $(DBUSMENUTESTS_CFLAGS) \
+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
+
+test_gtk_submenu_server_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ ../libdbusmenu-gtk/libdbusmenu-gtk.la \
+ $(DBUSMENUGTK_LIBS) \
+ $(DBUSMENUTESTS_LIBS)
+
+test_gtk_submenu_client_SOURCES = \
+ test-gtk-submenu-client.c
+
+test_gtk_submenu_client_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGTK_CFLAGS) \
+ $(DBUSMENUTESTS_CFLAGS) \
+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
+
+test_gtk_submenu_client_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ ../libdbusmenu-gtk/libdbusmenu-gtk.la \
+ $(DBUSMENUGTK_LIBS) \
+ $(DBUSMENUTESTS_LIBS)
+
+#########################
# Test Mago
#########################
@@ -329,6 +563,7 @@ EXTRA_DIST = \
$(examples_DATA) \
run-xvfb.sh \
$(json_DATA) \
+ test-gtk-objects.jpg \
dbusmenu-gtk/dbusMenuTest \
dbusmenu-gtk/mago_tests/dbusmenu.xml \
dbusmenu-gtk/mago_tests/dbusmenu.py \
@@ -347,9 +582,10 @@ EXTRA_DIST = \
dbusmenu-gtk/mago_tests/data/several_submenus_recursive.json \
dbusmenu-gtk/mago_tests/data/several_submenus_utf8.json \
dbusmenu-gtk/mago_tests/data/static.json \
- dbusmenu-gtk/mago_tests/data/test-gtk-label.json
+ dbusmenu-gtk/mago_tests/data/test-gtk-label.json \
+ test-json-01.json
-CLEANFILES = \
+CLEANFILES += \
dbusmenu-gtk/mago_tests/dbusmenu.pyc
distclean-local:
@@ -357,5 +593,6 @@ distclean-local:
DISTCLEANFILES = \
$(TESTS) \
- $(OBJECT_XML_REPORT)
+ $(OBJECT_XML_REPORT) \
+ $(GTK_OBJECT_XML_REPORT)
diff --git a/tests/dbusmenu-jsonloader.pc.in b/tests/dbusmenu-jsonloader.pc.in
new file mode 100644
index 0000000..d042132
--- /dev/null
+++ b/tests/dbusmenu-jsonloader.pc.in
@@ -0,0 +1,14 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+bindir=@bindir@
+includedir=@includedir@
+
+Cflags: -I${includedir}/libdbusmenu-0.1
+Requires: dbus-glib-1,dbusmenu-glib,json-glib-1.0
+Libs: -L${libdir} -ldbusmenu-jsonloader
+
+Name: libdbusmenu-jsonloader
+Description: A small library to load JSON descriptions of menus. Mostly for testing.
+Version: @VERSION@
+
diff --git a/tests/json-loader.c b/tests/json-loader.c
new file mode 100644
index 0000000..aad4295
--- /dev/null
+++ b/tests/json-loader.c
@@ -0,0 +1,220 @@
+/*
+A loader to turn JSON into dbusmenu menuitems
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "json-loader.h"
+#include <dbus/dbus-gtype-specialized.h>
+
+static GValue *
+node2value (JsonNode * node)
+{
+ if (node == NULL) {
+ return NULL;
+ }
+
+ GValue * value = g_new0(GValue, 1);
+
+ if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE) {
+ json_node_get_value(node, value);
+ return value;
+ }
+
+ if (JSON_NODE_TYPE(node) == JSON_NODE_ARRAY) {
+ JsonArray * array = json_node_get_array(node);
+ JsonNode * first = json_array_get_element(array, 0);
+
+ if (JSON_NODE_TYPE(first) == JSON_NODE_VALUE) {
+ GValue subvalue = {0};
+ json_node_get_value(first, &subvalue);
+
+ if (G_VALUE_TYPE(&subvalue) == G_TYPE_STRING) {
+ GArray * garray = g_array_sized_new(TRUE, TRUE, sizeof(gchar *), json_array_get_length(array));
+ g_value_init(value, G_TYPE_STRV);
+ g_value_take_boxed(value, garray->data);
+
+ int i;
+ for (i = 0; i < json_array_get_length(array); i++) {
+ const gchar * str = json_node_get_string(json_array_get_element(array, i));
+ gchar * dupstr = g_strdup(str);
+ g_array_append_val(garray, dupstr);
+ }
+
+ g_array_free(garray, FALSE);
+ } else {
+ GValueArray * varray = g_value_array_new(json_array_get_length(array));
+ g_value_init(value, G_TYPE_VALUE_ARRAY);
+ g_value_take_boxed(value, varray);
+
+ g_value_array_append(varray, &subvalue);
+ g_value_unset(&subvalue);
+
+ int i;
+ for (i = 1; i < json_array_get_length(array); i++) {
+ json_node_get_value(first, &subvalue);
+ g_value_array_append(varray, &subvalue);
+ g_value_unset(&subvalue);
+ }
+ }
+
+ } else {
+ GValue * subvalue = node2value(first);
+ GType type = dbus_g_type_get_collection("GPtrArray", G_VALUE_TYPE(subvalue));
+ gpointer * wrapper = dbus_g_type_specialized_construct(type);
+
+ g_value_init(value, type);
+ g_value_take_boxed(value, wrapper);
+
+ DBusGTypeSpecializedAppendContext ctx;
+ dbus_g_type_specialized_init_append(value, &ctx);
+
+ dbus_g_type_specialized_collection_append(&ctx, subvalue);
+ int i;
+ for (i = 1; i < json_array_get_length(array); i++) {
+ GValue * subvalue = node2value(node);
+ dbus_g_type_specialized_collection_append(&ctx, subvalue);
+ }
+
+ dbus_g_type_specialized_collection_end_append(&ctx);
+ }
+ }
+
+ if (JSON_NODE_TYPE(node) == JSON_NODE_OBJECT) {
+ JsonObject * obj = json_node_get_object(node);
+
+ GType type = dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE);
+ GHashTable * hash = (GHashTable *)dbus_g_type_specialized_construct(type);
+
+ g_value_init(value, type);
+ g_value_take_boxed(value, hash);
+
+ DBusGTypeSpecializedAppendContext ctx;
+ dbus_g_type_specialized_init_append(value, &ctx);
+
+ GList * members = NULL;
+ for (members = json_object_get_members(obj); members != NULL; members = g_list_next(members)) {
+ const gchar * member = members->data;
+
+ JsonNode * lnode = json_object_get_member(obj, member);
+ GValue * value = node2value(lnode);
+
+ if (value != NULL) {
+ GValue name = {0};
+ g_value_init(&name, G_TYPE_STRING);
+ g_value_set_static_string(&name, member);
+
+ dbus_g_type_specialized_map_append(&ctx, &name, value);
+
+ g_value_unset(&name);
+ g_value_unset(value);
+ g_free(value);
+ }
+ }
+ }
+
+ return value;
+}
+
+static void
+set_props (DbusmenuMenuitem * mi, JsonObject * node)
+{
+ if (node == NULL) return;
+
+ GList * members = NULL;
+ for (members = json_object_get_members(node); members != NULL; members = g_list_next(members)) {
+ const gchar * member = members->data;
+
+ if (!g_strcmp0(member, "id")) { continue; }
+ if (!g_strcmp0(member, "submenu")) { continue; }
+
+ JsonNode * lnode = json_object_get_member(node, member);
+ GValue * value = node2value(lnode);
+
+ if (value != NULL) {
+ dbusmenu_menuitem_property_set_value(mi, member, value);
+ g_value_unset(value);
+ g_free(value);
+ }
+ }
+
+ return;
+}
+
+DbusmenuMenuitem *
+dbusmenu_json_build_from_node (const JsonNode * cnode)
+{
+ JsonNode * node = (JsonNode *)cnode; /* To match the jsonglib API :( */
+
+ if (node == NULL) return NULL;
+ if (JSON_NODE_TYPE(node) != JSON_NODE_OBJECT) return NULL;
+
+ JsonObject * layout = json_node_get_object(node);
+
+ DbusmenuMenuitem * local = NULL;
+ if (json_object_has_member(layout, "id")) {
+ JsonNode * node = json_object_get_member(layout, "id");
+ g_return_val_if_fail(JSON_NODE_TYPE(node) == JSON_NODE_VALUE, NULL);
+ local = dbusmenu_menuitem_new_with_id(json_node_get_int(node));
+ } else {
+ local = dbusmenu_menuitem_new();
+ }
+
+ set_props(local, layout);
+
+ if (json_object_has_member(layout, "submenu")) {
+ JsonNode * node = json_object_get_member(layout, "submenu");
+ g_return_val_if_fail(JSON_NODE_TYPE(node) == JSON_NODE_ARRAY, local);
+ JsonArray * array = json_node_get_array(node);
+ guint count;
+ for (count = 0; count < json_array_get_length(array); count++) {
+ DbusmenuMenuitem * child = dbusmenu_json_build_from_node(json_array_get_element(array, count));
+ if (child != NULL) {
+ dbusmenu_menuitem_child_append(local, child);
+ }
+ }
+ }
+
+ /* g_debug("Layout to menu return: 0x%X", (unsigned int)local); */
+ return local;
+}
+
+DbusmenuMenuitem *
+dbusmenu_json_build_from_file (const gchar * filename)
+{
+ JsonParser * parser = json_parser_new();
+
+ GError * error = NULL;
+ if (!json_parser_load_from_file(parser, filename, &error)) {
+ g_warning("Failed parsing file %s because: %s", filename, error->message);
+ g_error_free(error);
+ return NULL;
+ }
+
+ JsonNode * root_node = json_parser_get_root(parser);
+ if (JSON_NODE_TYPE(root_node) != JSON_NODE_OBJECT) {
+ g_warning("Root node is not an object, fail. It's an: %s", json_node_type_name(root_node));
+ return NULL;
+ }
+
+ DbusmenuMenuitem * mi = dbusmenu_json_build_from_node(root_node);
+
+ g_object_unref(parser);
+
+ return mi;
+}
diff --git a/tests/json-loader.h b/tests/json-loader.h
new file mode 100644
index 0000000..666bb6e
--- /dev/null
+++ b/tests/json-loader.h
@@ -0,0 +1,31 @@
+/*
+A loader to turn JSON into dbusmenu menuitems
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __DBUSMENU_JSON_LOADER_H__
+#define __DBUSMENU_JSON_LOADER_H__
+
+#include <libdbusmenu-glib/menuitem.h>
+#include <json-glib/json-glib.h>
+
+DbusmenuMenuitem * dbusmenu_json_build_from_node (const JsonNode * node);
+DbusmenuMenuitem * dbusmenu_json_build_from_file (const gchar * filename);
+
+#endif /* __DBUSMENU_JSON_LOADER_H__ */
diff --git a/tests/run-xvfb.sh b/tests/run-xvfb.sh
index 3622dbf..3aa05c1 100644
--- a/tests/run-xvfb.sh
+++ b/tests/run-xvfb.sh
@@ -1,4 +1,4 @@
-if [ "$DISPLAY" == "" ]; then
+if [ "x$DISPLAY" == "x" ]; then
Xvfb -ac -noreset -screen 0 800x600x16 -help 2>/dev/null 1>&2
XID=`for id in 101 102 103 104 105 106 107 197 199 211 223 227 293 307 308 309 310 311 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 4703 4721 4723 4729 4733 4751 9973 9974 9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990 9991 9992 9993 9994 9995 9996 9997 9998 9999 ; do test -e /tmp/.X$id-lock || { echo $id; exit 0; }; done; exit 1`
{ Xvfb -ac -noreset -screen 0 800x600x16 :$XID -screen 0 800x600x16 -nolisten tcp -auth /dev/null >/dev/null 2>&1 & trap "kill -15 $! " 0 HUP INT QUIT TRAP USR1 PIPE TERM ; } || { echo "Gtk+Tests:ERROR: Failed to start Xvfb environment for X11 target tests."; exit 1; }
diff --git a/tests/test-glib-events-client.c b/tests/test-glib-events-client.c
new file mode 100644
index 0000000..97d5caf
--- /dev/null
+++ b/tests/test-glib-events-client.c
@@ -0,0 +1,140 @@
+/*
+A test for libdbusmenu to ensure its quality.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+
+#include <libdbusmenu-glib/client.h>
+#include <libdbusmenu-glib/menuitem.h>
+
+#include "test-glib-submenu.h"
+
+#define TIMESTAMP_VALUE 54
+#define DATA_VALUE 32
+#define USER_VALUE 76
+
+static GMainLoop * mainloop = NULL;
+static gboolean passed = TRUE;
+static gboolean first = TRUE;
+
+static void
+event_status (DbusmenuClient * client, DbusmenuMenuitem * item, gchar * name, GValue * data, guint timestamp, GError * error, gpointer user_data)
+{
+ g_debug("Event status: %s", error == NULL ? "Sent" : "Error");
+
+ if (timestamp != TIMESTAMP_VALUE) {
+ g_debug("Timestamp value pass fail got: %d", timestamp);
+ passed = FALSE;
+ g_main_loop_quit(mainloop);
+ return;
+ }
+
+ if (g_value_get_int(data) != DATA_VALUE) {
+ g_debug("Data value pass fail got: %d", g_value_get_int(data));
+ passed = FALSE;
+ g_main_loop_quit(mainloop);
+ return;
+ }
+
+ if (GPOINTER_TO_INT(user_data) != USER_VALUE) {
+ g_debug("User value pass fail got: %d", GPOINTER_TO_INT(user_data));
+ passed = FALSE;
+ g_main_loop_quit(mainloop);
+ return;
+ }
+
+ if (first && error != NULL) {
+ passed = FALSE;
+ g_debug("First signal back failed.");
+ g_main_loop_quit(mainloop);
+ return;
+ }
+
+ if (!first && error == NULL) {
+ passed = FALSE;
+ g_debug("Second signal didn't fail.");
+ g_main_loop_quit(mainloop);
+ return;
+ }
+
+ if (!first && error != NULL) {
+ g_debug("Second signal failed: pass.");
+ g_main_loop_quit(mainloop);
+ return;
+ }
+
+ first = FALSE;
+ dbusmenu_menuitem_handle_event(item, "clicked", data, timestamp);
+ return;
+}
+
+static void
+layout_updated (DbusmenuClient * client, gpointer user_data)
+{
+ g_debug("Layout Updated");
+
+ DbusmenuMenuitem * menuroot = dbusmenu_client_get_root(client);
+ if (menuroot == NULL) {
+ g_debug("Root is NULL?");
+ return;
+ }
+
+ GValue data = {0};
+ g_value_init(&data, G_TYPE_INT);
+ g_value_set_int(&data, DATA_VALUE);
+
+ dbusmenu_menuitem_handle_event(menuroot, "clicked", &data, TIMESTAMP_VALUE);
+
+ return;
+}
+
+static gboolean
+timer_func (gpointer data)
+{
+ g_debug("Death timer. Oops.");
+ passed = FALSE;
+ g_main_loop_quit(mainloop);
+ return FALSE;
+}
+
+int
+main (int argc, char ** argv)
+{
+ g_type_init();
+
+ DbusmenuClient * client = dbusmenu_client_new("org.dbusmenu.test", "/org/test");
+ g_signal_connect(G_OBJECT(client), DBUSMENU_CLIENT_SIGNAL_LAYOUT_UPDATED, G_CALLBACK(layout_updated), NULL);
+ g_signal_connect(G_OBJECT(client), DBUSMENU_CLIENT_SIGNAL_EVENT_RESULT, G_CALLBACK(event_status), GINT_TO_POINTER(USER_VALUE));
+
+ g_timeout_add_seconds(5, timer_func, client);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ g_object_unref(G_OBJECT(client));
+
+ if (passed) {
+ g_debug("Quiting");
+ return 0;
+ } else {
+ g_debug("Quiting as we're a failure");
+ return 1;
+ }
+}
diff --git a/tests/test-glib-events-server.c b/tests/test-glib-events-server.c
new file mode 100644
index 0000000..0d1e0b1
--- /dev/null
+++ b/tests/test-glib-events-server.c
@@ -0,0 +1,102 @@
+/*
+A test for libdbusmenu to ensure its quality.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <libdbusmenu-glib/server.h>
+#include <libdbusmenu-glib/menuitem.h>
+
+static DbusmenuServer * server = NULL;
+static GMainLoop * mainloop = NULL;
+static gboolean passed = TRUE;
+
+static void
+handle_event (void) {
+ g_debug("Handle event");
+ g_main_loop_quit(mainloop);
+ return;
+}
+
+static gboolean
+timer_func (gpointer data)
+{
+ passed = FALSE;
+ g_debug("Never got a signal");
+ g_main_loop_quit(mainloop);
+ return FALSE;
+}
+
+int
+main (int argc, char ** argv)
+{
+ GError * error = NULL;
+
+ g_type_init();
+
+ DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+ g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
+
+ DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+ guint nameret = 0;
+
+ if (!org_freedesktop_DBus_request_name(bus_proxy, "org.dbusmenu.test", 0, &nameret, &error)) {
+ g_error("Unable to call to request name");
+ return 1;
+ }
+
+ if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ g_error("Unable to get name");
+ return 1;
+ }
+
+ server = dbusmenu_server_new("/org/test");
+ DbusmenuMenuitem * menuitem = dbusmenu_menuitem_new();
+ dbusmenu_server_set_root(server, menuitem);
+
+ g_signal_connect(G_OBJECT(menuitem), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(handle_event), NULL);
+
+ g_timeout_add_seconds(3, timer_func, NULL);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ if (passed) {
+ int i;
+
+ for (i = 0; i < 5; i++) {
+ g_debug("Ignoring signals: %d", i);
+ g_usleep(1000 * 1000);
+ }
+ }
+
+ if (passed) {
+ g_debug("Test Passed");
+ return 0;
+ } else {
+ g_debug("Test Failed");
+ return 1;
+ }
+}
diff --git a/tests/test-glib-properties-client.c b/tests/test-glib-properties-client.c
index 434465a..ae7b80b 100644
--- a/tests/test-glib-properties-client.c
+++ b/tests/test-glib-properties-client.c
@@ -121,7 +121,7 @@ static void
layout_updated (DbusmenuClient * client, gpointer data)
{
g_debug("Layout Updated");
- g_timeout_add (250, layout_verify_timer, client);
+ g_timeout_add (500, layout_verify_timer, client);
return;
}
diff --git a/tests/test-gtk-label-client.c b/tests/test-gtk-label-client.c
index 070c278..14eb5bd 100644
--- a/tests/test-gtk-label-client.c
+++ b/tests/test-gtk-label-client.c
@@ -22,7 +22,6 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <gtk/gtk.h>
#include <libdbusmenu-gtk/menu.h>
-static guint layouton = 0;
static GMainLoop * mainloop = NULL;
static gboolean passed = TRUE;
static guint death_timer = 0;
@@ -105,7 +104,6 @@ verify_root_to_layout(DbusmenuMenuitem * mi, proplayout_t * layout)
static gboolean
timer_func (gpointer data)
{
- g_debug("Death timer. Oops. Got to: %d", layouton);
passed = TRUE;
g_main_loop_quit(mainloop);
return FALSE;
diff --git a/tests/test-gtk-label-server.c b/tests/test-gtk-label-server.c
index 32d7a43..32572fc 100644
--- a/tests/test-gtk-label-server.c
+++ b/tests/test-gtk-label-server.c
@@ -30,74 +30,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <libdbusmenu-glib/server.h>
#include <json-glib/json-glib.h>
-
-static void
-menuitem_click(DbusmenuMenuitem * mi, guint32 time, gpointer user_data)
-{
- g_debug("Clicked on: %d @ %d", dbusmenu_menuitem_get_id(mi), time);
- return;
-}
-
-static void
-set_props (DbusmenuMenuitem * mi, JsonObject * node)
-{
- if (node == NULL) return;
-
- GList * members = NULL;
- for (members = json_object_get_members(node); members != NULL; members = g_list_next(members)) {
- const gchar * member = members->data;
-
- if (!g_strcmp0(member, "id")) { continue; }
- if (!g_strcmp0(member, "submenu")) { continue; }
-
- JsonNode * lnode = json_object_get_member(node, member);
- if (JSON_NODE_TYPE(lnode) != JSON_NODE_VALUE) { continue; }
-
- GValue value = {0};
- json_node_get_value(lnode, &value);
- dbusmenu_menuitem_property_set_value(mi, member, &value);
- g_value_unset(&value);
- }
-
- return;
-}
-
-static DbusmenuMenuitem *
-layout2menuitem (JsonNode * inlayout)
-{
- if (inlayout == NULL) return NULL;
- if (JSON_NODE_TYPE(inlayout) != JSON_NODE_OBJECT) return NULL;
-
- JsonObject * layout = json_node_get_object(inlayout);
-
- DbusmenuMenuitem * local = NULL;
- if (json_object_has_member(layout, "id")) {
- JsonNode * node = json_object_get_member(layout, "id");
- g_return_val_if_fail(JSON_NODE_TYPE(node) == JSON_NODE_VALUE, NULL);
- local = dbusmenu_menuitem_new_with_id(json_node_get_int(node));
- } else {
- local = dbusmenu_menuitem_new();
- }
- g_signal_connect(G_OBJECT(local), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(menuitem_click), NULL);
-
- set_props(local, layout);
-
- if (json_object_has_member(layout, "submenu")) {
- JsonNode * node = json_object_get_member(layout, "submenu");
- g_return_val_if_fail(JSON_NODE_TYPE(node) == JSON_NODE_ARRAY, local);
- JsonArray * array = json_node_get_array(node);
- guint count;
- for (count = 0; count < json_array_get_length(array); count++) {
- DbusmenuMenuitem * child = layout2menuitem(json_array_get_element(array, count));
- if (child != NULL) {
- dbusmenu_menuitem_child_append(local, child);
- }
- }
- }
-
- /* g_debug("Layout to menu return: 0x%X", (unsigned int)local); */
- return local;
-}
+#include "json-loader.h"
static JsonArray * root_array = NULL;
static guint layouton = 0;
@@ -114,7 +47,7 @@ timer_func (gpointer data)
}
g_debug("Updating to Layout %d", layouton);
- dbusmenu_server_set_root(server, layout2menuitem(json_array_get_element(root_array, layouton)));
+ dbusmenu_server_set_root(server, dbusmenu_json_build_from_node(json_array_get_element(root_array, layouton)));
layouton++;
return TRUE;
diff --git a/tests/test-gtk-objects.c b/tests/test-gtk-objects.c
new file mode 100644
index 0000000..726f404
--- /dev/null
+++ b/tests/test-gtk-objects.c
@@ -0,0 +1,145 @@
+/*
+Testing for the various objects just by themselves.
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libdbusmenu-glib/menuitem.h>
+#include <libdbusmenu-gtk/menuitem.h>
+#include <gdk/gdkkeysyms.h>
+
+#define TEST_IMAGE SRCDIR "/" "test-gtk-objects.jpg"
+
+/* Building the basic menu item, make sure we didn't break
+ any core GObject stuff */
+static void
+test_object_menuitem (void)
+{
+ /* Build a menu item */
+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
+
+ /* Test to make sure it's a happy object */
+ g_assert(item != NULL);
+ g_assert(G_IS_OBJECT(item));
+ g_assert(DBUSMENU_IS_MENUITEM(item));
+
+ /* Set up a check to make sure it gets destroyed on unref */
+ g_object_add_weak_pointer(G_OBJECT(item), (gpointer *)&item);
+ g_object_unref(item);
+
+ /* Did it go away? */
+ g_assert(item == NULL);
+
+ return;
+}
+
+/* Setting and getting a pixbuf */
+static void
+test_object_prop_pixbuf (void)
+{
+ const gchar * prop_name = "image-test";
+
+ /* Build a menu item */
+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
+
+ /* Test to make sure it's a happy object */
+ g_assert(item != NULL);
+ g_assert(G_IS_OBJECT(item));
+ g_assert(DBUSMENU_IS_MENUITEM(item));
+
+ /* Load our image */
+ GdkPixbuf * pixbuf = gdk_pixbuf_new_from_file(TEST_IMAGE, NULL);
+ g_assert(pixbuf != NULL);
+
+ /* Set the property */
+ gboolean success = dbusmenu_menuitem_property_set_image(item, prop_name, pixbuf);
+ g_assert(success);
+ g_object_unref(pixbuf);
+
+ /* Check to see if it's set */
+ const GValue * val = dbusmenu_menuitem_property_get_value(item, prop_name);
+ g_assert(val != NULL);
+
+ /* Get the pixbuf back! */
+ GdkPixbuf * newpixbuf = dbusmenu_menuitem_property_get_image(item, prop_name);
+ g_assert(newpixbuf != NULL);
+ g_object_unref(newpixbuf);
+
+ g_object_unref(item);
+
+ return;
+}
+
+/* Setting and getting a shortcut */
+static void
+test_object_prop_shortcut (void)
+{
+ /* Build a menu item */
+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
+
+ /* Test to make sure it's a happy object */
+ g_assert(item != NULL);
+ g_assert(G_IS_OBJECT(item));
+ g_assert(DBUSMENU_IS_MENUITEM(item));
+
+ guint key = GDK_c;
+ GdkModifierType modifier = GDK_CONTROL_MASK;
+
+ /* Set a shortcut */
+ gboolean success = dbusmenu_menuitem_property_set_shortcut(item, key, modifier);
+ g_assert(success);
+
+ /* Check for value */
+ const GValue * val = dbusmenu_menuitem_property_get_value(item, DBUSMENU_MENUITEM_PROP_SHORTCUT);
+ g_assert(val != NULL);
+
+ /* Check to see if we love it */
+ guint newkey = 0;
+ GdkModifierType newmodifier = 0;
+ dbusmenu_menuitem_property_get_shortcut(item, &newkey, &newmodifier);
+
+ g_assert(key == newkey);
+ g_assert(newmodifier == modifier);
+
+ g_object_unref(item);
+
+ return;
+}
+
+/* Build the test suite */
+static void
+test_gtk_objects_suite (void)
+{
+ g_test_add_func ("/dbusmenu/gtk/objects/menuitem/base", test_object_menuitem);
+ g_test_add_func ("/dbusmenu/gtk/objects/menuitem/prop_pixbuf", test_object_prop_pixbuf);
+ g_test_add_func ("/dbusmenu/gtk/objects/menuitem/prop_shortcut", test_object_prop_shortcut);
+ return;
+}
+
+gint
+main (gint argc, gchar * argv[])
+{
+ gtk_init(&argc, &argv);
+
+ g_test_init(&argc, &argv, NULL);
+
+ /* Test suites */
+ test_gtk_objects_suite();
+
+ return g_test_run ();
+}
diff --git a/tests/test-gtk-objects.jpg b/tests/test-gtk-objects.jpg
new file mode 100644
index 0000000..478704e
--- /dev/null
+++ b/tests/test-gtk-objects.jpg
Binary files differ
diff --git a/tests/test-gtk-shortcut-client.c b/tests/test-gtk-shortcut-client.c
new file mode 100644
index 0000000..003885c
--- /dev/null
+++ b/tests/test-gtk-shortcut-client.c
@@ -0,0 +1,76 @@
+/*
+A test for libdbusmenu to ensure its quality.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <gtk/gtk.h>
+#include <libdbusmenu-gtk/menu.h>
+#include <libdbusmenu-gtk/client.h>
+
+static GMainLoop * mainloop = NULL;
+static gboolean passed = TRUE;
+static guint death_timer = 0;
+
+static gboolean
+timer_func (gpointer data)
+{
+ passed = TRUE;
+ g_main_loop_quit(mainloop);
+ return FALSE;
+}
+
+int
+main (int argc, char ** argv)
+{
+ gtk_init(&argc, &argv);
+
+ g_debug("Building Window");
+ GtkWidget * window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ GtkWidget * menubar = gtk_menu_bar_new();
+ GtkWidget * menuitem = gtk_menu_item_new_with_label("Test");
+
+ DbusmenuGtkMenu * dmenu = dbusmenu_gtkmenu_new ("glib.label.test", "/org/test");
+ DbusmenuGtkClient * dclient = dbusmenu_gtkmenu_get_client(dmenu);
+
+ GtkAccelGroup * agroup = gtk_accel_group_new();
+ dbusmenu_gtkclient_set_accel_group(dclient, agroup);
+
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), GTK_WIDGET(dmenu));
+ gtk_widget_show(menuitem);
+ gtk_menu_bar_append(menubar, menuitem);
+ gtk_widget_show(menubar);
+ gtk_container_add(GTK_CONTAINER(window), menubar);
+ gtk_window_set_title(GTK_WINDOW(window), "libdbusmenu-gtk test");
+ gtk_window_add_accel_group(GTK_WINDOW(window), agroup);
+ gtk_widget_show(window);
+
+ death_timer = g_timeout_add_seconds(10, timer_func, window);
+
+ g_debug("Entering Mainloop");
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ if (passed) {
+ g_debug("Quiting");
+ return 0;
+ } else {
+ g_debug("Quiting as we're a failure");
+ return 1;
+ }
+}
diff --git a/tests/test-gtk-shortcut-server.c b/tests/test-gtk-shortcut-server.c
new file mode 100644
index 0000000..3b703a1
--- /dev/null
+++ b/tests/test-gtk-shortcut-server.c
@@ -0,0 +1,99 @@
+/*
+A test for libdbusmenu to ensure its quality.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <libdbusmenu-glib/menuitem.h>
+#include <libdbusmenu-glib/server.h>
+#include <libdbusmenu-gtk/menuitem.h>
+
+GMainLoop * mainloop = NULL;
+DbusmenuServer * server = NULL;
+
+gboolean
+timer_func (gpointer userdata)
+{
+ g_main_loop_quit(mainloop);
+ return FALSE;
+}
+
+void
+build_menu (void)
+{
+ DbusmenuMenuitem * item;
+
+ DbusmenuMenuitem * root = dbusmenu_menuitem_new();
+
+ item = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, "Control-L");
+ dbusmenu_menuitem_property_set_shortcut(item, GDK_l, GDK_CONTROL_MASK);
+ dbusmenu_menuitem_child_append(root, item);
+ g_object_unref(item);
+
+
+ dbusmenu_server_set_root(server, root);
+ g_object_unref(root);
+
+ return;
+}
+
+int
+main (int argc, char ** argv)
+{
+ GError * error = NULL;
+
+ g_type_init();
+
+ DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+ g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
+
+ DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+ guint nameret = 0;
+
+ if (!org_freedesktop_DBus_request_name(bus_proxy, "glib.label.test", 0, &nameret, &error)) {
+ g_error("Unable to call to request name");
+ return 1;
+ }
+
+ if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ g_error("Unable to get name");
+ return 1;
+ }
+
+ server = dbusmenu_server_new("/org/test");
+ build_menu();
+
+ g_timeout_add_seconds(10, timer_func, NULL);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ g_debug("Quiting");
+
+ return 0;
+}
+
diff --git a/tests/test-gtk-submenu-client.c b/tests/test-gtk-submenu-client.c
new file mode 100644
index 0000000..ec46122
--- /dev/null
+++ b/tests/test-gtk-submenu-client.c
@@ -0,0 +1,150 @@
+/*
+A test for libdbusmenu to ensure its quality.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <gtk/gtk.h>
+#include <libdbusmenu-gtk/menu.h>
+
+static GMainLoop * mainloop = NULL;
+static gboolean passed = TRUE;
+
+static gboolean check_menu_content(GtkMenu * menu, char ** content)
+{
+ GList * child = gtk_container_get_children(GTK_CONTAINER(menu));
+ char ** expected = content;
+ for (; child != NULL; child = g_list_next(child), ++expected) {
+ if (*expected == NULL) {
+ g_warning("Too many gtk items");
+ return FALSE;
+ }
+ const char * label = gtk_menu_item_get_label(GTK_MENU_ITEM(child->data));
+ if (g_strcmp0(label, *expected) != 0) {
+ g_warning("Expected '%s', got '%s'", *expected, label);
+ return FALSE;
+ }
+ }
+ if (*expected != NULL) {
+ g_warning("Not enough gtk items");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void
+abort_test(const char * message)
+{
+ if (message) {
+ g_warning("%s", message);
+ }
+ passed = FALSE;
+ g_main_loop_quit(mainloop);
+}
+
+static gboolean
+timer_func (gpointer data)
+{
+ static char * root_content[] = { "Folder 1", "Folder 2", NULL };
+ static char * folder1_content[] = { "1.1", "1.2", "1.3", NULL };
+ static char * folder2_content[] = { "2.1", "2.2", "2.3", NULL };
+
+ GtkMenuItem * root_item = GTK_MENU_ITEM(data);
+ GtkMenu * menu = GTK_MENU(gtk_menu_item_get_submenu(root_item));
+
+ /* Root */
+ if (!check_menu_content(menu, root_content)) {
+ abort_test("Checking root content failed");
+ return FALSE;
+ }
+
+ /* Folder 1 */
+ GList * child = gtk_container_get_children(GTK_CONTAINER(menu));
+ GtkMenuItem * item = GTK_MENU_ITEM(child->data);
+ GtkMenu * folder_menu = GTK_MENU(gtk_menu_item_get_submenu(item));
+ if (!folder_menu) {
+ abort_test("Folder 1 has no menu");
+ return FALSE;
+ }
+
+ if (!check_menu_content(folder_menu, folder1_content)) {
+ abort_test("Checking folder1 content failed");
+ return FALSE;
+ }
+
+ /* Folder 2 */
+ child = g_list_next(child);
+ item = GTK_MENU_ITEM(child->data);
+ folder_menu = GTK_MENU(gtk_menu_item_get_submenu(item));
+ if (!folder_menu) {
+ abort_test("Folder 2 has no menu");
+ return FALSE;
+ }
+
+ if (!check_menu_content(folder_menu, folder2_content)) {
+ abort_test("Checking folder2 content failed");
+ return FALSE;
+ }
+
+ passed = TRUE;
+ return FALSE;
+}
+
+gboolean
+finished_func (gpointer user_data)
+{
+ g_main_loop_quit(mainloop);
+ return FALSE;
+}
+
+int
+main (int argc, char ** argv)
+{
+ gtk_init(&argc, &argv);
+
+ g_debug("Client Initialized. Waiting.");
+ /* Make sure the server starts up and all that */
+ g_usleep(500000);
+
+ g_debug("Building Window");
+ GtkWidget * window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ GtkWidget * menubar = gtk_menu_bar_new();
+ GtkWidget * menuitem = gtk_menu_item_new_with_label("Test");
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), GTK_WIDGET(dbusmenu_gtkmenu_new ("glib.label.test", "/org/test")));
+ gtk_widget_show(menuitem);
+ gtk_menu_bar_append(menubar, menuitem);
+ gtk_widget_show(menubar);
+ gtk_container_add(GTK_CONTAINER(window), menubar);
+ gtk_window_set_title(GTK_WINDOW(window), "libdbusmenu-gtk test");
+ gtk_widget_show(window);
+
+ g_timeout_add_seconds(2, timer_func, menuitem);
+ g_timeout_add_seconds(6, finished_func, menuitem);
+
+ g_debug("Entering Mainloop");
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ if (passed) {
+ g_debug("Quiting");
+ return 0;
+ } else {
+ g_debug("Quiting as we're a failure");
+ return 1;
+ }
+}
diff --git a/tests/test-gtk-submenu-server.c b/tests/test-gtk-submenu-server.c
new file mode 100644
index 0000000..11cede0
--- /dev/null
+++ b/tests/test-gtk-submenu-server.c
@@ -0,0 +1,113 @@
+/*
+A test for libdbusmenu to ensure its quality.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <libdbusmenu-glib/menuitem.h>
+#include <libdbusmenu-glib/server.h>
+
+static GMainLoop *mainloop = NULL;
+
+static gboolean
+timer_func (gpointer data)
+{
+ g_main_loop_quit (mainloop);
+
+ return FALSE;
+}
+
+static gboolean
+show_item (gpointer pmi)
+{
+ DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(pmi);
+ g_debug("Showing item");
+
+ dbusmenu_menuitem_show_to_user(mi, 0);
+
+ return FALSE;
+}
+
+DbusmenuMenuitem *
+add_item(DbusmenuMenuitem * parent, const char * label)
+{
+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(item, "label", label);
+ dbusmenu_menuitem_child_append(parent, item);
+ return item;
+}
+
+int
+main (int argc, char ** argv)
+{
+ GError * error = NULL;
+
+ g_type_init();
+
+ DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+ g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
+
+ DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+ guint nameret = 0;
+
+ if (!org_freedesktop_DBus_request_name(bus_proxy, "glib.label.test", 0, &nameret, &error)) {
+ g_error("Unable to call to request name");
+ return 1;
+ }
+
+ if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ g_error("Unable to get name");
+ return 1;
+ }
+
+ DbusmenuServer * server = dbusmenu_server_new("/org/test");
+ DbusmenuMenuitem * root = dbusmenu_menuitem_new();
+ dbusmenu_server_set_root(server, root);
+
+ DbusmenuMenuitem * item;
+ item = add_item(root, "Folder 1");
+ add_item(item, "1.1");
+ add_item(item, "1.2");
+ add_item(item, "1.3");
+
+ g_timeout_add_seconds(2, show_item, item);
+
+ item = add_item(root, "Folder 2");
+ add_item(item, "2.1");
+ add_item(item, "2.2");
+ add_item(item, "2.3");
+
+ g_timeout_add_seconds(4, show_item, item);
+
+ g_timeout_add_seconds(6, timer_func, NULL);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ g_debug("Quiting");
+
+ return 0;
+}
+
diff --git a/tests/test-json-01.json b/tests/test-json-01.json
new file mode 100644
index 0000000..08e9112
--- /dev/null
+++ b/tests/test-json-01.json
@@ -0,0 +1,4023 @@
+{
+ "id": 0,
+ "children-display": "submenu",
+ "submenu": [
+ {
+ "id": 5,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "File",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 6,
+ "enabled": true,
+ "label": "Quit",
+ "shortcut": [["Control", "q"]],
+ "visible": true
+ },
+ {
+ "id": 7,
+ "enabled": true,
+ "label": "Close all",
+ "shortcut": [["Control", "Shift", "w"]],
+ "visible": true
+ },
+ {
+ "id": 8,
+ "enabled": true,
+ "label": "Close",
+ "shortcut": [["Control", "w"]],
+ "visible": true
+ },
+ {
+ "id": 9,
+ "type": "separator"
+ },
+ {
+ "id": 10,
+ "enabled": true,
+ "label": "Send by Email...",
+ "visible": true
+ },
+ {
+ "id": 11,
+ "enabled": true,
+ "label": "Print...",
+ "shortcut": [["Control", "p"]],
+ "visible": true
+ },
+ {
+ "id": 12,
+ "enabled": true,
+ "label": "Page Setup",
+ "visible": true
+ },
+ {
+ "id": 13,
+ "type": "separator"
+ },
+ {
+ "id": 14,
+ "enabled": true,
+ "label": "Revert",
+ "visible": true
+ },
+ {
+ "id": 15,
+ "enabled": true,
+ "label": "Save as Template...",
+ "visible": true
+ },
+ {
+ "id": 16,
+ "enabled": true,
+ "label": "Save a Copy...",
+ "visible": true
+ },
+ {
+ "id": 17,
+ "enabled": true,
+ "label": "Save As...",
+ "shortcut": [["Control", "Shift", "s"]],
+ "visible": true
+ },
+ {
+ "id": 18,
+ "enabled": true,
+ "label": "Save",
+ "shortcut": [["Control", "s"]],
+ "visible": true
+ },
+ {
+ "id": 19,
+ "type": "separator"
+ },
+ {
+ "id": 20,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Open Recent",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 21,
+ "enabled": true,
+ "label": "Document History",
+ "visible": true
+ },
+ {
+ "id": 22,
+ "type": "separator"
+ },
+ {
+ "id": 23,
+ "enabled": true,
+ "label": "giggity.jpg",
+ "shortcut": [["Control", "2"]],
+ "visible": true
+ },
+ {
+ "id": 24,
+ "enabled": true,
+ "label": "Icon Height.svg",
+ "shortcut": [["Control", "1"]],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 25,
+ "enabled": true,
+ "label": "Open Location...",
+ "visible": true
+ },
+ {
+ "id": 26,
+ "enabled": true,
+ "label": "Open as Layers...",
+ "shortcut": [["Control", "Alt", "o"]],
+ "visible": true
+ },
+ {
+ "id": 27,
+ "enabled": true,
+ "label": "Open...",
+ "shortcut": [["Control", "o"]],
+ "visible": true
+ },
+ {
+ "id": 28,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Create",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 29,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Web Page Themes",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 30,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Classic.Gimp.Org",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 31,
+ "enabled": true,
+ "label": "Tube Sub-Sub-Button Label...",
+ "visible": true
+ },
+ {
+ "id": 32,
+ "enabled": true,
+ "label": "Tube Sub-Button Label...",
+ "visible": true
+ },
+ {
+ "id": 33,
+ "enabled": true,
+ "label": "Tube Button Label...",
+ "visible": true
+ },
+ {
+ "id": 34,
+ "enabled": true,
+ "label": "Small Header...",
+ "visible": true
+ },
+ {
+ "id": 35,
+ "enabled": true,
+ "label": "General Tube Labels...",
+ "visible": true
+ },
+ {
+ "id": 36,
+ "enabled": true,
+ "label": "Big Header...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 37,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Beveled Pattern",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 38,
+ "enabled": true,
+ "label": "Hrule...",
+ "visible": true
+ },
+ {
+ "id": 39,
+ "enabled": true,
+ "label": "Heading...",
+ "visible": true
+ },
+ {
+ "id": 40,
+ "enabled": true,
+ "label": "Button...",
+ "visible": true
+ },
+ {
+ "id": 41,
+ "enabled": true,
+ "label": "Bullet...",
+ "visible": true
+ },
+ {
+ "id": 42,
+ "enabled": true,
+ "label": "Arrow...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 43,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Alien Glow",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 44,
+ "enabled": true,
+ "label": "Hrule...",
+ "visible": true
+ },
+ {
+ "id": 45,
+ "enabled": true,
+ "label": "Button...",
+ "visible": true
+ },
+ {
+ "id": 46,
+ "enabled": true,
+ "label": "Bullet...",
+ "visible": true
+ },
+ {
+ "id": 47,
+ "enabled": true,
+ "label": "Arrow...",
+ "visible": true
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": 48,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Patterns",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 49,
+ "enabled": true,
+ "label": "Truchet...",
+ "visible": true
+ },
+ {
+ "id": 50,
+ "enabled": true,
+ "label": "Swirly...",
+ "visible": true
+ },
+ {
+ "id": 51,
+ "enabled": true,
+ "label": "Swirl-Tile...",
+ "visible": true
+ },
+ {
+ "id": 52,
+ "enabled": true,
+ "label": "Render Map...",
+ "visible": true
+ },
+ {
+ "id": 53,
+ "enabled": true,
+ "label": "Land...",
+ "visible": true
+ },
+ {
+ "id": 54,
+ "enabled": true,
+ "label": "Flatland...",
+ "visible": true
+ },
+ {
+ "id": 55,
+ "enabled": true,
+ "label": "Camouflage...",
+ "visible": true
+ },
+ {
+ "id": 56,
+ "enabled": true,
+ "label": "3D Truchet...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 57,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Logos",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 58,
+ "enabled": true,
+ "label": "Web Title Header...",
+ "visible": true
+ },
+ {
+ "id": 59,
+ "enabled": true,
+ "label": "Textured...",
+ "visible": true
+ },
+ {
+ "id": 60,
+ "enabled": true,
+ "label": "Text Circle...",
+ "visible": true
+ },
+ {
+ "id": 61,
+ "enabled": true,
+ "label": "Starscape...",
+ "visible": true
+ },
+ {
+ "id": 62,
+ "enabled": true,
+ "label": "Speed Text...",
+ "visible": true
+ },
+ {
+ "id": 63,
+ "enabled": true,
+ "label": "SOTA Chrome...",
+ "visible": true
+ },
+ {
+ "id": 64,
+ "enabled": true,
+ "label": "Particle Trace...",
+ "visible": true
+ },
+ {
+ "id": 65,
+ "enabled": true,
+ "label": "Newsprint Text...",
+ "visible": true
+ },
+ {
+ "id": 66,
+ "enabled": true,
+ "label": "Neon...",
+ "visible": true
+ },
+ {
+ "id": 67,
+ "enabled": true,
+ "label": "Imigre-26...",
+ "visible": true
+ },
+ {
+ "id": 68,
+ "enabled": true,
+ "label": "Gradient Bevel...",
+ "visible": true
+ },
+ {
+ "id": 69,
+ "enabled": true,
+ "label": "Glowing Hot...",
+ "visible": true
+ },
+ {
+ "id": 70,
+ "enabled": true,
+ "label": "Glossy...",
+ "visible": true
+ },
+ {
+ "id": 71,
+ "enabled": true,
+ "label": "Frosty...",
+ "visible": true
+ },
+ {
+ "id": 72,
+ "enabled": true,
+ "label": "Crystal...",
+ "visible": true
+ },
+ {
+ "id": 73,
+ "enabled": true,
+ "label": "Cool Metal...",
+ "visible": true
+ },
+ {
+ "id": 74,
+ "enabled": true,
+ "label": "Comic Book...",
+ "visible": true
+ },
+ {
+ "id": 75,
+ "enabled": true,
+ "label": "Chrome...",
+ "visible": true
+ },
+ {
+ "id": 76,
+ "enabled": true,
+ "label": "Chip Away...",
+ "visible": true
+ },
+ {
+ "id": 77,
+ "enabled": true,
+ "label": "Chalk...",
+ "visible": true
+ },
+ {
+ "id": 78,
+ "enabled": true,
+ "label": "Carved...",
+ "visible": true
+ },
+ {
+ "id": 79,
+ "enabled": true,
+ "label": "Bovination...",
+ "visible": true
+ },
+ {
+ "id": 80,
+ "enabled": true,
+ "label": "Blended...",
+ "visible": true
+ },
+ {
+ "id": 81,
+ "enabled": true,
+ "label": "Basic I...",
+ "visible": true
+ },
+ {
+ "id": 82,
+ "enabled": true,
+ "label": "Basic II...",
+ "visible": true
+ },
+ {
+ "id": 83,
+ "enabled": true,
+ "label": "Alien Neon...",
+ "visible": true
+ },
+ {
+ "id": 84,
+ "enabled": true,
+ "label": "Alien Glow...",
+ "visible": true
+ },
+ {
+ "id": 85,
+ "enabled": true,
+ "label": "3D Outline...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 86,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Buttons",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 87,
+ "enabled": true,
+ "label": "Simple Beveled Button...",
+ "visible": true
+ },
+ {
+ "id": 88,
+ "enabled": true,
+ "label": "Round Button...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 89,
+ "type": "separator"
+ },
+ {
+ "id": 90,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "xscanimage",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 91,
+ "enabled": false,
+ "label": "Device dialog...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 92,
+ "enabled": true,
+ "label": "Screenshot...",
+ "visible": true
+ },
+ {
+ "id": 93,
+ "enabled": true,
+ "label": "From Clipboard",
+ "shortcut": [["Control", "Shift", "v"]],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 94,
+ "enabled": true,
+ "label": "New...",
+ "shortcut": [["Control", "n"]],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 95,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Edit",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 96,
+ "enabled": true,
+ "label": "Units",
+ "visible": true
+ },
+ {
+ "id": 97,
+ "enabled": true,
+ "label": "Modules",
+ "visible": true
+ },
+ {
+ "id": 98,
+ "enabled": true,
+ "label": "Keyboard Shortcuts",
+ "visible": true
+ },
+ {
+ "id": 99,
+ "enabled": true,
+ "label": "Preferences",
+ "visible": true
+ },
+ {
+ "id": 100,
+ "type": "separator"
+ },
+ {
+ "id": 101,
+ "enabled": false,
+ "label": "Stroke Path...",
+ "visible": true
+ },
+ {
+ "id": 102,
+ "enabled": false,
+ "label": "Stroke Selection...",
+ "visible": true
+ },
+ {
+ "id": 103,
+ "enabled": true,
+ "label": "Fill with Pattern",
+ "shortcut": [["Control", "semicolon"]],
+ "visible": true
+ },
+ {
+ "id": 104,
+ "enabled": true,
+ "label": "Fill with BG Color",
+ "shortcut": [["Control", "period"]],
+ "visible": true
+ },
+ {
+ "id": 105,
+ "enabled": true,
+ "label": "Fill with FG Color",
+ "shortcut": [["Control", "comma"]],
+ "visible": true
+ },
+ {
+ "id": 106,
+ "enabled": true,
+ "label": "Clear",
+ "shortcut": [["Delete"]],
+ "visible": true
+ },
+ {
+ "id": 107,
+ "type": "separator"
+ },
+ {
+ "id": 108,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Buffer",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 109,
+ "enabled": true,
+ "label": "Paste Named...",
+ "visible": true
+ },
+ {
+ "id": 110,
+ "enabled": true,
+ "label": "Copy Visible Named...",
+ "visible": true
+ },
+ {
+ "id": 111,
+ "enabled": true,
+ "label": "Copy Named...",
+ "visible": true
+ },
+ {
+ "id": 112,
+ "enabled": true,
+ "label": "Cut Named...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 113,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Paste as",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 114,
+ "enabled": true,
+ "label": "New Pattern...",
+ "visible": true
+ },
+ {
+ "id": 115,
+ "enabled": true,
+ "label": "New Brush...",
+ "visible": true
+ },
+ {
+ "id": 116,
+ "enabled": true,
+ "label": "New Layer",
+ "visible": true
+ },
+ {
+ "id": 117,
+ "enabled": true,
+ "label": "New Image",
+ "shortcut": [["Control", "Shift", "v"]],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 118,
+ "enabled": true,
+ "label": "Paste Into",
+ "visible": true
+ },
+ {
+ "id": 119,
+ "enabled": true,
+ "label": "Paste",
+ "shortcut": [["Control", "v"]],
+ "visible": true
+ },
+ {
+ "id": 120,
+ "enabled": true,
+ "label": "Copy Visible",
+ "shortcut": [["Control", "Shift", "c"]],
+ "visible": true
+ },
+ {
+ "id": 121,
+ "enabled": true,
+ "label": "Copy",
+ "shortcut": [["Control", "c"]],
+ "visible": true
+ },
+ {
+ "id": 122,
+ "enabled": true,
+ "label": "Cut",
+ "shortcut": [["Control", "x"]],
+ "visible": true
+ },
+ {
+ "id": 123,
+ "type": "separator"
+ },
+ {
+ "id": 124,
+ "enabled": true,
+ "label": "Undo History",
+ "visible": true
+ },
+ {
+ "id": 3,
+ "enabled": false,
+ "label": "_Fade...",
+ "visible": true
+ },
+ {
+ "id": 2,
+ "enabled": false,
+ "label": "_Redo",
+ "shortcut": [["Control", "y"]],
+ "visible": true
+ },
+ {
+ "id": 1,
+ "enabled": false,
+ "label": "_Undo",
+ "shortcut": [["Control", "z"]],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 125,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Select",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 126,
+ "enabled": false,
+ "label": "To Path",
+ "visible": true
+ },
+ {
+ "id": 127,
+ "enabled": true,
+ "label": "Save to Channel",
+ "visible": true
+ },
+ {
+ "id": 128,
+ "enabled": true,
+ "label": "Toggle Quick Mask",
+ "shortcut": [["Shift", "q"]],
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 129,
+ "type": "separator"
+ },
+ {
+ "id": 130,
+ "enabled": true,
+ "label": "Distort...",
+ "visible": true
+ },
+ {
+ "id": 131,
+ "enabled": false,
+ "label": "Border...",
+ "visible": true
+ },
+ {
+ "id": 132,
+ "enabled": false,
+ "label": "Grow...",
+ "visible": true
+ },
+ {
+ "id": 133,
+ "enabled": false,
+ "label": "Shrink...",
+ "visible": true
+ },
+ {
+ "id": 134,
+ "enabled": false,
+ "label": "Sharpen",
+ "visible": true
+ },
+ {
+ "id": 135,
+ "enabled": false,
+ "label": "Feather...",
+ "visible": true
+ },
+ {
+ "id": 136,
+ "type": "separator"
+ },
+ {
+ "id": 137,
+ "enabled": true,
+ "label": "Selection Editor",
+ "visible": true
+ },
+ {
+ "id": 138,
+ "enabled": false,
+ "label": "From Path",
+ "shortcut": [["Shift", "v"]],
+ "visible": true
+ },
+ {
+ "id": 139,
+ "enabled": true,
+ "label": "By Color",
+ "shortcut": [["Shift", "o"]],
+ "visible": true
+ },
+ {
+ "id": 140,
+ "enabled": false,
+ "label": "Float",
+ "shortcut": [["Control", "Shift", "l"]],
+ "visible": true
+ },
+ {
+ "id": 141,
+ "enabled": true,
+ "label": "Invert",
+ "shortcut": [["Control", "i"]],
+ "visible": true
+ },
+ {
+ "id": 142,
+ "enabled": false,
+ "label": "None",
+ "shortcut": [["Control", "Shift", "a"]],
+ "visible": true
+ },
+ {
+ "id": 143,
+ "enabled": true,
+ "label": "All",
+ "shortcut": [["Control", "a"]],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 144,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "View",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 145,
+ "enabled": true,
+ "label": "Show Statusbar",
+ "toggle-state": 1,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 146,
+ "enabled": true,
+ "label": "Show Scrollbars",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 147,
+ "enabled": true,
+ "label": "Show Rulers",
+ "shortcut": [["Control", "Shift", "r"]],
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 148,
+ "enabled": true,
+ "label": "Show Menubar",
+ "toggle-state": 1,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 149,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Padding Color",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 150,
+ "enabled": true,
+ "label": "As in Preferences",
+ "visible": true
+ },
+ {
+ "id": 151,
+ "type": "separator"
+ },
+ {
+ "id": 152,
+ "enabled": true,
+ "label": "Select Custom Color...",
+ "visible": true
+ },
+ {
+ "id": 153,
+ "enabled": true,
+ "label": "Dark Check Color",
+ "visible": true
+ },
+ {
+ "id": 154,
+ "enabled": true,
+ "label": "Light Check Color",
+ "visible": true
+ },
+ {
+ "id": 155,
+ "enabled": true,
+ "label": "From Theme",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 156,
+ "type": "separator"
+ },
+ {
+ "id": 157,
+ "enabled": true,
+ "label": "Snap to Active Path",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 158,
+ "enabled": true,
+ "label": "Snap to Canvas Edges",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 159,
+ "enabled": true,
+ "label": "Snap to Grid",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 160,
+ "enabled": true,
+ "label": "Snap to Guides",
+ "toggle-state": 1,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 161,
+ "type": "separator"
+ },
+ {
+ "id": 162,
+ "enabled": true,
+ "label": "Show Sample Points",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 163,
+ "enabled": true,
+ "label": "Show Grid",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 164,
+ "enabled": true,
+ "label": "Show Guides",
+ "shortcut": [["Control", "Shift", "t"]],
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 165,
+ "enabled": true,
+ "label": "Show Layer Boundary",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 166,
+ "enabled": true,
+ "label": "Show Selection",
+ "shortcut": [["Control", "t"]],
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 167,
+ "type": "separator"
+ },
+ {
+ "id": 168,
+ "enabled": true,
+ "label": "Display Filters...",
+ "visible": true
+ },
+ {
+ "id": 169,
+ "enabled": true,
+ "label": "Navigation Window",
+ "visible": true
+ },
+ {
+ "id": 170,
+ "type": "separator"
+ },
+ {
+ "id": 171,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Fullscreen",
+ "shortcut": [["F11"]],
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 172,
+ "enabled": true,
+ "label": "Open Display...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 173,
+ "enabled": true,
+ "label": "Shrink Wrap",
+ "shortcut": [["Control", "e"]],
+ "visible": true
+ },
+ {
+ "id": 174,
+ "type": "separator"
+ },
+ {
+ "id": 175,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "_Zoom (67%)",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 176,
+ "enabled": true,
+ "label": "Othe_r (67%)...",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 177,
+ "type": "separator"
+ },
+ {
+ "id": 178,
+ "enabled": true,
+ "label": "1:16 (6.25%)",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 179,
+ "enabled": true,
+ "label": "1:8 (12.5%)",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 180,
+ "enabled": true,
+ "label": "1:4 (25%)",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 181,
+ "enabled": true,
+ "label": "1:2 (50%)",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 182,
+ "enabled": true,
+ "label": "1:1 (100%)",
+ "shortcut": [["1"]],
+ "toggle-state": 1,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 183,
+ "enabled": true,
+ "label": "2:1 (200%)",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 184,
+ "enabled": true,
+ "label": "4:1 (400%)",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 185,
+ "enabled": true,
+ "label": "8:1 (800%)",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 186,
+ "enabled": true,
+ "label": "16:1 (1600%)",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 187,
+ "type": "separator"
+ },
+ {
+ "id": 188,
+ "enabled": true,
+ "label": "Fill Window",
+ "visible": true
+ },
+ {
+ "id": 189,
+ "enabled": true,
+ "label": "Fit Image in Window",
+ "shortcut": [["Control", "Shift", "e"]],
+ "visible": true
+ },
+ {
+ "id": 190,
+ "enabled": true,
+ "label": "Zoom In",
+ "shortcut": [["plus"]],
+ "visible": true
+ },
+ {
+ "id": 191,
+ "enabled": true,
+ "label": "Zoom Out",
+ "shortcut": [["minus"]],
+ "visible": true
+ },
+ {
+ "id": 4,
+ "enabled": true,
+ "label": "Re_vert Zoom (67%)",
+ "shortcut": [["grave"]],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 192,
+ "enabled": true,
+ "label": "Dot for Dot",
+ "toggle-state": 1,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 193,
+ "enabled": true,
+ "label": "New View",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 194,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Image",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 195,
+ "enabled": true,
+ "label": "Image Properties",
+ "shortcut": [["Alt", "Return"]],
+ "visible": true
+ },
+ {
+ "id": 196,
+ "enabled": true,
+ "label": "Configure Grid...",
+ "visible": true
+ },
+ {
+ "id": 197,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Guides",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 198,
+ "enabled": true,
+ "label": "Remove all Guides",
+ "visible": true
+ },
+ {
+ "id": 199,
+ "enabled": true,
+ "label": "New Guides from Selection",
+ "visible": true
+ },
+ {
+ "id": 200,
+ "enabled": true,
+ "label": "New Guide...",
+ "visible": true
+ },
+ {
+ "id": 201,
+ "enabled": true,
+ "label": "New Guide (by Percent)...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 202,
+ "type": "separator"
+ },
+ {
+ "id": 203,
+ "enabled": true,
+ "label": "Align Visible Layers...",
+ "visible": true
+ },
+ {
+ "id": 204,
+ "enabled": true,
+ "label": "Flatten Image",
+ "visible": true
+ },
+ {
+ "id": 205,
+ "enabled": true,
+ "label": "Merge Visible Layers...",
+ "shortcut": [["Control", "m"]],
+ "visible": true
+ },
+ {
+ "id": 206,
+ "type": "separator"
+ },
+ {
+ "id": 207,
+ "enabled": true,
+ "label": "Zealous Crop",
+ "visible": true
+ },
+ {
+ "id": 208,
+ "enabled": true,
+ "label": "Autocrop Image",
+ "visible": true
+ },
+ {
+ "id": 209,
+ "enabled": false,
+ "label": "Crop to Selection",
+ "visible": true
+ },
+ {
+ "id": 210,
+ "type": "separator"
+ },
+ {
+ "id": 211,
+ "enabled": true,
+ "label": "Scale Image...",
+ "visible": true
+ },
+ {
+ "id": 212,
+ "enabled": true,
+ "label": "Print Size...",
+ "visible": true
+ },
+ {
+ "id": 213,
+ "enabled": false,
+ "label": "Fit Canvas to Selection",
+ "visible": true
+ },
+ {
+ "id": 214,
+ "enabled": true,
+ "label": "Fit Canvas to Layers",
+ "visible": true
+ },
+ {
+ "id": 215,
+ "enabled": true,
+ "label": "Canvas Size...",
+ "visible": true
+ },
+ {
+ "id": 216,
+ "type": "separator"
+ },
+ {
+ "id": 217,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Transform",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 218,
+ "enabled": true,
+ "label": "Guillotine",
+ "visible": true
+ },
+ {
+ "id": 219,
+ "type": "separator"
+ },
+ {
+ "id": 220,
+ "enabled": true,
+ "label": "Rotate 180\302\260",
+ "visible": true
+ },
+ {
+ "id": 221,
+ "enabled": true,
+ "label": "Rotate 90\302\260 counter-clockwise",
+ "visible": true
+ },
+ {
+ "id": 222,
+ "enabled": true,
+ "label": "Rotate 90\302\260 clockwise",
+ "visible": true
+ },
+ {
+ "id": 223,
+ "type": "separator"
+ },
+ {
+ "id": 224,
+ "enabled": true,
+ "label": "Flip Vertically",
+ "visible": true
+ },
+ {
+ "id": 225,
+ "enabled": true,
+ "label": "Flip Horizontally",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 226,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Mode",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 227,
+ "enabled": true,
+ "label": "Convert to Color Profile...",
+ "visible": true
+ },
+ {
+ "id": 228,
+ "enabled": true,
+ "label": "Assign Color Profile...",
+ "visible": true
+ },
+ {
+ "id": 229,
+ "type": "separator"
+ },
+ {
+ "id": 230,
+ "enabled": true,
+ "label": "Indexed...",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 231,
+ "enabled": true,
+ "label": "Grayscale",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 232,
+ "enabled": true,
+ "label": "RGB",
+ "toggle-state": 1,
+ "toggle-type": "checkmark",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 233,
+ "enabled": true,
+ "label": "Duplicate",
+ "shortcut": [["Control", "d"]],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 234,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Layer",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 235,
+ "enabled": true,
+ "label": "Autocrop Layer",
+ "visible": true
+ },
+ {
+ "id": 236,
+ "enabled": false,
+ "label": "Crop to Selection",
+ "visible": true
+ },
+ {
+ "id": 237,
+ "enabled": true,
+ "label": "Scale Layer...",
+ "visible": true
+ },
+ {
+ "id": 238,
+ "enabled": true,
+ "label": "Layer to Image Size",
+ "visible": true
+ },
+ {
+ "id": 239,
+ "enabled": true,
+ "label": "Layer Boundary Size...",
+ "visible": true
+ },
+ {
+ "id": 240,
+ "type": "separator"
+ },
+ {
+ "id": 241,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Transform",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 242,
+ "enabled": true,
+ "label": "Offset...",
+ "shortcut": [["Control", "Shift", "o"]],
+ "visible": true
+ },
+ {
+ "id": 243,
+ "type": "separator"
+ },
+ {
+ "id": 244,
+ "enabled": true,
+ "label": "Arbitrary Rotation...",
+ "visible": true
+ },
+ {
+ "id": 245,
+ "enabled": true,
+ "label": "Rotate 180\302\260",
+ "visible": true
+ },
+ {
+ "id": 246,
+ "enabled": true,
+ "label": "Rotate 90\302\260 counter-clockwise",
+ "visible": true
+ },
+ {
+ "id": 247,
+ "enabled": true,
+ "label": "Rotate 90\302\260 clockwise",
+ "visible": true
+ },
+ {
+ "id": 248,
+ "type": "separator"
+ },
+ {
+ "id": 249,
+ "enabled": true,
+ "label": "Flip Vertically",
+ "visible": true
+ },
+ {
+ "id": 250,
+ "enabled": true,
+ "label": "Flip Horizontally",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 251,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Transparency",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 252,
+ "enabled": true,
+ "label": "Intersect with Selection",
+ "visible": true
+ },
+ {
+ "id": 253,
+ "enabled": true,
+ "label": "Subtract from Selection",
+ "visible": true
+ },
+ {
+ "id": 254,
+ "enabled": true,
+ "label": "Add to Selection",
+ "visible": true
+ },
+ {
+ "id": 255,
+ "enabled": true,
+ "label": "Alpha to Selection",
+ "visible": true
+ },
+ {
+ "id": 256,
+ "type": "separator"
+ },
+ {
+ "id": 257,
+ "enabled": true,
+ "label": "Threshold Alpha...",
+ "visible": true
+ },
+ {
+ "id": 258,
+ "enabled": true,
+ "label": "Semi-Flatten",
+ "visible": true
+ },
+ {
+ "id": 259,
+ "enabled": true,
+ "label": "Color to Alpha...",
+ "visible": true
+ },
+ {
+ "id": 260,
+ "enabled": true,
+ "label": "Remove Alpha Channel",
+ "visible": true
+ },
+ {
+ "id": 261,
+ "enabled": false,
+ "label": "Add Alpha Channel",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 262,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Mask",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 263,
+ "enabled": false,
+ "label": "Intersect with Selection",
+ "visible": true
+ },
+ {
+ "id": 264,
+ "enabled": false,
+ "label": "Subtract from Selection",
+ "visible": true
+ },
+ {
+ "id": 265,
+ "enabled": false,
+ "label": "Add to Selection",
+ "visible": true
+ },
+ {
+ "id": 266,
+ "enabled": false,
+ "label": "Mask to Selection",
+ "visible": true
+ },
+ {
+ "id": 267,
+ "type": "separator"
+ },
+ {
+ "id": 268,
+ "enabled": false,
+ "label": "Disable Layer Mask",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 269,
+ "enabled": false,
+ "label": "Edit Layer Mask",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 270,
+ "enabled": false,
+ "label": "Show Layer Mask",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 271,
+ "type": "separator"
+ },
+ {
+ "id": 272,
+ "enabled": false,
+ "label": "Delete Layer Mask",
+ "visible": true
+ },
+ {
+ "id": 273,
+ "enabled": false,
+ "label": "Apply Layer Mask",
+ "visible": true
+ },
+ {
+ "id": 274,
+ "enabled": true,
+ "label": "Add Layer Mask...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 275,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Stack",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 276,
+ "enabled": true,
+ "label": "Reverse Layer Order",
+ "visible": true
+ },
+ {
+ "id": 277,
+ "type": "separator"
+ },
+ {
+ "id": 278,
+ "enabled": false,
+ "label": "Layer to Bottom",
+ "visible": true
+ },
+ {
+ "id": 279,
+ "enabled": false,
+ "label": "Layer to Top",
+ "visible": true
+ },
+ {
+ "id": 280,
+ "enabled": false,
+ "label": "Lower Layer",
+ "visible": true
+ },
+ {
+ "id": 281,
+ "enabled": false,
+ "label": "Raise Layer",
+ "visible": true
+ },
+ {
+ "id": 282,
+ "type": "separator"
+ },
+ {
+ "id": 283,
+ "enabled": false,
+ "label": "Select Bottom Layer",
+ "shortcut": [["End"]],
+ "visible": true
+ },
+ {
+ "id": 284,
+ "enabled": false,
+ "label": "Select Top Layer",
+ "shortcut": [["Home"]],
+ "visible": true
+ },
+ {
+ "id": 285,
+ "enabled": false,
+ "label": "Select Next Layer",
+ "shortcut": [["Page_Down"]],
+ "visible": true
+ },
+ {
+ "id": 286,
+ "enabled": false,
+ "label": "Select Previous Layer",
+ "shortcut": [["Page_Up"]],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 287,
+ "children-display": "submenu",
+ "type": "separator",
+ "submenu": [
+ {
+ "id": 288,
+ "enabled": false,
+ "label": "Empty",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 289,
+ "enabled": true,
+ "label": "Delete Layer",
+ "visible": true
+ },
+ {
+ "id": 290,
+ "enabled": false,
+ "label": "Merge Down",
+ "visible": true
+ },
+ {
+ "id": 291,
+ "enabled": false,
+ "label": "Anchor Layer",
+ "shortcut": [["Control", "h"]],
+ "visible": true
+ },
+ {
+ "id": 292,
+ "enabled": true,
+ "label": "Duplicate Layer",
+ "shortcut": [["Control", "Shift", "d"]],
+ "visible": true
+ },
+ {
+ "id": 293,
+ "enabled": true,
+ "label": "New from Visible",
+ "visible": true
+ },
+ {
+ "id": 294,
+ "enabled": true,
+ "label": "New Layer...",
+ "shortcut": [["Control", "Shift", "n"]],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 295,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Colors",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 296,
+ "enabled": true,
+ "label": "Retinex...",
+ "visible": true
+ },
+ {
+ "id": 297,
+ "enabled": true,
+ "label": "Maximum RGB...",
+ "visible": true
+ },
+ {
+ "id": 298,
+ "enabled": false,
+ "label": "Hot...",
+ "visible": true
+ },
+ {
+ "id": 299,
+ "enabled": true,
+ "label": "Filter Pack...",
+ "visible": true
+ },
+ {
+ "id": 300,
+ "enabled": true,
+ "label": "Color to Alpha...",
+ "visible": true
+ },
+ {
+ "id": 301,
+ "enabled": true,
+ "label": "Colorify...",
+ "visible": true
+ },
+ {
+ "id": 302,
+ "type": "separator"
+ },
+ {
+ "id": 303,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Info",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 304,
+ "enabled": true,
+ "label": "Smooth Palette...",
+ "visible": true
+ },
+ {
+ "id": 305,
+ "enabled": true,
+ "label": "Colorcube Analysis...",
+ "visible": true
+ },
+ {
+ "id": 306,
+ "enabled": true,
+ "label": "Border Average...",
+ "visible": true
+ },
+ {
+ "id": 307,
+ "enabled": true,
+ "label": "Histogram",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 308,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Map",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 309,
+ "enabled": true,
+ "label": "Sample Colorize...",
+ "visible": true
+ },
+ {
+ "id": 310,
+ "enabled": true,
+ "label": "Rotate Colors...",
+ "visible": true
+ },
+ {
+ "id": 311,
+ "enabled": true,
+ "label": "Palette Map",
+ "visible": true
+ },
+ {
+ "id": 312,
+ "enabled": true,
+ "label": "Gradient Map",
+ "visible": true
+ },
+ {
+ "id": 313,
+ "enabled": true,
+ "label": "Color Exchange...",
+ "visible": true
+ },
+ {
+ "id": 314,
+ "enabled": true,
+ "label": "Alien Map...",
+ "visible": true
+ },
+ {
+ "id": 315,
+ "type": "separator"
+ },
+ {
+ "id": 316,
+ "enabled": false,
+ "label": "Set Colormap...",
+ "visible": true
+ },
+ {
+ "id": 317,
+ "enabled": false,
+ "label": "Rearrange Colormap...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 318,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Components",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 319,
+ "enabled": false,
+ "label": "Recompose",
+ "visible": true
+ },
+ {
+ "id": 320,
+ "enabled": true,
+ "label": "Decompose...",
+ "visible": true
+ },
+ {
+ "id": 321,
+ "enabled": false,
+ "label": "Compose...",
+ "visible": true
+ },
+ {
+ "id": 322,
+ "enabled": true,
+ "label": "Channel Mixer...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 323,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Auto",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 324,
+ "enabled": true,
+ "label": "Stretch HSV",
+ "visible": true
+ },
+ {
+ "id": 325,
+ "enabled": true,
+ "label": "Stretch Contrast",
+ "visible": true
+ },
+ {
+ "id": 326,
+ "enabled": true,
+ "label": "Normalize",
+ "visible": true
+ },
+ {
+ "id": 327,
+ "enabled": true,
+ "label": "Color Enhance",
+ "visible": true
+ },
+ {
+ "id": 328,
+ "enabled": true,
+ "label": "White Balance",
+ "visible": true
+ },
+ {
+ "id": 329,
+ "enabled": true,
+ "label": "Equalize",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 330,
+ "type": "separator"
+ },
+ {
+ "id": 331,
+ "enabled": true,
+ "label": "Use GEGL",
+ "toggle-state": 0,
+ "toggle-type": "checkmark",
+ "visible": true
+ },
+ {
+ "id": 332,
+ "type": "separator"
+ },
+ {
+ "id": 333,
+ "enabled": true,
+ "label": "Value Invert",
+ "visible": true
+ },
+ {
+ "id": 334,
+ "enabled": true,
+ "label": "Invert",
+ "visible": true
+ },
+ {
+ "id": 335,
+ "type": "separator"
+ },
+ {
+ "id": 336,
+ "enabled": true,
+ "label": "Desaturate...",
+ "visible": true
+ },
+ {
+ "id": 337,
+ "enabled": true,
+ "label": "Posterize...",
+ "visible": true
+ },
+ {
+ "id": 338,
+ "enabled": true,
+ "label": "Curves...",
+ "visible": true
+ },
+ {
+ "id": 339,
+ "enabled": true,
+ "label": "Levels...",
+ "visible": true
+ },
+ {
+ "id": 340,
+ "enabled": true,
+ "label": "Threshold...",
+ "visible": true
+ },
+ {
+ "id": 341,
+ "enabled": true,
+ "label": "Brightness-Contrast...",
+ "visible": true
+ },
+ {
+ "id": 342,
+ "enabled": true,
+ "label": "Colorize...",
+ "visible": true
+ },
+ {
+ "id": 343,
+ "enabled": true,
+ "label": "Hue-Saturation...",
+ "visible": true
+ },
+ {
+ "id": 344,
+ "enabled": true,
+ "label": "Color Balance...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 345,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Tools",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 346,
+ "enabled": true,
+ "label": "Swap Colors",
+ "shortcut": [["x"]],
+ "visible": true
+ },
+ {
+ "id": 347,
+ "enabled": true,
+ "label": "Default Colors",
+ "shortcut": [["d"]],
+ "visible": true
+ },
+ {
+ "id": 348,
+ "enabled": true,
+ "label": "Toolbox",
+ "shortcut": [["Control", "b"]],
+ "visible": true
+ },
+ {
+ "id": 349,
+ "type": "separator"
+ },
+ {
+ "id": 350,
+ "enabled": true,
+ "label": "GEGL Operation...",
+ "visible": true
+ },
+ {
+ "id": 351,
+ "enabled": true,
+ "label": "Text",
+ "shortcut": [["t"]],
+ "visible": true
+ },
+ {
+ "id": 352,
+ "enabled": true,
+ "label": "Measure",
+ "shortcut": [["Shift", "m"]],
+ "visible": true
+ },
+ {
+ "id": 353,
+ "enabled": true,
+ "label": "Zoom",
+ "shortcut": [["z"]],
+ "visible": true
+ },
+ {
+ "id": 354,
+ "enabled": true,
+ "label": "Color Picker",
+ "shortcut": [["o"]],
+ "visible": true
+ },
+ {
+ "id": 355,
+ "enabled": true,
+ "label": "Paths",
+ "shortcut": [["b"]],
+ "visible": true
+ },
+ {
+ "id": 356,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Color Tools",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 357,
+ "enabled": true,
+ "label": "Desaturate...",
+ "visible": true
+ },
+ {
+ "id": 358,
+ "enabled": true,
+ "label": "Posterize...",
+ "visible": true
+ },
+ {
+ "id": 359,
+ "enabled": true,
+ "label": "Curves...",
+ "visible": true
+ },
+ {
+ "id": 360,
+ "enabled": true,
+ "label": "Levels...",
+ "visible": true
+ },
+ {
+ "id": 361,
+ "enabled": true,
+ "label": "Threshold...",
+ "visible": true
+ },
+ {
+ "id": 362,
+ "enabled": true,
+ "label": "Brightness-Contrast...",
+ "visible": true
+ },
+ {
+ "id": 363,
+ "enabled": true,
+ "label": "Colorize...",
+ "visible": true
+ },
+ {
+ "id": 364,
+ "enabled": true,
+ "label": "Hue-Saturation...",
+ "visible": true
+ },
+ {
+ "id": 365,
+ "enabled": true,
+ "label": "Color Balance...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 366,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Transform Tools",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 367,
+ "enabled": true,
+ "label": "Flip",
+ "shortcut": [["Shift", "f"]],
+ "visible": true
+ },
+ {
+ "id": 368,
+ "enabled": true,
+ "label": "Perspective",
+ "shortcut": [["Shift", "p"]],
+ "visible": true
+ },
+ {
+ "id": 369,
+ "enabled": true,
+ "label": "Shear",
+ "shortcut": [["Shift", "s"]],
+ "visible": true
+ },
+ {
+ "id": 370,
+ "enabled": true,
+ "label": "Scale",
+ "shortcut": [["Shift", "t"]],
+ "visible": true
+ },
+ {
+ "id": 371,
+ "enabled": true,
+ "label": "Rotate",
+ "shortcut": [["Shift", "r"]],
+ "visible": true
+ },
+ {
+ "id": 372,
+ "enabled": true,
+ "label": "Crop",
+ "shortcut": [["Shift", "c"]],
+ "visible": true
+ },
+ {
+ "id": 373,
+ "enabled": true,
+ "label": "Move",
+ "shortcut": [["m"]],
+ "visible": true
+ },
+ {
+ "id": 374,
+ "enabled": true,
+ "label": "Align",
+ "shortcut": [["q"]],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 375,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Paint Tools",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 376,
+ "enabled": true,
+ "label": "Dodge / Burn",
+ "shortcut": [["Shift", "d"]],
+ "visible": true
+ },
+ {
+ "id": 377,
+ "enabled": true,
+ "label": "Smudge",
+ "shortcut": [["s"]],
+ "visible": true
+ },
+ {
+ "id": 378,
+ "enabled": true,
+ "label": "Blur / Sharpen",
+ "shortcut": [["Shift", "u"]],
+ "visible": true
+ },
+ {
+ "id": 379,
+ "enabled": true,
+ "label": "Perspective Clone",
+ "visible": true
+ },
+ {
+ "id": 380,
+ "enabled": true,
+ "label": "Heal",
+ "shortcut": [["h"]],
+ "visible": true
+ },
+ {
+ "id": 381,
+ "enabled": true,
+ "label": "Clone",
+ "shortcut": [["c"]],
+ "visible": true
+ },
+ {
+ "id": 382,
+ "enabled": true,
+ "label": "Ink",
+ "shortcut": [["k"]],
+ "visible": true
+ },
+ {
+ "id": 383,
+ "enabled": true,
+ "label": "Airbrush",
+ "shortcut": [["a"]],
+ "visible": true
+ },
+ {
+ "id": 384,
+ "enabled": true,
+ "label": "Eraser",
+ "shortcut": [["Shift", "e"]],
+ "visible": true
+ },
+ {
+ "id": 385,
+ "enabled": true,
+ "label": "Paintbrush",
+ "shortcut": [["p"]],
+ "visible": true
+ },
+ {
+ "id": 386,
+ "enabled": true,
+ "label": "Pencil",
+ "shortcut": [["n"]],
+ "visible": true
+ },
+ {
+ "id": 387,
+ "enabled": true,
+ "label": "Blend",
+ "shortcut": [["l"]],
+ "visible": true
+ },
+ {
+ "id": 388,
+ "enabled": true,
+ "label": "Bucket Fill",
+ "shortcut": [["Shift", "b"]],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 389,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Selection Tools",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 390,
+ "enabled": true,
+ "label": "Intelligent Scissors",
+ "shortcut": [["i"]],
+ "visible": true
+ },
+ {
+ "id": 391,
+ "enabled": true,
+ "label": "By Color Select",
+ "shortcut": [["Shift", "o"]],
+ "visible": true
+ },
+ {
+ "id": 392,
+ "enabled": true,
+ "label": "Fuzzy Select",
+ "shortcut": [["u"]],
+ "visible": true
+ },
+ {
+ "id": 393,
+ "enabled": true,
+ "label": "Foreground Select",
+ "visible": true
+ },
+ {
+ "id": 394,
+ "enabled": true,
+ "label": "Free Select",
+ "shortcut": [["f"]],
+ "visible": true
+ },
+ {
+ "id": 395,
+ "enabled": true,
+ "label": "Ellipse Select",
+ "shortcut": [["e"]],
+ "visible": true
+ },
+ {
+ "id": 396,
+ "enabled": true,
+ "label": "Rectangle Select",
+ "shortcut": [["r"]],
+ "visible": true
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": 397,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Filters",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 398,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Script-Fu",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 399,
+ "enabled": true,
+ "label": "Start Server...",
+ "visible": true
+ },
+ {
+ "id": 400,
+ "enabled": true,
+ "label": "Refresh Scripts",
+ "visible": true
+ },
+ {
+ "id": 401,
+ "enabled": true,
+ "label": "Console",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 402,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Python-Fu",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 403,
+ "enabled": true,
+ "label": "Console",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 404,
+ "type": "separator"
+ },
+ {
+ "id": 405,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Alpha to Logo",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 406,
+ "enabled": true,
+ "label": "Textured...",
+ "visible": true
+ },
+ {
+ "id": 407,
+ "enabled": true,
+ "label": "Particle Trace...",
+ "visible": true
+ },
+ {
+ "id": 408,
+ "enabled": true,
+ "label": "Neon...",
+ "visible": true
+ },
+ {
+ "id": 409,
+ "enabled": true,
+ "label": "Gradient Bevel...",
+ "visible": true
+ },
+ {
+ "id": 410,
+ "enabled": true,
+ "label": "Glowing Hot...",
+ "visible": true
+ },
+ {
+ "id": 411,
+ "enabled": true,
+ "label": "Glossy...",
+ "visible": true
+ },
+ {
+ "id": 412,
+ "enabled": true,
+ "label": "Frosty...",
+ "visible": true
+ },
+ {
+ "id": 413,
+ "enabled": true,
+ "label": "Cool Metal...",
+ "visible": true
+ },
+ {
+ "id": 414,
+ "enabled": true,
+ "label": "Comic Book...",
+ "visible": true
+ },
+ {
+ "id": 415,
+ "enabled": true,
+ "label": "Chrome...",
+ "visible": true
+ },
+ {
+ "id": 416,
+ "enabled": true,
+ "label": "Chip Away...",
+ "visible": true
+ },
+ {
+ "id": 417,
+ "enabled": true,
+ "label": "Chalk...",
+ "visible": true
+ },
+ {
+ "id": 418,
+ "enabled": true,
+ "label": "Bovination...",
+ "visible": true
+ },
+ {
+ "id": 419,
+ "enabled": true,
+ "label": "Blended...",
+ "visible": true
+ },
+ {
+ "id": 420,
+ "enabled": true,
+ "label": "Basic I...",
+ "visible": true
+ },
+ {
+ "id": 421,
+ "enabled": true,
+ "label": "Basic II...",
+ "visible": true
+ },
+ {
+ "id": 422,
+ "enabled": true,
+ "label": "Alien Neon...",
+ "visible": true
+ },
+ {
+ "id": 423,
+ "enabled": true,
+ "label": "Alien Glow...",
+ "visible": true
+ },
+ {
+ "id": 424,
+ "enabled": true,
+ "label": "3D Outline...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 425,
+ "type": "separator"
+ },
+ {
+ "id": 426,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Animation",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 427,
+ "enabled": true,
+ "label": "Unoptimize",
+ "visible": true
+ },
+ {
+ "id": 428,
+ "enabled": true,
+ "label": "Playback...",
+ "visible": true
+ },
+ {
+ "id": 429,
+ "enabled": true,
+ "label": "Optimize (for GIF)",
+ "visible": true
+ },
+ {
+ "id": 430,
+ "enabled": true,
+ "label": "Optimize (Difference)",
+ "visible": true
+ },
+ {
+ "id": 431,
+ "type": "separator"
+ },
+ {
+ "id": 432,
+ "enabled": true,
+ "label": "Waves...",
+ "visible": true
+ },
+ {
+ "id": 433,
+ "enabled": true,
+ "label": "Spinning Globe...",
+ "visible": true
+ },
+ {
+ "id": 434,
+ "enabled": true,
+ "label": "Rippling...",
+ "visible": true
+ },
+ {
+ "id": 435,
+ "enabled": true,
+ "label": "Burn-In...",
+ "visible": true
+ },
+ {
+ "id": 436,
+ "enabled": true,
+ "label": "Blend...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 437,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Web",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 438,
+ "enabled": true,
+ "label": "Slice...",
+ "visible": true
+ },
+ {
+ "id": 439,
+ "enabled": true,
+ "label": "Semi-Flatten",
+ "visible": true
+ },
+ {
+ "id": 440,
+ "enabled": true,
+ "label": "Image Map...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 441,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Render",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 442,
+ "enabled": true,
+ "label": "Spyrogimp...",
+ "visible": true
+ },
+ {
+ "id": 443,
+ "enabled": true,
+ "label": "Sphere Designer...",
+ "visible": true
+ },
+ {
+ "id": 444,
+ "enabled": true,
+ "label": "Line Nova...",
+ "visible": true
+ },
+ {
+ "id": 445,
+ "enabled": true,
+ "label": "Lava...",
+ "visible": true
+ },
+ {
+ "id": 446,
+ "enabled": true,
+ "label": "Gfig...",
+ "visible": true
+ },
+ {
+ "id": 447,
+ "enabled": true,
+ "label": "Fractal Explorer...",
+ "visible": true
+ },
+ {
+ "id": 448,
+ "enabled": true,
+ "label": "Circuit...",
+ "visible": true
+ },
+ {
+ "id": 449,
+ "type": "separator"
+ },
+ {
+ "id": 450,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Pattern",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 451,
+ "enabled": true,
+ "label": "Sinus...",
+ "visible": true
+ },
+ {
+ "id": 452,
+ "enabled": true,
+ "label": "Qbist...",
+ "visible": true
+ },
+ {
+ "id": 453,
+ "enabled": true,
+ "label": "Maze...",
+ "visible": true
+ },
+ {
+ "id": 454,
+ "enabled": true,
+ "label": "Jigsaw...",
+ "visible": true
+ },
+ {
+ "id": 455,
+ "enabled": true,
+ "label": "Grid...",
+ "visible": true
+ },
+ {
+ "id": 456,
+ "enabled": true,
+ "label": "Diffraction Patterns...",
+ "visible": true
+ },
+ {
+ "id": 457,
+ "enabled": true,
+ "label": "CML Explorer...",
+ "visible": true
+ },
+ {
+ "id": 458,
+ "enabled": true,
+ "label": "Checkerboard...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 459,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Nature",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 460,
+ "enabled": true,
+ "label": "IFS Fractal...",
+ "visible": true
+ },
+ {
+ "id": 461,
+ "enabled": true,
+ "label": "Flame...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 462,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Clouds",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 463,
+ "enabled": true,
+ "label": "Solid Noise...",
+ "visible": true
+ },
+ {
+ "id": 464,
+ "enabled": true,
+ "label": "Plasma...",
+ "visible": true
+ },
+ {
+ "id": 465,
+ "enabled": true,
+ "label": "Fog...",
+ "visible": true
+ },
+ {
+ "id": 466,
+ "enabled": true,
+ "label": "Difference Clouds...",
+ "visible": true
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": 467,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Map",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 468,
+ "enabled": true,
+ "label": "Warp...",
+ "visible": true
+ },
+ {
+ "id": 469,
+ "enabled": true,
+ "label": "Tile...",
+ "visible": true
+ },
+ {
+ "id": 470,
+ "enabled": true,
+ "label": "Small Tiles...",
+ "visible": true
+ },
+ {
+ "id": 471,
+ "enabled": true,
+ "label": "Paper Tile...",
+ "visible": true
+ },
+ {
+ "id": 472,
+ "enabled": true,
+ "label": "Map Object...",
+ "visible": true
+ },
+ {
+ "id": 473,
+ "enabled": true,
+ "label": "Make Seamless",
+ "visible": true
+ },
+ {
+ "id": 474,
+ "enabled": true,
+ "label": "Illusion...",
+ "visible": true
+ },
+ {
+ "id": 475,
+ "enabled": true,
+ "label": "Fractal Trace...",
+ "visible": true
+ },
+ {
+ "id": 476,
+ "enabled": true,
+ "label": "Displace...",
+ "visible": true
+ },
+ {
+ "id": 477,
+ "enabled": true,
+ "label": "Bump Map...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 478,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Decor",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 479,
+ "enabled": false,
+ "label": "Stencil Chrome...",
+ "visible": true
+ },
+ {
+ "id": 480,
+ "enabled": false,
+ "label": "Stencil Carve...",
+ "visible": true
+ },
+ {
+ "id": 481,
+ "enabled": false,
+ "label": "Slide...",
+ "visible": true
+ },
+ {
+ "id": 482,
+ "enabled": false,
+ "label": "Round Corners...",
+ "visible": true
+ },
+ {
+ "id": 483,
+ "enabled": true,
+ "label": "Old Photo...",
+ "visible": true
+ },
+ {
+ "id": 484,
+ "enabled": true,
+ "label": "Fuzzy Border...",
+ "visible": true
+ },
+ {
+ "id": 485,
+ "enabled": true,
+ "label": "Coffee Stain...",
+ "visible": true
+ },
+ {
+ "id": 486,
+ "enabled": true,
+ "label": "Add Border...",
+ "visible": true
+ },
+ {
+ "id": 487,
+ "enabled": true,
+ "label": "Add Bevel...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 488,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Artistic",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 489,
+ "enabled": true,
+ "label": "Weave...",
+ "visible": true
+ },
+ {
+ "id": 490,
+ "enabled": true,
+ "label": "Van Gogh (LIC)...",
+ "visible": true
+ },
+ {
+ "id": 491,
+ "enabled": true,
+ "label": "Softglow...",
+ "visible": true
+ },
+ {
+ "id": 492,
+ "enabled": true,
+ "label": "Predator...",
+ "visible": true
+ },
+ {
+ "id": 493,
+ "enabled": true,
+ "label": "Photocopy...",
+ "visible": true
+ },
+ {
+ "id": 494,
+ "enabled": true,
+ "label": "Oilify...",
+ "visible": true
+ },
+ {
+ "id": 495,
+ "enabled": true,
+ "label": "GIMPressionist...",
+ "visible": true
+ },
+ {
+ "id": 496,
+ "enabled": true,
+ "label": "Cubism...",
+ "visible": true
+ },
+ {
+ "id": 497,
+ "enabled": true,
+ "label": "Clothify...",
+ "visible": true
+ },
+ {
+ "id": 498,
+ "enabled": true,
+ "label": "Cartoon...",
+ "visible": true
+ },
+ {
+ "id": 499,
+ "enabled": true,
+ "label": "Apply Canvas...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 500,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Combine",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 501,
+ "enabled": true,
+ "label": "Filmstrip...",
+ "visible": true
+ },
+ {
+ "id": 502,
+ "enabled": true,
+ "label": "Depth Merge...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 503,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Generic",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 504,
+ "enabled": true,
+ "label": "Erode",
+ "visible": true
+ },
+ {
+ "id": 505,
+ "enabled": true,
+ "label": "Dilate",
+ "visible": true
+ },
+ {
+ "id": 506,
+ "enabled": true,
+ "label": "Convolution Matrix...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 507,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Edge-Detect",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 508,
+ "enabled": true,
+ "label": "Sobel...",
+ "visible": true
+ },
+ {
+ "id": 509,
+ "enabled": true,
+ "label": "Neon...",
+ "visible": true
+ },
+ {
+ "id": 510,
+ "enabled": true,
+ "label": "Laplace",
+ "visible": true
+ },
+ {
+ "id": 511,
+ "enabled": true,
+ "label": "Edge...",
+ "visible": true
+ },
+ {
+ "id": 512,
+ "enabled": true,
+ "label": "Difference of Gaussians...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 513,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Noise",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 514,
+ "enabled": true,
+ "label": "Spread...",
+ "visible": true
+ },
+ {
+ "id": 515,
+ "enabled": true,
+ "label": "Slur...",
+ "visible": true
+ },
+ {
+ "id": 516,
+ "enabled": true,
+ "label": "RGB Noise...",
+ "visible": true
+ },
+ {
+ "id": 517,
+ "enabled": true,
+ "label": "Pick...",
+ "visible": true
+ },
+ {
+ "id": 518,
+ "enabled": true,
+ "label": "Hurl...",
+ "visible": true
+ },
+ {
+ "id": 519,
+ "enabled": true,
+ "label": "HSV Noise...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 520,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Light and Shadow",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 521,
+ "enabled": true,
+ "label": "Glass Tile...",
+ "visible": true
+ },
+ {
+ "id": 522,
+ "enabled": true,
+ "label": "Apply Lens...",
+ "visible": true
+ },
+ {
+ "id": 523,
+ "type": "separator"
+ },
+ {
+ "id": 524,
+ "enabled": true,
+ "label": "Xach-Effect...",
+ "visible": true
+ },
+ {
+ "id": 525,
+ "enabled": true,
+ "label": "Perspective...",
+ "visible": true
+ },
+ {
+ "id": 526,
+ "enabled": true,
+ "label": "Drop Shadow...",
+ "visible": true
+ },
+ {
+ "id": 527,
+ "type": "separator"
+ },
+ {
+ "id": 528,
+ "enabled": true,
+ "label": "Supernova...",
+ "visible": true
+ },
+ {
+ "id": 529,
+ "enabled": true,
+ "label": "Sparkle...",
+ "visible": true
+ },
+ {
+ "id": 530,
+ "enabled": true,
+ "label": "Lighting Effects...",
+ "visible": true
+ },
+ {
+ "id": 531,
+ "enabled": true,
+ "label": "Lens Flare...",
+ "visible": true
+ },
+ {
+ "id": 532,
+ "enabled": true,
+ "label": "Gradient Flare...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 533,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Distorts",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 534,
+ "enabled": true,
+ "label": "Wind...",
+ "visible": true
+ },
+ {
+ "id": 535,
+ "enabled": true,
+ "label": "Whirl and Pinch...",
+ "visible": true
+ },
+ {
+ "id": 536,
+ "enabled": true,
+ "label": "Waves...",
+ "visible": true
+ },
+ {
+ "id": 537,
+ "enabled": true,
+ "label": "Video...",
+ "visible": true
+ },
+ {
+ "id": 538,
+ "enabled": true,
+ "label": "Value Propagate...",
+ "visible": true
+ },
+ {
+ "id": 539,
+ "enabled": true,
+ "label": "Shift...",
+ "visible": true
+ },
+ {
+ "id": 540,
+ "enabled": true,
+ "label": "Ripple...",
+ "visible": true
+ },
+ {
+ "id": 541,
+ "enabled": true,
+ "label": "Polar Coordinates...",
+ "visible": true
+ },
+ {
+ "id": 542,
+ "enabled": true,
+ "label": "Pagecurl...",
+ "visible": true
+ },
+ {
+ "id": 543,
+ "enabled": true,
+ "label": "Newsprint...",
+ "visible": true
+ },
+ {
+ "id": 544,
+ "enabled": true,
+ "label": "Mosaic...",
+ "visible": true
+ },
+ {
+ "id": 545,
+ "enabled": true,
+ "label": "Lens Distortion...",
+ "visible": true
+ },
+ {
+ "id": 546,
+ "enabled": true,
+ "label": "IWarp...",
+ "visible": true
+ },
+ {
+ "id": 547,
+ "enabled": true,
+ "label": "Erase Every Other Row...",
+ "visible": true
+ },
+ {
+ "id": 548,
+ "enabled": true,
+ "label": "Engrave...",
+ "visible": true
+ },
+ {
+ "id": 549,
+ "enabled": true,
+ "label": "Emboss...",
+ "visible": true
+ },
+ {
+ "id": 550,
+ "enabled": true,
+ "label": "Curve Bend...",
+ "visible": true
+ },
+ {
+ "id": 551,
+ "enabled": true,
+ "label": "Blinds...",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 552,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Enhance",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 553,
+ "enabled": true,
+ "label": "Unsharp Mask...",
+ "visible": true
+ },
+ {
+ "id": 554,
+ "enabled": true,
+ "label": "Sharpen...",
+ "visible": true
+ },
+ {
+ "id": 555,
+ "enabled": true,
+ "label": "Red Eye Removal...",
+ "visible": true
+ },
+ {
+ "id": 556,
+ "enabled": false,
+ "label": "NL Filter...",
+ "visible": true
+ },
+ {
+ "id": 557,
+ "enabled": true,
+ "label": "Destripe...",
+ "visible": true
+ },
+ {
+ "id": 558,
+ "enabled": true,
+ "label": "Despeckle...",
+ "visible": true
+ },
+ {
+ "id": 559,
+ "enabled": true,
+ "label": "Deinterlace...",
+ "visible": true
+ },
+ {
+ "id": 560,
+ "enabled": true,
+ "label": "Antialias",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 561,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Blur",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 562,
+ "enabled": true,
+ "label": "Tileable Blur...",
+ "visible": true
+ },
+ {
+ "id": 563,
+ "enabled": true,
+ "label": "Selective Gaussian Blur...",
+ "visible": true
+ },
+ {
+ "id": 564,
+ "enabled": true,
+ "label": "Pixelize...",
+ "visible": true
+ },
+ {
+ "id": 565,
+ "enabled": true,
+ "label": "Motion Blur...",
+ "visible": true
+ },
+ {
+ "id": 566,
+ "enabled": true,
+ "label": "Gaussian Blur...",
+ "visible": true
+ },
+ {
+ "id": 567,
+ "enabled": true,
+ "label": "Blur",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 568,
+ "type": "separator"
+ },
+ {
+ "id": 569,
+ "enabled": true,
+ "label": "Reset all Filters",
+ "visible": true
+ },
+ {
+ "id": 570,
+ "children-display": "submenu",
+ "enabled": false,
+ "label": "Re-Show Last",
+ "shortcut": [["Control", "Shift", "f"]],
+ "visible": true,
+ "submenu": [
+ {
+ "id": 571,
+ "enabled": false,
+ "label": "Empty",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 572,
+ "enabled": false,
+ "label": "Repeat Last",
+ "shortcut": [["Control", "f"]],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 573,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Windows",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 574,
+ "enabled": true,
+ "label": "Toolbox",
+ "shortcut": [["Control", "b"]],
+ "visible": true
+ },
+ {
+ "id": 575,
+ "type": "separator"
+ },
+ {
+ "id": 576,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Dockable Dialogs",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 577,
+ "enabled": true,
+ "label": "Error Console",
+ "visible": true
+ },
+ {
+ "id": 578,
+ "enabled": true,
+ "label": "Tools",
+ "visible": true
+ },
+ {
+ "id": 579,
+ "enabled": true,
+ "label": "Templates",
+ "visible": true
+ },
+ {
+ "id": 580,
+ "enabled": true,
+ "label": "Document History",
+ "visible": true
+ },
+ {
+ "id": 581,
+ "enabled": true,
+ "label": "Images",
+ "visible": true
+ },
+ {
+ "id": 582,
+ "type": "separator"
+ },
+ {
+ "id": 583,
+ "enabled": true,
+ "label": "Buffers",
+ "visible": true
+ },
+ {
+ "id": 584,
+ "enabled": true,
+ "label": "Fonts",
+ "visible": true
+ },
+ {
+ "id": 585,
+ "enabled": true,
+ "label": "Palettes",
+ "visible": true
+ },
+ {
+ "id": 586,
+ "enabled": true,
+ "label": "Gradients",
+ "shortcut": [["Control", "g"]],
+ "visible": true
+ },
+ {
+ "id": 587,
+ "enabled": true,
+ "label": "Patterns",
+ "shortcut": [["Control", "Shift", "p"]],
+ "visible": true
+ },
+ {
+ "id": 588,
+ "enabled": true,
+ "label": "Brushes",
+ "shortcut": [["Control", "Shift", "b"]],
+ "visible": true
+ },
+ {
+ "id": 589,
+ "enabled": true,
+ "label": "Colors",
+ "visible": true
+ },
+ {
+ "id": 590,
+ "type": "separator"
+ },
+ {
+ "id": 591,
+ "enabled": true,
+ "label": "Sample Points",
+ "visible": true
+ },
+ {
+ "id": 592,
+ "enabled": true,
+ "label": "Pointer",
+ "visible": true
+ },
+ {
+ "id": 593,
+ "enabled": true,
+ "label": "Undo History",
+ "visible": true
+ },
+ {
+ "id": 594,
+ "enabled": true,
+ "label": "Navigation",
+ "visible": true
+ },
+ {
+ "id": 595,
+ "enabled": true,
+ "label": "Selection Editor",
+ "visible": true
+ },
+ {
+ "id": 596,
+ "enabled": true,
+ "label": "Histogram",
+ "visible": true
+ },
+ {
+ "id": 597,
+ "enabled": true,
+ "label": "Colormap",
+ "visible": true
+ },
+ {
+ "id": 598,
+ "enabled": true,
+ "label": "Paths",
+ "visible": true
+ },
+ {
+ "id": 599,
+ "enabled": true,
+ "label": "Channels",
+ "visible": true
+ },
+ {
+ "id": 600,
+ "enabled": true,
+ "label": "Layers",
+ "shortcut": [["Control", "l"]],
+ "visible": true
+ },
+ {
+ "id": 601,
+ "type": "separator"
+ },
+ {
+ "id": 602,
+ "enabled": true,
+ "label": "Device Status",
+ "visible": true
+ },
+ {
+ "id": 603,
+ "enabled": true,
+ "label": "Tool Options",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 604,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Recently Closed Docks",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 605,
+ "enabled": false,
+ "label": "Empty",
+ "visible": true
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": 606,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "Help",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 607,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "User Manual",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 608,
+ "enabled": true,
+ "label": "Working with Digital Camera Photos",
+ "visible": true
+ },
+ {
+ "id": 609,
+ "enabled": true,
+ "label": "Using Paths",
+ "visible": true
+ },
+ {
+ "id": 610,
+ "enabled": true,
+ "label": "Preparing your Images for the Web",
+ "visible": true
+ },
+ {
+ "id": 611,
+ "enabled": true,
+ "label": "How to Use Dialogs",
+ "visible": true
+ },
+ {
+ "id": 612,
+ "enabled": true,
+ "label": "Drawing Simple Objects",
+ "visible": true
+ },
+ {
+ "id": 613,
+ "enabled": true,
+ "label": "Create, Open and Save Files",
+ "visible": true
+ },
+ {
+ "id": 614,
+ "enabled": true,
+ "label": "Basic Concepts",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 615,
+ "children-display": "submenu",
+ "enabled": true,
+ "label": "GIMP Online",
+ "visible": true,
+ "submenu": [
+ {
+ "id": 616,
+ "enabled": true,
+ "label": "User Manual Web Site",
+ "visible": true
+ },
+ {
+ "id": 617,
+ "enabled": true,
+ "label": "Plug-in Registry",
+ "visible": true
+ },
+ {
+ "id": 618,
+ "enabled": true,
+ "label": "Main Web Site",
+ "visible": true
+ },
+ {
+ "id": 619,
+ "enabled": true,
+ "label": "Developer Web Site",
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 620,
+ "type": "separator"
+ },
+ {
+ "id": 621,
+ "enabled": true,
+ "label": "Procedure Browser",
+ "visible": true
+ },
+ {
+ "id": 622,
+ "enabled": true,
+ "label": "Plug-In Browser",
+ "visible": true
+ },
+ {
+ "id": 623,
+ "type": "separator"
+ },
+ {
+ "id": 624,
+ "enabled": true,
+ "label": "About",
+ "visible": true
+ },
+ {
+ "id": 625,
+ "enabled": true,
+ "label": "Tip of the Day",
+ "visible": true
+ },
+ {
+ "id": 626,
+ "enabled": true,
+ "label": "Context Help",
+ "shortcut": [["Shift", "F1"]],
+ "visible": true
+ },
+ {
+ "id": 627,
+ "enabled": true,
+ "label": "Help",
+ "shortcut": [["F1"]],
+ "visible": true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/test-json-client.c b/tests/test-json-client.c
new file mode 100644
index 0000000..f9da55e
--- /dev/null
+++ b/tests/test-json-client.c
@@ -0,0 +1,75 @@
+/*
+Test to check the json-loader and dbusmenu-dumper
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-bindings.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+GMainLoop * mainloop = NULL;
+
+int
+main (int argc, char ** argv)
+{
+ g_type_init();
+ g_debug("Wait for friends");
+
+ GError * error = NULL;
+ DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+ if (error != NULL) {
+ g_error("Unable to get session bus: %s", error->message);
+ return 1;
+ }
+
+ DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(session_bus, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+
+ gboolean has_owner = FALSE;
+ gint owner_count = 0;
+ while (!has_owner && owner_count < 10000) {
+ org_freedesktop_DBus_name_has_owner(bus_proxy, "org.dbusmenu.test", &has_owner, NULL);
+ owner_count++;
+ }
+
+ if (owner_count == 10000) {
+ g_error("Unable to get name owner after 10000 tries");
+ return 1;
+ }
+
+ g_usleep(500000);
+
+ g_debug("Initing");
+
+ gchar * command = g_strdup_printf("%s --dbus-name=org.dbusmenu.test --dbus-object=/org/test", argv[1]);
+ g_debug("Executing: %s", command);
+
+ gchar * output;
+ g_spawn_command_line_sync(command, &output, NULL, NULL, NULL);
+
+ GFile * ofile = g_file_new_for_commandline_arg(argv[2]);
+ if (ofile != NULL) {
+ g_file_replace_contents(ofile, output, g_utf8_strlen(output, -1), NULL, FALSE, 0, NULL, NULL, NULL);
+ }
+
+ g_debug("Exiting");
+
+ return 0;
+}
diff --git a/tests/test-json-server.c b/tests/test-json-server.c
new file mode 100644
index 0000000..fe9507a
--- /dev/null
+++ b/tests/test-json-server.c
@@ -0,0 +1,81 @@
+/*
+Test to check the json-loader and dbusmenu-dumper
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <libdbusmenu-glib/server.h>
+#include <libdbusmenu-glib/menuitem.h>
+
+#include "json-loader.h"
+
+static GMainLoop * mainloop = NULL;
+
+static gboolean
+timer_func (gpointer data)
+{
+ g_main_loop_quit(mainloop);
+ return FALSE;
+}
+
+int
+main (int argc, char ** argv)
+{
+ GError * error = NULL;
+
+ g_type_init();
+
+ DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+ g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
+
+ DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+ guint nameret = 0;
+
+ if (!org_freedesktop_DBus_request_name(bus_proxy, "org.dbusmenu.test", 0, &nameret, &error)) {
+ g_error("Unable to call to request name");
+ return 1;
+ }
+
+ if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ g_error("Unable to get name");
+ return 1;
+ }
+
+ DbusmenuServer * server = dbusmenu_server_new("/org/test");
+
+ DbusmenuMenuitem * root = dbusmenu_json_build_from_file(argv[1]);
+ g_return_val_if_fail(root!=NULL, 1);
+
+ dbusmenu_server_set_root(server, root);
+
+ g_timeout_add(10000, timer_func, NULL);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ g_debug("Quiting");
+
+ return 0;
+}