Merge lp:~mterry/indicator-appmenu/less-racy-window-closing into lp:indicator-appmenu/0.3

Proposed by Michael Terry
Status: Merged
Merged at revision: 95
Proposed branch: lp:~mterry/indicator-appmenu/less-racy-window-closing
Merge into: lp:indicator-appmenu/0.3
Diff against target: 106 lines (+9/-39)
2 files modified
src/indicator-appmenu.c (+9/-5)
src/window-menus.c (+0/-34)
To merge this branch: bzr merge lp:~mterry/indicator-appmenu/less-racy-window-closing
Reviewer Review Type Date Requested Status
Ted Gould (community) Approve
Review via email: mp+48381@code.launchpad.net

Description of the change

I noticed an issue with shotwell menus over several opens and closes. It appeared that indicator-appmenu was not noticing when it closed, and when it opened again, giving it the old stale menus which was not desired.

Looking into it, it appeared to be a race condition between appmenu-gtk calling RegisterWindow and bamf knowing about the window from libwnck.

To make this less racy, I moved the window-close watching up a level, from the WindowMenus object itself to the IndicatorAppmenu object. Now all window-closes are watched, and the windows are removed from the hash table if they exist.

There's still a slight race here, that they could be opened and closed before RegisterWindow hits us, but that seems low-risk and certainly better than the current situation where every open is a race unto itself.

To post a comment you must log in.
Revision history for this message
Michael Terry (mterry) wrote :

To be clear, the race before was that bamf_matcher_get_application_for_xid might return NULL if bamf didn't know about the xid yet. Thus, the WindowMenus object wouldn't watch for its own destruction and would hang around forever.

Revision history for this message
Ted Gould (ted) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/indicator-appmenu.c'
--- src/indicator-appmenu.c 2011-01-25 16:39:51 +0000
+++ src/indicator-appmenu.c 2011-02-02 20:48:58 +0000
@@ -776,13 +776,17 @@
776 return;776 return;
777 }777 }
778778
779 IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data);
779 BamfWindow * window = BAMF_WINDOW(view);780 BamfWindow * window = BAMF_WINDOW(view);
780 if (bamf_window_get_window_type(window) != BAMF_WINDOW_DESKTOP) {781 guint32 xid = bamf_window_get_xid(window);
781 return;
782 }
783782
784 IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data);783 if (bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP) {
785 g_hash_table_remove(iapp->desktop_windows, GUINT_TO_POINTER(bamf_window_get_xid(window)));784 g_hash_table_remove(iapp->desktop_windows, GUINT_TO_POINTER(xid));
785 }
786 else {
787 g_debug("Window removed for window: %d", xid);
788 g_hash_table_remove(iapp->apps, GUINT_TO_POINTER(xid));
789 }
786790
787 return;791 return;
788}792}
789793
=== modified file 'src/window-menus.c'
--- src/window-menus.c 2011-01-26 22:21:20 +0000
+++ src/window-menus.c 2011-02-02 20:48:58 +0000
@@ -26,7 +26,6 @@
26#include <libdbusmenu-gtk/menu.h>26#include <libdbusmenu-gtk/menu.h>
27#include <glib.h>27#include <glib.h>
28#include <gio/gio.h>28#include <gio/gio.h>
29#include <libbamf/bamf-matcher.h>
3029
31#include "window-menus.h"30#include "window-menus.h"
32#include "indicator-appmenu-marshal.h"31#include "indicator-appmenu-marshal.h"
@@ -47,8 +46,6 @@
47 gchar * retry_name;46 gchar * retry_name;
48 GVariant * retry_data;47 GVariant * retry_data;
49 guint retry_timestamp;48 guint retry_timestamp;
50 BamfApplication *app;
51 gulong window_removed_id;
52};49};
5350
54typedef struct _WMEntry WMEntry;51typedef struct _WMEntry WMEntry;
@@ -81,7 +78,6 @@
81static void window_menus_init (WindowMenus *self);78static void window_menus_init (WindowMenus *self);
82static void window_menus_dispose (GObject *object);79static void window_menus_dispose (GObject *object);
83static void window_menus_finalize (GObject *object);80static void window_menus_finalize (GObject *object);
84static void window_removed (GObject * gobject, BamfView * view, gpointer user_data);
85static void root_changed (DbusmenuClient * client, DbusmenuMenuitem * new_root, gpointer user_data);81static void root_changed (DbusmenuClient * client, DbusmenuMenuitem * new_root, gpointer user_data);
86static void menu_entry_added (DbusmenuMenuitem * root, DbusmenuMenuitem * newentry, guint position, gpointer user_data);82static void menu_entry_added (DbusmenuMenuitem * root, DbusmenuMenuitem * newentry, guint position, gpointer user_data);
87static void menu_entry_removed (DbusmenuMenuitem * root, DbusmenuMenuitem * oldentry, gpointer user_data);83static void menu_entry_removed (DbusmenuMenuitem * root, DbusmenuMenuitem * oldentry, gpointer user_data);
@@ -167,12 +163,6 @@
167163
168 WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(object);164 WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(object);
169165
170 if (priv->app != NULL) {
171 g_signal_handler_disconnect(priv->app, priv->window_removed_id);
172 g_object_unref(G_OBJECT(priv->app));
173 priv->app = NULL;
174 }
175
176 if (priv->root != NULL) {166 if (priv->root != NULL) {
177 g_object_unref(G_OBJECT(priv->root));167 g_object_unref(G_OBJECT(priv->root));
178 priv->root = NULL;168 priv->root = NULL;
@@ -424,12 +414,6 @@
424 root_changed(DBUSMENU_CLIENT(priv->client), root, newmenu);414 root_changed(DBUSMENU_CLIENT(priv->client), root, newmenu);
425 }415 }
426416
427 priv->app = bamf_matcher_get_application_for_xid(bamf_matcher_get_default(), windowid);
428 if (priv->app) {
429 g_object_ref(priv->app);
430 priv->window_removed_id = g_signal_connect(G_OBJECT(priv->app), "window-removed", G_CALLBACK(window_removed), newmenu);
431 }
432
433 return newmenu;417 return newmenu;
434}418}
435419
@@ -464,24 +448,6 @@
464 return;448 return;
465}449}
466450
467static void
468window_removed (GObject * gobject, BamfView * view, gpointer user_data)
469{
470 WindowMenus * wm = WINDOW_MENUS(user_data);
471 WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(wm);
472
473 if (!BAMF_IS_WINDOW(view)) {
474 return;
475 }
476
477 BamfWindow * window = BAMF_WINDOW(view);
478
479 if (bamf_window_get_xid(window) == priv->windowid) {
480 g_debug("Window removed for window: %d", priv->windowid);
481 g_object_unref(G_OBJECT(wm));
482 }
483}
484
485/* Get the location of this entry */451/* Get the location of this entry */
486guint452guint
487window_menus_get_location (WindowMenus * wm, IndicatorObjectEntry * entry)453window_menus_get_location (WindowMenus * wm, IndicatorObjectEntry * entry)

Subscribers

People subscribed via source and target branches