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
1=== modified file 'src/indicator-appmenu.c'
2--- src/indicator-appmenu.c 2011-01-25 16:39:51 +0000
3+++ src/indicator-appmenu.c 2011-02-02 20:48:58 +0000
4@@ -776,13 +776,17 @@
5 return;
6 }
7
8+ IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data);
9 BamfWindow * window = BAMF_WINDOW(view);
10- if (bamf_window_get_window_type(window) != BAMF_WINDOW_DESKTOP) {
11- return;
12- }
13+ guint32 xid = bamf_window_get_xid(window);
14
15- IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data);
16- g_hash_table_remove(iapp->desktop_windows, GUINT_TO_POINTER(bamf_window_get_xid(window)));
17+ if (bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP) {
18+ g_hash_table_remove(iapp->desktop_windows, GUINT_TO_POINTER(xid));
19+ }
20+ else {
21+ g_debug("Window removed for window: %d", xid);
22+ g_hash_table_remove(iapp->apps, GUINT_TO_POINTER(xid));
23+ }
24
25 return;
26 }
27
28=== modified file 'src/window-menus.c'
29--- src/window-menus.c 2011-01-26 22:21:20 +0000
30+++ src/window-menus.c 2011-02-02 20:48:58 +0000
31@@ -26,7 +26,6 @@
32 #include <libdbusmenu-gtk/menu.h>
33 #include <glib.h>
34 #include <gio/gio.h>
35-#include <libbamf/bamf-matcher.h>
36
37 #include "window-menus.h"
38 #include "indicator-appmenu-marshal.h"
39@@ -47,8 +46,6 @@
40 gchar * retry_name;
41 GVariant * retry_data;
42 guint retry_timestamp;
43- BamfApplication *app;
44- gulong window_removed_id;
45 };
46
47 typedef struct _WMEntry WMEntry;
48@@ -81,7 +78,6 @@
49 static void window_menus_init (WindowMenus *self);
50 static void window_menus_dispose (GObject *object);
51 static void window_menus_finalize (GObject *object);
52-static void window_removed (GObject * gobject, BamfView * view, gpointer user_data);
53 static void root_changed (DbusmenuClient * client, DbusmenuMenuitem * new_root, gpointer user_data);
54 static void menu_entry_added (DbusmenuMenuitem * root, DbusmenuMenuitem * newentry, guint position, gpointer user_data);
55 static void menu_entry_removed (DbusmenuMenuitem * root, DbusmenuMenuitem * oldentry, gpointer user_data);
56@@ -167,12 +163,6 @@
57
58 WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(object);
59
60- if (priv->app != NULL) {
61- g_signal_handler_disconnect(priv->app, priv->window_removed_id);
62- g_object_unref(G_OBJECT(priv->app));
63- priv->app = NULL;
64- }
65-
66 if (priv->root != NULL) {
67 g_object_unref(G_OBJECT(priv->root));
68 priv->root = NULL;
69@@ -424,12 +414,6 @@
70 root_changed(DBUSMENU_CLIENT(priv->client), root, newmenu);
71 }
72
73- priv->app = bamf_matcher_get_application_for_xid(bamf_matcher_get_default(), windowid);
74- if (priv->app) {
75- g_object_ref(priv->app);
76- priv->window_removed_id = g_signal_connect(G_OBJECT(priv->app), "window-removed", G_CALLBACK(window_removed), newmenu);
77- }
78-
79 return newmenu;
80 }
81
82@@ -464,24 +448,6 @@
83 return;
84 }
85
86-static void
87-window_removed (GObject * gobject, BamfView * view, gpointer user_data)
88-{
89- WindowMenus * wm = WINDOW_MENUS(user_data);
90- WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(wm);
91-
92- if (!BAMF_IS_WINDOW(view)) {
93- return;
94- }
95-
96- BamfWindow * window = BAMF_WINDOW(view);
97-
98- if (bamf_window_get_xid(window) == priv->windowid) {
99- g_debug("Window removed for window: %d", priv->windowid);
100- g_object_unref(G_OBJECT(wm));
101- }
102-}
103-
104 /* Get the location of this entry */
105 guint
106 window_menus_get_location (WindowMenus * wm, IndicatorObjectEntry * entry)

Subscribers

People subscribed via source and target branches