From 3c9734543b84ecd412ffd214ac0560b11858a00a Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 5 Jun 2009 15:05:12 -0500 Subject: Making the ID update function rebuild all of the properties. Result of a code review comment by Cody Russell. --- libdbusmenu-glib/client.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index c6833cc..6094eca 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -86,6 +86,7 @@ static DbusmenuMenuitem * parse_layout_xml(xmlNodePtr node, DbusmenuMenuitem * i static void 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); /* Build a type */ G_DEFINE_TYPE (DbusmenuClient, dbusmenu_client, G_TYPE_OBJECT); @@ -267,7 +268,7 @@ id_update (DBusGProxy * proxy, guint id, DbusmenuClient * client) DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id); g_return_if_fail(menuitem != NULL); - /* dbusmenu_menuitem_property_set(menuitem, property, value); */ + org_freedesktop_dbusmenu_get_properties_async(proxy, id, menuitem_get_properties_cb, menuitem); return; } -- cgit v1.2.3 From a0ba99c7840a0db2eb957138854050060221a8df Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 18 Jun 2009 15:28:54 -0500 Subject: Handling the concept of not having a property proxy. --- 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 61f8c34..ea77cc3 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -499,6 +499,10 @@ update_layout (DbusmenuClient * client) { DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + if (priv->propproxy == NULL) { + return; + } + if (priv->layoutcall != NULL) { return; } @@ -554,7 +558,8 @@ dbusmenu_client_new (const gchar * name, const gchar * object) it could block longer. Return value: A #DbusmenuMenuitem representing the root of - menu on the server. + menu on the server. If there is no server or there is + an error receiving its layout it'll return #NULL. */ DbusmenuMenuitem * dbusmenu_client_get_root (DbusmenuClient * client) @@ -563,6 +568,10 @@ dbusmenu_client_get_root (DbusmenuClient * client) DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + if (priv->propproxy == NULL) { + return NULL; + } + if (priv->layoutcall != NULL) { /* Will end the current call and block on it's completion */ update_layout_cb(priv->propproxy, priv->layoutcall, client); -- cgit v1.2.3 From 6b29e7e5a258644cc0c82963aab5d167748f8af2 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 18 Jun 2009 16:30:13 -0500 Subject: If we can't get a proxy on the stuff that we want, we're going to set up a DBus one and just wait for it to show up. When it showes up, then we'll pounce --- libdbusmenu-glib/client.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index ea77cc3..fec495d 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -64,6 +64,8 @@ struct _DbusmenuClientPrivate DBusGProxy * menuproxy; DBusGProxy * propproxy; DBusGProxyCall * layoutcall; + + DBusGProxy * dbusproxy; }; #define DBUSMENU_CLIENT_GET_PRIVATE(o) \ @@ -147,6 +149,8 @@ dbusmenu_client_init (DbusmenuClient *self) priv->propproxy = NULL; priv->layoutcall = NULL; + priv->dbusproxy = NULL; + return; } @@ -167,6 +171,10 @@ dbusmenu_client_dispose (GObject *object) g_object_unref(G_OBJECT(priv->propproxy)); priv->propproxy = NULL; } + if (priv->dbusproxy != NULL) { + g_object_unref(G_OBJECT(priv->dbusproxy)); + priv->dbusproxy = NULL; + } priv->session_bus = NULL; if (priv->root != NULL) { @@ -276,6 +284,62 @@ id_update (DBusGProxy * proxy, guint id, DbusmenuClient * client) return; } +/* Watches to see if our DBus savior comes onto the bus */ +static void +dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, DbusmenuClient * client) +{ + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + + if (!(new != NULL && prev == NULL)) { + /* If it's not someone new getting on the bus, sorry we + simply just don't care. It's not that your service isn't + important to someone, just not us. You'll find the right + process someday, there's lots of processes out there. */ + return; + } + + if (g_strcmp0(new, priv->dbus_name)) { + /* Again, someone else's service. */ + return; + } + + /* Woot! A service for us to love and to hold for ever + and ever and ever! */ + return build_proxies(client); +} + +/* This function builds the DBus proxy which will look out for + the service coming up. */ +static void +build_dbus_proxy (DbusmenuClient * client) +{ + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + GError * error = NULL; + + if (priv->dbusproxy != NULL) { + return; + } + + priv->dbusproxy = dbus_g_proxy_new_for_name_owner (priv->session_bus, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + &error); + if (error != NULL) { + g_debug("Oh, that's bad. That's really bad. We can't get a proxy to DBus itself? Seriously? Here's all I know: %s", error->message); + g_error_free(error); + return; + } + + dbus_g_proxy_add_signal(priv->dbusproxy, "NameOwnerChanged", + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal(priv->dbusproxy, "NameOwnerChanged", + G_CALLBACK(dbus_owner_change), client, NULL); + + return; +} + /* When we have a name and an object, build the two proxies and get the first version of the layout */ static void @@ -291,6 +355,7 @@ build_proxies (DbusmenuClient * client) if (error != NULL) { g_error("Unable to get session bus: %s", error->message); g_error_free(error); + build_dbus_proxy(client); return; } @@ -304,6 +369,7 @@ build_proxies (DbusmenuClient * client) g_error_free(error); return; } + // g_signal_connect(G_OBJECT(priv->propproxy), "destroy", proxy_destroyed, client); priv->menuproxy = dbus_g_proxy_new_for_name_owner(priv->session_bus, priv->dbus_name, @@ -315,6 +381,13 @@ build_proxies (DbusmenuClient * client) g_error_free(error); return; } + // g_signal_connect(G_OBJECT(priv->menuproxy), "destroy", proxy_destroyed, client); + + /* If we get here, we don't need the DBus proxy */ + if (priv->dbusproxy != NULL) { + g_object_unref(G_OBJECT(priv->dbusproxy)); + priv->dbusproxy = NULL; + } dbus_g_proxy_add_signal(priv->menuproxy, "LayoutUpdate", G_TYPE_INVALID); dbus_g_proxy_connect_signal(priv->menuproxy, "LayoutUpdate", G_CALLBACK(layout_update), client, NULL); -- cgit v1.2.3 From f56565b09f6747442f94f0218466f1a3d6b8869d Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 18 Jun 2009 16:54:25 -0500 Subject: Handle the server removing itself from the bus and putting us into a dark world waiting for it to rejoin the world. --- libdbusmenu-glib/client.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index fec495d..043bf43 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -340,6 +340,27 @@ build_dbus_proxy (DbusmenuClient * client) return; } +/* A signal handler that gets called when a proxy is destoryed a + so it needs to clean up a little. Make sure we don't think we + have a layout and setup the dbus watcher. */ +static void +proxy_destroyed (GObject * gobj_proxy, gpointer userdata) +{ + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(userdata); + + if (priv->root != NULL) { + g_object_unref(G_OBJECT(priv->root)); + priv->root = NULL; + } + + if ((gpointer)priv->menuproxy == (gpointer)gobj_proxy) { + priv->layoutcall = NULL; + } + + build_dbus_proxy(DBUSMENU_CLIENT(userdata)); + return; +} + /* When we have a name and an object, build the two proxies and get the first version of the layout */ static void @@ -369,7 +390,8 @@ build_proxies (DbusmenuClient * client) g_error_free(error); return; } - // g_signal_connect(G_OBJECT(priv->propproxy), "destroy", proxy_destroyed, client); + g_object_add_weak_pointer(G_OBJECT(priv->propproxy), (gpointer *)&priv->propproxy); + g_signal_connect(G_OBJECT(priv->propproxy), "destroy", G_CALLBACK(proxy_destroyed), client); priv->menuproxy = dbus_g_proxy_new_for_name_owner(priv->session_bus, priv->dbus_name, @@ -381,7 +403,8 @@ build_proxies (DbusmenuClient * client) g_error_free(error); return; } - // g_signal_connect(G_OBJECT(priv->menuproxy), "destroy", proxy_destroyed, client); + g_object_add_weak_pointer(G_OBJECT(priv->menuproxy), (gpointer *)&priv->menuproxy); + g_signal_connect(G_OBJECT(priv->menuproxy), "destroy", G_CALLBACK(proxy_destroyed), client); /* If we get here, we don't need the DBus proxy */ if (priv->dbusproxy != NULL) { -- cgit v1.2.3 From 369442ddbe17b5886f0dfb3d3cfc54b3d0518186 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 18 Jun 2009 16:56:11 -0500 Subject: Making it so that if we clear the menu structure by destroying the proxies we also signal that to the callers. --- libdbusmenu-glib/client.c | 1 + 1 file changed, 1 insertion(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 043bf43..97265db 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -351,6 +351,7 @@ proxy_destroyed (GObject * gobj_proxy, gpointer userdata) if (priv->root != NULL) { g_object_unref(G_OBJECT(priv->root)); priv->root = NULL; + g_signal_emit(G_OBJECT(userdata), signals[LAYOUT_UPDATED], 0, TRUE); } if ((gpointer)priv->menuproxy == (gpointer)gobj_proxy) { -- cgit v1.2.3