ayatana-commits team mailing list archive
-
ayatana-commits team
-
Mailing list archive
-
Message #01584
[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