From 15c11261bd45e2732a31b2fa235cc2a6261452e4 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 17 Sep 2009 13:36:38 -0500 Subject: Adding in handling of the child moved event --- libdbusmenu-glib/server.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index ab5951f..f4c1dcb 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -323,6 +323,13 @@ menuitem_child_removed (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, Dbu return; } +static void +menuitem_child_moved (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint newpos, guint oldpos, DbusmenuServer * server) +{ + g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, TRUE); + return; +} + /* Connects all the signals that we're interested in coming from a menuitem */ static void @@ -330,6 +337,7 @@ menuitem_signals_create (DbusmenuMenuitem * mi, gpointer data) { g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED, G_CALLBACK(menuitem_child_added), data); g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(menuitem_child_removed), data); + g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED, G_CALLBACK(menuitem_child_moved), data); g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(menuitem_property_changed), data); return; } @@ -341,6 +349,7 @@ menuitem_signals_remove (DbusmenuMenuitem * mi, gpointer data) { g_signal_handlers_disconnect_by_func(G_OBJECT(mi), G_CALLBACK(menuitem_child_added), data); g_signal_handlers_disconnect_by_func(G_OBJECT(mi), G_CALLBACK(menuitem_child_removed), data); + g_signal_handlers_disconnect_by_func(G_OBJECT(mi), G_CALLBACK(menuitem_child_moved), data); g_signal_handlers_disconnect_by_func(G_OBJECT(mi), G_CALLBACK(menuitem_property_changed), data); return; } -- cgit v1.2.3 From fa0e53c2e27f0c8ed7cbfa839265e91b4fdf8d67 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 17 Sep 2009 16:12:42 -0500 Subject: Adding in a second checking of the layout if we look for it while we're still requesting it. We're not sure if this creates an issue between the syncing of the two objects. --- libdbusmenu-glib/client.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 4ae4f75..1bf4e19 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -66,6 +66,7 @@ struct _DbusmenuClientPrivate DBusGProxy * menuproxy; DBusGProxy * propproxy; DBusGProxyCall * layoutcall; + gboolean check_layout; DBusGProxy * dbusproxy; @@ -194,6 +195,7 @@ dbusmenu_client_init (DbusmenuClient *self) priv->menuproxy = NULL; priv->propproxy = NULL; priv->layoutcall = NULL; + priv->check_layout = FALSE; priv->dbusproxy = NULL; @@ -721,6 +723,11 @@ update_layout_cb (DBusGProxy * proxy, DBusGProxyCall * call, void * data) /* g_debug("Root is now: 0x%X", (unsigned int)priv->root); */ g_signal_emit(G_OBJECT(client), signals[LAYOUT_UPDATED], 0, TRUE); + if (priv->check_layout) { + priv->check_layout = FALSE; + update_layout(client); + } + return; } @@ -736,6 +743,7 @@ update_layout (DbusmenuClient * client) } if (priv->layoutcall != NULL) { + priv->check_layout = TRUE; return; } @@ -803,16 +811,9 @@ dbusmenu_client_get_root (DbusmenuClient * client) return NULL; } -#if 0 -/* Seems to be a bug in dbus-glib that assert here, I think because - multiple people try and grab it. We're going to comment this out - for now as everyone should be listening to the root changed signal - anyway. */ if (priv->layoutcall != NULL) { - /* Will end the current call and block on it's completion */ - update_layout_cb(priv->propproxy, priv->layoutcall, client); + priv->check_layout = TRUE; } -#endif return priv->root; } -- cgit v1.2.3 From a1c878beeb2807e47fb06fd75019fe136322e9a1 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 21 Sep 2009 14:54:00 -0500 Subject: Updating the signal to send a revision number --- libdbusmenu-glib/server.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index f4c1dcb..efac804 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -47,6 +47,7 @@ struct _DbusmenuServerPrivate { DbusmenuMenuitem * root; gchar * dbusobject; + gint layout_revision; }; #define DBUSMENU_SERVER_GET_PRIVATE(o) \ @@ -151,8 +152,8 @@ dbusmenu_server_class_init (DbusmenuServerClass *class) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(DbusmenuServerClass, layout_update), NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, G_TYPE_INT); g_object_class_install_property (object_class, PROP_DBUS_OBJECT, @@ -183,6 +184,7 @@ dbusmenu_server_init (DbusmenuServer *self) priv->root = NULL; priv->dbusobject = NULL; + priv->layout_revision = 1; return; } @@ -235,7 +237,8 @@ set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec) } else { g_debug("Setting root node to NULL"); } - g_signal_emit(obj, signals[LAYOUT_UPDATE], 0, TRUE); + priv->layout_revision++; + g_signal_emit(obj, signals[LAYOUT_UPDATE], 0, priv->layout_revision, TRUE); break; case PROP_LAYOUT: /* Can't set this, fall through to error */ @@ -310,7 +313,9 @@ menuitem_child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint { menuitem_signals_create(child, server); /* TODO: We probably need to group the layout update signals to make the number more reasonble. */ - g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, TRUE); + DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); + priv->layout_revision++; + g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, TRUE); return; } @@ -319,14 +324,18 @@ menuitem_child_removed (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, Dbu { menuitem_signals_remove(child, server); /* TODO: We probably need to group the layout update signals to make the number more reasonble. */ - g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, TRUE); + DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); + priv->layout_revision++; + g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, TRUE); return; } static void menuitem_child_moved (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint newpos, guint oldpos, DbusmenuServer * server) { - g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, TRUE); + DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); + priv->layout_revision++; + g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, TRUE); return; } -- cgit v1.2.3 From 363f7fa805de63ee1a8e0bfca05ce56bcf475489 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 21 Sep 2009 14:55:10 -0500 Subject: Cleanup changes from last commit. --- libdbusmenu-glib/server.c | 2 ++ libdbusmenu-glib/server.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index efac804..af7bbef 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -143,6 +143,8 @@ dbusmenu_server_class_init (DbusmenuServerClass *class) /** DbusmenuServer::layout-update: @arg0: The #DbusmenuServer emitting the signal. + @arg1: A revision number representing which revision the update + represents itself as. This signal is emitted any time the layout of the menuitems under this server is changed. diff --git a/libdbusmenu-glib/server.h b/libdbusmenu-glib/server.h index 2c6c817..a966943 100644 --- a/libdbusmenu-glib/server.h +++ b/libdbusmenu-glib/server.h @@ -71,7 +71,7 @@ struct _DbusmenuServerClass { /* Signals */ void (*id_prop_update)(guint id, gchar * property, gchar * value); void (*id_update)(guint id); - void (*layout_update)(void); + void (*layout_update)(gint revision); /* Reserved */ void (*dbusmenu_server_reserved1)(void); -- cgit v1.2.3 From b8c1eb0bf8b17d703fa8fea3e2c68bac6a7fee61 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 21 Sep 2009 15:01:40 -0500 Subject: Putting the revision number into the XML sent across the bus. --- libdbusmenu-glib/menuitem.c | 10 ++++++---- libdbusmenu-glib/menuitem.h | 2 +- libdbusmenu-glib/server.c | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/libdbusmenu-glib/menuitem.c b/libdbusmenu-glib/menuitem.c index 41c48e2..0c44e3c 100644 --- a/libdbusmenu-glib/menuitem.c +++ b/libdbusmenu-glib/menuitem.c @@ -806,6 +806,7 @@ dbusmenu_menuitem_get_root (DbusmenuMenuitem * mi) dbusmenu_menuitem_buildxml: @mi: #DbusmenuMenuitem to represent in XML @array: A list of string that will be turned into an XML file + @revision: The revision of the layout to embed in the XML This function will add strings to the array @array. It will put at least one entry if this menu item has no children. If it has @@ -814,17 +815,18 @@ dbusmenu_menuitem_get_root (DbusmenuMenuitem * mi) children to place their own tags in the array in between those two. */ void -dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array) +dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array, gint revision) { g_return_if_fail(DBUSMENU_IS_MENUITEM(mi)); GList * children = dbusmenu_menuitem_get_children(mi); + /* TODO: Only put revision info in the root node. Save some bandwidth. */ if (children == NULL) { - g_ptr_array_add(array, g_strdup_printf("", dbusmenu_menuitem_get_id(mi))); + g_ptr_array_add(array, g_strdup_printf("", dbusmenu_menuitem_get_id(mi), revision)); } else { - g_ptr_array_add(array, g_strdup_printf("", dbusmenu_menuitem_get_id(mi))); + g_ptr_array_add(array, g_strdup_printf("", dbusmenu_menuitem_get_id(mi), revision)); for ( ; children != NULL; children = children->next) { - dbusmenu_menuitem_buildxml(DBUSMENU_MENUITEM(children->data), array); + dbusmenu_menuitem_buildxml(DBUSMENU_MENUITEM(children->data), array, revision); } g_ptr_array_add(array, g_strdup("")); } diff --git a/libdbusmenu-glib/menuitem.h b/libdbusmenu-glib/menuitem.h index ebde0a0..6c3c265 100644 --- a/libdbusmenu-glib/menuitem.h +++ b/libdbusmenu-glib/menuitem.h @@ -136,7 +136,7 @@ GHashTable * dbusmenu_menuitem_properties_copy (DbusmenuMenuitem * mi); void dbusmenu_menuitem_set_root (DbusmenuMenuitem * mi, gboolean root); gboolean dbusmenu_menuitem_get_root (DbusmenuMenuitem * mi); -void dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array); +void dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array, gint revision); void dbusmenu_menuitem_foreach (DbusmenuMenuitem * mi, void (*func) (DbusmenuMenuitem * mi, gpointer data), gpointer data); void dbusmenu_menuitem_activate (DbusmenuMenuitem * mi); diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index af7bbef..1ac1da6 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -280,9 +280,9 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) GPtrArray * xmlarray = g_ptr_array_new(); if (priv->root == NULL) { /* g_debug("Getting layout without root node!"); */ - g_ptr_array_add(xmlarray, g_strdup("")); + g_ptr_array_add(xmlarray, g_strdup_printf("", priv->layout_revision)); } else { - dbusmenu_menuitem_buildxml(priv->root, xmlarray); + dbusmenu_menuitem_buildxml(priv->root, xmlarray, priv->layout_revision); } g_ptr_array_add(xmlarray, NULL); -- cgit v1.2.3 From be2f874303bfab096b4f06cf535637c14393ee18 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 21 Sep 2009 15:16:00 -0500 Subject: Changing from a boolean to tracking rev numbers in the private structure. --- libdbusmenu-glib/client.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 1bf4e19..271483d 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -66,7 +66,9 @@ struct _DbusmenuClientPrivate DBusGProxy * menuproxy; DBusGProxy * propproxy; DBusGProxyCall * layoutcall; - gboolean check_layout; + + gint current_revision; + gint my_revision; DBusGProxy * dbusproxy; @@ -98,7 +100,7 @@ static void id_update (DBusGProxy * proxy, guint id, DbusmenuClient * client); static void build_proxies (DbusmenuClient * client); static guint parse_node_get_id (xmlNodePtr node); static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, DBusGProxy * proxy); -static void parse_layout (DbusmenuClient * client, const gchar * layout); +static gint parse_layout (DbusmenuClient * client, const gchar * layout); static void update_layout_cb (DBusGProxy * proxy, DBusGProxyCall * call, void * data); static void update_layout (DbusmenuClient * client); static void menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data); @@ -195,7 +197,9 @@ dbusmenu_client_init (DbusmenuClient *self) priv->menuproxy = NULL; priv->propproxy = NULL; priv->layoutcall = NULL; - priv->check_layout = FALSE; + + priv->current_revision = 0; + priv->my_revision = 0; priv->dbusproxy = NULL; @@ -673,7 +677,7 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it /* Take the layout passed to us over DBus and turn it into a set of beautiful objects */ -static void +static gint parse_layout (DbusmenuClient * client, const gchar * layout) { DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); @@ -696,7 +700,7 @@ parse_layout (DbusmenuClient * client, const gchar * layout) g_signal_emit(G_OBJECT(client), signals[ROOT_CHANGED], 0, priv->root, TRUE); } - return; + return 1; } /* When the layout property returns, here's where we take care of that. */ @@ -718,13 +722,18 @@ update_layout_cb (DBusGProxy * proxy, DBusGProxyCall * call, void * data) const gchar * xml = g_value_get_string(&value); /* g_debug("Got layout string: %s", xml); */ - parse_layout(client, xml); + gint rev = parse_layout(client, xml); + + if (rev == 0) { + g_warning("Unable to parse layout!"); + return; + } + priv->my_revision = rev; /* g_debug("Root is now: 0x%X", (unsigned int)priv->root); */ g_signal_emit(G_OBJECT(client), signals[LAYOUT_UPDATED], 0, TRUE); - if (priv->check_layout) { - priv->check_layout = FALSE; + if (priv->my_revision < priv->current_revision) { update_layout(client); } @@ -743,7 +752,6 @@ update_layout (DbusmenuClient * client) } if (priv->layoutcall != NULL) { - priv->check_layout = TRUE; return; } @@ -811,10 +819,6 @@ dbusmenu_client_get_root (DbusmenuClient * client) return NULL; } - if (priv->layoutcall != NULL) { - priv->check_layout = TRUE; - } - return priv->root; } -- cgit v1.2.3 From d8e66642e25a08bb4096b96ab101b34305ba4f84 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 21 Sep 2009 15:20:07 -0500 Subject: Save the 'current' version and track whether we need to request an update. --- libdbusmenu-glib/client.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 271483d..d4582a9 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -94,7 +94,7 @@ static void dbusmenu_client_finalize (GObject *object); static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec); static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec); /* Private Funcs */ -static void layout_update (DBusGProxy * proxy, DbusmenuClient * client); +static void layout_update (DBusGProxy * proxy, gint revision, DbusmenuClient * client); static void id_prop_update (DBusGProxy * proxy, guint id, gchar * property, gchar * value, DbusmenuClient * client); static void id_update (DBusGProxy * proxy, guint id, DbusmenuClient * client); static void build_proxies (DbusmenuClient * client); @@ -307,9 +307,13 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) /* Annoying little wrapper to make the right function update */ static void -layout_update (DBusGProxy * proxy, DbusmenuClient * client) +layout_update (DBusGProxy * proxy, gint revision, DbusmenuClient * client) { - update_layout(client); + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + priv->current_revision = revision; + if (priv->current_revision > priv->my_revision) { + update_layout(client); + } return; } -- cgit v1.2.3 From 3d18c3ba52732b35324069ac1bae45f481493510 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 21 Sep 2009 15:20:45 -0500 Subject: Adding the revision to the signal in the dbus spec. --- libdbusmenu-glib/dbus-menu.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/libdbusmenu-glib/dbus-menu.xml b/libdbusmenu-glib/dbus-menu.xml index 51c529b..cca9823 100644 --- a/libdbusmenu-glib/dbus-menu.xml +++ b/libdbusmenu-glib/dbus-menu.xml @@ -57,6 +57,7 @@ License version 3 and version 2.1 along with this program. If not, see + -- cgit v1.2.3 From 0e09fe611584c9af4e5e91c8c0858fc58eaf991e Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 21 Sep 2009 15:29:39 -0500 Subject: Getting the revision data off of the root node there. --- libdbusmenu-glib/client.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index d4582a9..4e11359 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -492,6 +492,34 @@ build_proxies (DbusmenuClient * client) return; } +/* Get the "revision" attribute of the node, parse it and + return it. Also we're checking to ensure the node + is a 'menu' here. */ +static gint +parse_node_get_revision (xmlNodePtr node) +{ + if (g_strcmp0((gchar *)node->name, "menu") != 0) { + /* This kills some nodes early */ + g_warning("XML Node is not 'menu' it is '%s'", node->name); + return 0; + } + + xmlAttrPtr attrib; + for (attrib = node->properties; attrib != NULL; attrib = attrib->next) { + if (g_strcmp0((gchar *)attrib->name, "revision") == 0) { + if (attrib->children != NULL) { + guint revision = (guint)g_ascii_strtoull((gchar *)attrib->children->content, NULL, 10); + /* g_debug ("Found ID: %d", id); */ + return revision; + } + break; + } + } + + g_warning("Unable to find a revision on the node"); + return 0; +} + /* Get the ID attribute of the node, parse it and return it. Also we're checking to ensure the node is a 'menu' here. */ @@ -691,6 +719,7 @@ parse_layout (DbusmenuClient * client, const gchar * layout) xmldoc = xmlReadMemory(layout, g_utf8_strlen(layout, 16*1024), "dbusmenu.xml", NULL, 0); xmlNodePtr root = xmlDocGetRootElement(xmldoc); + gint revision = parse_node_get_revision(root); DbusmenuMenuitem * oldroot = priv->root; priv->root = parse_layout_xml(client, root, priv->root, NULL, priv->menuproxy); @@ -704,7 +733,7 @@ parse_layout (DbusmenuClient * client, const gchar * layout) g_signal_emit(G_OBJECT(client), signals[ROOT_CHANGED], 0, priv->root, TRUE); } - return 1; + return revision; } /* When the layout property returns, here's where we take care of that. */ -- cgit v1.2.3 From 152034b24234c6d06649a48ae29643c5075c4bb1 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 21 Sep 2009 15:38:02 -0500 Subject: Updating prototype for signal --- 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 4e11359..e2679e1 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -477,7 +477,7 @@ build_proxies (DbusmenuClient * client) priv->dbusproxy = NULL; } - dbus_g_proxy_add_signal(priv->menuproxy, "LayoutUpdate", G_TYPE_INVALID); + dbus_g_proxy_add_signal(priv->menuproxy, "LayoutUpdate", G_TYPE_INT, G_TYPE_INVALID); dbus_g_proxy_connect_signal(priv->menuproxy, "LayoutUpdate", G_CALLBACK(layout_update), client, NULL); dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__UINT_STRING_STRING, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); -- cgit v1.2.3