← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~ted/indicator-appmenu/remove-people into lp:indicator-appmenu

 

Ted Gould has proposed merging lp:~ted/indicator-appmenu/remove-people into lp:indicator-appmenu.

Requested reviews:
  Indicator Applet Developers (indicator-applet-developers)


Track when people go away and remove their menus.
-- 
https://code.launchpad.net/~ted/indicator-appmenu/remove-people/+merge/27409
Your team ayatana-commits is subscribed to branch lp:indicator-appmenu.
=== modified file 'src/indicator-appmenu.c'
--- src/indicator-appmenu.c	2010-06-04 12:50:45 +0000
+++ src/indicator-appmenu.c	2010-06-12 04:41:23 +0000
@@ -419,6 +419,26 @@
 	return;
 }
 
+/* Respond to the menus being destroyed.  We need to deregister
+   and make sure we weren't being shown.  */
+static void
+menus_destroyed (GObject * menus, gpointer user_data)
+{
+	WindowMenus * wm = WINDOW_MENUS(menus);
+	IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data);
+
+	/* If we're it, let's remove ourselves and BAMF will probably
+	   give us a new entry in a bit. */
+	if (iapp->default_app == wm) {
+		switch_default_app(iapp, NULL);
+	}
+
+	guint xid = window_menus_get_xid(wm);
+	g_hash_table_steal(iapp->apps, GUINT_TO_POINTER(xid));
+
+	return;
+}
+
 /* A new window wishes to register it's windows with us */
 static gboolean
 _application_menu_registrar_server_register_window (IndicatorAppmenu * iapp, guint windowid, const gchar * objectpath, DBusGMethodInvocation * method)
@@ -427,6 +447,10 @@
 
 	if (g_hash_table_lookup(iapp->apps, GUINT_TO_POINTER(windowid)) == NULL) {
 		WindowMenus * wm = window_menus_new(windowid, dbus_g_method_get_sender(method), objectpath);
+		g_return_val_if_fail(wm != NULL, FALSE);
+
+		g_signal_connect(G_OBJECT(wm), WINDOW_MENUS_SIGNAL_DESTROY, G_CALLBACK(menus_destroyed), iapp);
+
 		g_hash_table_insert(iapp->apps, GUINT_TO_POINTER(windowid), wm);
 
 		g_signal_emit(G_OBJECT(iapp), signals[WINDOW_REGISTERED], 0, windowid, objectpath, TRUE);

=== modified file 'src/window-menus.c'
--- src/window-menus.c	2010-06-07 20:35:46 +0000
+++ src/window-menus.c	2010-06-12 04:41:23 +0000
@@ -24,6 +24,7 @@
 #endif
 
 #include <libdbusmenu-gtk/menu.h>
+#include <dbus/dbus-glib.h>
 
 #include "window-menus.h"
 
@@ -33,6 +34,7 @@
 struct _WindowMenusPrivate {
 	guint windowid;
 	DbusmenuGtkClient * client;
+	DBusGProxy * props;
 	GArray * entries;
 };
 
@@ -44,6 +46,7 @@
 enum {
 	ENTRY_ADDED,
 	ENTRY_REMOVED,
+	DESTROY,
 	LAST_SIGNAL
 };
 
@@ -55,6 +58,7 @@
 static void window_menus_init       (WindowMenus *self);
 static void window_menus_dispose    (GObject *object);
 static void window_menus_finalize   (GObject *object);
+static void properties_destroyed    (GObject * object, gpointer user_data);
 static void root_changed            (DbusmenuClient * client, DbusmenuMenuitem * new_root, gpointer user_data);
 static void menu_entry_added        (DbusmenuMenuitem * root, DbusmenuMenuitem * newentry, guint position, gpointer user_data);
 static void menu_entry_removed      (DbusmenuMenuitem * root, DbusmenuMenuitem * oldentry, gpointer user_data);
@@ -89,6 +93,13 @@
 	                                      NULL, NULL,
 	                                      g_cclosure_marshal_VOID__POINTER,
 	                                      G_TYPE_NONE, 1, G_TYPE_POINTER);
