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