From 4fbdf12b5671ebcc68ce2d41018cd2a567298be8 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 10 Jun 2010 21:11:45 -0500 Subject: Adding an extra callback to catch a race condition --- libdbusmenu-glib/client.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index c0d3b7a..fa233a4 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -30,6 +30,8 @@ License version 3 and version 2.1 along with this program. If not, see #include "config.h" #endif +#include + #include #include @@ -397,6 +399,25 @@ dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, c return build_proxies(client); } +/* This is the response to see if the name has an owner. If + it does, then we should build the proxies here. Race condition + check. */ +static void +name_owner_check (DBusGProxy *proxy, gboolean has_owner, GError *error, gpointer userdata) +{ + if (error != NULL) { + return; + } + + if (!has_owner) { + return; + } + + DbusmenuClient * client = DBUSMENU_CLIENT(userdata); + build_proxies(client); + return; +} + /* This function builds the DBus proxy which will look out for the service coming up. */ static void @@ -426,6 +447,13 @@ build_dbus_proxy (DbusmenuClient * client) dbus_g_proxy_connect_signal(priv->dbusproxy, "NameOwnerChanged", G_CALLBACK(dbus_owner_change), client, NULL); + /* Now let's check to make sure we're not in some race + condition case. */ + org_freedesktop_DBus_name_has_owner_async(priv->dbusproxy, + priv->dbus_name, + name_owner_check, + client); + return; } -- cgit v1.2.3 From f83f5f8dccbbc24f9a6256c3a116391000419004 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 7 Jul 2010 14:45:26 -0500 Subject: Adding NULL protection and a warning --- libdbusmenu-glib/client.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index fa233a4..871170a 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -561,6 +561,9 @@ build_proxies (DbusmenuClient * client) static gint parse_node_get_id (xmlNodePtr node) { + if (node == NULL) { + return -1; + } if (node->type != XML_ELEMENT_NODE) { return -1; } @@ -886,6 +889,10 @@ parse_layout (DbusmenuClient * client, const gchar * layout) xmlNodePtr root = xmlDocGetRootElement(xmldoc); + if (root == NULL) { + g_warning("Unable to get root node of menu XML"); + } + DbusmenuMenuitem * oldroot = priv->root; priv->root = parse_layout_xml(client, root, priv->root, NULL, priv->menuproxy); -- cgit v1.2.3 From 7c48e370ec2b9c3437a77e81b535b1f20672f817 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 14 Jul 2010 09:02:15 -0500 Subject: Adding protections on dbusmenu_client_send_event() --- libdbusmenu-glib/client.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 871170a..2e985d6 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -716,6 +716,17 @@ menuitem_call_cb (DBusGProxy * proxy, GError * error, gpointer userdata) void dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name, const GValue * value, guint timestamp) { + g_return_if_fail(DBUSMENU_IS_CLIENT(client)); + g_return_if_fail(id >= 0); + g_return_if_fail(name != NULL); + + if (value == NULL) { + GValue internalval = {0}; + g_value_init(&internalval, G_TYPE_INT); + g_value_set_int(&internalval, 0); + value = &internalval; + } + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); org_ayatana_dbusmenu_event_async (priv->menuproxy, id, name, value, timestamp, menuitem_call_cb, GINT_TO_POINTER(id)); return; -- cgit v1.2.3 From df399dd383c3ceaea44e6b173a842c7bfd1664ed Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 19 Jul 2010 14:15:31 -0500 Subject: Introducting a function to bring together all our get_properties_async friends. --- libdbusmenu-glib/client.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 2e985d6..bb7b4ee 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -109,6 +109,7 @@ static gint parse_layout (DbusmenuClient * client, const gchar * layout); static void update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError * in_error, void * data); static void update_layout (DbusmenuClient * client); static void menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data); +static void get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, org_ayatana_dbusmenu_get_properties_reply callback, gpointer user_data); /* Build a type */ G_DEFINE_TYPE (DbusmenuClient, dbusmenu_client, G_TYPE_OBJECT); @@ -310,6 +311,16 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) /* Internal funcs */ +/* A function to group all the get_properties commands to make them + more efficient over dbus. */ +static void +get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, org_ayatana_dbusmenu_get_properties_reply callback, gpointer user_data) +{ + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + org_ayatana_dbusmenu_get_properties_async(priv->menuproxy, id, properties, callback, user_data); + return; +} + /* Annoying little wrapper to make the right function update */ static void layout_update (DBusGProxy * proxy, guint revision, gint parent, DbusmenuClient * client) @@ -370,7 +381,7 @@ id_update (DBusGProxy * proxy, gint id, DbusmenuClient * client) gchar * properties[1] = {NULL}; /* This gets them all */ g_debug("Getting properties"); g_object_ref(menuitem); - org_ayatana_dbusmenu_get_properties_async(proxy, id, (const gchar **)properties, menuitem_get_properties_cb, menuitem); + get_properties_globber(client, id, (const gchar **)properties, menuitem_get_properties_cb, menuitem); return; } @@ -821,7 +832,7 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it gchar * properties[1] = {NULL}; /* This gets them all */ g_object_ref(item); - org_ayatana_dbusmenu_get_properties_async(proxy, id, (const gchar **)properties, menuitem_get_properties_new_cb, propdata); + get_properties_globber(client, id, (const gchar **)properties, menuitem_get_properties_new_cb, propdata); } else { g_warning("Unable to allocate memory to get properties for menuitem. This menuitem will never be realized."); } @@ -830,7 +841,7 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it /* XXX: We shouldn't need to get the properties everytime we reuse an entry */ gchar * properties[1] = {NULL}; /* This gets them all */ g_object_ref(item); - org_ayatana_dbusmenu_get_properties_async(proxy, id, (const gchar **)properties, menuitem_get_properties_replace_cb, item); + get_properties_globber(client, id, (const gchar **)properties, menuitem_get_properties_replace_cb, item); } xmlNodePtr children; -- cgit v1.2.3 From d7b7d66cea89b1466c9c9d462c648339ef5df1be Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 19 Jul 2010 14:46:00 -0500 Subject: Build our two arrays and look at putting data into them. --- libdbusmenu-glib/client.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index bb7b4ee..73b52e5 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -78,6 +78,9 @@ struct _DbusmenuClientPrivate DBusGProxy * dbusproxy; GHashTable * type_handlers; + + GArray * delayed_property_list; + GArray * delayed_property_listeners; }; typedef struct _newItemPropData newItemPropData; @@ -88,6 +91,14 @@ struct _newItemPropData DbusmenuMenuitem * parent; }; +typedef struct _properties_listener_t properties_listener_t; +struct _properties_listener_t { + DbusmenuClient * client; + gint id; + org_ayatana_dbusmenu_get_properties_reply callback; + gpointer user_data; +}; + #define DBUSMENU_CLIENT_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_TYPE_CLIENT, DbusmenuClientPrivate)) @@ -212,6 +223,9 @@ dbusmenu_client_init (DbusmenuClient *self) priv->type_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + priv->delayed_property_list = g_array_new(TRUE, FALSE, sizeof(gchar *)); + priv->delayed_property_listeners = g_array_new(FALSE, FALSE, sizeof(properties_listener_t)); + return; } @@ -220,6 +234,9 @@ dbusmenu_client_dispose (GObject *object) { DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(object); + /* TODO: Handle delayed_property_list */ + /* TODO: Handle delayed_property_listeners */ + if (priv->layoutcall != NULL) { dbus_g_proxy_cancel_call(priv->menuproxy, priv->layoutcall); priv->layoutcall = NULL; @@ -317,6 +334,32 @@ static void get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, org_ayatana_dbusmenu_get_properties_reply callback, gpointer user_data) { DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + + if (properties == NULL || properties[0] == NULL) { + /* get all case */ + if (priv->delayed_property_list->len != 0) { + /* If there are entries in the list, then we'll need to + remove them all, and start over */ + gchar ** dataregion = (gchar **)g_array_free(priv->delayed_property_list, FALSE); + if (dataregion != NULL) { + g_strfreev(dataregion); + } + priv->delayed_property_list = g_array_new(TRUE, FALSE, sizeof(gchar *)); + } + } else { + /* there could be a list we care about */ + /* TODO: No one uses this today */ + /* TODO: Copy them into the list */ + } + + properties_listener_t listener = {0}; + listener.client = client; + listener.id = id; + listener.callback = callback; + listener.user_data = user_data; + + g_array_append_val(priv->delayed_property_listeners, listener); + org_ayatana_dbusmenu_get_properties_async(priv->menuproxy, id, properties, callback, user_data); return; } -- cgit v1.2.3 From d3eff171a5dbfcdc1da55164097255244b5dc3a6 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 19 Jul 2010 15:09:13 -0500 Subject: Building up an idle function, let's issue this on DBus! --- libdbusmenu-glib/client.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 73b52e5..2328fb1 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -81,6 +81,7 @@ struct _DbusmenuClientPrivate GArray * delayed_property_list; GArray * delayed_property_listeners; + gint delayed_idle; }; typedef struct _newItemPropData newItemPropData; @@ -223,6 +224,7 @@ dbusmenu_client_init (DbusmenuClient *self) priv->type_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + priv->delayed_idle = 0; priv->delayed_property_list = g_array_new(TRUE, FALSE, sizeof(gchar *)); priv->delayed_property_listeners = g_array_new(FALSE, FALSE, sizeof(properties_listener_t)); @@ -234,6 +236,11 @@ dbusmenu_client_dispose (GObject *object) { DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(object); + if (priv->delayed_idle != 0) { + g_source_remove(priv->delayed_idle); + priv->delayed_idle = 0; + } + /* TODO: Handle delayed_property_list */ /* TODO: Handle delayed_property_listeners */ @@ -328,6 +335,55 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) /* Internal funcs */ +/* Call back from getting the group properties, now we need + to unwind and call the various functions. */ +static void +get_properties_callback (DBusGProxy *proxy, GPtrArray *OUT_properties, GError *error, gpointer userdata) +{ + + return; +} + +/* Idle handler to send out all of our property requests as one big + lovely property request. */ +static gboolean +get_properties_idle (gpointer user_data) +{ + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(user_data); + //org_ayatana_dbusmenu_get_properties_async(priv->menuproxy, id, properties, callback, user_data); + + if (priv->delayed_property_listeners->len == 0) { + g_warning("Odd, idle func got no listeners."); + return FALSE; + } + + GArray * idlist = g_array_new(FALSE, FALSE, sizeof(gint)); + gint i; + for (i = 0; i < priv->delayed_property_listeners->len; i++) { + g_array_append_val(idlist, g_array_index(priv->delayed_property_listeners, properties_listener_t, i).id); + } + + org_ayatana_dbusmenu_get_group_properties_async(priv->menuproxy, idlist, (const gchar **)priv->delayed_property_list->data, get_properties_callback, priv->delayed_property_listeners); + + /* Free ID List */ + g_array_free(idlist, TRUE); + + /* Free properties */ + gchar ** dataregion = (gchar **)g_array_free(priv->delayed_property_list, FALSE); + if (dataregion != NULL) { + g_strfreev(dataregion); + } + priv->delayed_property_list = g_array_new(TRUE, FALSE, sizeof(gchar *)); + + /* Rebuild the listeners */ + priv->delayed_property_listeners = g_array_new(FALSE, FALSE, sizeof(properties_listener_t)); + + /* Make sure we set for a new idle */ + priv->delayed_idle = 0; + + return FALSE; +} + /* A function to group all the get_properties commands to make them more efficient over dbus. */ static void @@ -360,7 +416,10 @@ get_properties_globber (DbusmenuClient * client, gint id, const gchar ** propert g_array_append_val(priv->delayed_property_listeners, listener); - org_ayatana_dbusmenu_get_properties_async(priv->menuproxy, id, properties, callback, user_data); + if (priv->delayed_idle == 0) { + priv->delayed_idle = g_idle_add(get_properties_idle, client); + } + return; } -- cgit v1.2.3 From fe94f6d9c9e676565e73bcd7597540411901f87b Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 19 Jul 2010 15:49:00 -0500 Subject: Fleshing out the callback, need some more data to test though. --- libdbusmenu-glib/client.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 2328fb1..ff5b33b 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -340,6 +340,33 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) static void get_properties_callback (DBusGProxy *proxy, GPtrArray *OUT_properties, GError *error, gpointer userdata) { + GArray * listeners = (GArray *)userdata; + int i; + + if (error != NULL) { + /* If we get an error, all our callbacks need to hear about it. */ + g_warning("Group Properties error: %s", error->message); + for (i = 0; i < listeners->len; i++) { + properties_listener_t * listener = &g_array_index(listeners, properties_listener_t, i); + listener->callback(proxy, NULL, error, listener->user_data); + } + g_array_free(listeners, TRUE); + return; + } + + /* Callback all the folks we can find */ + for (i = 0; i < OUT_properties->len; i++) { + g_error("Properties type: %s", G_OBJECT_TYPE_NAME(g_ptr_array_index(OUT_properties, i))); + + } + + /* Provide errors for those who we can't */ + for (i = 0; i < listeners->len; i++) { + + } + + /* Clean up */ + g_array_free(listeners, TRUE); return; } @@ -357,6 +384,7 @@ get_properties_idle (gpointer user_data) return FALSE; } + /* Build up an ID list to pass */ GArray * idlist = g_array_new(FALSE, FALSE, sizeof(gint)); gint i; for (i = 0; i < priv->delayed_property_listeners->len; i++) { -- cgit v1.2.3 From e9e9462196b283161cefff84f19a2c9a6130b3ad Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 19 Jul 2010 21:32:48 -0500 Subject: Unpacking the array and getting the fields out. --- libdbusmenu-glib/client.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index ff5b33b..7c040ce 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -343,6 +343,8 @@ get_properties_callback (DBusGProxy *proxy, GPtrArray *OUT_properties, GError *e GArray * listeners = (GArray *)userdata; int i; + g_debug("Get properties callback: %d", OUT_properties->len); + if (error != NULL) { /* If we get an error, all our callbacks need to hear about it. */ g_warning("Group Properties error: %s", error->message); @@ -356,7 +358,25 @@ get_properties_callback (DBusGProxy *proxy, GPtrArray *OUT_properties, GError *e /* Callback all the folks we can find */ for (i = 0; i < OUT_properties->len; i++) { - g_error("Properties type: %s", G_OBJECT_TYPE_NAME(g_ptr_array_index(OUT_properties, i))); + GValueArray * varray = (GValueArray *)g_ptr_array_index(OUT_properties, i); + + if (varray->n_values != 2) { + g_warning("Value Array is %d entries long but we expected 2.", varray->n_values); + continue; + } + + GValue * vid = g_value_array_get_nth(varray, 0); + GValue * vproperties = g_value_array_get_nth(varray, 1); + + if (G_VALUE_TYPE(vid) != G_TYPE_INT) { + g_warning("ID Entry not holding an int: %s", G_VALUE_TYPE_NAME(vid)); + } + if (G_VALUE_TYPE(vproperties) != dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) { + g_warning("Properties Entry not holding an a{sv}: %s", G_VALUE_TYPE_NAME(vproperties)); + } + + // gint id = g_value_get_int(vid); + // GHashTable * properties = g_value_get_boxed(vproperties); } -- cgit v1.2.3 From f034bdd080b7579b0e5e57c8f34780a756bb8b17 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 09:11:01 -0500 Subject: Finding the listener and calling it's callback. --- libdbusmenu-glib/client.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 7c040ce..ab00636 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -335,6 +335,23 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) /* Internal funcs */ +/* Quick little function to search through the listeners and find + one that matches an ID */ +static properties_listener_t * +find_listener (GArray * listeners, guint index, gint id) +{ + if (index >= listeners->len) { + return NULL; + } + + properties_listener_t * retval = &g_array_index(listeners, properties_listener_t, index); + if (retval->id == id) { + return retval; + } + + return find_listener(listeners, index + 1, id); +} + /* Call back from getting the group properties, now we need to unwind and call the various functions. */ static void @@ -375,9 +392,12 @@ get_properties_callback (DBusGProxy *proxy, GPtrArray *OUT_properties, GError *e g_warning("Properties Entry not holding an a{sv}: %s", G_VALUE_TYPE_NAME(vproperties)); } - // gint id = g_value_get_int(vid); - // GHashTable * properties = g_value_get_boxed(vproperties); + gint id = g_value_get_int(vid); + GHashTable * properties = g_value_get_boxed(vproperties); + + properties_listener_t * listener = find_listener(listeners, 0, id); + listener->callback(proxy, properties, NULL, listener->user_data); } /* Provide errors for those who we can't */ -- cgit v1.2.3 From 08fae7619012309a0ef9024c1e91effc7bf99529 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 09:38:13 -0500 Subject: Tracking who we reply to, and ensuring that we reply to everyone. --- libdbusmenu-glib/client.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index ab00636..4faf7c6 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -94,10 +94,10 @@ struct _newItemPropData typedef struct _properties_listener_t properties_listener_t; struct _properties_listener_t { - DbusmenuClient * client; gint id; org_ayatana_dbusmenu_get_properties_reply callback; gpointer user_data; + gboolean replied; }; #define DBUSMENU_CLIENT_GET_PRIVATE(o) \ @@ -398,11 +398,22 @@ get_properties_callback (DBusGProxy *proxy, GPtrArray *OUT_properties, GError *e properties_listener_t * listener = find_listener(listeners, 0, id); listener->callback(proxy, properties, NULL, listener->user_data); + listener->replied = TRUE; } /* Provide errors for those who we can't */ + GError * localerror = NULL; for (i = 0; i < listeners->len; i++) { - + properties_listener_t * listener = &g_array_index(listeners, properties_listener_t, i); + if (!listener->replied) { + if (localerror == NULL) { + g_set_error_literal(&localerror, 0, 0, "Error getting properties for ID"); + } + listener->callback(proxy, NULL, localerror, listener->user_data); + } + } + if (localerror != NULL) { + g_error_free(localerror); } /* Clean up */ @@ -477,10 +488,10 @@ get_properties_globber (DbusmenuClient * client, gint id, const gchar ** propert } properties_listener_t listener = {0}; - listener.client = client; listener.id = id; listener.callback = callback; listener.user_data = user_data; + listener.replied = FALSE; g_array_append_val(priv->delayed_property_listeners, listener); -- cgit v1.2.3 From 7941bec0ab70845d60efd374b5dae4976197e4b5 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 09:55:08 -0500 Subject: Cleaning up our arrays, with some callbacks, eh, it's what we gotta do. --- libdbusmenu-glib/client.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 4faf7c6..5e8c08a 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -241,8 +241,38 @@ dbusmenu_client_dispose (GObject *object) priv->delayed_idle = 0; } - /* TODO: Handle delayed_property_list */ - /* TODO: Handle delayed_property_listeners */ + /* Only used for queueing up a new command, so we can + just drop this array. */ + if (priv->delayed_property_list == NULL) { + gchar ** dataregion = (gchar **)g_array_free(priv->delayed_property_list, FALSE); + if (dataregion != NULL) { + g_strfreev(dataregion); + } + priv->delayed_property_list = NULL; + } + + if (priv->delayed_property_listeners == NULL) { + gint i; + GError * localerror = NULL; + + /* Making sure all the callbacks get called so that if they had + memory in their user_data that needs to be free'd that happens. */ + for (i = 0; i < priv->delayed_property_listeners->len; i++) { + properties_listener_t * listener = &g_array_index(priv->delayed_property_listeners, properties_listener_t, i); + if (!listener->replied) { + if (localerror == NULL) { + g_set_error_literal(&localerror, 0, 0, "DbusmenuClient Shutdown"); + } + listener->callback(priv->menuproxy, NULL, localerror, listener->user_data); + } + } + if (localerror != NULL) { + g_error_free(localerror); + } + + g_array_free(priv->delayed_property_listeners, TRUE); + priv->delayed_property_listeners = NULL; + } if (priv->layoutcall != NULL) { dbus_g_proxy_cancel_call(priv->menuproxy, priv->layoutcall); -- cgit v1.2.3 From 2e95e1f828ce1b75331e99883244c94f7629408f Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 10:14:02 -0500 Subject: Putting properties debug message under massive debugging. --- libdbusmenu-glib/client.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 5e8c08a..bd391e0 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -390,7 +390,9 @@ get_properties_callback (DBusGProxy *proxy, GPtrArray *OUT_properties, GError *e GArray * listeners = (GArray *)userdata; int i; + #ifdef MASSIVEDEBUGGING g_debug("Get properties callback: %d", OUT_properties->len); + #endif if (error != NULL) { /* If we get an error, all our callbacks need to hear about it. */ -- cgit v1.2.3 From 57547736e1a274928546a291147a199f67d1bc50 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 11:00:35 -0500 Subject: Ensuring that we only reply once. Shouldn't be an issue... --- libdbusmenu-glib/client.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index bd391e0..84e0efc 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -429,8 +429,12 @@ get_properties_callback (DBusGProxy *proxy, GPtrArray *OUT_properties, GError *e properties_listener_t * listener = find_listener(listeners, 0, id); - listener->callback(proxy, properties, NULL, listener->user_data); - listener->replied = TRUE; + if (!listener->replied) { + listener->callback(proxy, properties, NULL, listener->user_data); + listener->replied = TRUE; + } else { + g_warning("Odd, we've already replied to the listener on ID %d", id); + } } /* Provide errors for those who we can't */ -- cgit v1.2.3 From 90ebe32795a5af7f659da78ba96414c49c268b46 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 11:08:32 -0500 Subject: Making sure we got a listener before we go all callin' stuff on it. --- libdbusmenu-glib/client.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 84e0efc..1c962dd 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -428,6 +428,10 @@ get_properties_callback (DBusGProxy *proxy, GPtrArray *OUT_properties, GError *e GHashTable * properties = g_value_get_boxed(vproperties); properties_listener_t * listener = find_listener(listeners, 0, id); + if (listener == NULL) { + g_warning("Unable to find listener for ID %d", id); + continue; + } if (!listener->replied) { listener->callback(proxy, properties, NULL, listener->user_data); -- cgit v1.2.3 From bb0a4f168ea59d6afdfbe9a5c9473ef1ee6f37ad Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 11:26:08 -0500 Subject: Add a check to protect against adding the same ID twice to the queue. --- libdbusmenu-glib/client.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 1c962dd..e962f78 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -509,6 +509,14 @@ static void get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, org_ayatana_dbusmenu_get_properties_reply callback, gpointer user_data) { DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + if (find_listener(priv->delayed_property_listeners, 0, id) != NULL) { + g_warning("Asking for properties from same ID twice: %d", id); + GError * localerror = NULL; + g_set_error_literal(&localerror, 0, 0, "ID already queued"); + callback(priv->menuproxy, NULL, localerror, user_data); + g_error_free(localerror); + return; + } if (properties == NULL || properties[0] == NULL) { /* get all case */ -- cgit v1.2.3 From 9abd75fc8f41e0d1642bfd8dbf3cb6aaae36dfda Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 11:31:36 -0500 Subject: Adding in an error domain, because, well, GError likes that. --- libdbusmenu-glib/client.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index e962f78..b142e15 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -122,6 +122,7 @@ static void update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError static void update_layout (DbusmenuClient * client); static void menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data); static void get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, org_ayatana_dbusmenu_get_properties_reply callback, gpointer user_data); +static GQuark error_domain (void); /* Build a type */ G_DEFINE_TYPE (DbusmenuClient, dbusmenu_client, G_TYPE_OBJECT); @@ -261,7 +262,7 @@ dbusmenu_client_dispose (GObject *object) properties_listener_t * listener = &g_array_index(priv->delayed_property_listeners, properties_listener_t, i); if (!listener->replied) { if (localerror == NULL) { - g_set_error_literal(&localerror, 0, 0, "DbusmenuClient Shutdown"); + g_set_error_literal(&localerror, error_domain(), 0, "DbusmenuClient Shutdown"); } listener->callback(priv->menuproxy, NULL, localerror, listener->user_data); } @@ -365,6 +366,16 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) /* Internal funcs */ +static GQuark +error_domain (void) +{ + static GQuark error = 0; + if (error == 0) { + error = g_quark_from_static_string(G_LOG_DOMAIN "-CLIENT"); + } + return error; +} + /* Quick little function to search through the listeners and find one that matches an ID */ static properties_listener_t * @@ -447,7 +458,7 @@ get_properties_callback (DBusGProxy *proxy, GPtrArray *OUT_properties, GError *e properties_listener_t * listener = &g_array_index(listeners, properties_listener_t, i); if (!listener->replied) { if (localerror == NULL) { - g_set_error_literal(&localerror, 0, 0, "Error getting properties for ID"); + g_set_error_literal(&localerror, error_domain(), 0, "Error getting properties for ID"); } listener->callback(proxy, NULL, localerror, listener->user_data); } @@ -512,7 +523,7 @@ get_properties_globber (DbusmenuClient * client, gint id, const gchar ** propert if (find_listener(priv->delayed_property_listeners, 0, id) != NULL) { g_warning("Asking for properties from same ID twice: %d", id); GError * localerror = NULL; - g_set_error_literal(&localerror, 0, 0, "ID already queued"); + g_set_error_literal(&localerror, error_domain(), 0, "ID already queued"); callback(priv->menuproxy, NULL, localerror, user_data); g_error_free(localerror); return; -- cgit v1.2.3 From 508c02c4188070e326839a3bbbf3e161592d7e4f Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 11:39:56 -0500 Subject: Fixing error handling in get_properties_new_cb --- libdbusmenu-glib/client.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index b142e15..b59aecd 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -906,16 +906,19 @@ menuitem_get_properties_replace_cb (DBusGProxy * proxy, GHashTable * properties, static void menuitem_get_properties_new_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data) { + g_return_if_fail(data != NULL); + newItemPropData * propdata = (newItemPropData *)data; + if (error != NULL) { g_warning("Error getting properties on a new menuitem: %s", error->message); - g_object_unref(data); + g_object_unref(propdata->item); + g_free(data); return; } - g_return_if_fail(data != NULL); - newItemPropData * propdata = (newItemPropData *)data; DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(propdata->client); + /* Extra ref as get_properties will unref once itself */ g_object_ref(propdata->item); menuitem_get_properties_cb (proxy, properties, error, propdata->item); -- cgit v1.2.3 From ae9a8d2c2fa9b657b20516737bf72dbc2be7102d Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 12:58:29 -0500 Subject: Slight optimization to not create a useless structure. --- libdbusmenu-glib/client.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index b59aecd..b68c3b3 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -618,10 +618,9 @@ id_update (DBusGProxy * proxy, gint id, DbusmenuClient * client) DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id); g_return_if_fail(menuitem != NULL); - gchar * properties[1] = {NULL}; /* This gets them all */ g_debug("Getting properties"); g_object_ref(menuitem); - get_properties_globber(client, id, (const gchar **)properties, menuitem_get_properties_cb, menuitem); + get_properties_globber(client, id, NULL, menuitem_get_properties_cb, menuitem); return; } @@ -1073,18 +1072,16 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it propdata->item = item; propdata->parent = parent; - gchar * properties[1] = {NULL}; /* This gets them all */ g_object_ref(item); - get_properties_globber(client, id, (const gchar **)properties, menuitem_get_properties_new_cb, propdata); + get_properties_globber(client, id, NULL, menuitem_get_properties_new_cb, propdata); } else { g_warning("Unable to allocate memory to get properties for menuitem. This menuitem will never be realized."); } } else { /* Refresh the properties */ /* XXX: We shouldn't need to get the properties everytime we reuse an entry */ - gchar * properties[1] = {NULL}; /* This gets them all */ g_object_ref(item); - get_properties_globber(client, id, (const gchar **)properties, menuitem_get_properties_replace_cb, item); + get_properties_globber(client, id, NULL, menuitem_get_properties_replace_cb, item); } xmlNodePtr children; -- cgit v1.2.3 From 871df0f10c49d538d80a405c1420bddf8baff79b Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 13:21:14 -0500 Subject: Pulling out the new item code into a function --- libdbusmenu-glib/client.c | 50 +++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 19 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index b59aecd..baa3e93 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1038,6 +1038,36 @@ dbusmenu_client_send_about_to_show(DbusmenuClient * client, gint id, void (*cb)( return; } +/* Builds a new child with property requests and everything + else to clean up the code a bit */ +static DbusmenuMenuitem * +parse_layout_new_child (gint id, DbusmenuClient * client, DbusmenuMenuitem * parent) +{ + DbusmenuMenuitem * item = NULL; + + /* Build a new item */ + item = DBUSMENU_MENUITEM(dbusmenu_client_menuitem_new(id, client)); + if (parent == NULL) { + dbusmenu_menuitem_set_root(item, TRUE); + } + + /* Get the properties queued up for this item */ + /* Not happy allocating about this, but I need these :( */ + newItemPropData * propdata = g_new0(newItemPropData, 1); + if (propdata != NULL) { + propdata->client = client; + propdata->item = item; + propdata->parent = parent; + + g_object_ref(item); + get_properties_globber(client, id, NULL, menuitem_get_properties_new_cb, propdata); + } else { + g_warning("Unable to allocate memory to get properties for menuitem. This menuitem will never be realized."); + } + + return item; +} + /* Parse recursively through the XML and make it into objects as need be */ static DbusmenuMenuitem * @@ -1060,25 +1090,7 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it } /* Build a new item */ - item = DBUSMENU_MENUITEM(dbusmenu_client_menuitem_new(id, client)); - if (parent == NULL) { - dbusmenu_menuitem_set_root(item, TRUE); - } - - /* Get the properties queued up for this item */ - /* Not happy about this, but I need these :( */ - newItemPropData * propdata = g_new0(newItemPropData, 1); - if (propdata != NULL) { - propdata->client = client; - propdata->item = item; - propdata->parent = parent; - - gchar * properties[1] = {NULL}; /* This gets them all */ - g_object_ref(item); - get_properties_globber(client, id, (const gchar **)properties, menuitem_get_properties_new_cb, propdata); - } else { - g_warning("Unable to allocate memory to get properties for menuitem. This menuitem will never be realized."); - } + item = parse_layout_new_child(id, client, parent); } else { /* Refresh the properties */ /* XXX: We shouldn't need to get the properties everytime we reuse an entry */ -- cgit v1.2.3 From 42f883725a882b1391e79d96efbdcead50dae98c Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 13:24:22 -0500 Subject: Pulling out the update code into it's own function as well. --- libdbusmenu-glib/client.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index baa3e93..257ad3f 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1068,6 +1068,15 @@ parse_layout_new_child (gint id, DbusmenuClient * client, DbusmenuMenuitem * par return item; } +/* Refresh the properties on this item */ +static void +parse_layout_update (DbusmenuMenuitem * item, DbusmenuClient * client) +{ + g_object_ref(item); + get_properties_globber(client, dbusmenu_menuitem_get_id(item), NULL, menuitem_get_properties_replace_cb, item); + return; +} + /* Parse recursively through the XML and make it into objects as need be */ static DbusmenuMenuitem * @@ -1092,11 +1101,7 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it /* Build a new item */ item = parse_layout_new_child(id, client, parent); } else { - /* Refresh the properties */ - /* XXX: We shouldn't need to get the properties everytime we reuse an entry */ - gchar * properties[1] = {NULL}; /* This gets them all */ - g_object_ref(item); - get_properties_globber(client, id, (const gchar **)properties, menuitem_get_properties_replace_cb, item); + parse_layout_update(item, client); } xmlNodePtr children; -- cgit v1.2.3 From 4e30bfbc1203e5c3135f5f541cf7c8ea3efcb62c Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 13:34:18 -0500 Subject: Making it so that we create the child, and then move down it's XML tree. --- libdbusmenu-glib/client.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 257ad3f..aad9fdc 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1127,17 +1127,15 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it } } - DbusmenuMenuitem * newchildmi = parse_layout_xml(client, children, childmi, item, proxy); - - if (newchildmi != childmi) { - if (childmi != NULL) { - dbusmenu_menuitem_child_delete(item, childmi); - } - dbusmenu_menuitem_child_add_position(item, newchildmi, position); - g_object_unref(newchildmi); + if (childmi == NULL) { + childmi = parse_layout_new_child(id, client, parent); + dbusmenu_menuitem_child_add_position(item, childmi, position); + g_object_unref(childmi); } else { dbusmenu_menuitem_child_reorder(item, childmi, position); } + + parse_layout_xml(client, children, childmi, item, proxy); } /* g_debug("Stopping old children: %d", g_list_length(oldchildren)); */ -- cgit v1.2.3 From 88f54f11f9020b5ade4cc4e7b8df2d9f24b83622 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 13:49:06 -0500 Subject: Turns out you have to pass the right parameters to EVERY function. They don't teach you that in school. Test suite FTW. --- libdbusmenu-glib/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index aad9fdc..5b9e406 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1128,7 +1128,7 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it } if (childmi == NULL) { - childmi = parse_layout_new_child(id, client, parent); + childmi = parse_layout_new_child(childid, client, item); dbusmenu_menuitem_child_add_position(item, childmi, position); g_object_unref(childmi); } else { -- cgit v1.2.3 From 7180f1940bfa95ed9cc7d06a38ed8e459b8aa18f Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 13:55:10 -0500 Subject: Switching to the assumption that the item is made before calling parse_layout_xml(), and making it true. --- libdbusmenu-glib/client.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 5b9e406..e9a4e59 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1089,20 +1089,9 @@ 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) { - dbusmenu_menuitem_child_delete(parent, item); - } - item = NULL; - } - /* Build a new item */ - item = parse_layout_new_child(id, client, parent); - } else { - parse_layout_update(item, client); - } + g_return_val_if_fail(item != NULL, NULL); + g_return_val_if_fail(id == dbusmenu_menuitem_get_id(item), NULL); xmlNodePtr children; guint position; @@ -1133,6 +1122,7 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it g_object_unref(childmi); } else { dbusmenu_menuitem_child_reorder(item, childmi, position); + parse_layout_update(childmi, client); } parse_layout_xml(client, children, childmi, item, proxy); @@ -1175,6 +1165,10 @@ parse_layout (DbusmenuClient * client, const gchar * layout) DbusmenuMenuitem * oldroot = priv->root; + if (priv->root == NULL) { + priv->root = parse_layout_new_child(0, client, NULL); + } + priv->root = parse_layout_xml(client, root, priv->root, NULL, priv->menuproxy); xmlFreeDoc(xmldoc); -- cgit v1.2.3 From 25fa88e0f02624887022ff78e987fecfadb8ffaf Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 14:01:12 -0500 Subject: Updating properties on the root node. --- libdbusmenu-glib/client.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index e9a4e59..67c5354 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1167,6 +1167,8 @@ parse_layout (DbusmenuClient * client, const gchar * layout) if (priv->root == NULL) { priv->root = parse_layout_new_child(0, client, NULL); + } else { + parse_layout_update(priv->root, client); } priv->root = parse_layout_xml(client, root, priv->root, NULL, priv->menuproxy); -- cgit v1.2.3 From 464535d5f3482e0ff08834a79512ce04dfd5883e Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 15:04:40 -0500 Subject: Move the parse to the end and make it dual pass through the list of children. --- libdbusmenu-glib/client.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 67c5354..078b6ad 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1124,8 +1124,6 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it dbusmenu_menuitem_child_reorder(item, childmi, position); parse_layout_update(childmi, client); } - - parse_layout_xml(client, children, childmi, item, proxy); } /* g_debug("Stopping old children: %d", g_list_length(oldchildren)); */ @@ -1139,6 +1137,23 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it } g_list_free(oldchildren); + /* We've got everything built up at this node and reconcilled */ + /* now it's time to recurse down the tree. */ + children = node->children; + GList * childmis = dbusmenu_menuitem_get_children(item); + while (children != NULL && childmis != NULL) { + parse_layout_xml(client, children, DBUSMENU_MENUITEM(childmis->data), item, proxy); + + children = children->next; + childmis = g_list_next(childmis); + } + if (children != NULL) { + g_warning("Sync failed, now we've got extra XML nodes."); + } + if (childmis != NULL) { + g_warning("Sync failed, now we've got extra menu items."); + } + return item; } -- cgit v1.2.3 From 2ef5fad1187c79a33dae89971cc75d5ed7287c42 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 15:07:22 -0500 Subject: Adding in some comments. --- libdbusmenu-glib/client.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 078b6ad..4dcf90c 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1082,6 +1082,7 @@ parse_layout_update (DbusmenuMenuitem * item, DbusmenuClient * client) static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, DBusGProxy * proxy) { + /* First verify and figure out what we've got */ gint id = parse_node_get_id(node); if (id < 0) { return NULL; @@ -1093,11 +1094,14 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it g_return_val_if_fail(item != NULL, NULL); g_return_val_if_fail(id == dbusmenu_menuitem_get_id(item), NULL); + /* Some variables */ xmlNodePtr children; guint position; GList * oldchildren = g_list_copy(dbusmenu_menuitem_get_children(item)); /* g_debug("Starting old children: %d", g_list_length(oldchildren)); */ + /* Go through all the XML Nodes and make sure that we have menuitems + to cover those XML nodes. */ for (children = node->children, position = 0; children != NULL; children = children->next, position++) { /* g_debug("Looking at child: %d", position); */ gint childid = parse_node_get_id(children); @@ -1106,6 +1110,8 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it } DbusmenuMenuitem * childmi = NULL; + /* First see if we can recycle a node that we've already built + on this menu item */ GList * childsearch = NULL; for (childsearch = oldchildren; childsearch != NULL; childsearch = g_list_next(childsearch)) { DbusmenuMenuitem * cs_mi = DBUSMENU_MENUITEM(childsearch->data); @@ -1117,16 +1123,19 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it } if (childmi == NULL) { + /* If we can't recycle, then we build a new one */ childmi = parse_layout_new_child(childid, client, item); dbusmenu_menuitem_child_add_position(item, childmi, position); g_object_unref(childmi); } else { + /* If we can recycle, make sure it's in the right place */ dbusmenu_menuitem_child_reorder(item, childmi, position); parse_layout_update(childmi, client); } } - /* g_debug("Stopping old children: %d", g_list_length(oldchildren)); */ + /* Remove any children that are no longer used by this version of + the layout. */ GList * oldchildleft = NULL; for (oldchildleft = oldchildren; oldchildleft != NULL; oldchildleft = g_list_next(oldchildleft)) { DbusmenuMenuitem * oldmi = DBUSMENU_MENUITEM(oldchildleft->data); -- cgit v1.2.3 From 7467274b62cd6db89dc51a9b0e4ad0b5b3bc6f91 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 15:15:24 -0500 Subject: After getting all the nodes requested at a particular level we should flush the properties requests. --- libdbusmenu-glib/client.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 4dcf90c..5ecfbde 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -514,6 +514,25 @@ get_properties_idle (gpointer user_data) return FALSE; } +/* Forces a call out to start getting properties with the menu items + that we have queued up already. */ +static void +get_properties_flush (DbusmenuClient * client) +{ + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + + if (priv->delayed_idle != 0) { + g_source_remove(priv->delayed_idle); + priv->delayed_idle = 0; + } + + get_properties_idle(client); + + dbus_g_connection_flush(priv->session_bus); + + return; +} + /* A function to group all the get_properties commands to make them more efficient over dbus. */ static void @@ -1147,6 +1166,10 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it g_list_free(oldchildren); /* We've got everything built up at this node and reconcilled */ + + /* Flush the properties requests */ + get_properties_flush(client); + /* now it's time to recurse down the tree. */ children = node->children; GList * childmis = dbusmenu_menuitem_get_children(item); -- cgit v1.2.3 From 76b3d5020bef447e78cc6205309464b411b13836 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 15:17:50 -0500 Subject: If there's no idle setup we don't need to worry about flushing, there's nothing to do. --- libdbusmenu-glib/client.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 5ecfbde..5e1fe0c 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -521,11 +521,13 @@ get_properties_flush (DbusmenuClient * client) { DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); - if (priv->delayed_idle != 0) { - g_source_remove(priv->delayed_idle); - priv->delayed_idle = 0; + if (priv->delayed_idle == 0) { + return; } + g_source_remove(priv->delayed_idle); + priv->delayed_idle = 0; + get_properties_idle(client); dbus_g_connection_flush(priv->session_bus); -- cgit v1.2.3 From dc103227e86bf67c8c9118010887f8ba7c924e35 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 16 Aug 2010 10:58:16 -0500 Subject: Handling comment nodes better. --- libdbusmenu-glib/client.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 7c73b7b..98049d5 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1126,6 +1126,9 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it /* g_debug("Looking at child: %d", position); */ gint childid = parse_node_get_id(children); if (childid < 0) { + /* Don't increment the position when there isn't a valid + node in the XML tree. It's probably a comment. */ + position--; continue; } DbusmenuMenuitem * childmi = NULL; @@ -1143,11 +1146,13 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it } if (childmi == NULL) { + g_debug("Building new menu item %d at position %d", childid, position); /* If we can't recycle, then we build a new one */ childmi = parse_layout_new_child(childid, client, item); dbusmenu_menuitem_child_add_position(item, childmi, position); g_object_unref(childmi); } else { + g_debug("Recycling menu item %d at position %d", childid, position); /* If we can recycle, make sure it's in the right place */ dbusmenu_menuitem_child_reorder(item, childmi, position); parse_layout_update(childmi, client); @@ -1175,6 +1180,19 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it children = node->children; GList * childmis = dbusmenu_menuitem_get_children(item); while (children != NULL && childmis != NULL) { + gint xmlid = parse_node_get_id(children); + /* If this isn't a valid menu item we need to move on + until we have one. This avoids things like comments. */ + if (xmlid < 0) { + children = children->next; + continue; + } + + #if 1 + gint miid = dbusmenu_menuitem_get_id(DBUSMENU_MENUITEM(childmis->data)); + g_debug("Recursing parse_layout_xml. XML ID: %d MI ID: %d", xmlid, miid); + #endif + parse_layout_xml(client, children, DBUSMENU_MENUITEM(childmis->data), item, proxy); children = children->next; -- cgit v1.2.3 From d2bd004b2cbb7a383d1b75200fe857091f6fe89c Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 16 Aug 2010 10:59:53 -0500 Subject: Putting the debugging messages under MASSIVEDEBUGGING --- libdbusmenu-glib/client.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 98049d5..73a7aac 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1146,13 +1146,17 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it } if (childmi == NULL) { + #ifdef MASSIVEDEBUGGING g_debug("Building new menu item %d at position %d", childid, position); + #endif /* If we can't recycle, then we build a new one */ childmi = parse_layout_new_child(childid, client, item); dbusmenu_menuitem_child_add_position(item, childmi, position); g_object_unref(childmi); } else { + #ifdef MASSIVEDEBUGGING g_debug("Recycling menu item %d at position %d", childid, position); + #endif /* If we can recycle, make sure it's in the right place */ dbusmenu_menuitem_child_reorder(item, childmi, position); parse_layout_update(childmi, client); @@ -1188,7 +1192,7 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it continue; } - #if 1 + #ifdef MASSIVEDEBUGGING gint miid = dbusmenu_menuitem_get_id(DBUSMENU_MENUITEM(childmis->data)); g_debug("Recursing parse_layout_xml. XML ID: %d MI ID: %d", xmlid, miid); #endif -- cgit v1.2.3 From 98b759aaa21779694f5708a93d900c3204742133 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 17 Aug 2010 16:12:48 -0500 Subject: Getting the signal for the request to activate the item --- libdbusmenu-glib/client.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 73a7aac..d127b21 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -123,6 +123,7 @@ static void update_layout (DbusmenuClient * client); static void menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data); static void get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, org_ayatana_dbusmenu_get_properties_reply callback, gpointer user_data); static GQuark error_domain (void); +static void item_activated (DBusGProxy * proxy, gint id, gint timestamp, DbusmenuClient * client); /* Build a type */ G_DEFINE_TYPE (DbusmenuClient, dbusmenu_client, G_TYPE_OBJECT); @@ -582,6 +583,14 @@ get_properties_globber (DbusmenuClient * client, gint id, const gchar ** propert return; } +/* Called when a server item wants to activate the menu */ +static void +item_activated (DBusGProxy * proxy, gint id, gint timestamp, DbusmenuClient * client) +{ + + return; +} + /* Annoying little wrapper to make the right function update */ static void layout_update (DBusGProxy * proxy, guint revision, gint parent, DbusmenuClient * client) @@ -821,6 +830,10 @@ build_proxies (DbusmenuClient * client) dbus_g_proxy_add_signal(priv->menuproxy, "ItemUpdated", G_TYPE_INT, G_TYPE_INVALID); dbus_g_proxy_connect_signal(priv->menuproxy, "ItemUpdated", G_CALLBACK(id_update), client, NULL); + dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__INT_UINT, G_TYPE_NONE, G_TYPE_INT, G_TYPE_UINT, G_TYPE_INVALID); + dbus_g_proxy_add_signal(priv->menuproxy, "ItemActivationRequested", G_TYPE_INT, G_TYPE_UINT, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(priv->menuproxy, "ItemActivationRequested", G_CALLBACK(item_activated), client, NULL); + update_layout(client); return; -- cgit v1.2.3 From 65d0fad51540858ca7a8cf850f6d0c3e0feaf949 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 17 Aug 2010 16:45:09 -0500 Subject: Getting to the menu item. --- libdbusmenu-glib/client.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index d127b21..25d64b6 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -123,7 +123,7 @@ static void update_layout (DbusmenuClient * client); static void menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data); static void get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, org_ayatana_dbusmenu_get_properties_reply callback, gpointer user_data); static GQuark error_domain (void); -static void item_activated (DBusGProxy * proxy, gint id, gint timestamp, DbusmenuClient * client); +static void item_activated (DBusGProxy * proxy, gint id, guint timestamp, DbusmenuClient * client); /* Build a type */ G_DEFINE_TYPE (DbusmenuClient, dbusmenu_client, G_TYPE_OBJECT); @@ -585,8 +585,21 @@ get_properties_globber (DbusmenuClient * client, gint id, const gchar ** propert /* Called when a server item wants to activate the menu */ static void -item_activated (DBusGProxy * proxy, gint id, gint timestamp, DbusmenuClient * client) +item_activated (DBusGProxy * proxy, gint id, guint timestamp, DbusmenuClient * client) { + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + + if (priv->root == NULL) { + g_warning("Asked to activate item %d when we don't have a menu structure.", id); + return; + } + + DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id); + if (menuitem == NULL) { + g_warning("Unable to find menu item %d to activate.", id); + return; + } + return; } -- cgit v1.2.3 From 6566022e1f2afc97d6ffafbec3ca54bf63fd19f9 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 17 Aug 2010 20:42:22 -0500 Subject: Adding a new signal for when items activate. --- libdbusmenu-glib/client.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 25d64b6..7b1a762 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -41,6 +41,7 @@ License version 3 and version 2.1 along with this program. If not, see #include "client-menuitem.h" #include "dbusmenu-client.h" #include "server-marshal.h" +#include "client-marshal.h" /* Properties */ enum { @@ -54,6 +55,7 @@ enum { LAYOUT_UPDATED, ROOT_CHANGED, NEW_MENUITEM, + ITEM_ACTIVATE, LAST_SIGNAL }; @@ -188,6 +190,22 @@ dbusmenu_client_class_init (DbusmenuClientClass *klass) NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); + /** + DbusmenuClient::item-activate: + @arg0: The #DbusmenuClient object + @arg1: The #DbusmenuMenuitem activated + @arg2: A timestamp that the event happened at + + Signaled when the server wants to activate an item in + order to display the menu. + */ + signals[ITEM_ACTIVATE] = g_signal_new(DBUSMENU_CLIENT_SIGNAL_ITEM_ACTIVATE, + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (DbusmenuClientClass, item_activate), + NULL, NULL, + _dbusmenu_client_marshal_VOID__OBJECT_UINT, + G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_UINT); g_object_class_install_property (object_class, PROP_DBUSOBJECT, g_param_spec_string(DBUSMENU_CLIENT_PROP_DBUS_OBJECT, "DBus Object we represent", -- cgit v1.2.3 From 8fd2e5cea3d717c2332aeefe9c74f6ac9bebe4af Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 17 Aug 2010 20:45:19 -0500 Subject: Passing the signal up the pipe --- libdbusmenu-glib/client.c | 1 + 1 file changed, 1 insertion(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 7b1a762..cc91b32 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -618,6 +618,7 @@ item_activated (DBusGProxy * proxy, gint id, guint timestamp, DbusmenuClient * c return; } + g_signal_emit(G_OBJECT(client), signals[ITEM_ACTIVATE], 0, menuitem, timestamp, TRUE); return; } -- cgit v1.2.3 From 3cd94732c2393b0ff73b9e89f3ae4d300aedbaad Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 20 Aug 2010 09:21:21 -0500 Subject: Increasing the max size of the string --- libdbusmenu-glib/client.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 73a7aac..4a93b8e 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1225,7 +1225,8 @@ parse_layout (DbusmenuClient * client, const gchar * layout) xmlDocPtr xmldoc; - xmldoc = xmlReadMemory(layout, g_utf8_strlen(layout, 16*1024), "dbusmenu.xml", NULL, 0); + /* No one should need more characters than this! */ + xmldoc = xmlReadMemory(layout, g_utf8_strlen(layout, 1024*1024), "dbusmenu.xml", NULL, 0); xmlNodePtr root = xmlDocGetRootElement(xmldoc); -- cgit v1.2.3 From 8156d1d7abd95d7f4c0cb564bb9e3c4921a87b60 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 23 Aug 2010 09:25:40 -0500 Subject: Adding a check on the client object from code review --- libdbusmenu-glib/client.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index cc91b32..0a06c5e 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -605,6 +605,8 @@ get_properties_globber (DbusmenuClient * client, gint id, const gchar ** propert static void item_activated (DBusGProxy * proxy, gint id, guint timestamp, DbusmenuClient * client) { + g_return_if_fail(DBUSMENU_IS_CLIENT(client)); + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); if (priv->root == NULL) { -- cgit v1.2.3 From ffd29638de796d57380def939ef23c7ad8e892cd Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 26 Aug 2010 10:34:33 -0500 Subject: Creating a signal for the error situation on the signal. --- libdbusmenu-glib/client.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index d88478c..ac9561e 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -56,6 +56,7 @@ enum { ROOT_CHANGED, NEW_MENUITEM, ITEM_ACTIVATE, + EVENT_ERROR, LAST_SIGNAL }; @@ -206,6 +207,24 @@ dbusmenu_client_class_init (DbusmenuClientClass *klass) NULL, NULL, _dbusmenu_client_marshal_VOID__OBJECT_UINT, G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_UINT); + /** + DbusmenuClient::event-error: + @arg0: The #DbusmenuClient object + @arg1: The #DbusmenuMenuitem sent an event + @arg2: The ID of the event sent + @arg3: The data sent along with the event + @arg4: A timestamp that the event happened at + + Signal sent to show that there was an error in sending the event + to the server. + */ + signals[ITEM_ACTIVATE] = g_signal_new(DBUSMENU_CLIENT_SIGNAL_EVENT_ERROR, + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (DbusmenuClientClass, event_error), + NULL, NULL, + _dbusmenu_client_marshal_VOID__OBJECT_STRING_POINTER_UINT, + G_TYPE_NONE, 4, G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_UINT); g_object_class_install_property (object_class, PROP_DBUSOBJECT, g_param_spec_string(DBUSMENU_CLIENT_PROP_DBUS_OBJECT, "DBus Object we represent", -- cgit v1.2.3 From 9a8c525d75c3f92351c0e60f15504d061fde4160 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 26 Aug 2010 10:56:29 -0500 Subject: Building a data structure to track all the data we need to emit the event error signal --- libdbusmenu-glib/client.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index ac9561e..5d0325a 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -103,6 +103,16 @@ struct _properties_listener_t { gboolean replied; }; +typedef struct _event_data_t event_data_t; +struct _event_data_t { + DbusmenuClient * client; + DbusmenuMenuitem * menuitem; + gchar * event; + GValue data; + guint timestamp; +}; + + #define DBUSMENU_CLIENT_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_TYPE_CLIENT, DbusmenuClientPrivate)) @@ -1044,10 +1054,18 @@ menuitem_get_properties_new_cb (DBusGProxy * proxy, GHashTable * properties, GEr static void menuitem_call_cb (DBusGProxy * proxy, GError * error, gpointer userdata) { + event_data_t * edata = (event_data_t *)userdata; + if (error != NULL) { g_warning("Unable to call menu item %d: %s", GPOINTER_TO_INT(userdata), error->message); + g_signal_emit(edata->client, signals[EVENT_ERROR], 0, edata->menuitem, edata->event, edata->data, edata->timestamp, TRUE); } + g_value_unset(&edata->data); + g_free(edata->event); + g_object_unref(edata->menuitem); + g_free(edata); + return; } @@ -1060,6 +1078,13 @@ dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name g_return_if_fail(id >= 0); g_return_if_fail(name != NULL); + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id); + if (mi == NULL) { + g_warning("Asked to activate a menuitem %d that we don't know about", id); + return; + } + if (value == NULL) { GValue internalval = {0}; g_value_init(&internalval, G_TYPE_INT); @@ -1067,8 +1092,16 @@ dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name value = &internalval; } - DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); - org_ayatana_dbusmenu_event_async (priv->menuproxy, id, name, value, timestamp, menuitem_call_cb, GINT_TO_POINTER(id)); + event_data_t * edata = g_new0(event_data_t, 1); + edata->client = client; + edata->menuitem = mi; + g_object_ref(edata->menuitem); + edata->event = g_strdup(name); + g_value_init(&edata->data, G_VALUE_TYPE(value)); + g_value_copy(value, &edata->data); + edata->timestamp = timestamp; + + org_ayatana_dbusmenu_event_async (priv->menuproxy, id, name, value, timestamp, menuitem_call_cb, edata); return; } -- cgit v1.2.3 From 21e96fee225eab6ee2bee051c90a7458cf867b7f Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 26 Aug 2010 14:45:26 -0500 Subject: Changing to result instead of just errors. --- libdbusmenu-glib/client.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 5d0325a..43bde5f 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -56,7 +56,7 @@ enum { ROOT_CHANGED, NEW_MENUITEM, ITEM_ACTIVATE, - EVENT_ERROR, + EVENT_RESULT, LAST_SIGNAL }; @@ -224,17 +224,18 @@ dbusmenu_client_class_init (DbusmenuClientClass *klass) @arg2: The ID of the event sent @arg3: The data sent along with the event @arg4: A timestamp that the event happened at + @arg5: Possibly the error in sending the event (or NULL) Signal sent to show that there was an error in sending the event to the server. */ - signals[ITEM_ACTIVATE] = g_signal_new(DBUSMENU_CLIENT_SIGNAL_EVENT_ERROR, + signals[EVENT_RESULT] = g_signal_new(DBUSMENU_CLIENT_SIGNAL_EVENT_RESULT, G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (DbusmenuClientClass, event_error), + G_STRUCT_OFFSET (DbusmenuClientClass, event_result), NULL, NULL, - _dbusmenu_client_marshal_VOID__OBJECT_STRING_POINTER_UINT, - G_TYPE_NONE, 4, G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_UINT); + _dbusmenu_client_marshal_VOID__OBJECT_STRING_POINTER_UINT_POINTER, + G_TYPE_NONE, 5, G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_POINTER); g_object_class_install_property (object_class, PROP_DBUSOBJECT, g_param_spec_string(DBUSMENU_CLIENT_PROP_DBUS_OBJECT, "DBus Object we represent", @@ -1058,9 +1059,10 @@ menuitem_call_cb (DBusGProxy * proxy, GError * error, gpointer userdata) if (error != NULL) { g_warning("Unable to call menu item %d: %s", GPOINTER_TO_INT(userdata), error->message); - g_signal_emit(edata->client, signals[EVENT_ERROR], 0, edata->menuitem, edata->event, edata->data, edata->timestamp, TRUE); } + g_signal_emit(edata->client, signals[EVENT_RESULT], 0, edata->menuitem, edata->event, edata->data, edata->timestamp, error, TRUE); + g_value_unset(&edata->data); g_free(edata->event); g_object_unref(edata->menuitem); -- cgit v1.2.3 From 72f52f7f170e28a87ed58436d438aa1bea2ecf11 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 27 Aug 2010 15:20:48 -0500 Subject: Setting default timeout to 2 seconds. We need to be responsive. --- libdbusmenu-glib/client.c | 1 + 1 file changed, 1 insertion(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 43bde5f..7051e96 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -876,6 +876,7 @@ build_proxies (DbusmenuClient * client) } g_object_add_weak_pointer(G_OBJECT(priv->menuproxy), (gpointer *)&priv->menuproxy); g_signal_connect(G_OBJECT(priv->menuproxy), "destroy", G_CALLBACK(proxy_destroyed), client); + dbus_g_proxy_set_default_timeout(priv->menuproxy, 2000); /* If we get here, we don't need the DBus proxy */ if (priv->dbusproxy != NULL) { -- cgit v1.2.3 From 0b3dc82b5f2885d7ef3dca837f7fa02b0e73012b Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 27 Aug 2010 16:13:59 -0500 Subject: Fixing the parameter type --- libdbusmenu-glib/client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 7051e96..3f06618 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1059,10 +1059,10 @@ menuitem_call_cb (DBusGProxy * proxy, GError * error, gpointer userdata) event_data_t * edata = (event_data_t *)userdata; if (error != NULL) { - g_warning("Unable to call menu item %d: %s", GPOINTER_TO_INT(userdata), error->message); + g_warning("Unable to call event '%s' on menu item %d: %s", edata->event, dbusmenu_menuitem_get_id(edata->menuitem), error->message); } - g_signal_emit(edata->client, signals[EVENT_RESULT], 0, edata->menuitem, edata->event, edata->data, edata->timestamp, error, TRUE); + g_signal_emit(edata->client, signals[EVENT_RESULT], 0, edata->menuitem, edata->event, &edata->data, edata->timestamp, error, TRUE); g_value_unset(&edata->data); g_free(edata->event); -- cgit v1.2.3 From 8ea939e19d5f50d020e33a08237105a96ed4ae30 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 27 Aug 2010 17:01:01 -0500 Subject: Instead of setting the default timeout, we're copying the generated code to set a custom timeout for the event signal --- libdbusmenu-glib/client.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 3f06618..ca16c9a 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -876,7 +876,6 @@ build_proxies (DbusmenuClient * client) } g_object_add_weak_pointer(G_OBJECT(priv->menuproxy), (gpointer *)&priv->menuproxy); g_signal_connect(G_OBJECT(priv->menuproxy), "destroy", G_CALLBACK(proxy_destroyed), client); - dbus_g_proxy_set_default_timeout(priv->menuproxy, 2000); /* If we get here, we don't need the DBus proxy */ if (priv->dbusproxy != NULL) { @@ -1104,7 +1103,12 @@ dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name g_value_copy(value, &edata->data); edata->timestamp = timestamp; - org_ayatana_dbusmenu_event_async (priv->menuproxy, id, name, value, timestamp, menuitem_call_cb, edata); + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (menuitem_call_cb); + stuff->userdata = edata; + dbus_g_proxy_begin_call_with_timeout (priv->menuproxy, "Event", org_ayatana_dbusmenu_event_async_callback, stuff, _dbus_glib_async_data_free, 1000, G_TYPE_INT, id, G_TYPE_STRING, name, G_TYPE_VALUE, value, G_TYPE_UINT, timestamp, G_TYPE_INVALID); + return; } -- cgit v1.2.3 From 7fa04256d9aac8e1ea2a2982a7b93276fb981fa4 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 27 Sep 2010 20:11:29 -0500 Subject: Only flush at the top level --- libdbusmenu-glib/client.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index ca16c9a..91dc356 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1283,8 +1283,10 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it /* We've got everything built up at this node and reconcilled */ - /* Flush the properties requests */ - get_properties_flush(client); + /* Flush the properties requests if this is the first level */ + if (dbusmenu_menuitem_get_id(parent) == 0) { + get_properties_flush(client); + } /* now it's time to recurse down the tree. */ children = node->children; -- cgit v1.2.3 From 761c9cc00f19001548d23fe09a3e1676e728ad73 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 27 Sep 2010 20:15:46 -0500 Subject: Set a maximum number of entries to queue before sending the message. --- libdbusmenu-glib/client.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 91dc356..52cb24f 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -43,6 +43,10 @@ License version 3 and version 2.1 along with this program. If not, see #include "server-marshal.h" #include "client-marshal.h" +/* How many property requests should we queue before + sending the message on dbus */ +#define MAX_PROPERTIES_TO_QUEUE 100 + /* Properties */ enum { PROP_0, @@ -628,6 +632,13 @@ get_properties_globber (DbusmenuClient * client, gint id, const gchar ** propert priv->delayed_idle = g_idle_add(get_properties_idle, client); } + /* Look at how many proprites we have queued up and + make it so that we don't leave too many in one + request. */ + if (priv->delayed_property_listeners->len == MAX_PROPERTIES_TO_QUEUE) { + get_properties_flush(client); + } + return; } -- cgit v1.2.3 From 3dcaae7b7da97aa3b84f94ed5ebc3f6fba86cc41 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 12 Oct 2010 16:14:21 -0500 Subject: Putting the pointer to the private area in the instance --- libdbusmenu-glib/client.c | 1 - 1 file changed, 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index ca16c9a..30a415b 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -62,7 +62,6 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -typedef struct _DbusmenuClientPrivate DbusmenuClientPrivate; struct _DbusmenuClientPrivate { DbusmenuMenuitem * root; -- cgit v1.2.3 From 7a07a55969ba3700ad7d447a38171bfaec889ec6 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 12 Oct 2010 16:24:07 -0500 Subject: Switching to using the pointer in the instance --- libdbusmenu-glib/client.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 30a415b..6a51764 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -112,8 +112,7 @@ struct _event_data_t { }; -#define DBUSMENU_CLIENT_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_TYPE_CLIENT, DbusmenuClientPrivate)) +#define DBUSMENU_CLIENT_GET_PRIVATE(o) (DBUSMENU_CLIENT(o)->priv) /* GObject Stuff */ static void dbusmenu_client_class_init (DbusmenuClientClass *klass); @@ -253,6 +252,8 @@ dbusmenu_client_class_init (DbusmenuClientClass *klass) static void dbusmenu_client_init (DbusmenuClient *self) { + self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), DBUSMENU_TYPE_CLIENT, DbusmenuClientPrivate); + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(self); priv->root = NULL; -- cgit v1.2.3 From e4b55fd76e9506e3ecfe98b60518849c8b1ac87d Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 12 Nov 2010 13:20:29 -0600 Subject: Switching the headers and private variables --- libdbusmenu-glib/client.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 6a51764..2aa938c 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -30,7 +30,7 @@ License version 3 and version 2.1 along with this program. If not, see #include "config.h" #endif -#include +#include #include #include @@ -39,7 +39,6 @@ License version 3 and version 2.1 along with this program. If not, see #include "menuitem.h" #include "menuitem-private.h" #include "client-menuitem.h" -#include "dbusmenu-client.h" #include "server-marshal.h" #include "client-marshal.h" @@ -69,15 +68,15 @@ struct _DbusmenuClientPrivate gchar * dbus_object; gchar * dbus_name; - DBusGConnection * session_bus; - DBusGProxy * menuproxy; - DBusGProxy * propproxy; - DBusGProxyCall * layoutcall; + GDBusConnection * session_bus; + GDBusProxy * menuproxy; + GDBusProxy * propproxy; + GCancellable * layoutcall; gint current_revision; gint my_revision; - DBusGProxy * dbusproxy; + GDBusProxy * dbusproxy; GHashTable * type_handlers; -- cgit v1.2.3 From 6d36d55acf43696ba371d1af757e0662d89918d3 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 12 Nov 2010 13:20:48 -0600 Subject: Changing the flush --- libdbusmenu-glib/client.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 2aa938c..8ede85d 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -562,6 +562,21 @@ get_properties_idle (gpointer user_data) return FALSE; } +/* Report and error if we're unable to flush the connection, likely + to be a cause of some other issues. */ +static void +connection_flush_cb (GObject * object, GAsyncResult * result, gpointer user_data) +{ + GError * error = NULL; + + if (!g_dbus_connection_flush_finish(G_DBUS_CONNECTION(object), result, &error)) { + g_warning("Unable to flush DBus connection: %s", error->message); + g_error_free(error); + } + + return; +} + /* Forces a call out to start getting properties with the menu items that we have queued up already. */ static void @@ -578,7 +593,11 @@ get_properties_flush (DbusmenuClient * client) get_properties_idle(client); - dbus_g_connection_flush(priv->session_bus); + /* I'm not sure this flush is necissary with GDBus running the + DBus connection in another thread. But, I don't think that + it'll hurt anything either, so I'm leaving it in. */ + g_return_if_fail(priv->session_bus != NULL); + g_dbus_connection_flush(priv->session_bus, NULL, connection_flush_cb, NULL); return; } -- cgit v1.2.3 From 51c9cc0eb87f0a379c891a23162e232b1f597bd6 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 12 Nov 2010 13:57:22 -0600 Subject: Changing the flow for creating the async session bus. It is now cancellable. --- libdbusmenu-glib/client.c | 65 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 6 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 8ede85d..f662f74 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -69,6 +69,8 @@ struct _DbusmenuClientPrivate gchar * dbus_name; GDBusConnection * session_bus; + GCancelable * session_bus_cancel; + GDBusProxy * menuproxy; GDBusProxy * propproxy; GCancellable * layoutcall; @@ -261,6 +263,8 @@ dbusmenu_client_init (DbusmenuClient *self) priv->dbus_name = NULL; priv->session_bus = NULL; + priv->session_bus_cancel = NULL; + priv->menuproxy = NULL; priv->propproxy = NULL; priv->layoutcall = NULL; @@ -339,7 +343,16 @@ dbusmenu_client_dispose (GObject *object) g_object_unref(G_OBJECT(priv->dbusproxy)); priv->dbusproxy = NULL; } - priv->session_bus = NULL; + + if (priv->session_bus_cancel != NULL) { + g_cancellable_cancel(priv->session_bus_cancel); + g_object_unref(priv->session_bus_cancel); + priv->session_bus_cancel = NULL; + } + if (priv->session_bus != NULL) { + g_object_unref(priv->session_bus); + priv->session_bus = NULL; + } if (priv->root != NULL) { g_object_unref(G_OBJECT(priv->root)); @@ -848,6 +861,37 @@ proxy_destroyed (GObject * gobj_proxy, gpointer userdata) return; } +/* Respond to us getting the session bus (hopefully) or handle + the error if not */ +void +session_bus_cb (GObject * object, GAsyncResult * res, gpointer user_data) +{ + GError * error = NULL; + + /* NOTE: We're not using any other variables before checking + the result because they could be destroyed and thus invalid */ + GDBusConnection * bus = g_bus_get_finish(res, &error); + if (error != NULL) { + g_warning("Unable to get session bus: %s", error->message); + g_error_free(error); + return; + } + + /* If this wasn't cancelled, we should be good */ + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + priv->session_bus = bus; + + if (priv->session_bus_cancel != NULL) { + g_object_unref(priv->session_bus_cancel); + priv->session_bus_cancel = NULL; + } + + /* Retry to build the proxies now that we have a bus */ + build_proxies(DBUSMENU_CLIENT(user_data)); + + return; +} + /* When we have a name and an object, build the two proxies and get the first version of the layout */ static void @@ -859,11 +903,20 @@ build_proxies (DbusmenuClient * client) g_return_if_fail(priv->dbus_object != NULL); g_return_if_fail(priv->dbus_name != NULL); - priv->session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); - if (error != NULL) { - g_error("Unable to get session bus: %s", error->message); - g_error_free(error); - build_dbus_proxy(client); + if (priv->session_bus == NULL) { + /* We don't have the session bus yet, that's okay, but + we need to handle that. */ + + /* If we're already running we don't need to look again. */ + if (priv->session_bus_cancel == NULL) { + priv->session_bus_cancel = g_cancellable_new(); + + /* Async get the session bus */ + g_bus_get(G_BUS_SESSION, priv->session_bus_cancel, session_bus_cb, client); + } + + /* This function exists, it'll be called again when we get + the session bus so this condition will be ignored */ return; } -- cgit v1.2.3 From 030de7ba74d6560ef61b31913c244a4be1d5116b Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 12 Nov 2010 14:26:31 -0600 Subject: Removing the proxy for the property interface on the object as GDBus puts that in the standard proxy now --- libdbusmenu-glib/client.c | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index f662f74..f672696 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -69,10 +69,9 @@ struct _DbusmenuClientPrivate gchar * dbus_name; GDBusConnection * session_bus; - GCancelable * session_bus_cancel; + GCancellable * session_bus_cancel; GDBusProxy * menuproxy; - GDBusProxy * propproxy; GCancellable * layoutcall; gint current_revision; @@ -266,7 +265,6 @@ dbusmenu_client_init (DbusmenuClient *self) priv->session_bus_cancel = NULL; priv->menuproxy = NULL; - priv->propproxy = NULL; priv->layoutcall = NULL; priv->current_revision = 0; @@ -335,10 +333,6 @@ dbusmenu_client_dispose (GObject *object) g_object_unref(G_OBJECT(priv->menuproxy)); priv->menuproxy = NULL; } - if (priv->propproxy != NULL) { - g_object_unref(G_OBJECT(priv->propproxy)); - priv->propproxy = NULL; - } if (priv->dbusproxy != NULL) { g_object_unref(G_OBJECT(priv->dbusproxy)); priv->dbusproxy = NULL; @@ -920,20 +914,6 @@ build_proxies (DbusmenuClient * client) return; } - priv->propproxy = dbus_g_proxy_new_for_name_owner(priv->session_bus, - priv->dbus_name, - priv->dbus_object, - DBUS_INTERFACE_PROPERTIES, - &error); - if (error != NULL) { - g_warning("Unable to get property proxy for %s on %s: %s", priv->dbus_name, priv->dbus_object, error->message); - g_error_free(error); - build_dbus_proxy(client); - return; - } - g_object_add_weak_pointer(G_OBJECT(priv->propproxy), (gpointer *)&priv->propproxy); - g_signal_connect(G_OBJECT(priv->propproxy), "destroy", G_CALLBACK(proxy_destroyed), client); - priv->menuproxy = dbus_g_proxy_new_for_name_owner(priv->session_bus, priv->dbus_name, priv->dbus_object, @@ -1551,10 +1531,6 @@ dbusmenu_client_get_root (DbusmenuClient * client) DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); - if (priv->propproxy == NULL) { - return NULL; - } - #ifdef MASSIVEDEBUGGING g_debug("Client get root: %X", (guint)priv->root); #endif -- cgit v1.2.3 From efd88243d8e4e8911f08e86744ef13387ac4ae6a Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 12 Nov 2010 14:30:46 -0600 Subject: Including the interface description and building the objects from it once --- libdbusmenu-glib/client.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index f672696..30dce89 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -41,6 +41,7 @@ License version 3 and version 2.1 along with this program. If not, see #include "client-menuitem.h" #include "server-marshal.h" #include "client-marshal.h" +#include "dbus-menu.xml.h" /* Properties */ enum { @@ -136,6 +137,10 @@ static void get_properties_globber (DbusmenuClient * client, gint id, const gcha static GQuark error_domain (void); static void item_activated (DBusGProxy * proxy, gint id, guint timestamp, DbusmenuClient * client); +/* Globals */ +static GDBusNodeInfo * dbusmenu_node_info = NULL; +static GDBusInterfaceInfo * dbusmenu_interface_info = NULL; + /* Build a type */ G_DEFINE_TYPE (DbusmenuClient, dbusmenu_client, G_TYPE_OBJECT); @@ -246,6 +251,24 @@ dbusmenu_client_class_init (DbusmenuClientClass *klass) NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + if (dbusmenu_node_info == NULL) { + GError * error = NULL; + + dbusmenu_node_info = g_dbus_node_info_new_for_xml(dbus_menu_xml, &error); + if (error != NULL) { + g_error("Unable to parse DBusmenu Interface description: %s", error->message); + g_error_free(error); + } + } + + if (dbusmenu_interface_info == NULL) { + dbusmenu_interface_info = g_dbus_node_info_lookup_interface(dbusmenu_node_info, DBUSMENU_INTERFACE); + + if (dbusmenu_interface_info == NULL) { + g_error("Unable to find interface '" DBUSMENU_INTERFACE "'"); + } + } + return; } -- cgit v1.2.3 From 08053906621fc5240e7bb7a549a09b0acf930809 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 12 Nov 2010 15:04:45 -0600 Subject: Adding a cancellable for the menu proxy in the private object --- libdbusmenu-glib/client.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 30dce89..17f52b4 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -73,6 +73,8 @@ struct _DbusmenuClientPrivate GCancellable * session_bus_cancel; GDBusProxy * menuproxy; + GCancellable * menuproxy_cancel; + GCancellable * layoutcall; gint current_revision; @@ -288,6 +290,8 @@ dbusmenu_client_init (DbusmenuClient *self) priv->session_bus_cancel = NULL; priv->menuproxy = NULL; + priv->menuproxy_cancel = NULL; + priv->layoutcall = NULL; priv->current_revision = 0; @@ -352,15 +356,26 @@ dbusmenu_client_dispose (GObject *object) dbus_g_proxy_cancel_call(priv->menuproxy, priv->layoutcall); priv->layoutcall = NULL; } + + /* Bring down the menu proxy, ensure we're not + looking for one at the same time. */ + if (priv->menuproxy_cancel != NULL) { + g_cancellable_cancel(priv->menuproxy_cancel); + g_object_unref(priv->menuproxy_cancel); + priv->menuproxy_cancel = NULL; + } if (priv->menuproxy != NULL) { g_object_unref(G_OBJECT(priv->menuproxy)); priv->menuproxy = NULL; } + if (priv->dbusproxy != NULL) { g_object_unref(G_OBJECT(priv->dbusproxy)); priv->dbusproxy = NULL; } + /* Bring down the session bus, ensure we're not + looking for one at the same time. */ if (priv->session_bus_cancel != NULL) { g_cancellable_cancel(priv->session_bus_cancel); g_object_unref(priv->session_bus_cancel); -- cgit v1.2.3 From 88cc4c919ee836870a326f22eb0b773f8395aeec Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 12 Nov 2010 15:05:22 -0600 Subject: Reshuffling the creation of the menu proxy to be async with a callback. --- libdbusmenu-glib/client.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 17f52b4..42144ae 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -138,6 +138,7 @@ static void menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * propert static void get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, org_ayatana_dbusmenu_get_properties_reply callback, gpointer user_data); static GQuark error_domain (void); static void item_activated (DBusGProxy * proxy, gint id, guint timestamp, DbusmenuClient * client); +static void menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data); /* Globals */ static GDBusNodeInfo * dbusmenu_node_info = NULL; @@ -952,17 +953,33 @@ build_proxies (DbusmenuClient * client) return; } - priv->menuproxy = dbus_g_proxy_new_for_name_owner(priv->session_bus, - priv->dbus_name, - priv->dbus_object, - "org.ayatana.dbusmenu", - &error); - if (error != NULL) { - g_warning("Unable to get dbusmenu proxy for %s on %s: %s", priv->dbus_name, priv->dbus_object, error->message); - g_error_free(error); - build_dbus_proxy(client); - return; + /* Build us a menu proxy */ + if (priv->menuproxy == NULL) { + + /* Check to see if we're already building one */ + if (priv->menuproxy_cancel == NULL) { + priv->menuproxy_cancel = g_cancellable_new(); + + g_dbus_proxy_new(priv->session_bus, + G_DBUS_PROXY_FLAGS_NONE, + dbusmenu_interface_info, + priv->dbus_name, + priv->dbus_object, + DBUSMENU_INTERFACE, + priv->menuproxy_cancel, + menuproxy_build_cb, + client); + } } + + return; +} + +/* Callback when we know if the menu proxy can be created or + not and do something with it! */ +static void +menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data) +{ g_object_add_weak_pointer(G_OBJECT(priv->menuproxy), (gpointer *)&priv->menuproxy); g_signal_connect(G_OBJECT(priv->menuproxy), "destroy", G_CALLBACK(proxy_destroyed), client); -- cgit v1.2.3 From 567ff35378371596e1304cad97f634969e954cc1 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 12 Nov 2010 16:56:07 -0600 Subject: Adjusting how the menu proxy gets built up and signals connected --- libdbusmenu-glib/client.c | 83 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 14 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 42144ae..d2bfc8f 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -139,6 +139,8 @@ static void get_properties_globber (DbusmenuClient * client, gint id, const gcha static GQuark error_domain (void); static void item_activated (DBusGProxy * proxy, gint id, guint timestamp, DbusmenuClient * client); static void menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data); +static void menuproxy_name_changed_cb (GObject * object, GParamSpec * pspec, gpointer user_data); +static void menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVariant * params, gpointer user_data); /* Globals */ static GDBusNodeInfo * dbusmenu_node_info = NULL; @@ -980,8 +982,25 @@ build_proxies (DbusmenuClient * client) static void menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data) { - g_object_add_weak_pointer(G_OBJECT(priv->menuproxy), (gpointer *)&priv->menuproxy); - g_signal_connect(G_OBJECT(priv->menuproxy), "destroy", G_CALLBACK(proxy_destroyed), client); + GError * error = NULL; + + /* NOTE: We're not using any other variables before checking + the result because they could be destroyed and thus invalid */ + GDBusProxy * proxy = g_dbus_proxy_new_finish(res, &error); + if (error != NULL) { + g_warning("Unable to get menu proxy: %s", error->message); + g_error_free(error); + return; + } + + /* If this wasn't cancelled, we should be good */ + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(user_data); + priv->menuproxy = proxy; + + if (priv->menuproxy_cancel != NULL) { + g_object_unref(priv->menuproxy_cancel); + priv->menuproxy_cancel = NULL; + } /* If we get here, we don't need the DBus proxy */ if (priv->dbusproxy != NULL) { @@ -989,22 +1008,58 @@ menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data) priv->dbusproxy = NULL; } - dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__UINT_INT, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_INT, G_TYPE_INVALID); - dbus_g_proxy_add_signal(priv->menuproxy, "LayoutUpdated", G_TYPE_UINT, G_TYPE_INT, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(priv->menuproxy, "LayoutUpdated", G_CALLBACK(layout_update), client, NULL); + g_signal_connect(priv->menuproxy, "g-signal", G_CALLBACK(menuproxy_signal_cb), client); + g_signal_connect(priv->menuproxy, "notify::g-name-owner", G_CALLBACK(menuproxy_name_changed_cb), client); - dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__INT_STRING_POINTER, G_TYPE_NONE, G_TYPE_INT, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID); - dbus_g_proxy_add_signal(priv->menuproxy, "ItemPropertyUpdated", G_TYPE_INT, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(priv->menuproxy, "ItemPropertyUpdated", G_CALLBACK(id_prop_update), client, NULL); + update_layout(client); - dbus_g_proxy_add_signal(priv->menuproxy, "ItemUpdated", G_TYPE_INT, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(priv->menuproxy, "ItemUpdated", G_CALLBACK(id_update), client, NULL); + return; +} + +/* Handle the case where we change owners */ +static void +menuproxy_name_changed_cb (GObject * object, GParamSpec * pspec, gpointer user_data) +{ + GDBusProxy * proxy = G_DBUS_PROXY(object); - dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__INT_UINT, G_TYPE_NONE, G_TYPE_INT, G_TYPE_UINT, G_TYPE_INVALID); - dbus_g_proxy_add_signal(priv->menuproxy, "ItemActivationRequested", G_TYPE_INT, G_TYPE_UINT, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(priv->menuproxy, "ItemActivationRequested", G_CALLBACK(item_activated), client, NULL); + gchar * owner = g_dbus_proxy_get_name_owner(proxy); - update_layout(client); + if (owner == NULL) { + /* Oh, no! We lost our owner! */ + proxy_destroyed(G_OBJECT(proxy), user_data); + } else { + g_free(owner); + } + + return; +} + +/* Handle the signals out of the proxy */ +static void +menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVariant * params, gpointer user_data) +{ + g_return_if_fail(DBUSMENU_IS_CLIENT(user_data)); + DbusmenuClient * client = DBUSMENU_CLIENT(user_data); + + if (g_strcmp0(signal, "LayoutUpdated") == 0) { + guint revision; gint parent; + g_variant_get(params, "(ui)", &revision, &parent); + layout_update(proxy, revision, parent, client); + } else if (g_strcmp0(signal, "ItemPropertyUpdated") == 0) { + gint id; gchar * property; GVariant * value; + g_variant_get(params, "(isv)", &id, &property, &value); + id_prop_update(proxy, id, property, value, client); + } else if (g_strcmp0(signal, "ItemUpdated") == 0) { + gint id; + g_variant_get(params, "(i)", &id); + id_update(proxy, id, client); + } else if (g_strcmp0(signal, "ItemActivationRequested") == 0) { + gint id; guint timestamp; + g_variant_get(params, "(iu)", &id, ×tamp); + item_activated(proxy, id, timestamp, client); + } else { + g_warning("Received signal '%s' from menu proxy that is unknown", signal); + } return; } -- cgit v1.2.3 From a71b34a9103a9a383cff69bfe7b44319f7cb114c Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 08:45:02 -0600 Subject: Changing the function prototype for properties callback to be local, and make more sense. --- libdbusmenu-glib/client.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index d2bfc8f..6f31354 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -60,6 +60,8 @@ enum { LAST_SIGNAL }; +typedef void (*properties_func) (DbusmenuClient * client, GVariant * properties); + static guint signals[LAST_SIGNAL] = { 0 }; struct _DbusmenuClientPrivate @@ -100,7 +102,7 @@ struct _newItemPropData typedef struct _properties_listener_t properties_listener_t; struct _properties_listener_t { gint id; - org_ayatana_dbusmenu_get_properties_reply callback; + properties_func callback; gpointer user_data; gboolean replied; }; @@ -135,7 +137,7 @@ static gint parse_layout (DbusmenuClient * client, const gchar * layout); static void update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError * in_error, void * data); static void update_layout (DbusmenuClient * client); static void menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data); -static void get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, org_ayatana_dbusmenu_get_properties_reply callback, gpointer user_data); +static void get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, properties_func callback, gpointer user_data); static GQuark error_domain (void); static void item_activated (DBusGProxy * proxy, gint id, guint timestamp, DbusmenuClient * client); static void menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data); @@ -653,7 +655,7 @@ get_properties_flush (DbusmenuClient * client) /* A function to group all the get_properties commands to make them more efficient over dbus. */ static void -get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, org_ayatana_dbusmenu_get_properties_reply callback, gpointer user_data) +get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, properties_func callback, gpointer user_data) { DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); if (find_listener(priv->delayed_property_listeners, 0, id) != NULL) { -- cgit v1.2.3 From fb510a52796e9ff1a5bfc52fad72e94c22efc6e1 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 08:47:36 -0600 Subject: Blanket replace of DBusGProxy with GDBusProxy --- libdbusmenu-glib/client.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 6f31354..92991b3 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -127,19 +127,19 @@ static void dbusmenu_client_finalize (GObject *object); static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec); static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec); /* Private Funcs */ -static void layout_update (DBusGProxy * proxy, guint revision, gint parent, DbusmenuClient * client); -static void id_prop_update (DBusGProxy * proxy, gint id, gchar * property, GValue * value, DbusmenuClient * client); -static void id_update (DBusGProxy * proxy, gint id, DbusmenuClient * client); +static void layout_update (GDBusProxy * proxy, guint revision, gint parent, DbusmenuClient * client); +static void id_prop_update (GDBusProxy * proxy, gint id, gchar * property, GValue * value, DbusmenuClient * client); +static void id_update (GDBusProxy * proxy, gint id, DbusmenuClient * client); static void build_proxies (DbusmenuClient * client); static gint parse_node_get_id (xmlNodePtr node); -static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, DBusGProxy * proxy); +static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, GDBusProxy * proxy); static gint parse_layout (DbusmenuClient * client, const gchar * layout); -static void update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError * in_error, void * data); +static void update_layout_cb (GDBusProxy * proxy, guint rev, gchar * xml, GError * in_error, void * data); static void update_layout (DbusmenuClient * client); -static void menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data); +static void menuitem_get_properties_cb (GDBusProxy * proxy, GHashTable * properties, GError * error, gpointer data); static void get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, properties_func callback, gpointer user_data); static GQuark error_domain (void); -static void item_activated (DBusGProxy * proxy, gint id, guint timestamp, DbusmenuClient * client); +static void item_activated (GDBusProxy * proxy, gint id, guint timestamp, DbusmenuClient * client); static void menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data); static void menuproxy_name_changed_cb (GObject * object, GParamSpec * pspec, gpointer user_data); static void menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVariant * params, gpointer user_data); @@ -494,7 +494,7 @@ find_listener (GArray * listeners, guint index, gint id) /* Call back from getting the group properties, now we need to unwind and call the various functions. */ static void -get_properties_callback (DBusGProxy *proxy, GPtrArray *OUT_properties, GError *error, gpointer userdata) +get_properties_callback (GDBusProxy *proxy, GPtrArray *OUT_properties, GError *error, gpointer userdata) { GArray * listeners = (GArray *)userdata; int i; @@ -701,7 +701,7 @@ get_properties_globber (DbusmenuClient * client, gint id, const gchar ** propert /* Called when a server item wants to activate the menu */ static void -item_activated (DBusGProxy * proxy, gint id, guint timestamp, DbusmenuClient * client) +item_activated (GDBusProxy * proxy, gint id, guint timestamp, DbusmenuClient * client) { g_return_if_fail(DBUSMENU_IS_CLIENT(client)); @@ -725,7 +725,7 @@ item_activated (DBusGProxy * proxy, gint id, guint timestamp, DbusmenuClient * c /* Annoying little wrapper to make the right function update */ static void -layout_update (DBusGProxy * proxy, guint revision, gint parent, DbusmenuClient * client) +layout_update (GDBusProxy * proxy, guint revision, gint parent, DbusmenuClient * client) { DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); priv->current_revision = revision; @@ -738,7 +738,7 @@ layout_update (DBusGProxy * proxy, guint revision, gint parent, DbusmenuClient * /* Signal from the server that a property has changed on one of our menuitems */ static void -id_prop_update (DBusGProxy * proxy, gint id, gchar * property, GValue * value, DbusmenuClient * client) +id_prop_update (GDBusProxy * proxy, gint id, gchar * property, GValue * value, DbusmenuClient * client) { #ifdef MASSIVEDEBUGGING GValue valstr = {0}; @@ -768,7 +768,7 @@ id_prop_update (DBusGProxy * proxy, gint id, gchar * property, GValue * value, D /* Oh, lots of updates now. That silly server, they want to change all kinds of stuff! */ static void -id_update (DBusGProxy * proxy, gint id, DbusmenuClient * client) +id_update (GDBusProxy * proxy, gint id, DbusmenuClient * client) { #ifdef MASSIVEDEBUGGING g_debug("Client side ID update: %d", id); @@ -788,7 +788,7 @@ id_update (DBusGProxy * proxy, gint id, DbusmenuClient * client) /* Watches to see if our DBus savior comes onto the bus */ static void -dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, DbusmenuClient * client) +dbus_owner_change (GDBusProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, DbusmenuClient * client) { DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); /* g_debug("Owner change: %s %s %s", name, prev, new); */ @@ -815,7 +815,7 @@ dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, c it does, then we should build the proxies here. Race condition check. */ static void -name_owner_check (DBusGProxy *proxy, gboolean has_owner, GError *error, gpointer userdata) +name_owner_check (GDBusProxy *proxy, gboolean has_owner, GError *error, gpointer userdata) { if (error != NULL) { return; @@ -1115,7 +1115,7 @@ get_properties_helper (gpointer key, gpointer value, gpointer data) This isn't the most efficient way. We can optimize this by somehow removing the foreach. But that is for later. */ static void -menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data) +menuitem_get_properties_cb (GDBusProxy * proxy, GHashTable * properties, GError * error, gpointer data) { g_return_if_fail(DBUSMENU_IS_MENUITEM(data)); if (error != NULL) { @@ -1133,7 +1133,7 @@ menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError is getting recycled with the update, but we think might have prop changes. */ static void -menuitem_get_properties_replace_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data) +menuitem_get_properties_replace_cb (GDBusProxy * proxy, GHashTable * properties, GError * error, gpointer data) { g_return_if_fail(DBUSMENU_IS_MENUITEM(data)); gboolean have_error = FALSE; @@ -1164,7 +1164,7 @@ menuitem_get_properties_replace_cb (DBusGProxy * proxy, GHashTable * properties, /* This is a different get properites call back that also sends new signals. It basically is a small wrapper around the original. */ static void -menuitem_get_properties_new_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data) +menuitem_get_properties_new_cb (GDBusProxy * proxy, GHashTable * properties, GError * error, gpointer data) { g_return_if_fail(data != NULL); newItemPropData * propdata = (newItemPropData *)data; @@ -1216,7 +1216,7 @@ menuitem_get_properties_new_cb (DBusGProxy * proxy, GHashTable * properties, GEr /* Respond to the call function to make sure that the other side got it, or print a warning. */ static void -menuitem_call_cb (DBusGProxy * proxy, GError * error, gpointer userdata) +menuitem_call_cb (GDBusProxy * proxy, GError * error, gpointer userdata) { event_data_t * edata = (event_data_t *)userdata; @@ -1285,7 +1285,7 @@ struct _about_to_show_t { /* Reports errors and responds to update request that were a result of sending the about to show signal. */ static void -about_to_show_cb (DBusGProxy * proxy, gboolean need_update, GError * error, gpointer userdata) +about_to_show_cb (GDBusProxy * proxy, gboolean need_update, GError * error, gpointer userdata) { about_to_show_t * data = (about_to_show_t *)userdata; @@ -1369,7 +1369,7 @@ parse_layout_update (DbusmenuMenuitem * item, DbusmenuClient * client) /* Parse recursively through the XML and make it into objects as need be */ static DbusmenuMenuitem * -parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, DBusGProxy * proxy) +parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, GDBusProxy * proxy) { /* First verify and figure out what we've got */ gint id = parse_node_get_id(node); @@ -1540,7 +1540,7 @@ parse_layout (DbusmenuClient * client, const gchar * layout) /* When the layout property returns, here's where we take care of that. */ static void -update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError * error, void * data) +update_layout_cb (GDBusProxy * proxy, guint rev, gchar * xml, GError * error, void * data) { DbusmenuClient * client = DBUSMENU_CLIENT(data); DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); -- cgit v1.2.3 From 5a5e31fd65810bd106f01833c5b66545d936e831 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 08:49:20 -0600 Subject: Adding in the dbusmenu interface --- libdbusmenu-glib/client.c | 1 + 1 file changed, 1 insertion(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 92991b3..e24a182 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -118,6 +118,7 @@ struct _event_data_t { #define DBUSMENU_CLIENT_GET_PRIVATE(o) (DBUSMENU_CLIENT(o)->priv) +#define DBUSMENU_INTERFACE "org.ayatana.dbusmenu" /* GObject Stuff */ static void dbusmenu_client_class_init (DbusmenuClientClass *klass); -- cgit v1.2.3 From dbb933c7da1d7ec7d3a40b7f0aead90aafe87911 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 08:54:03 -0600 Subject: Changing the prototype for one call to the callback, need a different approach --- libdbusmenu-glib/client.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index e24a182..b80999e 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -60,7 +60,7 @@ enum { LAST_SIGNAL }; -typedef void (*properties_func) (DbusmenuClient * client, GVariant * properties); +typedef void (*properties_func) (DbusmenuClient * client, GVariant * properties, GError * error); static guint signals[LAST_SIGNAL] = { 0 }; @@ -318,6 +318,7 @@ dbusmenu_client_init (DbusmenuClient *self) static void dbusmenu_client_dispose (GObject *object) { + DbusmenuClient * client = DBUSMENU_CLIENT(object); DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(object); if (priv->delayed_idle != 0) { @@ -347,7 +348,7 @@ dbusmenu_client_dispose (GObject *object) if (localerror == NULL) { g_set_error_literal(&localerror, error_domain(), 0, "DbusmenuClient Shutdown"); } - listener->callback(priv->menuproxy, NULL, localerror, listener->user_data); + listener->callback(client, NULL, localerror); } } if (localerror != NULL) { -- cgit v1.2.3 From 80fe2298aff27d9c10b3fbb8bbab120954e7f2be Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 14:24:14 -0600 Subject: Changing the properties callback to use the proper prototype and GVariant --- libdbusmenu-glib/client.c | 57 +++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 29 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index b80999e..50b379c 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -60,7 +60,7 @@ enum { LAST_SIGNAL }; -typedef void (*properties_func) (DbusmenuClient * client, GVariant * properties, GError * error); +typedef void (*properties_func) (GVariant * properties, GError * error, gpointer user_data); static guint signals[LAST_SIGNAL] = { 0 }; @@ -348,7 +348,7 @@ dbusmenu_client_dispose (GObject *object) if (localerror == NULL) { g_set_error_literal(&localerror, error_domain(), 0, "DbusmenuClient Shutdown"); } - listener->callback(client, NULL, localerror); + listener->callback(NULL, localerror, listener->user_data); } } if (localerror != NULL) { @@ -496,47 +496,37 @@ find_listener (GArray * listeners, guint index, gint id) /* Call back from getting the group properties, now we need to unwind and call the various functions. */ static void -get_properties_callback (GDBusProxy *proxy, GPtrArray *OUT_properties, GError *error, gpointer userdata) +get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data) { - GArray * listeners = (GArray *)userdata; + GArray * listeners = (GArray *)user_data; int i; + GError * error = NULL; + GVariant * params = NULL; - #ifdef MASSIVEDEBUGGING - g_debug("Get properties callback: %d", OUT_properties->len); - #endif + params = g_dbus_proxy_call_finish(G_DBUS_PROXY(obj), res, &error); if (error != NULL) { /* If we get an error, all our callbacks need to hear about it. */ g_warning("Group Properties error: %s", error->message); for (i = 0; i < listeners->len; i++) { properties_listener_t * listener = &g_array_index(listeners, properties_listener_t, i); - listener->callback(proxy, NULL, error, listener->user_data); + listener->callback(NULL, error, listener->user_data); } g_array_free(listeners, TRUE); return; } /* Callback all the folks we can find */ - for (i = 0; i < OUT_properties->len; i++) { - GValueArray * varray = (GValueArray *)g_ptr_array_index(OUT_properties, i); - - if (varray->n_values != 2) { - g_warning("Value Array is %d entries long but we expected 2.", varray->n_values); + GVariantIter * iter = g_variant_iter_new(params); + GVariant * child; + while ((child = g_variant_iter_next_value(iter)) != NULL) { + if (g_strcmp0(g_variant_get_type_string(child), "ia(sv)") != 0) { + g_warning("Properties return signature is not 'ia(sv)' it is '%s'", g_variant_get_type_string(child)); continue; } - GValue * vid = g_value_array_get_nth(varray, 0); - GValue * vproperties = g_value_array_get_nth(varray, 1); - - if (G_VALUE_TYPE(vid) != G_TYPE_INT) { - g_warning("ID Entry not holding an int: %s", G_VALUE_TYPE_NAME(vid)); - } - if (G_VALUE_TYPE(vproperties) != dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) { - g_warning("Properties Entry not holding an a{sv}: %s", G_VALUE_TYPE_NAME(vproperties)); - } - - gint id = g_value_get_int(vid); - GHashTable * properties = g_value_get_boxed(vproperties); + gint id = g_variant_get_int32(g_variant_get_child_value(child, 0)); + GVariant * properties = g_variant_get_child_value(child, 1); properties_listener_t * listener = find_listener(listeners, 0, id); if (listener == NULL) { @@ -545,12 +535,13 @@ get_properties_callback (GDBusProxy *proxy, GPtrArray *OUT_properties, GError *e } if (!listener->replied) { - listener->callback(proxy, properties, NULL, listener->user_data); + listener->callback(properties, NULL, listener->user_data); listener->replied = TRUE; } else { g_warning("Odd, we've already replied to the listener on ID %d", id); } } + g_variant_iter_free(iter); /* Provide errors for those who we can't */ GError * localerror = NULL; @@ -560,7 +551,7 @@ get_properties_callback (GDBusProxy *proxy, GPtrArray *OUT_properties, GError *e if (localerror == NULL) { g_set_error_literal(&localerror, error_domain(), 0, "Error getting properties for ID"); } - listener->callback(proxy, NULL, localerror, listener->user_data); + listener->callback(NULL, localerror, listener->user_data); } } if (localerror != NULL) { @@ -579,7 +570,7 @@ static gboolean get_properties_idle (gpointer user_data) { DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(user_data); - //org_ayatana_dbusmenu_get_properties_async(priv->menuproxy, id, properties, callback, user_data); + g_return_val_if_fail(priv->menuproxy != NULL, TRUE); if (priv->delayed_property_listeners->len == 0) { g_warning("Odd, idle func got no listeners."); @@ -593,7 +584,15 @@ get_properties_idle (gpointer user_data) g_array_append_val(idlist, g_array_index(priv->delayed_property_listeners, properties_listener_t, i).id); } - org_ayatana_dbusmenu_get_group_properties_async(priv->menuproxy, idlist, (const gchar **)priv->delayed_property_list->data, get_properties_callback, priv->delayed_property_listeners); + GVariant * variant_params = g_variant_new("a(s)", (const gchar **)priv->delayed_property_list->data); + g_dbus_proxy_call(priv->menuproxy, + "GetGroupProperties", + variant_params, + G_DBUS_CALL_FLAGS_NONE, + -1, /* timeout */ + NULL, /* cancellable */ + get_properties_callback, + priv->delayed_property_listeners); /* Free ID List */ g_array_free(idlist, TRUE); -- cgit v1.2.3 From 26311e4db0f50c805374a1cf2265e7a5c81dd083 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 14:37:53 -0600 Subject: Fixing the menuitem_get_properties_cb to use Variants and match the right prototype --- libdbusmenu-glib/client.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 50b379c..23981de 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -137,7 +137,7 @@ static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, xmlNodePtr n static gint parse_layout (DbusmenuClient * client, const gchar * layout); static void update_layout_cb (GDBusProxy * proxy, guint rev, gchar * xml, GError * in_error, void * data); static void update_layout (DbusmenuClient * client); -static void menuitem_get_properties_cb (GDBusProxy * proxy, GHashTable * properties, GError * error, gpointer data); +static void menuitem_get_properties_cb (GVariant * properties, GError * error, gpointer data); static void get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, properties_func callback, gpointer user_data); static GQuark error_domain (void); static void item_activated (GDBusProxy * proxy, gint id, guint timestamp, DbusmenuClient * client); @@ -542,6 +542,7 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data) } } g_variant_iter_free(iter); + g_variant_unref(params); /* Provide errors for those who we can't */ GError * localerror = NULL; @@ -1116,17 +1117,32 @@ get_properties_helper (gpointer key, gpointer value, gpointer data) This isn't the most efficient way. We can optimize this by somehow removing the foreach. But that is for later. */ static void -menuitem_get_properties_cb (GDBusProxy * proxy, GHashTable * properties, GError * error, gpointer data) +menuitem_get_properties_cb (GVariant * properties, GError * error, gpointer data) { g_return_if_fail(DBUSMENU_IS_MENUITEM(data)); + DbusmenuMenuitem * item = DBUSMENU_MENUITEM(data); + if (error != NULL) { g_warning("Error getting properties on a menuitem: %s", error->message); g_object_unref(data); return; } - g_hash_table_foreach(properties, get_properties_helper, data); - g_hash_table_destroy(properties); + + GVariantIter * iter = g_variant_iter_new(properties); + gchar * key; + GVariant * value; + + while (g_variant_iter_next(iter, "{sv}", &key, &value)) { + dbusmenu_menuitem_property_set_variant(item, key, value); + + g_variant_unref(value); + g_free(key); + } + + g_variant_iter_free(iter); + g_object_unref(data); + return; } @@ -1154,7 +1170,7 @@ menuitem_get_properties_replace_cb (GDBusProxy * proxy, GHashTable * properties, } if (!have_error) { - menuitem_get_properties_cb(proxy, properties, error, data); + menuitem_get_properties_cb(properties, error, data); } else { g_object_unref(data); } @@ -1181,7 +1197,7 @@ menuitem_get_properties_new_cb (GDBusProxy * proxy, GHashTable * properties, GEr /* Extra ref as get_properties will unref once itself */ g_object_ref(propdata->item); - menuitem_get_properties_cb (proxy, properties, error, propdata->item); + menuitem_get_properties_cb (properties, error, propdata->item); gboolean handled = FALSE; -- cgit v1.2.3 From cbabf67cabb66079fa89d3972fea2aaee9543b5e Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 14:46:12 -0600 Subject: Changing the prototypes for the get_properties wrappers --- libdbusmenu-glib/client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 23981de..c206e47 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1150,7 +1150,7 @@ menuitem_get_properties_cb (GVariant * properties, GError * error, gpointer data is getting recycled with the update, but we think might have prop changes. */ static void -menuitem_get_properties_replace_cb (GDBusProxy * proxy, GHashTable * properties, GError * error, gpointer data) +menuitem_get_properties_replace_cb (GVariant * properties, GError * error, gpointer data) { g_return_if_fail(DBUSMENU_IS_MENUITEM(data)); gboolean have_error = FALSE; @@ -1181,7 +1181,7 @@ menuitem_get_properties_replace_cb (GDBusProxy * proxy, GHashTable * properties, /* This is a different get properites call back that also sends new signals. It basically is a small wrapper around the original. */ static void -menuitem_get_properties_new_cb (GDBusProxy * proxy, GHashTable * properties, GError * error, gpointer data) +menuitem_get_properties_new_cb (GVariant * properties, GError * error, gpointer data) { g_return_if_fail(data != NULL); newItemPropData * propdata = (newItemPropData *)data; -- cgit v1.2.3 From e911ad73aadd6cb2cb58771a750df1e600613c08 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 15:20:38 -0600 Subject: Completely change layoutcall to be a GCancellable --- libdbusmenu-glib/client.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index c206e47..51113f0 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -360,7 +360,8 @@ dbusmenu_client_dispose (GObject *object) } if (priv->layoutcall != NULL) { - dbus_g_proxy_cancel_call(priv->menuproxy, priv->layoutcall); + g_cancellable_cancel(priv->layoutcall); + g_object_unref(priv->layoutcall); priv->layoutcall = NULL; } @@ -890,7 +891,11 @@ proxy_destroyed (GObject * gobj_proxy, gpointer userdata) } if ((gpointer)priv->menuproxy == (gpointer)gobj_proxy) { - priv->layoutcall = NULL; + if (priv->layoutcall != NULL) { + g_cancellable_cancel(priv->layoutcall); + g_object_unref(priv->layoutcall); + priv->layoutcall = NULL; + } } priv->current_revision = 0; @@ -1574,7 +1579,10 @@ update_layout_cb (GDBusProxy * proxy, guint rev, gchar * xml, GError * error, vo priv->my_revision = rev; /* g_debug("Root is now: 0x%X", (unsigned int)priv->root); */ - priv->layoutcall = NULL; + if (priv->layoutcall != NULL) { + g_object_unref(priv->layoutcall); + priv->layoutcall = NULL; + } #ifdef MASSIVEDEBUGGING g_debug("Client signaling layout has changed."); #endif @@ -1604,7 +1612,9 @@ update_layout (DbusmenuClient * client) return; } - priv->layoutcall = org_ayatana_dbusmenu_get_layout_async(priv->menuproxy, + priv->layoutcall = g_cancellable_new(); + + org_ayatana_dbusmenu_get_layout_async(priv->menuproxy, 0, /* Parent is the root */ update_layout_cb, client); -- cgit v1.2.3 From 187694edd077b979c6e19c511b5227791c3cd3f6 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 15:21:48 -0600 Subject: A couple of clean ups from the compiler --- libdbusmenu-glib/client.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 51113f0..2027e7a 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -318,7 +318,6 @@ dbusmenu_client_init (DbusmenuClient *self) static void dbusmenu_client_dispose (GObject *object) { - DbusmenuClient * client = DBUSMENU_CLIENT(object); DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(object); if (priv->delayed_idle != 0) { @@ -665,7 +664,7 @@ get_properties_globber (DbusmenuClient * client, gint id, const gchar ** propert g_warning("Asking for properties from same ID twice: %d", id); GError * localerror = NULL; g_set_error_literal(&localerror, error_domain(), 0, "ID already queued"); - callback(priv->menuproxy, NULL, localerror, user_data); + callback(NULL, localerror, user_data); g_error_free(localerror); return; } -- cgit v1.2.3 From c4882fb11cece780073e56ba186e87b9cc2e90d7 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 15:29:34 -0600 Subject: Switching over our call to AboutToShow --- libdbusmenu-glib/client.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 2027e7a..ab3730d 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1306,14 +1306,22 @@ struct _about_to_show_t { /* Reports errors and responds to update request that were a result of sending the about to show signal. */ static void -about_to_show_cb (GDBusProxy * proxy, gboolean need_update, GError * error, gpointer userdata) +about_to_show_cb (GObject * proxy, GAsyncResult * res, gpointer userdata) { + gboolean need_update = FALSE; + GError * error = NULL; about_to_show_t * data = (about_to_show_t *)userdata; + GVariant * params = NULL; + + params = g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), res, &error); if (error != NULL) { g_warning("Unable to send about_to_show: %s", error->message); /* Note: we're just ensuring only the callback gets called */ need_update = FALSE; + } else { + g_variant_get(params, "b", &need_update); + g_variant_unref(params); } /* If we need to update, do that first. */ @@ -1344,7 +1352,14 @@ dbusmenu_client_send_about_to_show(DbusmenuClient * client, gint id, void (*cb)( data->cb_data = cb_data; g_object_ref(client); - org_ayatana_dbusmenu_about_to_show_async (priv->menuproxy, id, about_to_show_cb, data); + g_dbus_proxy_call(priv->menuproxy, + "AboutToShow", + g_variant_new("i", id), + G_DBUS_CALL_FLAGS_NONE, + -1, /* timeout */ + NULL, /* cancellable */ + about_to_show_cb, + data); return; } -- cgit v1.2.3 From f60be7e8228a685fadc88e4b41ae707b5c67ec94 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 15:39:00 -0600 Subject: Reshuffling update layout to use GDBus and GVariants --- libdbusmenu-glib/client.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index ab3730d..7f6da7b 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -135,7 +135,7 @@ static void build_proxies (DbusmenuClient * client); static gint parse_node_get_id (xmlNodePtr node); static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, GDBusProxy * proxy); static gint parse_layout (DbusmenuClient * client, const gchar * layout); -static void update_layout_cb (GDBusProxy * proxy, guint rev, gchar * xml, GError * in_error, void * data); +static void update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data); static void update_layout (DbusmenuClient * client); static void menuitem_get_properties_cb (GVariant * properties, GError * error, gpointer data); static void get_properties_globber (DbusmenuClient * client, gint id, const gchar ** properties, properties_func callback, gpointer user_data); @@ -1576,17 +1576,31 @@ parse_layout (DbusmenuClient * client, const gchar * layout) /* When the layout property returns, here's where we take care of that. */ static void -update_layout_cb (GDBusProxy * proxy, guint rev, gchar * xml, GError * error, void * data) +update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data) { - DbusmenuClient * client = DBUSMENU_CLIENT(data); - DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + GError * error = NULL; + GVariant * params = NULL; + + params = g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), res, &error); if (error != NULL) { - g_warning("Getting layout failed on client %s object %s: %s", priv->dbus_name, priv->dbus_object, error->message); + g_warning("Getting layout failed: %s", error->message); return; } - if (!parse_layout(client, xml)) { + guint rev; + gchar * xml; + + g_variant_get(params, "us", &rev, &xml); + g_variant_unref(params); + + DbusmenuClient * client = DBUSMENU_CLIENT(data); + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + + guint parseable = parse_layout(client, xml); + g_free(xml); + + if (parseable == 0) { g_warning("Unable to parse layout!"); return; } @@ -1628,10 +1642,14 @@ update_layout (DbusmenuClient * client) priv->layoutcall = g_cancellable_new(); - org_ayatana_dbusmenu_get_layout_async(priv->menuproxy, - 0, /* Parent is the root */ - update_layout_cb, - client); + g_dbus_proxy_call(priv->menuproxy, + "GetLayout", + g_variant_new("i", 0), /* root */ + G_DBUS_CALL_FLAGS_NONE, + -1, /* timeout */ + priv->layoutcall, /* cancellable */ + update_layout_cb, + client); return; } -- cgit v1.2.3 From 4d1386938c19e6819c3d7ae631336bc8f37bfc48 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 15:51:03 -0600 Subject: Changing the 'Event' call to use GDBus and GVariant --- libdbusmenu-glib/client.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 7f6da7b..3a47465 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1237,9 +1237,13 @@ menuitem_get_properties_new_cb (GVariant * properties, GError * error, gpointer /* Respond to the call function to make sure that the other side got it, or print a warning. */ static void -menuitem_call_cb (GDBusProxy * proxy, GError * error, gpointer userdata) +menuitem_call_cb (GObject * proxy, GAsyncResult * res, gpointer userdata) { + GError * error = NULL; event_data_t * edata = (event_data_t *)userdata; + GVariant * params; + + params = g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), res, &error); if (error != NULL) { g_warning("Unable to call event '%s' on menu item %d: %s", edata->event, dbusmenu_menuitem_get_id(edata->menuitem), error->message); @@ -1252,6 +1256,11 @@ menuitem_call_cb (GDBusProxy * proxy, GError * error, gpointer userdata) g_object_unref(edata->menuitem); g_free(edata); + if (error != NULL) { + g_error_free(error); + } + g_variant_unref(params); + return; } @@ -1287,11 +1296,14 @@ dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name g_value_copy(value, &edata->data); edata->timestamp = timestamp; - DBusGAsyncData *stuff; - stuff = g_slice_new (DBusGAsyncData); - stuff->cb = G_CALLBACK (menuitem_call_cb); - stuff->userdata = edata; - dbus_g_proxy_begin_call_with_timeout (priv->menuproxy, "Event", org_ayatana_dbusmenu_event_async_callback, stuff, _dbus_glib_async_data_free, 1000, G_TYPE_INT, id, G_TYPE_STRING, name, G_TYPE_VALUE, value, G_TYPE_UINT, timestamp, G_TYPE_INVALID); + g_dbus_proxy_call(priv->menuproxy, + "Event", + g_variant_new("isvu", id, name, value, timestamp), + G_DBUS_CALL_FLAGS_NONE, + 1000, /* timeout */ + NULL, /* cancellable */ + menuitem_call_cb, + edata); return; } -- cgit v1.2.3 From c5ddb96e4b861edf0d0281942bea99d22296d077 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 16:00:35 -0600 Subject: Changing how the watcher is setup --- libdbusmenu-glib/client.c | 59 +++++++++++++++-------------------------------- 1 file changed, 19 insertions(+), 40 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 3a47465..f9584a9 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -82,7 +82,7 @@ struct _DbusmenuClientPrivate gint current_revision; gint my_revision; - GDBusProxy * dbusproxy; + guint dbusproxy; GHashTable * type_handlers; @@ -303,7 +303,7 @@ dbusmenu_client_init (DbusmenuClient *self) priv->current_revision = 0; priv->my_revision = 0; - priv->dbusproxy = NULL; + priv->dbusproxy = 0; priv->type_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); @@ -376,9 +376,9 @@ dbusmenu_client_dispose (GObject *object) priv->menuproxy = NULL; } - if (priv->dbusproxy != NULL) { - g_object_unref(G_OBJECT(priv->dbusproxy)); - priv->dbusproxy = NULL; + if (priv->dbusproxy != 0) { + g_bus_unwatch_name(priv->dbusproxy); + priv->dbusproxy = 0; } /* Bring down the session bus, ensure we're not @@ -790,23 +790,11 @@ id_update (GDBusProxy * proxy, gint id, DbusmenuClient * client) /* Watches to see if our DBus savior comes onto the bus */ static void -dbus_owner_change (GDBusProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, DbusmenuClient * client) +dbus_owner_change (GDBusConnection * connection, const gchar * name, const gchar * owner, gpointer user_data) { - DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); - /* g_debug("Owner change: %s %s %s", name, prev, new); */ - - if (!(new[0] != '\0' && prev[0] == '\0')) { - /* If it's not someone new getting on the bus, sorry we - simply just don't care. It's not that your service isn't - important to someone, just not us. You'll find the right - process someday, there's lots of processes out there. */ - return; - } + g_return_if_fail(DBUSMENU_IS_CLIENT(user_data)); - if (g_strcmp0(name, priv->dbus_name)) { - /* Again, someone else's service. */ - return; - } + DbusmenuClient * client = DBUSMENU_CLIENT(user_data); /* Woot! A service for us to love and to hold for ever and ever and ever! */ @@ -840,26 +828,17 @@ build_dbus_proxy (DbusmenuClient * client) DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); GError * error = NULL; - if (priv->dbusproxy != NULL) { - return; - } - - priv->dbusproxy = dbus_g_proxy_new_for_name_owner (priv->session_bus, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - &error); - if (error != NULL) { - g_debug("Oh, that's bad. That's really bad. We can't get a proxy to DBus itself? Seriously? Here's all I know: %s", error->message); - g_error_free(error); + if (priv->dbusproxy != 0) { return; } - dbus_g_proxy_add_signal(priv->dbusproxy, "NameOwnerChanged", - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal(priv->dbusproxy, "NameOwnerChanged", - G_CALLBACK(dbus_owner_change), client, NULL); + priv->dbusproxy = g_bus_watch_name_on_connection(priv->session_bus, + priv->dbus_name, + G_BUS_NAME_WATCHER_FLAGS_NONE, + dbus_owner_change, + NULL, + client, + NULL); /* Now let's check to make sure we're not in some race condition case. */ @@ -1011,9 +990,9 @@ menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data) } /* If we get here, we don't need the DBus proxy */ - if (priv->dbusproxy != NULL) { - g_object_unref(G_OBJECT(priv->dbusproxy)); - priv->dbusproxy = NULL; + if (priv->dbusproxy != 0) { + g_bus_unwatch(priv->dbusproxy); + priv->dbusproxy = 0; } g_signal_connect(priv->menuproxy, "g-signal", G_CALLBACK(menuproxy_signal_cb), client); -- cgit v1.2.3 From 7fd7547baeb728c162de08b7278ebbbff81832d3 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 16:09:34 -0600 Subject: Dropping the name check, need to figure out another way to do this. --- libdbusmenu-glib/client.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index f9584a9..563fbe0 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -801,25 +801,6 @@ dbus_owner_change (GDBusConnection * connection, const gchar * name, const gchar return build_proxies(client); } -/* This is the response to see if the name has an owner. If - it does, then we should build the proxies here. Race condition - check. */ -static void -name_owner_check (GDBusProxy *proxy, gboolean has_owner, GError *error, gpointer userdata) -{ - if (error != NULL) { - return; - } - - if (!has_owner) { - return; - } - - DbusmenuClient * client = DBUSMENU_CLIENT(userdata); - build_proxies(client); - return; -} - /* This function builds the DBus proxy which will look out for the service coming up. */ static void @@ -842,10 +823,7 @@ build_dbus_proxy (DbusmenuClient * client) /* Now let's check to make sure we're not in some race condition case. */ - org_freedesktop_DBus_name_has_owner_async(priv->dbusproxy, - priv->dbus_name, - name_owner_check, - client); + /* TODO: Not sure how to check for names in GDBus */ return; } -- cgit v1.2.3 From fb8c8e53f6bcbac9e589e1ee86a364765ce4ec83 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 16:15:04 -0600 Subject: A set of basically typos caught by the compiler --- libdbusmenu-glib/client.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 563fbe0..8658104 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -807,7 +807,6 @@ static void build_dbus_proxy (DbusmenuClient * client) { DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); - GError * error = NULL; if (priv->dbusproxy != 0) { return; @@ -878,6 +877,7 @@ session_bus_cb (GObject * object, GAsyncResult * res, gpointer user_data) } /* If this wasn't cancelled, we should be good */ + DbusmenuClient * client = DBUSMENU_CLIENT(user_data); DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); priv->session_bus = bus; @@ -898,7 +898,6 @@ static void build_proxies (DbusmenuClient * client) { DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); - GError * error = NULL; g_return_if_fail(priv->dbus_object != NULL); g_return_if_fail(priv->dbus_name != NULL); @@ -912,7 +911,7 @@ build_proxies (DbusmenuClient * client) priv->session_bus_cancel = g_cancellable_new(); /* Async get the session bus */ - g_bus_get(G_BUS_SESSION, priv->session_bus_cancel, session_bus_cb, client); + g_bus_get(G_BUS_TYPE_SESSION, priv->session_bus_cancel, session_bus_cb, client); } /* This function exists, it'll be called again when we get @@ -959,7 +958,8 @@ menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data) } /* If this wasn't cancelled, we should be good */ - DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(user_data); + DbusmenuClient * client = DBUSMENU_CLIENT(user_data); + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); priv->menuproxy = proxy; if (priv->menuproxy_cancel != NULL) { @@ -969,7 +969,7 @@ menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data) /* If we get here, we don't need the DBus proxy */ if (priv->dbusproxy != 0) { - g_bus_unwatch(priv->dbusproxy); + g_bus_unwatch_name(priv->dbusproxy); priv->dbusproxy = 0; } -- cgit v1.2.3 From 1b970b18f1ef93c597ae4d079eba78340eaced20 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 16:16:29 -0600 Subject: Changing property update to use variants --- libdbusmenu-glib/client.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 8658104..18cbfce 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -129,7 +129,7 @@ static void set_property (GObject * obj, guint id, const GValue * value, GParamS static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec); /* Private Funcs */ static void layout_update (GDBusProxy * proxy, guint revision, gint parent, DbusmenuClient * client); -static void id_prop_update (GDBusProxy * proxy, gint id, gchar * property, GValue * value, DbusmenuClient * client); +static void id_prop_update (GDBusProxy * proxy, gint id, gchar * property, GVariant * value, DbusmenuClient * client); static void id_update (GDBusProxy * proxy, gint id, DbusmenuClient * client); static void build_proxies (DbusmenuClient * client); static gint parse_node_get_id (xmlNodePtr node); @@ -740,16 +740,8 @@ layout_update (GDBusProxy * proxy, guint revision, gint parent, DbusmenuClient * /* Signal from the server that a property has changed on one of our menuitems */ static void -id_prop_update (GDBusProxy * proxy, gint id, gchar * property, GValue * value, DbusmenuClient * client) +id_prop_update (GDBusProxy * proxy, gint id, gchar * property, GVariant * value, DbusmenuClient * client) { - #ifdef MASSIVEDEBUGGING - GValue valstr = {0}; - g_value_init(&valstr, G_TYPE_STRING); - g_value_transform(value, &valstr); - g_debug("Property change sent to client for item %d property %s value %s", id, property, g_utf8_strlen(g_value_get_string(&valstr), 50) < 25 ? g_value_get_string(&valstr) : ""); - g_value_unset(&valstr); - #endif - DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); g_return_if_fail(priv->root != NULL); @@ -762,7 +754,7 @@ id_prop_update (GDBusProxy * proxy, gint id, gchar * property, GValue * value, D return; } - dbusmenu_menuitem_property_set_value(menuitem, property, value); + dbusmenu_menuitem_property_set_variant(menuitem, property, value); return; } -- cgit v1.2.3 From ab90d78d2079ac5dbdd8c6ae259e893559307246 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 16:20:35 -0600 Subject: Removing the lookup in the properties to see if an item should be replaced, since we're calling all of them, I don't think we want any leftovers. --- libdbusmenu-glib/client.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 18cbfce..f25ed7d 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1116,11 +1116,11 @@ menuitem_get_properties_replace_cb (GVariant * properties, GError * error, gpoin 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 (have_error || g_hash_table_lookup(properties, current_props->data) == NULL) { - dbusmenu_menuitem_property_remove(DBUSMENU_MENUITEM(data), (const gchar *)current_props->data); - } + current_props != NULL && have_error == FALSE; + current_props = g_list_next(current_props)) { + dbusmenu_menuitem_property_remove(DBUSMENU_MENUITEM(data), (const gchar *)current_props->data); } + g_list_free(current_props); if (!have_error) { menuitem_get_properties_cb(properties, error, data); -- cgit v1.2.3 From 80ab7485e816b687caeee4d6f0395ba010b99d2e Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 16:21:07 -0600 Subject: Oops, unused helper --- libdbusmenu-glib/client.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index f25ed7d..ff7d5ec 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1055,15 +1055,6 @@ parse_node_get_id (xmlNodePtr node) return -1; } -/* A small helper that calls _property_set on each hash table - entry in the properties hash. */ -static void -get_properties_helper (gpointer key, gpointer value, gpointer data) -{ - dbusmenu_menuitem_property_set_value((DbusmenuMenuitem *)data, (gchar *)key, (GValue *)value); - return; -} - /* This is the callback for the properties on a menu item. There should be all of them in the Hash, and they we use foreach to copy them into the menuitem. -- cgit v1.2.3 From 080cf37f48dba3dc521167bd3ddc51f45681ea1d Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Nov 2010 16:55:43 -0600 Subject: Cleaning out namespaces from the XML so that GDBus will read it. --- libdbusmenu-glib/client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index ff7d5ec..7c90fa6 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -41,7 +41,7 @@ License version 3 and version 2.1 along with this program. If not, see #include "client-menuitem.h" #include "server-marshal.h" #include "client-marshal.h" -#include "dbus-menu.xml.h" +#include "dbus-menu-clean.xml.h" /* Properties */ enum { @@ -262,7 +262,7 @@ dbusmenu_client_class_init (DbusmenuClientClass *klass) if (dbusmenu_node_info == NULL) { GError * error = NULL; - dbusmenu_node_info = g_dbus_node_info_new_for_xml(dbus_menu_xml, &error); + dbusmenu_node_info = g_dbus_node_info_new_for_xml(dbus_menu_clean_xml, &error); if (error != NULL) { g_error("Unable to parse DBusmenu Interface description: %s", error->message); g_error_free(error); -- cgit v1.2.3 From 01603a653335b7f4f09120fc5e04f3273c36a8b5 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 17 Nov 2010 20:50:45 -0600 Subject: Change all the event handling to use GVariants --- libdbusmenu-glib/client.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 7c90fa6..6f16eb2 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -112,7 +112,7 @@ struct _event_data_t { DbusmenuClient * client; DbusmenuMenuitem * menuitem; gchar * event; - GValue data; + GVariant * variant; guint timestamp; }; @@ -1189,9 +1189,9 @@ menuitem_call_cb (GObject * proxy, GAsyncResult * res, gpointer userdata) g_warning("Unable to call event '%s' on menu item %d: %s", edata->event, dbusmenu_menuitem_get_id(edata->menuitem), error->message); } - g_signal_emit(edata->client, signals[EVENT_RESULT], 0, edata->menuitem, edata->event, &edata->data, edata->timestamp, error, TRUE); + g_signal_emit(edata->client, signals[EVENT_RESULT], 0, edata->menuitem, edata->event, edata->variant, edata->timestamp, error, TRUE); - g_value_unset(&edata->data); + g_variant_unref(edata->variant); g_free(edata->event); g_object_unref(edata->menuitem); g_free(edata); @@ -1207,7 +1207,7 @@ menuitem_call_cb (GObject * proxy, GAsyncResult * res, gpointer userdata) /* Sends the event over DBus to the server on the other side of the bus. */ void -dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name, const GValue * value, guint timestamp) +dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name, GVariant * variant, guint timestamp) { g_return_if_fail(DBUSMENU_IS_CLIENT(client)); g_return_if_fail(id >= 0); @@ -1220,11 +1220,8 @@ dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name return; } - if (value == NULL) { - GValue internalval = {0}; - g_value_init(&internalval, G_TYPE_INT); - g_value_set_int(&internalval, 0); - value = &internalval; + if (variant == NULL) { + variant = g_variant_new("i", 0); } event_data_t * edata = g_new0(event_data_t, 1); @@ -1232,13 +1229,13 @@ dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name edata->menuitem = mi; g_object_ref(edata->menuitem); edata->event = g_strdup(name); - g_value_init(&edata->data, G_VALUE_TYPE(value)); - g_value_copy(value, &edata->data); edata->timestamp = timestamp; + edata->variant = variant; + g_variant_ref(variant); g_dbus_proxy_call(priv->menuproxy, "Event", - g_variant_new("isvu", id, name, value, timestamp), + g_variant_new("isvu", id, name, variant, timestamp), G_DBUS_CALL_FLAGS_NONE, 1000, /* timeout */ NULL, /* cancellable */ -- cgit v1.2.3 From 0dea1bb0779b8cddbf631ee80f76d13aa8920ec5 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 17 Nov 2010 21:11:40 -0600 Subject: Fixing our signals and marshallers for them as well --- libdbusmenu-glib/client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 6f16eb2..629a1be 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -245,8 +245,8 @@ dbusmenu_client_class_init (DbusmenuClientClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (DbusmenuClientClass, event_result), NULL, NULL, - _dbusmenu_client_marshal_VOID__OBJECT_STRING_POINTER_UINT_POINTER, - G_TYPE_NONE, 5, G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_POINTER); + _dbusmenu_client_marshal_VOID__OBJECT_STRING_VARIANT_UINT_POINTER, + G_TYPE_NONE, 5, G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_VARIANT, G_TYPE_UINT, G_TYPE_POINTER); g_object_class_install_property (object_class, PROP_DBUSOBJECT, g_param_spec_string(DBUSMENU_CLIENT_PROP_DBUS_OBJECT, "DBus Object we represent", -- cgit v1.2.3 From 72da1b32a6a834de66496fbaa6f3c57cac4d4d7a Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 18 Nov 2010 09:13:19 -0600 Subject: Fixing our use of GVariant type strings --- libdbusmenu-glib/client.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 629a1be..e0ab2d4 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1221,7 +1221,7 @@ dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name } if (variant == NULL) { - variant = g_variant_new("i", 0); + variant = g_variant_new("(i)", 0); } event_data_t * edata = g_new0(event_data_t, 1); @@ -1235,7 +1235,7 @@ dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name g_dbus_proxy_call(priv->menuproxy, "Event", - g_variant_new("isvu", id, name, variant, timestamp), + g_variant_new("(isvu)", id, name, variant, timestamp), G_DBUS_CALL_FLAGS_NONE, 1000, /* timeout */ NULL, /* cancellable */ @@ -1303,7 +1303,7 @@ dbusmenu_client_send_about_to_show(DbusmenuClient * client, gint id, void (*cb)( g_dbus_proxy_call(priv->menuproxy, "AboutToShow", - g_variant_new("i", id), + g_variant_new("(i)", id), G_DBUS_CALL_FLAGS_NONE, -1, /* timeout */ NULL, /* cancellable */ @@ -1540,7 +1540,7 @@ update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data) guint rev; gchar * xml; - g_variant_get(params, "us", &rev, &xml); + g_variant_get(params, "(us)", &rev, &xml); g_variant_unref(params); DbusmenuClient * client = DBUSMENU_CLIENT(data); @@ -1593,7 +1593,7 @@ update_layout (DbusmenuClient * client) g_dbus_proxy_call(priv->menuproxy, "GetLayout", - g_variant_new("i", 0), /* root */ + g_variant_new("(i)", 0), /* root */ G_DBUS_CALL_FLAGS_NONE, -1, /* timeout */ priv->layoutcall, /* cancellable */ -- cgit v1.2.3 From 62a03e300af33f8ad306c08337f33f59fb8511b3 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 18 Nov 2010 11:54:41 -0600 Subject: Cleaning up the building of the property requests --- libdbusmenu-glib/client.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index e0ab2d4..1e6e479 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -579,13 +579,26 @@ get_properties_idle (gpointer user_data) } /* Build up an ID list to pass */ - GArray * idlist = g_array_new(FALSE, FALSE, sizeof(gint)); + GVariantBuilder builder; + g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); + gint i; for (i = 0; i < priv->delayed_property_listeners->len; i++) { - g_array_append_val(idlist, g_array_index(priv->delayed_property_listeners, properties_listener_t, i).id); + g_variant_builder_add(&builder, "i", g_array_index(priv->delayed_property_listeners, properties_listener_t, i).id); } - GVariant * variant_params = g_variant_new("a(s)", (const gchar **)priv->delayed_property_list->data); + GVariant * variant_ids = g_variant_builder_end(&builder); + + /* Build up a prop list to pass */ + g_variant_builder_init(&builder, g_variant_type_new("as")); + GVariant * variant_props = g_variant_builder_end(&builder); + + /* Combine them into a value for the parameter */ + g_variant_builder_init(&builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value(&builder, variant_ids); + g_variant_builder_add_value(&builder, variant_props); + GVariant * variant_params = g_variant_builder_end(&builder); + g_dbus_proxy_call(priv->menuproxy, "GetGroupProperties", variant_params, @@ -595,9 +608,6 @@ get_properties_idle (gpointer user_data) get_properties_callback, priv->delayed_property_listeners); - /* Free ID List */ - g_array_free(idlist, TRUE); - /* Free properties */ gchar ** dataregion = (gchar **)g_array_free(priv->delayed_property_list, FALSE); if (dataregion != NULL) { -- cgit v1.2.3 From b5e90b0ce320570a1338e84538874a02c5dd5753 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 18 Nov 2010 13:49:50 -0600 Subject: Break out of the tuple --- libdbusmenu-glib/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 1e6e479..696f7c5 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -517,7 +517,7 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data) } /* Callback all the folks we can find */ - GVariantIter * iter = g_variant_iter_new(params); + GVariantIter * iter = g_variant_iter_new(g_variant_get_child_value(params, 0)); GVariant * child; while ((child = g_variant_iter_next_value(iter)) != NULL) { if (g_strcmp0(g_variant_get_type_string(child), "ia(sv)") != 0) { -- cgit v1.2.3 From c35642d47693feb5dce6fc6b5e3e5f258b255982 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 18 Nov 2010 13:52:24 -0600 Subject: Correcting type check --- libdbusmenu-glib/client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 696f7c5..50df570 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -520,8 +520,8 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data) GVariantIter * iter = g_variant_iter_new(g_variant_get_child_value(params, 0)); GVariant * child; while ((child = g_variant_iter_next_value(iter)) != NULL) { - if (g_strcmp0(g_variant_get_type_string(child), "ia(sv)") != 0) { - g_warning("Properties return signature is not 'ia(sv)' it is '%s'", g_variant_get_type_string(child)); + if (g_strcmp0(g_variant_get_type_string(child), "(ia{sv})") != 0) { + g_warning("Properties return signature is not '(ia{sv})' it is '%s'", g_variant_get_type_string(child)); continue; } -- cgit v1.2.3 From fc235b7eb4e7102b349fb711991e5c121a1c7a7d Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 18 Nov 2010 14:40:58 -0600 Subject: Switching to not put into a tuple --- libdbusmenu-glib/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 50df570..0479548 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1231,7 +1231,7 @@ dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name } if (variant == NULL) { - variant = g_variant_new("(i)", 0); + variant = g_variant_new_int32(0); } event_data_t * edata = g_new0(event_data_t, 1); -- cgit v1.2.3 From c40c70c6cee475ab2bf8d7e6e5804571b25deb9c Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 18 Nov 2010 14:41:27 -0600 Subject: Protect against NULL params (which they should be) but not leak just in case --- libdbusmenu-glib/client.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 0479548..cb3377a 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1206,10 +1206,12 @@ menuitem_call_cb (GObject * proxy, GAsyncResult * res, gpointer userdata) g_object_unref(edata->menuitem); g_free(edata); - if (error != NULL) { + if (G_UNLIKELY(error != NULL)) { g_error_free(error); } - g_variant_unref(params); + if (G_LIKELY(params != NULL)) { + g_variant_unref(params); + } return; } -- cgit v1.2.3 From caea84d6056d1ab1dd9744af5be9ac05670be8f9 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 18 Nov 2010 15:06:29 -0600 Subject: We can't really be autostarting as we don't know enough to make a judgement there. --- libdbusmenu-glib/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index cb3377a..f283a78 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -929,7 +929,7 @@ build_proxies (DbusmenuClient * client) priv->menuproxy_cancel = g_cancellable_new(); g_dbus_proxy_new(priv->session_bus, - G_DBUS_PROXY_FLAGS_NONE, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, dbusmenu_interface_info, priv->dbus_name, priv->dbus_object, -- cgit v1.2.3 From 92d355c18217c43c358ccda9d6eb74af9eed30d9 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 23 Nov 2010 13:21:52 -0600 Subject: Protect update_layout from not having an owner yet, and if we get one immediately call update_layout() --- libdbusmenu-glib/client.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index f283a78..be35dde 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -978,7 +978,11 @@ menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data) g_signal_connect(priv->menuproxy, "g-signal", G_CALLBACK(menuproxy_signal_cb), client); g_signal_connect(priv->menuproxy, "notify::g-name-owner", G_CALLBACK(menuproxy_name_changed_cb), client); - update_layout(client); + gchar * name_owner = g_dbus_proxy_get_name_owner(priv->menuproxy); + if (name_owner != NULL) { + update_layout(client); + g_free(name_owner); + } return; } @@ -996,6 +1000,7 @@ menuproxy_name_changed_cb (GObject * object, GParamSpec * pspec, gpointer user_d proxy_destroyed(G_OBJECT(proxy), user_data); } else { g_free(owner); + update_layout(DBUSMENU_CLIENT(user_data)); } return; @@ -1597,6 +1602,12 @@ update_layout (DbusmenuClient * client) return; } + gchar * name_owner = g_dbus_proxy_get_name_owner(priv->menuproxy); + if (name_owner == NULL) { + return; + } + g_free(name_owner); + if (priv->layoutcall != NULL) { return; } -- cgit v1.2.3 From c661b1ec2a71c8e78e72db7f72116a205059e292 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 23 Nov 2010 13:22:40 -0600 Subject: Adding another todo about the properties... need to do that everywhere --- libdbusmenu-glib/client.c | 1 + 1 file changed, 1 insertion(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index be35dde..a918f43 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -591,6 +591,7 @@ get_properties_idle (gpointer user_data) /* Build up a prop list to pass */ g_variant_builder_init(&builder, g_variant_type_new("as")); + /* TODO: need to use delayed property list here */ GVariant * variant_props = g_variant_builder_end(&builder); /* Combine them into a value for the parameter */ -- cgit v1.2.3 From 7a12cdc4cff4546e911bd49fd38b6fed9511d506 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 29 Nov 2010 15:19:31 -0600 Subject: Fixing the return values from AboutToShow --- libdbusmenu-glib/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index a918f43..7a6d87c 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1287,7 +1287,7 @@ about_to_show_cb (GObject * proxy, GAsyncResult * res, gpointer userdata) /* Note: we're just ensuring only the callback gets called */ need_update = FALSE; } else { - g_variant_get(params, "b", &need_update); + g_variant_get(params, "(b)", &need_update); g_variant_unref(params); } -- cgit v1.2.3 From b953ca847127fcc9698b83dbfcb8f760b7b62b30 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 1 Dec 2010 14:40:30 -0600 Subject: Removing the flush. It seems to be broken in GDBus and I can't fix it. --- libdbusmenu-glib/client.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 7a6d87c..454e8bb 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -549,6 +549,7 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data) for (i = 0; i < listeners->len; i++) { properties_listener_t * listener = &g_array_index(listeners, properties_listener_t, i); if (!listener->replied) { + g_warning("Generating properties error for: %d", listener->id); if (localerror == NULL) { g_set_error_literal(&localerror, error_domain(), 0, "Error getting properties for ID"); } @@ -625,21 +626,6 @@ get_properties_idle (gpointer user_data) return FALSE; } -/* Report and error if we're unable to flush the connection, likely - to be a cause of some other issues. */ -static void -connection_flush_cb (GObject * object, GAsyncResult * result, gpointer user_data) -{ - GError * error = NULL; - - if (!g_dbus_connection_flush_finish(G_DBUS_CONNECTION(object), result, &error)) { - g_warning("Unable to flush DBus connection: %s", error->message); - g_error_free(error); - } - - return; -} - /* Forces a call out to start getting properties with the menu items that we have queued up already. */ static void @@ -656,12 +642,6 @@ get_properties_flush (DbusmenuClient * client) get_properties_idle(client); - /* I'm not sure this flush is necissary with GDBus running the - DBus connection in another thread. But, I don't think that - it'll hurt anything either, so I'm leaving it in. */ - g_return_if_fail(priv->session_bus != NULL); - g_dbus_connection_flush(priv->session_bus, NULL, connection_flush_cb, NULL); - return; } -- cgit v1.2.3 From a8b425c5868c73739f60997ebc2013df3b3d6d4b Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 13 Jan 2011 09:53:15 -0600 Subject: Ayatana purge --- libdbusmenu-glib/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index a15469b..58d6360 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -122,7 +122,7 @@ struct _event_data_t { #define DBUSMENU_CLIENT_GET_PRIVATE(o) (DBUSMENU_CLIENT(o)->priv) -#define DBUSMENU_INTERFACE "org.ayatana.dbusmenu" +#define DBUSMENU_INTERFACE "com.canonical.dbusmenu" /* GObject Stuff */ static void dbusmenu_client_class_init (DbusmenuClientClass *klass); -- cgit v1.2.3 From 17632d1272a0741e5f5a11abcc4e8f758bc9e98c Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 18 Jan 2011 16:56:14 -0600 Subject: Adding in a 'full' function to deal with user data and destruction. --- libdbusmenu-glib/client.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 58d6360..a57b7ba 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1163,7 +1163,7 @@ menuitem_get_properties_new_cb (GVariant * properties, GError * error, gpointer } if (newfunc != NULL) { - handled = newfunc(propdata->item, propdata->parent, propdata->client); + handled = newfunc(propdata->item, propdata->parent, propdata->client, NULL); } #ifdef MASSIVEDEBUGGING @@ -1698,6 +1698,12 @@ dbusmenu_client_get_root (DbusmenuClient * client) */ gboolean dbusmenu_client_add_type_handler (DbusmenuClient * client, const gchar * type, DbusmenuClientTypeHandler newfunc) +{ + return dbusmenu_client_add_type_handler_full(client, type, newfunc, NULL, NULL); +} + +gboolean +dbusmenu_client_add_type_handler_full (DbusmenuClient * client, const gchar * type, DbusmenuClientTypeHandler newfunc, gpointer user_data, DbusmenuClientTypeDestroyHandler destory_func) { g_return_val_if_fail(DBUSMENU_IS_CLIENT(client), FALSE); g_return_val_if_fail(type != NULL, FALSE); @@ -1722,3 +1728,4 @@ dbusmenu_client_add_type_handler (DbusmenuClient * client, const gchar * type, D g_hash_table_insert(priv->type_handlers, g_strdup(type), newfunc); return TRUE; } + -- cgit v1.2.3 From be239149b9b3b875f9c52137e6bdc19a78724f72 Mon Sep 17 00:00:00 2001 From: Chris Coulson Date: Wed, 19 Jan 2011 14:55:37 +0000 Subject: Ensure that we can recover from GetLayout failing --- libdbusmenu-glib/client.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 58d6360..29ed4a0 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1538,6 +1538,14 @@ parse_layout (DbusmenuClient * client, const gchar * layout) static void update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data) { + DbusmenuClient * client = DBUSMENU_CLIENT(data); + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + + if (priv->layoutcall != NULL) { + g_object_unref(priv->layoutcall); + priv->layoutcall = NULL; + } + GError * error = NULL; GVariant * params = NULL; @@ -1554,9 +1562,6 @@ update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data) g_variant_get(params, "(us)", &rev, &xml); g_variant_unref(params); - DbusmenuClient * client = DBUSMENU_CLIENT(data); - DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); - guint parseable = parse_layout(client, xml); g_free(xml); @@ -1567,10 +1572,6 @@ update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data) priv->my_revision = rev; /* g_debug("Root is now: 0x%X", (unsigned int)priv->root); */ - if (priv->layoutcall != NULL) { - g_object_unref(priv->layoutcall); - priv->layoutcall = NULL; - } #ifdef MASSIVEDEBUGGING g_debug("Client signaling layout has changed."); #endif -- cgit v1.2.3 From d3e03f289c5d04e36686ea758f523758ea0a783f Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 19 Jan 2011 11:29:19 -0600 Subject: Adding in some documentation --- libdbusmenu-glib/client.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index a57b7ba..f102dee 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1702,8 +1702,33 @@ dbusmenu_client_add_type_handler (DbusmenuClient * client, const gchar * type, D return dbusmenu_client_add_type_handler_full(client, type, newfunc, NULL, NULL); } +/** + dbusmenu_client_add_type_handler_full: + @client: Client where we're getting types coming in + @type: A text string that will be matched with the 'type' + property on incoming menu items + @newfunc: The function that will be executed with those new + items when they come in. + @user_data: Data passed to @newfunc when it is called + @destroy_func: A function that is called when the type handler is + removed (usually on client destruction) which will free + the resources in @user_data. + + This function connects into the type handling of the #DbusmenuClient. + Every new menuitem that comes in immediately gets asked for it's + properties. When we get those properties we check the 'type' + property and look to see if it matches a handler that is known + by the client. If so, the @newfunc function is executed on that + #DbusmenuMenuitem. If not, then the DbusmenuClient::new-menuitem + signal is sent. + + In the future the known types will be sent to the server so that it + can make choices about the menu item types availble. + + Return value: If registering the new type was successful. +*/ gboolean -dbusmenu_client_add_type_handler_full (DbusmenuClient * client, const gchar * type, DbusmenuClientTypeHandler newfunc, gpointer user_data, DbusmenuClientTypeDestroyHandler destory_func) +dbusmenu_client_add_type_handler_full (DbusmenuClient * client, const gchar * type, DbusmenuClientTypeHandler newfunc, gpointer user_data, DbusmenuClientTypeDestroyHandler destroy_func) { g_return_val_if_fail(DBUSMENU_IS_CLIENT(client), FALSE); g_return_val_if_fail(type != NULL, FALSE); -- cgit v1.2.3 From e58df7a09fb28a4ae38888f54edf09d937bf70b2 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 19 Jan 2011 16:05:08 -0600 Subject: Switch to having the type handlers have a small structure of all their data and clean themselves up. Woot! --- libdbusmenu-glib/client.c | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index f102dee..f84d6e0 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -120,6 +120,15 @@ struct _event_data_t { guint timestamp; }; +typedef struct _type_handler_t type_handler_t; +struct _type_handler_t { + DbusmenuClient * client; + DbusmenuClientTypeHandler cb; + DbusmenuClientTypeDestroyHandler destroy_cb; + gpointer user_data; + gchar * type; +}; + #define DBUSMENU_CLIENT_GET_PRIVATE(o) (DBUSMENU_CLIENT(o)->priv) #define DBUSMENU_INTERFACE "com.canonical.dbusmenu" @@ -148,6 +157,7 @@ static void item_activated (GDBusProxy * proxy, gint id, guint timestamp, Dbusme static void menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data); static void menuproxy_name_changed_cb (GObject * object, GParamSpec * pspec, gpointer user_data); static void menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVariant * params, gpointer user_data); +static void type_handler_destroy (gpointer user_data); /* Globals */ static GDBusNodeInfo * dbusmenu_node_info = NULL; @@ -310,7 +320,7 @@ dbusmenu_client_init (DbusmenuClient *self) priv->dbusproxy = 0; priv->type_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, NULL); + g_free, type_handler_destroy); priv->delayed_idle = 0; priv->delayed_property_list = g_array_new(TRUE, FALSE, sizeof(gchar *)); @@ -1153,17 +1163,17 @@ menuitem_get_properties_new_cb (GVariant * properties, GError * error, gpointer gboolean handled = FALSE; const gchar * type; - DbusmenuClientTypeHandler newfunc = NULL; + type_handler_t * th = NULL; type = dbusmenu_menuitem_property_get(propdata->item, DBUSMENU_MENUITEM_PROP_TYPE); if (type != NULL) { - newfunc = g_hash_table_lookup(priv->type_handlers, type); + th = (type_handler_t *)g_hash_table_lookup(priv->type_handlers, type); } else { - newfunc = g_hash_table_lookup(priv->type_handlers, DBUSMENU_CLIENT_TYPES_DEFAULT); + th = (type_handler_t *)g_hash_table_lookup(priv->type_handlers, DBUSMENU_CLIENT_TYPES_DEFAULT); } - if (newfunc != NULL) { - handled = newfunc(propdata->item, propdata->parent, propdata->client, NULL); + if (th != NULL && th->cb != NULL) { + handled = th->cb(propdata->item, propdata->parent, propdata->client, th->user_data); } #ifdef MASSIVEDEBUGGING @@ -1675,6 +1685,19 @@ dbusmenu_client_get_root (DbusmenuClient * client) return priv->root; } +/* Remove the type handler when we're all done with it */ +static void +type_handler_destroy (gpointer user_data) +{ + type_handler_t * th = (type_handler_t *)user_data; + if (th->destroy_cb != NULL) { + th->destroy_cb(th->client, th->type, th->user_data); + } + g_free(th->type); + g_free(th); + return; +} + /** dbusmenu_client_add_type_handler: @client: Client where we're getting types coming in @@ -1750,7 +1773,14 @@ dbusmenu_client_add_type_handler_full (DbusmenuClient * client, const gchar * ty return FALSE; } - g_hash_table_insert(priv->type_handlers, g_strdup(type), newfunc); + type_handler_t * th = g_new0(type_handler_t, 1); + th->client = client; + th->cb = newfunc; + th->destroy_cb = destroy_func; + th->user_data = user_data; + th->type = g_strdup(type); + + g_hash_table_insert(priv->type_handlers, g_strdup(type), th); return TRUE; } -- cgit v1.2.3 From 59b8be494e5fbccdbed59b49fa4f190fbbb55343 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 21 Jan 2011 13:33:01 -0600 Subject: Ensuring that all the errors are free'd correctly. --- libdbusmenu-glib/client.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 29ed4a0..86b023d 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -517,6 +517,7 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data) listener->callback(NULL, error, listener->user_data); } g_array_free(listeners, TRUE); + g_error_free(error); return; } @@ -1140,7 +1141,6 @@ menuitem_get_properties_new_cb (GVariant * properties, GError * error, gpointer if (error != NULL) { g_warning("Error getting properties on a new menuitem: %s", error->message); g_object_unref(propdata->item); - g_free(data); return; } @@ -1277,6 +1277,8 @@ about_to_show_cb (GObject * proxy, GAsyncResult * res, gpointer userdata) g_warning("Unable to send about_to_show: %s", error->message); /* Note: we're just ensuring only the callback gets called */ need_update = FALSE; + g_error_free(error); + error = NULL; } else { g_variant_get(params, "(b)", &need_update); g_variant_unref(params); @@ -1553,6 +1555,7 @@ update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data) if (error != NULL) { g_warning("Getting layout failed: %s", error->message); + g_error_free(error); return; } -- cgit v1.2.3 From 0cdd25e225a88a67fedeae4ddb9686213820ac2c Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Tue, 25 Jan 2011 13:18:05 -0500 Subject: avoid critical warning from calling a function on a NULL pointer --- libdbusmenu-glib/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 29ed4a0..a5fb1dd 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1441,7 +1441,7 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it /* We've got everything built up at this node and reconcilled */ /* Flush the properties requests if this is the first level */ - if (dbusmenu_menuitem_get_id(parent) == 0) { + if (parent != NULL && dbusmenu_menuitem_get_id(parent) == 0) { get_properties_flush(client); } -- cgit v1.2.3 From 6a6a292ffadadf9f5389fe0c8507ef047daffce1 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 31 Jan 2011 08:58:18 -0600 Subject: Keep a ref to the client through-out the call to the update --- libdbusmenu-glib/client.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index b196c9f..f59dcf6 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1553,11 +1553,6 @@ update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data) DbusmenuClient * client = DBUSMENU_CLIENT(data); DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); - if (priv->layoutcall != NULL) { - g_object_unref(priv->layoutcall); - priv->layoutcall = NULL; - } - GError * error = NULL; GVariant * params = NULL; @@ -1566,7 +1561,7 @@ update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data) if (error != NULL) { g_warning("Getting layout failed: %s", error->message); g_error_free(error); - return; + goto out; } guint rev; @@ -1580,7 +1575,7 @@ update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data) if (parseable == 0) { g_warning("Unable to parse layout!"); - return; + goto out; } priv->my_revision = rev; @@ -1596,6 +1591,13 @@ update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data) update_layout(client); } +out: + if (priv->layoutcall != NULL) { + g_object_unref(priv->layoutcall); + priv->layoutcall = NULL; + } + + g_object_unref(G_OBJECT(client)); return; } @@ -1622,6 +1624,7 @@ update_layout (DbusmenuClient * client) priv->layoutcall = g_cancellable_new(); + g_object_ref(G_OBJECT(client)); g_dbus_proxy_call(priv->menuproxy, "GetLayout", g_variant_new("(i)", 0), /* root */ -- cgit v1.2.3 From 565cc0962042839e4b35f8ae2d01a64864bc665c Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 31 Jan 2011 10:48:21 -0600 Subject: Switching the properties callback to use custom structure so that we can reference the client throughout the callback. --- libdbusmenu-glib/client.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index f59dcf6..5e492a3 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -129,6 +129,12 @@ struct _type_handler_t { gchar * type; }; +typedef struct _properties_callback_t properties_callback_t; +struct _properties_callback_t { + DbusmenuClient * client; + GArray * listeners; +}; + #define DBUSMENU_CLIENT_GET_PRIVATE(o) (DBUSMENU_CLIENT(o)->priv) #define DBUSMENU_INTERFACE "com.canonical.dbusmenu" @@ -512,7 +518,8 @@ find_listener (GArray * listeners, guint index, gint id) static void get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data) { - GArray * listeners = (GArray *)user_data; + properties_callback_t * cbdata = (properties_callback_t *)user_data; + GArray * listeners = cbdata->listeners; int i; GError * error = NULL; GVariant * params = NULL; @@ -526,9 +533,8 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data) properties_listener_t * listener = &g_array_index(listeners, properties_listener_t, i); listener->callback(NULL, error, listener->user_data); } - g_array_free(listeners, TRUE); g_error_free(error); - return; + goto out; } /* Callback all the folks we can find */ @@ -575,8 +581,11 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data) g_error_free(localerror); } +out: /* Clean up */ g_array_free(listeners, TRUE); + g_object_unref(cbdata->client); + g_free(user_data); return; } @@ -586,6 +595,7 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data) static gboolean get_properties_idle (gpointer user_data) { + properties_callback_t * cbdata = NULL; DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(user_data); g_return_val_if_fail(priv->menuproxy != NULL, TRUE); @@ -616,6 +626,11 @@ get_properties_idle (gpointer user_data) g_variant_builder_add_value(&builder, variant_props); GVariant * variant_params = g_variant_builder_end(&builder); + cbdata = g_new(properties_callback_t, 1); + cbdata->listeners = priv->delayed_property_listeners; + cbdata->client = DBUSMENU_CLIENT(user_data); + g_object_ref(G_OBJECT(user_data)); + g_dbus_proxy_call(priv->menuproxy, "GetGroupProperties", variant_params, @@ -623,7 +638,7 @@ get_properties_idle (gpointer user_data) -1, /* timeout */ NULL, /* cancellable */ get_properties_callback, - priv->delayed_property_listeners); + cbdata); /* Free properties */ gchar ** dataregion = (gchar **)g_array_free(priv->delayed_property_list, FALSE); -- cgit v1.2.3 From fd553bb625a37ac77d84e8100bd2404748ea21e2 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 8 Feb 2011 09:14:41 -0600 Subject: Handling and unrolling the properties updated signal --- libdbusmenu-glib/client.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 5e492a3..aa0b3f0 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1035,6 +1035,22 @@ menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVarian guint revision; gint parent; g_variant_get(params, "(ui)", &revision, &parent); layout_update(proxy, revision, parent, client); + } else if (g_strcmp0(signal, "ItemPropertiesUpdated") == 0) { + GVariantIter items; + g_variant_iter_init(&items, g_variant_get_child_value(params, 0)); + + GVariant * item; + while ((item = g_variant_iter_next_value(&items)) != NULL) { + gint id = g_variant_get_int32(g_variant_get_child_value(item, 0)); + GVariantIter properties; + g_variant_iter_init(&properties, g_variant_get_child_value(item, 1)); + gchar * property; + GVariant * value; + + while (g_variant_iter_next(&properties, "{sv}", &property, &value)) { + id_prop_update(proxy, id, property, value, client); + } + } } else if (g_strcmp0(signal, "ItemPropertyUpdated") == 0) { gint id; gchar * property; GVariant * value; g_variant_get(params, "(isv)", &id, &property, &value); -- cgit v1.2.3 From 436d5042bbb97d2bec691a655e79875e8a1d7573 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 8 Feb 2011 11:17:31 -0600 Subject: Unbox the variants if they're boxed --- libdbusmenu-glib/client.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index aa0b3f0..cb90789 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1048,7 +1048,12 @@ menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVarian GVariant * value; while (g_variant_iter_next(&properties, "{sv}", &property, &value)) { - id_prop_update(proxy, id, property, value, client); + GVariant * internalvalue = value; + if (G_LIKELY(g_variant_is_of_type(value, G_VARIANT_TYPE_VARIANT))) { + /* Unboxing if needed */ + internalvalue = g_variant_get_variant(value); + } + id_prop_update(proxy, id, property, internalvalue, client); } } } else if (g_strcmp0(signal, "ItemPropertyUpdated") == 0) { -- cgit v1.2.3 From b1ec6fff879179f0fdcc9aff72d770ca5020dee6 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 14 Feb 2011 13:04:28 -0600 Subject: Adding removing properties on the client side of things. --- libdbusmenu-glib/client.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index cb90789..63fa089 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1030,12 +1030,37 @@ menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVarian { g_return_if_fail(DBUSMENU_IS_CLIENT(user_data)); DbusmenuClient * client = DBUSMENU_CLIENT(user_data); + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); if (g_strcmp0(signal, "LayoutUpdated") == 0) { guint revision; gint parent; g_variant_get(params, "(ui)", &revision, &parent); layout_update(proxy, revision, parent, client); } else if (g_strcmp0(signal, "ItemPropertiesUpdated") == 0) { + /* Remove before adding just incase there is a duplicate, against the + rules, but we can handle it so let's do it. */ + GVariantIter ritems; + g_variant_iter_init(&ritems, g_variant_get_child_value(params, 1)); + + GVariant * ritem; + while ((ritem = g_variant_iter_next_value(&ritems)) != NULL) { + gint id = g_variant_get_int32(g_variant_get_child_value(ritem, 0)); + DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id); + + if (menuitem == NULL) { + continue; + } + + GVariantIter properties; + g_variant_iter_init(&properties, g_variant_get_child_value(ritem, 1)); + gchar * property; + + while (g_variant_iter_next(&properties, "s", &property)) { + g_debug("Removing property '%s' on %d", property, id); + dbusmenu_menuitem_property_remove(menuitem, property); + } + } + GVariantIter items; g_variant_iter_init(&items, g_variant_get_child_value(params, 0)); -- cgit v1.2.3 From 1f1eb89cbf0317ea9e464354cd47b11502efc9de Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 14 Feb 2011 13:32:49 -0600 Subject: Ignore signals if there's no root node --- libdbusmenu-glib/client.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 63fa089..9502bfd 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1036,6 +1036,9 @@ menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVarian guint revision; gint parent; g_variant_get(params, "(ui)", &revision, &parent); layout_update(proxy, revision, parent, client); + } else if (priv->root == NULL) { + /* Drop out here, all the rest of these really need to have a root + node so we can just ignore them if there isn't one. */ } else if (g_strcmp0(signal, "ItemPropertiesUpdated") == 0) { /* Remove before adding just incase there is a duplicate, against the rules, but we can handle it so let's do it. */ -- cgit v1.2.3 From 7930b8fa5e726b4b5136d71871a7a98a4885bbeb Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 14 Feb 2011 15:59:40 -0600 Subject: Changing the client over from XML to taking in the variant structures --- libdbusmenu-glib/client.c | 118 +++++++++++++++++----------------------------- 1 file changed, 43 insertions(+), 75 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index cb90789..574a8e0 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -151,9 +151,8 @@ static void layout_update (GDBusProxy * proxy, guint revision, gint parent, Dbus static void id_prop_update (GDBusProxy * proxy, gint id, gchar * property, GVariant * value, DbusmenuClient * client); static void id_update (GDBusProxy * proxy, gint id, DbusmenuClient * client); static void build_proxies (DbusmenuClient * client); -static gint parse_node_get_id (xmlNodePtr node); -static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, GDBusProxy * proxy); -static gint parse_layout (DbusmenuClient * client, const gchar * layout); +static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, GVariant * layout, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, GDBusProxy * proxy); +static gint parse_layout (DbusmenuClient * client, GVariant * layout); static void update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data); static void update_layout (DbusmenuClient * client); static void menuitem_get_properties_cb (GVariant * properties, GError * error, gpointer data); @@ -1075,40 +1074,6 @@ menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVarian return; } -/* Get the ID attribute of the node, parse it and - return it. Also we're checking to ensure the node - is a 'menu' here. */ -static gint -parse_node_get_id (xmlNodePtr node) -{ - if (node == NULL) { - return -1; - } - if (node->type != XML_ELEMENT_NODE) { - return -1; - } - if (g_strcmp0((gchar *)node->name, "menu") != 0) { - /* This kills some nodes early */ - g_warning("XML Node is not 'menu' it is '%s'", node->name); - return -1; - } - - xmlAttrPtr attrib; - for (attrib = node->properties; attrib != NULL; attrib = attrib->next) { - if (g_strcmp0((gchar *)attrib->name, "id") == 0) { - if (attrib->children != NULL) { - gint id = (guint)g_ascii_strtoll((gchar *)attrib->children->content, NULL, 10); - /* g_debug ("Found ID: %d", id); */ - return id; - } - break; - } - } - - g_warning("Unable to find an ID on the node"); - return -1; -} - /* This is the callback for the properties on a menu item. There should be all of them in the Hash, and they we use foreach to copy them into the menuitem. @@ -1411,10 +1376,14 @@ parse_layout_update (DbusmenuMenuitem * item, DbusmenuClient * client) /* Parse recursively through the XML and make it into objects as need be */ static DbusmenuMenuitem * -parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, GDBusProxy * proxy) +parse_layout_xml(DbusmenuClient * client, GVariant * layout, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, GDBusProxy * proxy) { + if (layout == NULL) { + return NULL; + } + /* First verify and figure out what we've got */ - gint id = parse_node_get_id(node); + gint id = g_variant_get_int32(g_variant_get_child_value(layout, 0)); if (id < 0) { return NULL; } @@ -1426,20 +1395,26 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it g_return_val_if_fail(id == dbusmenu_menuitem_get_id(item), NULL); /* Some variables */ - xmlNodePtr children; - guint position; + GVariantIter children; + g_variant_iter_init(&children, g_variant_get_child_value(layout, 2)); + GVariant * child; + + guint position = 0; GList * oldchildren = g_list_copy(dbusmenu_menuitem_get_children(item)); /* g_debug("Starting old children: %d", g_list_length(oldchildren)); */ /* Go through all the XML Nodes and make sure that we have menuitems to cover those XML nodes. */ - for (children = node->children, position = 0; children != NULL; children = children->next, position++) { + while ((child = g_variant_iter_next_value(&children)) != NULL) { /* g_debug("Looking at child: %d", position); */ - gint childid = parse_node_get_id(children); + if (g_variant_is_of_type(child, G_VARIANT_TYPE_VARIANT)) { + child = g_variant_get_variant(child); + } + + gint childid = g_variant_get_uint32(g_variant_get_child_value(child, 0)); if (childid < 0) { /* Don't increment the position when there isn't a valid node in the XML tree. It's probably a comment. */ - position--; continue; } DbusmenuMenuitem * childmi = NULL; @@ -1472,6 +1447,8 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it dbusmenu_menuitem_child_reorder(item, childmi, position); parse_layout_update(childmi, client); } + + position++; } /* Remove any children that are no longer used by this version of @@ -1494,14 +1471,16 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it } /* now it's time to recurse down the tree. */ - children = node->children; + g_variant_iter_init(&children, g_variant_get_child_value(layout, 2)); + + child = g_variant_iter_next_value(&children); GList * childmis = dbusmenu_menuitem_get_children(item); - while (children != NULL && childmis != NULL) { - gint xmlid = parse_node_get_id(children); + while (child != NULL && childmis != NULL) { + gint xmlid = g_variant_get_uint32(g_variant_get_child_value(child, 0)); /* If this isn't a valid menu item we need to move on until we have one. This avoids things like comments. */ if (xmlid < 0) { - children = children->next; + child = g_variant_iter_next_value(&children); continue; } @@ -1510,13 +1489,14 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it g_debug("Recursing parse_layout_xml. XML ID: %d MI ID: %d", xmlid, miid); #endif - parse_layout_xml(client, children, DBUSMENU_MENUITEM(childmis->data), item, proxy); + parse_layout_xml(client, child, DBUSMENU_MENUITEM(childmis->data), item, proxy); - children = children->next; + child = g_variant_iter_next_value(&children); childmis = g_list_next(childmis); } - if (children != NULL) { - g_warning("Sync failed, now we've got extra XML nodes."); + + if (child != NULL) { + g_warning("Sync failed, now we've got extra layout nodes."); } if (childmis != NULL) { g_warning("Sync failed, now we've got extra menu items."); @@ -1528,7 +1508,7 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it /* Take the layout passed to us over DBus and turn it into a set of beautiful objects */ static gint -parse_layout (DbusmenuClient * client, const gchar * layout) +parse_layout (DbusmenuClient * client, GVariant * layout) { #ifdef MASSIVEDEBUGGING g_debug("Client Parsing a new layout"); @@ -1536,17 +1516,6 @@ parse_layout (DbusmenuClient * client, const gchar * layout) DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); - xmlDocPtr xmldoc; - - /* No one should need more characters than this! */ - xmldoc = xmlReadMemory(layout, g_utf8_strlen(layout, 1024*1024), "dbusmenu.xml", NULL, 0); - - xmlNodePtr root = xmlDocGetRootElement(xmldoc); - - if (root == NULL) { - g_warning("Unable to get root node of menu XML"); - } - DbusmenuMenuitem * oldroot = priv->root; if (priv->root == NULL) { @@ -1555,11 +1524,10 @@ parse_layout (DbusmenuClient * client, const gchar * layout) parse_layout_update(priv->root, client); } - priv->root = parse_layout_xml(client, root, priv->root, NULL, priv->menuproxy); - xmlFreeDoc(xmldoc); + priv->root = parse_layout_xml(client, layout, priv->root, NULL, priv->menuproxy); if (priv->root == NULL) { - g_warning("Unable to parse layout on client %s object %s: %s", priv->dbus_name, priv->dbus_object, layout); + g_warning("Unable to parse layout on client %s object %s: %s", priv->dbus_name, priv->dbus_object, g_variant_print(layout, TRUE)); } if (priv->root != oldroot) { @@ -1600,14 +1568,10 @@ update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data) goto out; } - guint rev; - gchar * xml; - - g_variant_get(params, "(us)", &rev, &xml); - g_variant_unref(params); + guint rev = g_variant_get_uint32(g_variant_get_child_value(params, 0)); + GVariant * layout = g_variant_get_child_value(params, 1); - guint parseable = parse_layout(client, xml); - g_free(xml); + guint parseable = parse_layout(client, layout); if (parseable == 0) { g_warning("Unable to parse layout!"); @@ -1633,6 +1597,10 @@ out: priv->layoutcall = NULL; } + if (params != NULL) { + g_variant_unref(params); + } + g_object_unref(G_OBJECT(client)); return; } @@ -1663,7 +1631,7 @@ update_layout (DbusmenuClient * client) g_object_ref(G_OBJECT(client)); g_dbus_proxy_call(priv->menuproxy, "GetLayout", - g_variant_new("(i)", 0), /* root */ + g_variant_new("(iia(s))", 0, -1, NULL), /* root */ G_DBUS_CALL_FLAGS_NONE, -1, /* timeout */ priv->layoutcall, /* cancellable */ -- cgit v1.2.3 From 9e1ab7f70ffee850bd09660d27199ece367b0c5d Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 14 Feb 2011 16:00:51 -0600 Subject: Dropping libxml --- libdbusmenu-glib/client.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 574a8e0..fb4509b 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -32,9 +32,6 @@ License version 3 and version 2.1 along with this program. If not, see #include -#include -#include - #include "client.h" #include "menuitem.h" #include "menuitem-private.h" -- cgit v1.2.3 From bf3230927208a3bcd5f8f5edb000e14481ffb9b8 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 14 Feb 2011 16:19:09 -0600 Subject: Making the build of the message more explicit and correct --- libdbusmenu-glib/client.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index fb4509b..60ec1ee 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1625,10 +1625,17 @@ update_layout (DbusmenuClient * client) priv->layoutcall = g_cancellable_new(); + GVariantBuilder tupleb; + g_variant_builder_init(&tupleb, G_VARIANT_TYPE_TUPLE); + + g_variant_builder_add_value(&tupleb, g_variant_new_int32(0)); // root + g_variant_builder_add_value(&tupleb, g_variant_new_int32(-1)); // recurse + g_variant_builder_add_value(&tupleb, g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0)); // props + g_object_ref(G_OBJECT(client)); g_dbus_proxy_call(priv->menuproxy, "GetLayout", - g_variant_new("(iia(s))", 0, -1, NULL), /* root */ + g_variant_builder_end(&tupleb), G_DBUS_CALL_FLAGS_NONE, -1, /* timeout */ priv->layoutcall, /* cancellable */ -- cgit v1.2.3 From bb4167eeb1810687c8c56a376a0a0566c1e46f41 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 14 Feb 2011 16:35:57 -0600 Subject: Splitting out the args for easier debugging --- libdbusmenu-glib/client.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 60ec1ee..7721787 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1632,10 +1632,13 @@ update_layout (DbusmenuClient * client) g_variant_builder_add_value(&tupleb, g_variant_new_int32(-1)); // recurse g_variant_builder_add_value(&tupleb, g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0)); // props + GVariant * args = g_variant_builder_end(&tupleb); + // g_debug("Args (type: %s): %s", g_variant_get_type_string(args), g_variant_print(args, TRUE)); + g_object_ref(G_OBJECT(client)); g_dbus_proxy_call(priv->menuproxy, "GetLayout", - g_variant_builder_end(&tupleb), + args, G_DBUS_CALL_FLAGS_NONE, -1, /* timeout */ priv->layoutcall, /* cancellable */ -- cgit v1.2.3 From b145235e39b4ac35c1cad312d04e7c0471c518d7 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 14 Feb 2011 17:09:04 -0600 Subject: Get the IDs properly. ints and unpacked --- libdbusmenu-glib/client.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 7721787..fa3b1d2 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1408,7 +1408,7 @@ parse_layout_xml(DbusmenuClient * client, GVariant * layout, DbusmenuMenuitem * child = g_variant_get_variant(child); } - gint childid = g_variant_get_uint32(g_variant_get_child_value(child, 0)); + gint childid = g_variant_get_int32(g_variant_get_child_value(child, 0)); if (childid < 0) { /* Don't increment the position when there isn't a valid node in the XML tree. It's probably a comment. */ @@ -1473,7 +1473,11 @@ parse_layout_xml(DbusmenuClient * client, GVariant * layout, DbusmenuMenuitem * child = g_variant_iter_next_value(&children); GList * childmis = dbusmenu_menuitem_get_children(item); while (child != NULL && childmis != NULL) { - gint xmlid = g_variant_get_uint32(g_variant_get_child_value(child, 0)); + if (g_variant_is_of_type(child, G_VARIANT_TYPE_VARIANT)) { + child = g_variant_get_variant(child); + } + + gint xmlid = g_variant_get_int32(g_variant_get_child_value(child, 0)); /* If this isn't a valid menu item we need to move on until we have one. This avoids things like comments. */ if (xmlid < 0) { -- cgit v1.2.3 From ee4fda3072d31b828c5d607b9ac0a4ab6c7ee320 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 15 Feb 2011 11:42:52 -0600 Subject: Making sure all refs sink incase of floating variants --- libdbusmenu-glib/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 6a9dc23..ba4ae7e 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1276,7 +1276,7 @@ dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name edata->event = g_strdup(name); edata->timestamp = timestamp; edata->variant = variant; - g_variant_ref(variant); + g_variant_ref_sink(variant); g_dbus_proxy_call(priv->menuproxy, "Event", -- cgit v1.2.3 From bafe476c0fa84277c6136605680c3d349430db50 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Wed, 16 Feb 2011 20:34:17 +0100 Subject: Fix GI annotations for Dbusmenu Now everything is introspectable except for dbusmenu_client_add_type_handler{,_full}(). These do not take a standard GDestroyNotify argument, and thus the newfunc callback cannot get any valid scope annotation. To fix this we need to break the API and ABI. --- libdbusmenu-glib/client.c | 136 +++++++++++++++++++++++----------------------- 1 file changed, 68 insertions(+), 68 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 5e492a3..8a1d213 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1654,17 +1654,17 @@ update_layout (DbusmenuClient * client) /* Public API */ /** - dbusmenu_client_new: - @name: The DBus name for the server to connect to - @object: The object on the server to monitor - - This function creates a new client that connects to a specific - server on DBus. That server is at a specific location sharing - a known object. The interface is assumed by the code to be - the DBus menu interface. The newly created client will start - sending out events as it syncs up with the server. - - Return value: A brand new #DbusmenuClient + * dbusmenu_client_new: + * @name: The DBus name for the server to connect to + * @object: The object on the server to monitor + * + * This function creates a new client that connects to a specific + * server on DBus. That server is at a specific location sharing + * a known object. The interface is assumed by the code to be + * the DBus menu interface. The newly created client will start + * sending out events as it syncs up with the server. + * + * Return value: A brand new #DbusmenuClient */ DbusmenuClient * dbusmenu_client_new (const gchar * name, const gchar * object) @@ -1678,21 +1678,21 @@ dbusmenu_client_new (const gchar * name, const gchar * object) } /** - dbusmenu_client_get_root: - @client: The #DbusmenuClient to get the root node from - - Grabs the root node for the specified client @client. This - function may block. It will block if there is currently a - call to update the layout, it will block on that layout - updated and then return the newly updated layout. Chances - are that this update is in the queue for the mainloop as - it would have been requested some time ago, but in theory - it could block longer. - - Return value: A #DbusmenuMenuitem representing the root of - menu on the server. If there is no server or there is - an error receiving its layout it'll return #NULL. -*/ + * dbusmenu_client_get_root: + * @client: The #DbusmenuClient to get the root node from + * + * Grabs the root node for the specified client @client. This + * function may block. It will block if there is currently a + * call to update the layout, it will block on that layout + * updated and then return the newly updated layout. Chances + * are that this update is in the queue for the mainloop as + * it would have been requested some time ago, but in theory + * it could block longer. + * + * Return value: (transfer none): A #DbusmenuMenuitem representing the root of + * menu on the server. If there is no server or there is + * an error receiving its layout it'll return #NULL. + */ DbusmenuMenuitem * dbusmenu_client_get_root (DbusmenuClient * client) { @@ -1721,25 +1721,25 @@ type_handler_destroy (gpointer user_data) } /** - dbusmenu_client_add_type_handler: - @client: Client where we're getting types coming in - @type: A text string that will be matched with the 'type' - property on incoming menu items - @newfunc: The function that will be executed with those new - items when they come in. - - This function connects into the type handling of the #DbusmenuClient. - Every new menuitem that comes in immediately gets asked for it's - properties. When we get those properties we check the 'type' - property and look to see if it matches a handler that is known - by the client. If so, the @newfunc function is executed on that - #DbusmenuMenuitem. If not, then the DbusmenuClient::new-menuitem - signal is sent. - - In the future the known types will be sent to the server so that it - can make choices about the menu item types availble. - - Return value: If registering the new type was successful. + * dbusmenu_client_add_type_handler: + * @client: Client where we're getting types coming in + * @type: A text string that will be matched with the 'type' + * property on incoming menu items + * @newfunc: The function that will be executed with those new + * items when they come in. + * + * This function connects into the type handling of the #DbusmenuClient. + * Every new menuitem that comes in immediately gets asked for it's + * properties. When we get those properties we check the 'type' + * property and look to see if it matches a handler that is known + * by the client. If so, the @newfunc function is executed on that + * #DbusmenuMenuitem. If not, then the DbusmenuClient::new-menuitem + * signal is sent. + * + * In the future the known types will be sent to the server so that it + * can make choices about the menu item types availble. + * + * Return value: If registering the new type was successful. */ gboolean dbusmenu_client_add_type_handler (DbusmenuClient * client, const gchar * type, DbusmenuClientTypeHandler newfunc) @@ -1748,29 +1748,29 @@ dbusmenu_client_add_type_handler (DbusmenuClient * client, const gchar * type, D } /** - dbusmenu_client_add_type_handler_full: - @client: Client where we're getting types coming in - @type: A text string that will be matched with the 'type' - property on incoming menu items - @newfunc: The function that will be executed with those new - items when they come in. - @user_data: Data passed to @newfunc when it is called - @destroy_func: A function that is called when the type handler is - removed (usually on client destruction) which will free - the resources in @user_data. - - This function connects into the type handling of the #DbusmenuClient. - Every new menuitem that comes in immediately gets asked for it's - properties. When we get those properties we check the 'type' - property and look to see if it matches a handler that is known - by the client. If so, the @newfunc function is executed on that - #DbusmenuMenuitem. If not, then the DbusmenuClient::new-menuitem - signal is sent. - - In the future the known types will be sent to the server so that it - can make choices about the menu item types availble. - - Return value: If registering the new type was successful. + * dbusmenu_client_add_type_handler_full: + * @client: Client where we're getting types coming in + * @type: A text string that will be matched with the 'type' + * property on incoming menu items + * @newfunc: The function that will be executed with those new + * items when they come in. + * @user_data: Data passed to @newfunc when it is called + * @destroy_func: A function that is called when the type handler is + * removed (usually on client destruction) which will free + * the resources in @user_data. + * + * This function connects into the type handling of the #DbusmenuClient. + * Every new menuitem that comes in immediately gets asked for it's + * properties. When we get those properties we check the 'type' + * property and look to see if it matches a handler that is known + * by the client. If so, the @newfunc function is executed on that + * #DbusmenuMenuitem. If not, then the DbusmenuClient::new-menuitem + * signal is sent. + * + * In the future the known types will be sent to the server so that it + * can make choices about the menu item types availble. + * + * Return value: If registering the new type was successful. */ gboolean dbusmenu_client_add_type_handler_full (DbusmenuClient * client, const gchar * type, DbusmenuClientTypeHandler newfunc, gpointer user_data, DbusmenuClientTypeDestroyHandler destroy_func) -- cgit v1.2.3