+	signals[DESTROY] =       g_signal_new(WINDOW_MENUS_SIGNAL_DESTROY,
+	                                      G_TYPE_FROM_CLASS(klass),
+	                                      G_SIGNAL_RUN_LAST,
+	                                      G_STRUCT_OFFSET (WindowMenusClass, destroy),
+	                                      NULL, NULL,
+	                                      g_cclosure_marshal_VOID__VOID,
+	                                      G_TYPE_NONE, 0, G_TYPE_NONE);
 
 	return;
 }
@@ -100,6 +111,7 @@
 	WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(self);
 
 	priv->client = NULL;
+	priv->props = NULL;
 
 	priv->entries = g_array_new(FALSE, FALSE, sizeof(IndicatorObjectEntry *));
 
@@ -110,12 +122,19 @@
 static void
 window_menus_dispose (GObject *object)
 {
+	g_signal_emit(object, signals[DESTROY], 0, TRUE);
+
 	WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(object);
 
 	if (priv->client != NULL) {
 		g_object_unref(G_OBJECT(priv->client));
 		priv->client = NULL;
 	}
+	
+	if (priv->props != NULL) {
+		g_object_unref(G_OBJECT(priv->props));
+		priv->props = NULL;
+	}
 
 	G_OBJECT_CLASS (window_menus_parent_class)->dispose (object);
 	return;
@@ -155,9 +174,25 @@
 {
 	g_debug("Creating new windows menu: %X, %s, %s", windowid, dbus_addr, dbus_object);
 
+	DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+	g_return_val_if_fail(session_bus != NULL, NULL);
+
 	WindowMenus * newmenu = WINDOW_MENUS(g_object_new(WINDOW_MENUS_TYPE, NULL));
 	WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(newmenu);
 
+	priv->props = dbus_g_proxy_new_for_name_owner(session_bus,
+	                                              dbus_addr,
+	                                              dbus_object,
+	                                              DBUS_INTERFACE_PROPERTIES,
+	                                              NULL);
+	if (priv->props == NULL) {
+		g_warning("Unable to get property proxy on '%s' object '%s'", dbus_addr, dbus_object);
+		g_object_unref(newmenu);
+		return NULL;
+	}
+
+	g_signal_connect(G_OBJECT(priv->props), "destroy", G_CALLBACK(properties_destroyed), newmenu);
+
 	priv->client = dbusmenu_gtkclient_new((gchar *)dbus_addr, (gchar *)dbus_object);
 
 	g_signal_connect(G_OBJECT(priv->client), DBUSMENU_GTKCLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(root_changed),   newmenu);
@@ -170,6 +205,20 @@
 	return newmenu;
 }
 
+/* Respond to the proxies getting destoryed.  I means that we need
+   to kill ourselves. */
+static void
+properties_destroyed (GObject * object, gpointer user_data)
+{
+	WindowMenus * wm = WINDOW_MENUS(user_data);
+	WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(wm);
+
+	priv->props = NULL;
+
+	g_object_unref(G_OBJECT(wm));
+	return;
+}
+
 /* Get the location of this entry */
 guint
 window_menus_get_location (WindowMenus * wm, IndicatorObjectEntry * entry)

=== modified file 'src/window-menus.h'
--- src/window-menus.h	2010-06-02 16:58:24 +0000
+++ src/window-menus.h	2010-06-12 04:41:23 +0000
@@ -37,6 +37,7 @@
 
 #define WINDOW_MENUS_SIGNAL_ENTRY_ADDED    "entry-added"
 #define WINDOW_MENUS_SIGNAL_ENTRY_REMOVED  "entry-removed"
+#define WINDOW_MENUS_SIGNAL_DESTROY        "destroy"
 
 typedef struct _WindowMenus      WindowMenus;
 typedef struct _WindowMenusClass WindowMenusClass;
@@ -47,6 +48,8 @@
 	/* Signals */
 	void (*entry_added)   (WindowMenus * wm, IndicatorObjectEntry * entry, gpointer user_data);
 	void (*entry_removed) (WindowMenus * wm, IndicatorObjectEntry * entry, gpointer user_data);
+
+	void (*destroy)       (WindowMenus * wm, gpointer user_data);
 };
 
 struct _WindowMenus {


Follow ups