diff options
-rw-r--r-- | libdbusmenu-glib/client.c | 38 | ||||
-rw-r--r-- | libdbusmenu-glib/menuitem.c | 26 | ||||
-rw-r--r-- | libdbusmenu-glib/menuitem.h | 1 | ||||
-rw-r--r-- | tests/Makefile.am | 7 | ||||
-rw-r--r-- | tests/test-glib-layout-client.c | 4 | ||||
-rw-r--r-- | tests/test-glib-properties-client.c | 12 | ||||
-rw-r--r-- | tests/test-glib-properties-server.c | 6 | ||||
-rw-r--r-- | tests/test-glib-properties.h | 12 | ||||
-rw-r--r-- | tests/test-gtk-label.json | 4 | ||||
-rw-r--r-- | tools/Makefile.am | 6 | ||||
-rw-r--r-- | tools/README.dbusmenu-bench | 27 |
11 files changed, 121 insertions, 22 deletions
diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 0f7fd65..2302110 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -339,6 +339,7 @@ id_prop_update (DBusGProxy * proxy, gint id, gchar * property, GValue * value, D g_return_if_fail(menuitem != NULL); dbusmenu_menuitem_property_set_value(menuitem, property, value); + return; } @@ -569,6 +570,22 @@ menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError return; } +static void +menuitem_get_properties_replace_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data) +{ + GList * current_props = NULL; + + for (current_props = dbusmenu_menuitem_properties_list(DBUSMENU_MENUITEM(data)); + current_props != NULL ; current_props = g_list_next(current_props)) { + if (g_hash_table_lookup(properties, current_props->data) == NULL) { + dbusmenu_menuitem_property_remove(DBUSMENU_MENUITEM(data), (const gchar *)current_props->data); + } + } + + menuitem_get_properties_cb(proxy, properties, error, data); + return; +} + /* This is a different get properites call back that also sends new signals. It basically is a small wrapper around the original. */ static void @@ -647,6 +664,7 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it #ifdef MASSIVEDEBUGGING g_debug("Client looking at node with id: %d", id); #endif + /* If we don't have any item, or the IDs don't match */ if (item == NULL || dbusmenu_menuitem_get_id(item) != id) { if (item != NULL) { if (parent != NULL) { @@ -675,7 +693,11 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it } else { g_warning("Unable to allocate memory to get properties for menuitem. This menuitem will never be realized."); } - } + } else { + /* Refresh the properties */ + gchar * properties[1] = {NULL}; /* This gets them all */ + org_ayatana_dbusmenu_get_properties_async(proxy, id, (const gchar **)properties, menuitem_get_properties_replace_cb, item); + } xmlNodePtr children; guint position; @@ -736,6 +758,10 @@ parse_layout (DbusmenuClient * client, const gchar * layout) xmlNodePtr root = xmlDocGetRootElement(xmldoc); DbusmenuMenuitem * oldroot = priv->root; + if (oldroot != NULL) { + g_object_ref(oldroot); + } + priv->root = parse_layout_xml(client, root, priv->root, NULL, priv->menuproxy); xmlFreeDoc(xmldoc); @@ -747,6 +773,16 @@ parse_layout (DbusmenuClient * client, const gchar * layout) #ifdef MASSIVEDEBUGGING g_debug("Client signaling root changed."); #endif + + /* Switch the root around */ + g_object_ref(priv->root); + dbusmenu_menuitem_set_root(priv->root, TRUE); + + if (oldroot != NULL) { + dbusmenu_menuitem_set_root(oldroot, FALSE); + g_object_unref(oldroot); + } + g_signal_emit(G_OBJECT(client), signals[ROOT_CHANGED], 0, priv->root, TRUE); } diff --git a/libdbusmenu-glib/menuitem.c b/libdbusmenu-glib/menuitem.c index cacc0a8..a2d2682 100644 --- a/libdbusmenu-glib/menuitem.c +++ b/libdbusmenu-glib/menuitem.c @@ -343,7 +343,11 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) if (priv->id == -1) { priv->id = menuitem_next_id++; } - g_value_set_int(value, priv->id); + if (dbusmenu_menuitem_get_root(DBUSMENU_MENUITEM(obj))) { + g_value_set_int(value, 0); + } else { + g_value_set_int(value, priv->id); + } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, pspec); @@ -984,6 +988,26 @@ dbusmenu_menuitem_property_exist (DbusmenuMenuitem * mi, const gchar * property) } /** + dbusmenu_menuitem_property_remove: + @mi: The #DbusmenuMenuitem to remove the property on. + @property: The property to look for. + + Removes a property from the menuitem. +*/ +void +dbusmenu_menuitem_property_remove (DbusmenuMenuitem * mi, const gchar * property) +{ + g_return_if_fail(DBUSMENU_IS_MENUITEM(mi)); + g_return_if_fail(property != NULL); + + DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi); + + g_hash_table_remove(priv->properties, property); + + return; +} + +/** dbusmenu_menuitem_properties_list: @mi: #DbusmenuMenuitem to list the properties on diff --git a/libdbusmenu-glib/menuitem.h b/libdbusmenu-glib/menuitem.h index 69f82e5..1382335 100644 --- a/libdbusmenu-glib/menuitem.h +++ b/libdbusmenu-glib/menuitem.h @@ -152,6 +152,7 @@ gint dbusmenu_menuitem_property_get_int (DbusmenuMenuitem * mi, const gchar * pr gboolean dbusmenu_menuitem_property_exist (DbusmenuMenuitem * mi, const gchar * property); GList * dbusmenu_menuitem_properties_list (DbusmenuMenuitem * mi) G_GNUC_WARN_UNUSED_RESULT; GHashTable * dbusmenu_menuitem_properties_copy (DbusmenuMenuitem * mi); +void dbusmenu_menuitem_property_remove (DbusmenuMenuitem * mi, const gchar * property); void dbusmenu_menuitem_set_root (DbusmenuMenuitem * mi, gboolean root); gboolean dbusmenu_menuitem_get_root (DbusmenuMenuitem * mi); diff --git a/tests/Makefile.am b/tests/Makefile.am index 5297dbd..746ac23 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -231,10 +231,15 @@ examplesdir = $(docdir)/examples/ examples_DATA = \ $(glib_server_nomenu_SOURCES) +jsondir = $(datadir)/${PACKAGE}/json/ + +json_DATA = \ + test-gtk-label.json + EXTRA_DIST = \ $(examples_DATA) \ run-xvfb.sh \ - test-gtk-label.json \ + $(json_DATA) \ dbusmenu-gtk/dbusMenuTest \ dbusmenu-gtk/mago_tests/dbusmenu.xml \ dbusmenu-gtk/mago_tests/dbusmenu.py \ diff --git a/tests/test-glib-layout-client.c b/tests/test-glib-layout-client.c index 82228b5..5ea0cf8 100644 --- a/tests/test-glib-layout-client.c +++ b/tests/test-glib-layout-client.c @@ -57,13 +57,13 @@ verify_root_to_layout(DbusmenuMenuitem * mi, layout_t * layout) } guint i = 0; - for (i = 0; children != NULL && layout->submenu[i].id != 0; children = g_list_next(children), i++) { + for (i = 0; children != NULL && layout->submenu[i].id != -1; children = g_list_next(children), i++) { if (!verify_root_to_layout(DBUSMENU_MENUITEM(children->data), &layout->submenu[i])) { return FALSE; } } - if (children == NULL && layout->submenu[i].id == 0) { + if (children == NULL && layout->submenu[i].id == -1) { return TRUE; } diff --git a/tests/test-glib-properties-client.c b/tests/test-glib-properties-client.c index 39815aa..434465a 100644 --- a/tests/test-glib-properties-client.c +++ b/tests/test-glib-properties-client.c @@ -60,8 +60,10 @@ verify_root_to_layout(DbusmenuMenuitem * mi, proplayout_t * layout) g_debug("Verifying ID: %d", layout->id); if (layout->id != dbusmenu_menuitem_get_id(mi)) { - g_debug("\tFailed as ID %d is not equal to %d", layout->id, dbusmenu_menuitem_get_id(mi)); - return FALSE; + if (!dbusmenu_menuitem_get_root(mi)) { + g_debug("\tFailed as ID %d is not equal to %d", layout->id, dbusmenu_menuitem_get_id(mi)); + return FALSE; + } } if (!verify_props(mi, layout->properties)) { @@ -85,13 +87,13 @@ verify_root_to_layout(DbusmenuMenuitem * mi, proplayout_t * layout) } guint i = 0; - for (i = 0; children != NULL && layout->submenu[i].id != 0; children = g_list_next(children), i++) { + for (i = 0; children != NULL && layout->submenu[i].id != -1; children = g_list_next(children), i++) { if (!verify_root_to_layout(DBUSMENU_MENUITEM(children->data), &layout->submenu[i])) { return FALSE; } } - if (children == NULL && layout->submenu[i].id == 0) { + if (children == NULL && layout->submenu[i].id == -1) { g_debug("\tPassed: %d", layout->id); return TRUE; } @@ -140,7 +142,7 @@ layout_verify_timer (gpointer data) layouton++; - if (layouts[layouton].id == 0) { + if (layouts[layouton].id == -1) { g_main_loop_quit(mainloop); } diff --git a/tests/test-glib-properties-server.c b/tests/test-glib-properties-server.c index 8dad37f..091e550 100644 --- a/tests/test-glib-properties-server.c +++ b/tests/test-glib-properties-server.c @@ -46,14 +46,14 @@ set_props (DbusmenuMenuitem * mi, gchar ** props) static DbusmenuMenuitem * layout2menuitem (proplayout_t * layout) { - if (layout == NULL || layout->id == 0) return NULL; + if (layout == NULL || layout->id == -1) return NULL; DbusmenuMenuitem * local = dbusmenu_menuitem_new_with_id(layout->id); set_props(local, layout->properties); if (layout->submenu != NULL) { guint count; - for (count = 0; layout->submenu[count].id != 0; count++) { + for (count = 0; layout->submenu[count].id != -1; count++) { DbusmenuMenuitem * child = layout2menuitem(&layout->submenu[count]); if (child != NULL) { dbusmenu_menuitem_child_append(local, child); @@ -72,7 +72,7 @@ static GMainLoop * mainloop = NULL; static gboolean timer_func (gpointer data) { - if (layouts[layouton].id == 0) { + if (layouts[layouton].id == -1) { g_main_loop_quit(mainloop); return FALSE; } diff --git a/tests/test-glib-properties.h b/tests/test-glib-properties.h index 5e83f5c..c0c929a 100644 --- a/tests/test-glib-properties.h +++ b/tests/test-glib-properties.h @@ -24,7 +24,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. typedef struct _proplayout_t proplayout_t; struct _proplayout_t { - guint id; + gint id; gchar ** properties; proplayout_t * submenu; }; @@ -68,7 +68,7 @@ proplayout_t submenu_4_1[] = { {id: 17, properties: props2, submenu: NULL}, {id: 18, properties: props2, submenu: NULL}, {id: 19, properties: props2, submenu: NULL}, - {id: 0, properties: NULL, submenu: NULL} + {id: -1, properties: NULL, submenu: NULL} }; proplayout_t submenu_4_2[] = { @@ -82,7 +82,7 @@ proplayout_t submenu_4_2[] = { {id: 27, properties: props2, submenu: NULL}, {id: 28, properties: props2, submenu: NULL}, {id: 29, properties: props2, submenu: NULL}, - {id: 0, properties: NULL, submenu: NULL} + {id: -1, properties: NULL, submenu: NULL} }; proplayout_t submenu_4_3[] = { @@ -96,14 +96,14 @@ proplayout_t submenu_4_3[] = { {id: 37, properties: props2, submenu: NULL}, {id: 38, properties: props2, submenu: NULL}, {id: 39, properties: props2, submenu: NULL}, - {id: 0, properties: NULL, submenu: NULL} + {id: -1, properties: NULL, submenu: NULL} }; proplayout_t submenu_4_0[] = { {id: 1, properties: props2, submenu: submenu_4_1}, {id: 2, properties: props2, submenu: submenu_4_2}, {id: 3, properties: props2, submenu: submenu_4_3}, - {id: 0, properties: NULL, submenu: NULL} + {id: -1, properties: NULL, submenu: NULL} }; proplayout_t layouts[] = { @@ -111,6 +111,6 @@ proplayout_t layouts[] = { {id: 10, properties: props2, submenu: NULL}, {id: 20, properties: props3, submenu: NULL}, {id: 100, properties: props2, submenu: submenu_4_0}, - {id: 0, properties: NULL, submenu: NULL} + {id: -1, properties: NULL, submenu: NULL} }; diff --git a/tests/test-gtk-label.json b/tests/test-gtk-label.json index 1a46dcf..973ab7b 100644 --- a/tests/test-gtk-label.json +++ b/tests/test-gtk-label.json @@ -198,7 +198,7 @@ {"id": 39, "type": "standard", "label": "value39"} ] - }, + } ] }, {"id": 8, "type": "standard", @@ -367,5 +367,5 @@ QmCC", "toggle-state": -1 } ] - }, + } ] diff --git a/tools/Makefile.am b/tools/Makefile.am index eedfa29..77d6eef 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -16,4 +16,8 @@ dbusmenu_dumper_LDADD = \ ../libdbusmenu-glib/libdbusmenu-glib.la \ $(DBUSMENUGLIB_LIBS) -EXTRA_DIST = dbusmenu-bench +doc_DATA = README.dbusmenu-bench + +EXTRA_DIST = \ + $(doc_DATA) \ + dbusmenu-bench diff --git a/tools/README.dbusmenu-bench b/tools/README.dbusmenu-bench new file mode 100644 index 0000000..91045df --- /dev/null +++ b/tools/README.dbusmenu-bench @@ -0,0 +1,27 @@ +# Introduction + +dbusmenu-bench measures the time it takes to call various DBusMenu methods and +print the results on stdout. A test dbusmenu application must be started before +running dbusmenu-bench. + +A GLib test application is included in this archive. libdbusmenu-qt provides an +equivalent Qt test application. They both can load the same menu hierarchy from +a JSON file. + +# Using it + +1. Start dbusmenu-testapp: + + dbusmenu-testapp /usr/share/libdbusmenu/json/test-gtk-label.json + +2. Run dbusmenu-bench + + dbusmenu-bench --count 1000 + +1000 is the number of times each DBusMenu method is called. Calling them 1000 +times helps getting meaningful average values. + +3. Stop dbusmenu-testapp + +For debugging purpose, you can also run dbusmenu-bench with the "--dump" +parameter, which will dump the output of the called methods. |