Merge lp:~mterry/appmenu-gtk/watch-menubar-parents into lp:appmenu-gtk/0.4

Proposed by Michael Terry
Status: Merged
Approved by: Ted Gould
Approved revision: 126
Merged at revision: 126
Proposed branch: lp:~mterry/appmenu-gtk/watch-menubar-parents
Merge into: lp:appmenu-gtk/0.4
Diff against target: 161 lines (+61/-47)
1 file modified
src/bridge.c (+61/-47)
To merge this branch: bzr merge lp:~mterry/appmenu-gtk/watch-menubar-parents
Reviewer Review Type Date Requested Status
Ted Gould (community) Approve
Review via email: mp+52706@code.launchpad.net

Description of the change

This watches menubars for reparenting, so that if they get swapped in and out, like they do for shotwell, we notice and rebuild.

Some notes:
 * I also got rid of a couple of variables (append and after_startup) that weren't used

 * I guarded the connect for toplevel_notify_cb so it only gets connected if toplevel isn't a window and only once (not a big deal, since when run, it disconnects all other connected instances, but cleanliness is next to something or other)

 * I didn't bother handling the case of a menubar disappearing and not immediately being replaced by another. In this hopefully-rare case, we'd need to be able to find the old window context (so we'd need to save a pointer to the old parented toplevel) and set its root to NULL.

To post a comment you must log in.
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/bridge.c'
2--- src/bridge.c 2011-03-07 22:05:29 +0000
3+++ src/bridge.c 2011-03-09 16:02:46 +0000
4@@ -52,7 +52,10 @@
5 static void mnemonic_shown_cb (GtkWidget *widget,
6 GParamSpec *pspec,
7 AppWindowContext *context);
8-static void toplevel_notify_cb (GtkWidget *widget,
9+static void toplevel_notify_parent_cb (GtkWidget *widget,
10+ GParamSpec *pspec,
11+ UbuntuMenuProxy *proxy);
12+static void menubar_notify_parent_cb (GtkWidget *widget,
13 GParamSpec *pspec,
14 UbuntuMenuProxy *proxy);
15 static void rebuild_window_items (AppMenuBridge *bridge,
16@@ -99,7 +102,6 @@
17 static GHashTable *rebuild_ids = NULL;
18 static GDBusNodeInfo * registrar_node_info = NULL;
19 static GDBusInterfaceInfo * registrar_interface_info = NULL;
20-static gboolean after_startup = FALSE;
21
22 static void
23 activate_menu (AppMenuBridge *bridge,
24@@ -624,8 +626,8 @@
25 if (!GTK_IS_WINDOW (toplevel))
26 {
27 g_signal_connect (G_OBJECT (toplevel),
28- "notify",
29- G_CALLBACK (toplevel_notify_cb),
30+ "notify::parent",
31+ G_CALLBACK (toplevel_notify_parent_cb),
32 bridge);
33
34 return;
35@@ -750,33 +752,42 @@
36 }
37
38 static void
39-toplevel_notify_cb (GtkWidget *widget,
40- GParamSpec *pspec,
41- UbuntuMenuProxy *proxy)
42-{
43- if (pspec->name == g_intern_static_string ("parent"))
44- {
45- GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
46- AppMenuBridge *bridge = APP_MENU_BRIDGE (proxy);
47-
48- if (gtk_widget_get_parent (widget) == NULL)
49- return;
50-
51- if (GTK_IS_WINDOW (toplevel))
52- {
53- g_signal_handlers_disconnect_by_func (widget,
54- G_CALLBACK (toplevel_notify_cb),
55- proxy);
56- rebuild (bridge, toplevel);
57- }
58- else
59- {
60- g_signal_connect (G_OBJECT (toplevel),
61- "notify",
62- G_CALLBACK (toplevel_notify_cb),
63- proxy);
64- }
65- }
66+toplevel_notify_parent_cb (GtkWidget *widget,
67+ GParamSpec *pspec,
68+ UbuntuMenuProxy *proxy)
69+{
70+ GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
71+ AppMenuBridge *bridge = APP_MENU_BRIDGE (proxy);
72+
73+ if (gtk_widget_get_parent (widget) == NULL)
74+ return;
75+
76+ if (GTK_IS_WINDOW (toplevel))
77+ {
78+ g_signal_handlers_disconnect_by_func (widget,
79+ G_CALLBACK (toplevel_notify_parent_cb),
80+ proxy);
81+ rebuild (bridge, toplevel);
82+ }
83+ else
84+ {
85+ g_signal_connect (G_OBJECT (toplevel),
86+ "notify::parent",
87+ G_CALLBACK (toplevel_notify_parent_cb),
88+ proxy);
89+ }
90+}
91+
92+static void
93+menubar_notify_parent_cb (GtkWidget *widget,
94+ GParamSpec *pspec,
95+ UbuntuMenuProxy *proxy)
96+{
97+ if (gtk_widget_get_parent (widget) == NULL)
98+ return; /* TODO: Should clear all entries (find old context and set root to NULL) */
99+
100+ /* Rebuild now or when toplevel window appears */
101+ toplevel_notify_parent_cb (widget, NULL, proxy);
102 }
103
104 static void
105@@ -794,14 +805,6 @@
106 }
107 }
108
109-gboolean
110-startup_timeout (gpointer data)
111-{
112- after_startup = TRUE;
113-
114- return FALSE;
115-}
116-
117 static void
118 app_menu_bridge_insert (UbuntuMenuProxy *proxy,
119 GtkWidget *parent,
120@@ -811,9 +814,6 @@
121 AppMenuBridge *bridge;
122 AppMenuBridgePrivate *priv;
123 GtkWidget *toplevel = NULL;
124- gboolean append = FALSE;
125-
126- g_idle_add ((GSourceFunc)startup_timeout, NULL);
127
128 if (GTK_IS_TEAROFF_MENU_ITEM (child))
129 return;
130@@ -825,12 +825,26 @@
131
132 if (GTK_IS_MENU_BAR (parent))
133 {
134- g_signal_connect (G_OBJECT (toplevel),
135- "notify",
136- G_CALLBACK (toplevel_notify_cb),
137- proxy);
138+ /* Watch for toplevel window to appear */
139+ if (!GTK_IS_WINDOW (toplevel) &&
140+ g_signal_handler_find (toplevel, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
141+ toplevel_notify_parent_cb, NULL) == 0)
142+ {
143+ g_signal_connect (toplevel,
144+ "notify::parent",
145+ G_CALLBACK (toplevel_notify_parent_cb),
146+ proxy);
147+ }
148
149- append = TRUE;
150+ /* Watch for parent changes for the menubar itself */
151+ if (g_signal_handler_find (parent, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
152+ menubar_notify_parent_cb, NULL) == 0)
153+ {
154+ g_signal_connect (parent,
155+ "notify::parent",
156+ G_CALLBACK (menubar_notify_parent_cb),
157+ proxy);
158+ }
159 }
160 else if (GTK_IS_MENU (parent))
161 {

Subscribers

People subscribed via source and target branches