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(-) 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(+) 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(-) 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(+) 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 960663e01f1bb8a59e20b62892f6945868c510d3 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 19 Jul 2010 16:47:40 -0500 Subject: Initial write of group properties, has errors though :( --- libdbusmenu-glib/server.c | 49 ++++++++++++++++++++++++++++++++--------- tests/test-glib-layout-server.c | 1 + 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index 13c2843..42fe61f 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -37,8 +37,8 @@ License version 3 and version 2.1 along with this program. If not, see /* DBus Prototypes */ static gboolean _dbusmenu_server_get_layout (DbusmenuServer * server, gint parent, guint * revision, gchar ** layout, GError ** error); static gboolean _dbusmenu_server_get_property (DbusmenuServer * server, gint id, gchar * property, gchar ** value, GError ** error); -static gboolean _dbusmenu_server_get_properties (DbusmenuServer * server, gint id, GPtrArray * properties, GHashTable ** dict, GError ** error); -static gboolean _dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, GArray * properties, GHashTable ** values, GError ** error); +static gboolean _dbusmenu_server_get_properties (DbusmenuServer * server, gint id, gchar ** properties, GHashTable ** dict, GError ** error); +static gboolean _dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, gchar ** properties, GPtrArray ** values, GError ** error); static gboolean _dbusmenu_server_event (DbusmenuServer * server, gint id, gchar * eventid, GValue * data, guint timestamp, GError ** error); static gboolean _dbusmenu_server_get_children (DbusmenuServer * server, gint id, GPtrArray * properties, GPtrArray ** output, GError ** error); static gboolean _dbusmenu_server_about_to_show (DbusmenuServer * server, gint id, gboolean * need_update, GError ** error); @@ -480,7 +480,7 @@ _dbusmenu_server_get_property (DbusmenuServer * server, gint id, gchar * propert } static gboolean -_dbusmenu_server_get_properties (DbusmenuServer * server, gint id, GPtrArray * properties, GHashTable ** dict, GError ** error) +_dbusmenu_server_get_properties (DbusmenuServer * server, gint id, gchar ** properties, GHashTable ** dict, GError ** error) { DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id); @@ -501,16 +501,45 @@ _dbusmenu_server_get_properties (DbusmenuServer * server, gint id, GPtrArray * p return TRUE; } +/* Handles getting a bunch of properties from a variety of menu items + to make one mega dbus message */ static gboolean -_dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, GArray * properties, GHashTable ** values, GError ** error) +_dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, gchar ** properties, GPtrArray ** values, GError ** error) { - if (error != NULL) { - g_set_error(error, - error_quark(), - NOT_IMPLEMENTED, - "The GetGroupProperties function is not implemented, sorry."); + /* Build an initial pointer array */ + *values = g_ptr_array_new(); + + /* Go through each ID to get that ID's properties */ + int idcnt; + for (idcnt = 0; idcnt < ids->len; idcnt++) { + GHashTable * idprops = NULL; + GError * error = NULL; + gint id = g_array_index(ids, int, idcnt); + + /* Get the properties for this ID the old fashioned way. */ + if (!_dbusmenu_server_get_properties(server, id, properties, &idprops, &error)) { + g_warning("Error getting the properties from ID %d: %s", id, error->message); + g_error_free(error); + error = NULL; + continue; + } + + GValueArray * valarray = g_value_array_new(2); + + GValue idval = {0}; + g_value_init(&idval, G_TYPE_INT); + g_value_set_int(&idval, id); + g_value_array_append(valarray, &idval); + + GValue propval = {0}; + g_value_init(&propval, G_TYPE_HASH_TABLE); + g_value_set_boxed(&propval, idprops); + g_value_array_append(valarray, &propval); + + g_ptr_array_add(*values, valarray); } - return FALSE; + + return TRUE; } static void diff --git a/tests/test-glib-layout-server.c b/tests/test-glib-layout-server.c index 111e164..d739726 100644 --- a/tests/test-glib-layout-server.c +++ b/tests/test-glib-layout-server.c @@ -78,6 +78,7 @@ main (int argc, char ** argv) GError * error = NULL; g_type_init(); + g_log_set_always_fatal(G_LOG_LEVEL_WARNING); DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL)))); -- cgit v1.2.3 From 68e46ae11fda7dc9e9a7eada5b105536bdf9f574 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 19 Jul 2010 20:42:36 -0500 Subject: Apparently it's a GValueArray. Feel like I'm coding freakin' Python. Guess and check. --- libdbusmenu-glib/server.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index 42fe61f..dc505a1 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -38,7 +38,7 @@ License version 3 and version 2.1 along with this program. If not, see static gboolean _dbusmenu_server_get_layout (DbusmenuServer * server, gint parent, guint * revision, gchar ** layout, GError ** error); static gboolean _dbusmenu_server_get_property (DbusmenuServer * server, gint id, gchar * property, gchar ** value, GError ** error); static gboolean _dbusmenu_server_get_properties (DbusmenuServer * server, gint id, gchar ** properties, GHashTable ** dict, GError ** error); -static gboolean _dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, gchar ** properties, GPtrArray ** values, GError ** error); +static gboolean _dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, gchar ** properties, GValueArray ** values, GError ** error); static gboolean _dbusmenu_server_event (DbusmenuServer * server, gint id, gchar * eventid, GValue * data, guint timestamp, GError ** error); static gboolean _dbusmenu_server_get_children (DbusmenuServer * server, gint id, GPtrArray * properties, GPtrArray ** output, GError ** error); static gboolean _dbusmenu_server_about_to_show (DbusmenuServer * server, gint id, gboolean * need_update, GError ** error); @@ -504,10 +504,10 @@ _dbusmenu_server_get_properties (DbusmenuServer * server, gint id, gchar ** prop /* Handles getting a bunch of properties from a variety of menu items to make one mega dbus message */ static gboolean -_dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, gchar ** properties, GPtrArray ** values, GError ** error) +_dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, gchar ** properties, GValueArray ** values, GError ** error) { /* Build an initial pointer array */ - *values = g_ptr_array_new(); + *values = g_value_array_new(ids->len); /* Go through each ID to get that ID's properties */ int idcnt; @@ -536,7 +536,11 @@ _dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, gc g_value_set_boxed(&propval, idprops); g_value_array_append(valarray, &propval); - g_ptr_array_add(*values, valarray); + GValue * valwrapper = g_new0(GValue, 1); + g_value_init(valwrapper, G_TYPE_VALUE_ARRAY); + g_value_set_boxed(valwrapper, valarray); + + g_value_array_append(*values, valwrapper); } return TRUE; -- cgit v1.2.3 From 63601bed2c1bb3ffb786efa6c25e47fa97c0acb0 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 19 Jul 2010 21:19:19 -0500 Subject: Switch array back and use the helpers, duh, now it works. --- libdbusmenu-glib/server.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index dc505a1..08a6631 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -38,10 +38,13 @@ License version 3 and version 2.1 along with this program. If not, see static gboolean _dbusmenu_server_get_layout (DbusmenuServer * server, gint parent, guint * revision, gchar ** layout, GError ** error); static gboolean _dbusmenu_server_get_property (DbusmenuServer * server, gint id, gchar * property, gchar ** value, GError ** error); static gboolean _dbusmenu_server_get_properties (DbusmenuServer * server, gint id, gchar ** properties, GHashTable ** dict, GError ** error); -static gboolean _dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, gchar ** properties, GValueArray ** values, GError ** error); +static gboolean _dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, gchar ** properties, GPtrArray ** values, GError ** error); static gboolean _dbusmenu_server_event (DbusmenuServer * server, gint id, gchar * eventid, GValue * data, guint timestamp, GError ** error); static gboolean _dbusmenu_server_get_children (DbusmenuServer * server, gint id, GPtrArray * properties, GPtrArray ** output, GError ** error); static gboolean _dbusmenu_server_about_to_show (DbusmenuServer * server, gint id, gboolean * need_update, GError ** error); +/* DBus Helpers */ +static void _gvalue_array_append_int(GValueArray *array, gint i); +static void _gvalue_array_append_hashtable(GValueArray *array, GHashTable * dict); #include "dbusmenu-server.h" @@ -504,10 +507,10 @@ _dbusmenu_server_get_properties (DbusmenuServer * server, gint id, gchar ** prop /* Handles getting a bunch of properties from a variety of menu items to make one mega dbus message */ static gboolean -_dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, gchar ** properties, GValueArray ** values, GError ** error) +_dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, gchar ** properties, GPtrArray ** values, GError ** error) { /* Build an initial pointer array */ - *values = g_value_array_new(ids->len); + *values = g_ptr_array_new(); /* Go through each ID to get that ID's properties */ int idcnt; @@ -526,26 +529,17 @@ _dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, gc GValueArray * valarray = g_value_array_new(2); - GValue idval = {0}; - g_value_init(&idval, G_TYPE_INT); - g_value_set_int(&idval, id); - g_value_array_append(valarray, &idval); + _gvalue_array_append_int(valarray, id); + _gvalue_array_append_hashtable(valarray, idprops); - GValue propval = {0}; - g_value_init(&propval, G_TYPE_HASH_TABLE); - g_value_set_boxed(&propval, idprops); - g_value_array_append(valarray, &propval); - - GValue * valwrapper = g_new0(GValue, 1); - g_value_init(valwrapper, G_TYPE_VALUE_ARRAY); - g_value_set_boxed(valwrapper, valarray); - - g_value_array_append(*values, valwrapper); + g_ptr_array_add(*values, valarray); } return TRUE; } +/* Allocate a value on the stack for the int and append + it to the array. */ static void _gvalue_array_append_int(GValueArray *array, gint i) { @@ -557,6 +551,8 @@ _gvalue_array_append_int(GValueArray *array, gint i) g_value_unset(&value); } +/* Allocate a value on the stack for the hashtable and append + it to the array. */ static void _gvalue_array_append_hashtable(GValueArray *array, GHashTable * dict) { @@ -577,7 +573,7 @@ serialize_menuitem(gpointer data, gpointer user_data) gint id = dbusmenu_menuitem_get_id(mi); GHashTable * dict = dbusmenu_menuitem_properties_copy(mi); - GValueArray * item = g_value_array_new(1); + GValueArray * item = g_value_array_new(2); _gvalue_array_append_int(item, id); _gvalue_array_append_hashtable(item, dict); -- 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(-) 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(-) 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(-) 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(-) 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(+) 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(-) 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(+) 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(+) 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(-) 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(-) 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 200f6ed7975b11257af8a3d7e0989c3c55dd4f28 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 11:51:42 -0500 Subject: releasing version 0.3.6-0ubuntu2~ppa1~glob1 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 31f52b2..43f6e4b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,9 @@ -libdbusmenu (0.3.6-0ubuntu2~ppa1~glob1) UNRELEASED; urgency=low +libdbusmenu (0.3.6-0ubuntu2~ppa1~glob1) lucid; urgency=low * Upstream Merge * Globbing property requests into group requests - -- Ted Gould Tue, 20 Jul 2010 11:47:20 -0500 + -- Ted Gould Tue, 20 Jul 2010 11:51:40 -0500 libdbusmenu (0.3.6-0ubuntu1) maverick; urgency=low -- cgit v1.2.3 From 8c9e1febb85e0bd28cfc175cd015a4a1934baf55 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 12:13:18 -0500 Subject: Pulling the layout count update into a function along with signalling it. --- libdbusmenu-glib/server.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index 08a6631..7a39f1e 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -48,6 +48,8 @@ static void _gvalue_array_append_hashtable(GValueArray *array, GHashTable * dict #include "dbusmenu-server.h" +static void layout_update_signal (DbusmenuServer * server); + #define DBUSMENU_VERSION_NUMBER 2 /* Privates, I'll show you mine... */ @@ -260,8 +262,7 @@ set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec) } else { g_debug("Setting root node to NULL"); } - priv->layout_revision++; - g_signal_emit(obj, signals[LAYOUT_UPDATED], 0, priv->layout_revision, 0, TRUE); + layout_update_signal(DBUSMENU_SERVER(obj)); break; default: g_return_if_reached(); @@ -305,6 +306,16 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) return; } +/* Signals that the layout has been updated */ +static void +layout_update_signal (DbusmenuServer * server) +{ + DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); + priv->layout_revision++; + g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATED], 0, priv->layout_revision, 0, TRUE); + return; +} + static void menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GValue * value, DbusmenuServer * server) { @@ -335,10 +346,7 @@ menuitem_child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint menuitem_signals_create(child, server); g_list_foreach(dbusmenu_menuitem_get_children(child), added_check_children, server); - /* TODO: We probably need to group the layout update signals to make the number more reasonble. */ - DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); - priv->layout_revision++; - g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATED], 0, priv->layout_revision, 0, TRUE); + layout_update_signal(server); return; } @@ -346,19 +354,14 @@ static void menuitem_child_removed (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, DbusmenuServer * server) { menuitem_signals_remove(child, server); - /* TODO: We probably need to group the layout update signals to make the number more reasonble. */ - DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); - priv->layout_revision++; - g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATED], 0, priv->layout_revision, 0, TRUE); + layout_update_signal(server); return; } static void menuitem_child_moved (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint newpos, guint oldpos, DbusmenuServer * server) { - DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); - priv->layout_revision++; - g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATED], 0, priv->layout_revision, 0, TRUE); + layout_update_signal(server); return; } -- cgit v1.2.3 From fe213d96ed2ff025c1c60cbffb4e0dd562d1c154 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 12:27:03 -0500 Subject: Adding in an idle function that queues the updates. --- libdbusmenu-glib/server.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index 7a39f1e..4afd0c2 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -60,6 +60,7 @@ struct _DbusmenuServerPrivate DbusmenuMenuitem * root; gchar * dbusobject; gint layout_revision; + guint layout_idle; }; #define DBUSMENU_SERVER_GET_PRIVATE(o) \ @@ -201,6 +202,7 @@ dbusmenu_server_init (DbusmenuServer *self) priv->root = NULL; priv->dbusobject = NULL; priv->layout_revision = 1; + priv->layout_idle = 0; return; } @@ -210,6 +212,10 @@ dbusmenu_server_dispose (GObject *object) { DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(object); + if (priv->layout_idle != 0) { + g_source_remove(priv->layout_idle); + } + if (priv->root != NULL) { dbusmenu_menuitem_foreach(priv->root, menuitem_signals_remove, object); g_object_unref(priv->root); @@ -306,13 +312,32 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) return; } +/* Handle actually signalling in the idle loop. This way we collect all + the updates. */ +static gboolean +layout_update_idle (gpointer user_data) +{ + DbusmenuServer * server = DBUSMENU_SERVER(user_data); + DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); + + g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATED], 0, priv->layout_revision, 0, TRUE); + + priv->layout_idle = 0; + + return FALSE; +} + /* Signals that the layout has been updated */ static void layout_update_signal (DbusmenuServer * server) { DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); priv->layout_revision++; - g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATED], 0, priv->layout_revision, 0, TRUE); + + if (priv->layout_idle == 0) { + priv->layout_idle = g_idle_add(layout_update_idle, server); + } + return; } -- cgit v1.2.3 From e7b8662134bf98f136abc9fef5b71e5e6cdecfbc Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 12:34:14 -0500 Subject: releasing version 0.3.6-0ubuntu2~ppa1~glob2 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 7b3a37a..094fc7f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,9 @@ -libdbusmenu (0.3.6-0ubuntu2~ppa1~glob2) UNRELEASED; urgency=low +libdbusmenu (0.3.6-0ubuntu2~ppa1~glob2) lucid; urgency=low * Upstream Merge * Globbing layout signaling from the server - -- Ted Gould Tue, 20 Jul 2010 12:32:26 -0500 + -- Ted Gould Tue, 20 Jul 2010 12:34:11 -0500 libdbusmenu (0.3.6-0ubuntu2~ppa1~glob1) lucid; urgency=low -- 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(-) 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(-) 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(-) 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(-) 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(-) 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(-) 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(+) 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(-) 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(-) 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(+) 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(-) 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 c6c4c285c3844cb3ed50a41068bf7278604c41dd Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 20 Jul 2010 15:24:10 -0500 Subject: releasing version 0.3.6-0ubuntu2~ppa1~glob3 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 48e47c2..82e2261 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,9 @@ -libdbusmenu (0.3.6-0ubuntu2~ppa1~glob3) UNRELEASED; urgency=low +libdbusmenu (0.3.6-0ubuntu2~ppa1~glob3) lucid; urgency=low * Upstream Merge * Making it so that properties are requested bredth first - -- Ted Gould Tue, 20 Jul 2010 15:22:10 -0500 + -- Ted Gould Tue, 20 Jul 2010 15:24:08 -0500 libdbusmenu (0.3.6-0ubuntu2~ppa1~glob2) lucid; urgency=low -- cgit v1.2.3 From d67f6d110e74b777721f2dd5086e655e4c16f085 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 2 Aug 2010 14:41:39 -0500 Subject: releasing version 0.3.8-0ubuntu2~ppa1~glob1 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 2520315..d3ad4a2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -libdbusmenu (0.3.8-0ubuntu2~ppa1~glob1) UNRELEASED; urgency=low +libdbusmenu (0.3.8-0ubuntu2~ppa1~glob1) lucid; urgency=low * Updating to packaging branch * Upstream Merge @@ -6,7 +6,7 @@ libdbusmenu (0.3.8-0ubuntu2~ppa1~glob1) UNRELEASED; urgency=low * Globbing layout signaling from the server * Globbing property requests into group requests - -- Ted Gould Mon, 02 Aug 2010 14:37:28 -0500 + -- Ted Gould Mon, 02 Aug 2010 14:41:36 -0500 libdbusmenu (0.3.8-0ubuntu1) maverick; urgency=low -- cgit v1.2.3