Merge lp:~3v1n0/indicator-appmenu/all-menus-mode into lp:indicator-appmenu/15.04
- all-menus-mode
- Merge into trunk.15.04
Status: | Merged |
---|---|
Approved by: | Lars Karlitski |
Approved revision: | 266 |
Merged at revision: | 267 |
Proposed branch: | lp:~3v1n0/indicator-appmenu/all-menus-mode |
Merge into: | lp:indicator-appmenu/15.04 |
Diff against target: |
943 lines (+235/-211) 6 files modified
configure.ac (+1/-1) debian/changelog (+6/-0) m4/gcov.m4 (+1/-1) src/indicator-appmenu.c (+213/-173) src/window-menu-dbusmenu.c (+7/-12) src/window-menu-model.c (+7/-24) |
To merge this branch: | bzr merge lp:~3v1n0/indicator-appmenu/all-menus-mode |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Lars Karlitski (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+248064@code.launchpad.net |
Commit message
IndicatorAppmenu: add modes support and implement unity-all-menus mode
When this mode is enabled, we export all the menus to the indicator, it will be up
to unity to filter them out based on their parent xid.
Description of the change
Set the parent_window xid to each menu and add a new mode so that the indicator will export all the menus he knows, leaving to unity the job of selecting the ones to show.
PS Jenkins bot (ps-jenkins) wrote : | # |
- 265. By Marco Trevisan (Treviño)
-
gcov.m4: add more lcov supported versions
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:265
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
- 266. By Marco Trevisan (Treviño)
-
Bump version to 15.02
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:266
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Lars Karlitski (larsu) wrote : | # |
I'm a bit concerned about the additional bus traffic. But shouldn't be too much and doesn't even register for me on first testing.
Thanks for the patch.
Preview Diff
1 | === modified file 'configure.ac' |
2 | --- configure.ac 2013-10-24 14:43:59 +0000 |
3 | +++ configure.ac 2015-02-03 10:10:58 +0000 |
4 | @@ -1,5 +1,5 @@ |
5 | AC_INIT([indicator-appmenu], |
6 | - [13.01.0], |
7 | + [15.02.0], |
8 | [http://bugs.launchpad.net/indicator-appmenu], |
9 | [indicator-appmenu], |
10 | [http://launchpad.net/indicator-appmenu]) |
11 | |
12 | === modified file 'debian/changelog' |
13 | --- debian/changelog 2015-01-20 22:02:20 +0000 |
14 | +++ debian/changelog 2015-02-03 10:10:58 +0000 |
15 | @@ -1,3 +1,9 @@ |
16 | +indicator-appmenu (15.02.0+15.04.20150203-0ubuntu1) UNRELEASED; urgency=medium |
17 | + |
18 | + * Bump indicator-appmenu version to 15.02 |
19 | + |
20 | + -- Marco Trevisan (Treviño) <marco@ubuntu.com> Tue, 03 Feb 2015 11:05:53 +0100 |
21 | + |
22 | indicator-appmenu (13.01.0+15.04.20150120-0ubuntu1) vivid; urgency=low |
23 | |
24 | [ Dmitry Shachnev ] |
25 | |
26 | === modified file 'm4/gcov.m4' |
27 | --- m4/gcov.m4 2014-02-06 19:57:18 +0000 |
28 | +++ m4/gcov.m4 2015-02-03 10:10:58 +0000 |
29 | @@ -30,7 +30,7 @@ |
30 | AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.]) |
31 | fi |
32 | |
33 | - lcov_version_list="1.6 1.7 1.8 1.9 1.10" |
34 | + lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11 1.12" |
35 | AC_CHECK_PROG(LCOV, lcov, lcov) |
36 | AC_CHECK_PROG(GENHTML, genhtml, genhtml) |
37 | |
38 | |
39 | === modified file 'src/indicator-appmenu.c' |
40 | --- src/indicator-appmenu.c 2014-03-19 14:23:20 +0000 |
41 | +++ src/indicator-appmenu.c 2015-02-03 10:10:58 +0000 |
42 | @@ -5,6 +5,7 @@ |
43 | |
44 | Authors: |
45 | Ted Gould <ted@canonical.com> |
46 | + Marco Trevisan <marco@canonical.com> |
47 | |
48 | This program is free software: you can redistribute it and/or modify it |
49 | under the terms of the GNU General Public License version 3, as published |
50 | @@ -73,16 +74,22 @@ |
51 | STUBS_HIDE |
52 | }; |
53 | |
54 | +typedef enum _AppmenuMode AppmenuMode; |
55 | +enum _AppmenuMode { |
56 | + MODE_STANDARD, |
57 | + MODE_UNITY, |
58 | + MODE_UNITY_ALL_MENUS |
59 | +}; |
60 | + |
61 | struct _IndicatorAppmenuClass { |
62 | IndicatorObjectClass parent_class; |
63 | - |
64 | - void (*window_registered) (IndicatorAppmenu * iapp, guint wid, gchar * address, gpointer path, gpointer user_data); |
65 | - void (*window_unregistered) (IndicatorAppmenu * iapp, guint wid, gpointer user_data); |
66 | }; |
67 | |
68 | struct _IndicatorAppmenu { |
69 | IndicatorObject parent; |
70 | |
71 | + AppmenuMode mode; |
72 | + |
73 | WindowMenu * default_app; |
74 | GHashTable * apps; |
75 | |
76 | @@ -90,14 +97,7 @@ |
77 | BamfWindow * active_window; |
78 | ActiveStubsState active_stubs; |
79 | |
80 | - gulong sig_entry_added; |
81 | - gulong sig_entry_removed; |
82 | - gulong sig_status_changed; |
83 | - gulong sig_show_menu; |
84 | - gulong sig_a11y_update; |
85 | - |
86 | GtkMenuItem * close_item; |
87 | - |
88 | GArray * window_menus; |
89 | |
90 | GHashTable * desktop_windows; |
91 | @@ -137,6 +137,7 @@ |
92 | /********************** |
93 | Prototypes |
94 | **********************/ |
95 | +static gboolean indicator_appmenu_delayed_init (IndicatorAppmenu * iapp); |
96 | static void indicator_appmenu_dispose (GObject *object); |
97 | static void indicator_appmenu_finalize (GObject *object); |
98 | static void build_window_menus (IndicatorAppmenu * iapp); |
99 | @@ -153,7 +154,7 @@ |
100 | static void switch_default_app (IndicatorAppmenu * iapp, |
101 | WindowMenu * newdef, |
102 | BamfWindow * active_window); |
103 | -static void find_desktop_windows (IndicatorAppmenu * iapp); |
104 | +static void find_relevant_windows (IndicatorAppmenu * iapp); |
105 | static void new_window (BamfMatcher * matcher, |
106 | BamfView * view, |
107 | gpointer user_data); |
108 | @@ -195,8 +196,12 @@ |
109 | static void on_name_lost (GDBusConnection * connection, |
110 | const gchar * name, |
111 | gpointer user_data); |
112 | +static WindowMenu * ensure_menus (IndicatorAppmenu * iapp, |
113 | + BamfWindow * window); |
114 | static GVariant * unregister_window (IndicatorAppmenu * iapp, |
115 | guint windowid); |
116 | +static void connect_to_menu_signals (IndicatorAppmenu * iapp, |
117 | + WindowMenu * menus); |
118 | |
119 | /* Unique error codes for debug interface */ |
120 | enum { |
121 | @@ -260,24 +265,31 @@ |
122 | static void |
123 | indicator_appmenu_init (IndicatorAppmenu *self) |
124 | { |
125 | - self->default_app = NULL; |
126 | self->apps = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref); |
127 | - self->matcher = NULL; |
128 | - self->active_window = NULL; |
129 | + self->mode = MODE_STANDARD; |
130 | self->active_stubs = STUBS_UNKNOWN; |
131 | - self->close_item = NULL; |
132 | - self->bus = NULL; |
133 | - self->owner_id = 0; |
134 | - self->dbus_registration = 0; |
135 | - |
136 | - /* Setup the entries for the fallbacks */ |
137 | - self->window_menus = g_array_sized_new(FALSE, FALSE, sizeof(IndicatorObjectEntry), 2); |
138 | |
139 | /* Setup the cache of windows with possible desktop entries */ |
140 | self->desktop_windows = g_hash_table_new(g_direct_hash, g_direct_equal); |
141 | - self->desktop_menu = NULL; /* Starts NULL until found */ |
142 | - |
143 | - build_window_menus(self); |
144 | + |
145 | + g_idle_add((GSourceFunc) indicator_appmenu_delayed_init, self); |
146 | +} |
147 | + |
148 | +/* Delayed Init, this is done so it can happen after that the mode has been set */ |
149 | +static gboolean |
150 | +indicator_appmenu_delayed_init (IndicatorAppmenu *self) |
151 | +{ |
152 | + if (indicator_object_check_environment(INDICATOR_OBJECT(self), "unity-all-menus")) { |
153 | + self->mode = MODE_UNITY_ALL_MENUS; |
154 | + } else if (indicator_object_check_environment(INDICATOR_OBJECT(self), "unity")) { |
155 | + self->mode = MODE_UNITY; |
156 | + } |
157 | + |
158 | + if (self->mode != MODE_STANDARD) |
159 | + self->active_stubs = STUBS_HIDE; |
160 | + |
161 | + if (self->active_stubs != STUBS_HIDE) |
162 | + build_window_menus(self); |
163 | |
164 | /* Get the default BAMF matcher */ |
165 | self->matcher = bamf_matcher_get_default(); |
166 | @@ -293,7 +305,7 @@ |
167 | g_signal_connect(G_OBJECT(self->matcher), "view-closed", G_CALLBACK(old_window), self); |
168 | } |
169 | |
170 | - find_desktop_windows(self); |
171 | + find_relevant_windows(self); |
172 | |
173 | /* Request a name so others can find us */ |
174 | self->owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, |
175 | @@ -304,6 +316,8 @@ |
176 | on_name_lost, |
177 | self, |
178 | NULL); |
179 | + |
180 | + return G_SOURCE_REMOVE; |
181 | } |
182 | |
183 | static void |
184 | @@ -365,10 +379,7 @@ |
185 | iapp->dbus_registration = 0; |
186 | } |
187 | |
188 | - if (iapp->bus != NULL) { |
189 | - g_object_unref(iapp->bus); |
190 | - iapp->bus = NULL; |
191 | - } |
192 | + g_clear_object(&iapp->bus); |
193 | |
194 | if (iapp->owner_id != 0) { |
195 | g_bus_unown_name(iapp->owner_id); |
196 | @@ -377,23 +388,13 @@ |
197 | |
198 | /* bring down the matcher before resetting to no menu so we don't |
199 | get match signals */ |
200 | - if (iapp->matcher != NULL) { |
201 | - g_object_unref(iapp->matcher); |
202 | - iapp->matcher = NULL; |
203 | - } |
204 | + g_clear_object(&iapp->matcher); |
205 | |
206 | /* No specific ref */ |
207 | - switch_default_app (iapp, NULL, NULL); |
208 | - |
209 | - if (iapp->apps != NULL) { |
210 | - g_hash_table_destroy(iapp->apps); |
211 | - iapp->apps = NULL; |
212 | - } |
213 | - |
214 | - if (iapp->desktop_windows != NULL) { |
215 | - g_hash_table_destroy(iapp->desktop_windows); |
216 | - iapp->desktop_windows = NULL; |
217 | - } |
218 | + switch_default_app(iapp, NULL, NULL); |
219 | + |
220 | + g_clear_pointer(&iapp->apps, g_hash_table_destroy); |
221 | + g_clear_pointer(&iapp->desktop_windows, g_hash_table_destroy); |
222 | |
223 | if (iapp->desktop_menu != NULL) { |
224 | /* Wait, nothing here? Yup. We're not referencing the |
225 | @@ -413,13 +414,19 @@ |
226 | IndicatorAppmenu * iapp = INDICATOR_APPMENU(object); |
227 | |
228 | if (iapp->window_menus != NULL) { |
229 | - if (iapp->window_menus->len != 0) { |
230 | - g_warning("Window menus weren't free'd in dispose!"); |
231 | + g_signal_handlers_disconnect_by_data(iapp->close_item, iapp); |
232 | + |
233 | + gint i; |
234 | + for (i = 0; i < iapp->window_menus->len; ++i) { |
235 | + IndicatorObjectEntry *entry = &g_array_index(iapp->window_menus, IndicatorObjectEntry, i); |
236 | + g_clear_object(&(entry->label)); |
237 | + g_clear_object(&(entry->menu)); |
238 | } |
239 | g_array_free(iapp->window_menus, TRUE); |
240 | - iapp->window_menus = NULL; |
241 | } |
242 | |
243 | + g_signal_handlers_disconnect_by_data(iapp->matcher, iapp); |
244 | + |
245 | G_OBJECT_CLASS (indicator_appmenu_parent_class)->finalize (object); |
246 | return; |
247 | } |
248 | @@ -496,11 +503,17 @@ |
249 | GtkMenuItem * mi = NULL; |
250 | GtkStockItem stockitem; |
251 | |
252 | + /* Setup the entries for the fallbacks */ |
253 | + iapp->window_menus = g_array_sized_new(FALSE, FALSE, sizeof(IndicatorObjectEntry), 2); |
254 | + |
255 | +G_GNUC_BEGIN_IGNORE_DEPRECATIONS |
256 | /* File Menu */ |
257 | if (!gtk_stock_lookup(GTK_STOCK_FILE, &stockitem)) { |
258 | g_warning("Unable to find the file menu stock item"); |
259 | stockitem.label = "_File"; |
260 | } |
261 | +G_GNUC_END_IGNORE_DEPRECATIONS |
262 | + |
263 | entries[0].label = GTK_LABEL(gtk_label_new_with_mnemonic(stockitem.label)); |
264 | g_object_ref(G_OBJECT(entries[0].label)); |
265 | gtk_widget_show(GTK_WIDGET(entries[0].label)); |
266 | @@ -508,7 +521,10 @@ |
267 | entries[0].menu = GTK_MENU(gtk_menu_new()); |
268 | g_object_ref(G_OBJECT(entries[0].menu)); |
269 | |
270 | +G_GNUC_BEGIN_IGNORE_DEPRECATIONS |
271 | mi = GTK_MENU_ITEM(gtk_image_menu_item_new_from_stock(GTK_STOCK_CLOSE, agroup)); |
272 | +G_GNUC_END_IGNORE_DEPRECATIONS |
273 | + |
274 | gtk_widget_set_sensitive(GTK_WIDGET(mi), FALSE); |
275 | g_signal_connect(G_OBJECT(mi), "activate", G_CALLBACK(close_current), iapp); |
276 | gtk_widget_show(GTK_WIDGET(mi)); |
277 | @@ -519,8 +535,6 @@ |
278 | |
279 | /* Copy the entries on the stack into the array */ |
280 | g_array_insert_vals(iapp->window_menus, 0, entries, 1); |
281 | - |
282 | - return; |
283 | } |
284 | |
285 | /* Determine which windows should be used as the desktop |
286 | @@ -537,6 +551,7 @@ |
287 | if (pwm != NULL) { |
288 | g_debug("Setting Desktop Menus to: %X", xid); |
289 | iapp->desktop_menu = WINDOW_MENU(pwm); |
290 | + break; |
291 | } |
292 | } |
293 | |
294 | @@ -545,10 +560,10 @@ |
295 | return; |
296 | } |
297 | |
298 | -/* Puts all the desktop windows into the hash table so that we |
299 | +/* Puts all the windows we care about into the hash table so that we |
300 | can have a nice list of them. */ |
301 | static void |
302 | -find_desktop_windows (IndicatorAppmenu * iapp) |
303 | +find_relevant_windows (IndicatorAppmenu * iapp) |
304 | { |
305 | GList * windows = bamf_matcher_get_windows(iapp->matcher); |
306 | GList * lwindow; |
307 | @@ -568,7 +583,7 @@ |
308 | static void |
309 | new_window (BamfMatcher * matcher, BamfView * view, gpointer user_data) |
310 | { |
311 | - if (view == NULL || !BAMF_IS_WINDOW(view)) { |
312 | + if (!BAMF_IS_WINDOW(view)) { |
313 | return; |
314 | } |
315 | |
316 | @@ -576,6 +591,11 @@ |
317 | IndicatorAppmenu * iapp = INDICATOR_APPMENU(user_data); |
318 | guint32 xid = bamf_window_get_xid(window); |
319 | |
320 | + if (iapp->mode == MODE_UNITY_ALL_MENUS) { |
321 | + ensure_menus(iapp, window); |
322 | + return; |
323 | + } |
324 | + |
325 | if (bamf_window_get_window_type(window) != BAMF_WINDOW_DESKTOP) { |
326 | return; |
327 | } |
328 | @@ -593,15 +613,13 @@ |
329 | switch_default_app(iapp, NULL, NULL); |
330 | } |
331 | } |
332 | - |
333 | - return; |
334 | } |
335 | |
336 | /* When windows leave us, this function gets called */ |
337 | static void |
338 | old_window (BamfMatcher * matcher, BamfView * view, gpointer user_data) |
339 | { |
340 | - if (view == NULL || !BAMF_IS_WINDOW(view)) { |
341 | + if (!BAMF_IS_WINDOW(view)) { |
342 | return; |
343 | } |
344 | |
345 | @@ -617,21 +635,21 @@ |
346 | /* List of desktop files that shouldn't have menu stubs. */ |
347 | const static gchar * stubs_blacklist[] = { |
348 | /* Firefox */ |
349 | - "/usr/share/applications/firefox.desktop", |
350 | + "/firefox.desktop", |
351 | /* Thunderbird */ |
352 | - "/usr/share/applications/thunderbird.desktop", |
353 | + "/thunderbird.desktop", |
354 | /* Open Office */ |
355 | - "/usr/share/applications/openoffice.org-base.desktop", |
356 | - "/usr/share/applications/openoffice.org-impress.desktop", |
357 | - "/usr/share/applications/openoffice.org-calc.desktop", |
358 | - "/usr/share/applications/openoffice.org-math.desktop", |
359 | - "/usr/share/applications/openoffice.org-draw.desktop", |
360 | - "/usr/share/applications/openoffice.org-writer.desktop", |
361 | + "/openoffice.org-base.desktop", |
362 | + "/openoffice.org-impress.desktop", |
363 | + "/openoffice.org-calc.desktop", |
364 | + "/openoffice.org-math.desktop", |
365 | + "/openoffice.org-draw.desktop", |
366 | + "/openoffice.org-writer.desktop", |
367 | /* Blender */ |
368 | - "/usr/share/applications/blender-fullscreen.desktop", |
369 | - "/usr/share/applications/blender-windowed.desktop", |
370 | + "/blender-fullscreen.desktop", |
371 | + "/blender-windowed.desktop", |
372 | /* Eclipse */ |
373 | - "/usr/share/applications/eclipse.desktop", |
374 | + "/eclipse.desktop", |
375 | |
376 | NULL |
377 | }; |
378 | @@ -652,7 +670,7 @@ |
379 | |
380 | int i; |
381 | for (i = 0; stubs_blacklist[i] != NULL; i++) { |
382 | - if (g_strcmp0(stubs_blacklist[i], desktop_file) == 0) { |
383 | + if (g_str_has_suffix(desktop_file, stubs_blacklist[i]) == 0) { |
384 | return FALSE; |
385 | } |
386 | } |
387 | @@ -666,6 +684,19 @@ |
388 | { |
389 | g_return_val_if_fail(IS_INDICATOR_APPMENU(io), NULL); |
390 | IndicatorAppmenu * iapp = INDICATOR_APPMENU(io); |
391 | + GHashTableIter iter; |
392 | + gpointer value; |
393 | + GList* entries = NULL; |
394 | + |
395 | + if (iapp->mode == MODE_UNITY_ALL_MENUS) { |
396 | + g_hash_table_iter_init(&iter, iapp->apps); |
397 | + while (g_hash_table_iter_next(&iter, NULL, &value)) { |
398 | + GList *app_entries = window_menu_get_entries(WINDOW_MENU (value)); |
399 | + entries = g_list_concat(app_entries, entries); |
400 | + } |
401 | + |
402 | + return entries; |
403 | + } |
404 | |
405 | /* If we have a focused app with menus, use it's windows */ |
406 | if (iapp->default_app != NULL) { |
407 | @@ -702,21 +733,15 @@ |
408 | return NULL; |
409 | } |
410 | |
411 | - if (indicator_object_check_environment(INDICATOR_OBJECT(iapp), "unity")) { |
412 | - return NULL; |
413 | - } |
414 | - |
415 | - GList * output = NULL; |
416 | - int i; |
417 | - |
418 | /* There is only one item in window_menus now, but there |
419 | was more, and there is likely to be more in the future |
420 | so we're leaving this here to avoid a possible bug. */ |
421 | + int i; |
422 | for (i = 0; i < iapp->window_menus->len; i++) { |
423 | - output = g_list_append(output, &g_array_index(iapp->window_menus, IndicatorObjectEntry, i)); |
424 | + entries = g_list_append(entries, &g_array_index(iapp->window_menus, IndicatorObjectEntry, i)); |
425 | } |
426 | |
427 | - return output; |
428 | + return entries; |
429 | } |
430 | |
431 | /* Grabs the location of the entry */ |
432 | @@ -728,7 +753,7 @@ |
433 | if (iapp->default_app != NULL) { |
434 | /* Find the location in the app */ |
435 | count = window_menu_get_location(iapp->default_app, entry); |
436 | - } else if (iapp->active_window != NULL) { |
437 | + } else if (iapp->active_window != NULL && iapp->window_menus) { |
438 | /* Find the location in the window menus */ |
439 | for (count = 0; count < iapp->window_menus->len; count++) { |
440 | if (entry == &g_array_index(iapp->window_menus, IndicatorObjectEntry, count)) { |
441 | @@ -760,23 +785,24 @@ |
442 | static BamfWindow * |
443 | xid_to_bamf_window (IndicatorAppmenu * iapp, guint xid) |
444 | { |
445 | - GList * windows = bamf_matcher_get_windows(iapp->matcher); |
446 | - GList * window; |
447 | + BamfApplication *application = bamf_matcher_get_application_for_xid(iapp->matcher, xid); |
448 | + GList * children = bamf_view_get_children (BAMF_VIEW (application)); |
449 | + GList * l; |
450 | BamfWindow * newwindow = NULL; |
451 | |
452 | - for (window = windows; window != NULL; window = g_list_next(window)) { |
453 | - if (!BAMF_IS_WINDOW(window->data)) { |
454 | + for (l = children; l; l = l->next) { |
455 | + if (!BAMF_IS_WINDOW(l->data)) { |
456 | continue; |
457 | } |
458 | |
459 | - BamfWindow * testwindow = BAMF_WINDOW(window->data); |
460 | + BamfWindow * testwindow = BAMF_WINDOW(l->data); |
461 | |
462 | if (xid == bamf_window_get_xid(testwindow)) { |
463 | newwindow = testwindow; |
464 | break; |
465 | } |
466 | } |
467 | - g_list_free(windows); |
468 | + g_list_free(children); |
469 | |
470 | return newwindow; |
471 | } |
472 | @@ -842,7 +868,7 @@ |
473 | static void |
474 | switch_active_window (IndicatorAppmenu * iapp, BamfWindow * active_window) |
475 | { |
476 | - if (iapp->active_window == active_window) { |
477 | + if (iapp->active_window == active_window || iapp->mode == MODE_UNITY_ALL_MENUS) { |
478 | return; |
479 | } |
480 | |
481 | @@ -851,7 +877,9 @@ |
482 | } |
483 | |
484 | iapp->active_window = active_window; |
485 | - iapp->active_stubs = STUBS_UNKNOWN; |
486 | + |
487 | + if (iapp->mode == MODE_STANDARD) |
488 | + iapp->active_stubs = STUBS_UNKNOWN; |
489 | |
490 | /* Close any existing open menu by showing a null entry */ |
491 | window_show_menu(iapp->default_app, NULL, gtk_get_current_event_time(), iapp); |
492 | @@ -875,7 +903,7 @@ |
493 | if (xid == 0 || bamf_view_is_closed (BAMF_VIEW (iapp->active_window))) { |
494 | return; |
495 | } |
496 | - |
497 | + |
498 | GdkWMFunction functions; |
499 | if (!egg_xid_get_functions(xid, &functions)) { |
500 | g_debug("Unable to get MWM functions for: %d", xid); |
501 | @@ -889,11 +917,43 @@ |
502 | return; |
503 | } |
504 | |
505 | +static void |
506 | +connect_to_menu_signals (IndicatorAppmenu * iapp, WindowMenu * menus) |
507 | +{ |
508 | + g_return_if_fail(G_IS_OBJECT(menus)); |
509 | + |
510 | + /* Connect signals */ |
511 | + g_signal_connect(menus, |
512 | + WINDOW_MENU_SIGNAL_ENTRY_ADDED, |
513 | + G_CALLBACK(window_entry_added), |
514 | + iapp); |
515 | + g_signal_connect(menus, |
516 | + WINDOW_MENU_SIGNAL_ENTRY_REMOVED, |
517 | + G_CALLBACK(window_entry_removed), |
518 | + iapp); |
519 | + g_signal_connect(menus, |
520 | + WINDOW_MENU_SIGNAL_STATUS_CHANGED, |
521 | + G_CALLBACK(window_status_changed), |
522 | + iapp); |
523 | + g_signal_connect(menus, |
524 | + WINDOW_MENU_SIGNAL_SHOW_MENU, |
525 | + G_CALLBACK(window_show_menu), |
526 | + iapp); |
527 | + g_signal_connect(menus, |
528 | + WINDOW_MENU_SIGNAL_A11Y_UPDATE, |
529 | + G_CALLBACK(window_a11y_update), |
530 | + iapp); |
531 | +} |
532 | + |
533 | /* Switch applications, remove all the entires for the previous |
534 | one and add them for the new application */ |
535 | static void |
536 | switch_default_app (IndicatorAppmenu * iapp, WindowMenu * newdef, BamfWindow * active_window) |
537 | { |
538 | + if (iapp->mode == MODE_UNITY_ALL_MENUS) { |
539 | + return; |
540 | + } |
541 | + |
542 | if (iapp->default_app == newdef && iapp->default_app != NULL) { |
543 | /* We've got an app with menus and it hasn't changed. */ |
544 | |
545 | @@ -911,31 +971,15 @@ |
546 | |
547 | /* hide the entries that we're swapping out */ |
548 | indicator_object_set_visible (INDICATOR_OBJECT(iapp), FALSE); |
549 | - |
550 | - /* Disconnect signals */ |
551 | - if (iapp->sig_entry_added != 0) { |
552 | - g_signal_handler_disconnect(G_OBJECT(iapp->default_app), iapp->sig_entry_added); |
553 | - iapp->sig_entry_added = 0; |
554 | - } |
555 | - if (iapp->sig_entry_removed != 0) { |
556 | - g_signal_handler_disconnect(G_OBJECT(iapp->default_app), iapp->sig_entry_removed); |
557 | - iapp->sig_entry_removed = 0; |
558 | - } |
559 | - if (iapp->sig_status_changed != 0) { |
560 | - g_signal_handler_disconnect(G_OBJECT(iapp->default_app), iapp->sig_status_changed); |
561 | - iapp->sig_status_changed = 0; |
562 | - } |
563 | - if (iapp->sig_show_menu != 0) { |
564 | - g_signal_handler_disconnect(G_OBJECT(iapp->default_app), iapp->sig_show_menu); |
565 | - iapp->sig_show_menu = 0; |
566 | - } |
567 | - if (iapp->sig_a11y_update != 0) { |
568 | - g_signal_handler_disconnect(G_OBJECT(iapp->default_app), iapp->sig_a11y_update); |
569 | - iapp->sig_a11y_update = 0; |
570 | - } |
571 | - |
572 | - /* Default App is NULL, let's see if it needs replacement */ |
573 | - iapp->default_app = NULL; |
574 | + |
575 | + if (iapp->default_app) |
576 | + { |
577 | + /* Disconnect signals */ |
578 | + g_signal_handlers_disconnect_by_data(iapp->default_app, iapp); |
579 | + |
580 | + /* Default App is NULL, let's see if it needs replacement */ |
581 | + iapp->default_app = NULL; |
582 | + } |
583 | |
584 | /* Update the active window pointer -- may be NULL */ |
585 | switch_active_window(iapp, active_window); |
586 | @@ -944,28 +988,7 @@ |
587 | if (newdef != NULL) { |
588 | /* Switch */ |
589 | iapp->default_app = newdef; |
590 | - |
591 | - /* Connect signals */ |
592 | - iapp->sig_entry_added = g_signal_connect(G_OBJECT(iapp->default_app), |
593 | - WINDOW_MENU_SIGNAL_ENTRY_ADDED, |
594 | - G_CALLBACK(window_entry_added), |
595 | - iapp); |
596 | - iapp->sig_entry_removed = g_signal_connect(G_OBJECT(iapp->default_app), |
597 | - WINDOW_MENU_SIGNAL_ENTRY_REMOVED, |
598 | - G_CALLBACK(window_entry_removed), |
599 | - iapp); |
600 | - iapp->sig_status_changed = g_signal_connect(G_OBJECT(iapp->default_app), |
601 | - WINDOW_MENU_SIGNAL_STATUS_CHANGED, |
602 | - G_CALLBACK(window_status_changed), |
603 | - iapp); |
604 | - iapp->sig_show_menu = g_signal_connect(G_OBJECT(iapp->default_app), |
605 | - WINDOW_MENU_SIGNAL_SHOW_MENU, |
606 | - G_CALLBACK(window_show_menu), |
607 | - iapp); |
608 | - iapp->sig_a11y_update = g_signal_connect(G_OBJECT(iapp->default_app), |
609 | - WINDOW_MENU_SIGNAL_A11Y_UPDATE, |
610 | - G_CALLBACK(window_a11y_update), |
611 | - iapp); |
612 | + connect_to_menu_signals(iapp, iapp->default_app); |
613 | } |
614 | |
615 | /* show the entries that we're swapping in */ |
616 | @@ -982,6 +1005,53 @@ |
617 | return; |
618 | } |
619 | |
620 | +static void |
621 | +track_menus (IndicatorAppmenu * iapp, guint xid, WindowMenu * menus) |
622 | +{ |
623 | + g_return_if_fail(IS_WINDOW_MENU(menus)); |
624 | + |
625 | + g_hash_table_insert(iapp->apps, GUINT_TO_POINTER(xid), menus); |
626 | + |
627 | + if (iapp->mode == MODE_UNITY_ALL_MENUS) { |
628 | + connect_to_menu_signals(iapp, menus); |
629 | + } |
630 | +} |
631 | + |
632 | +static WindowMenu * |
633 | +ensure_menus (IndicatorAppmenu * iapp, BamfWindow * window) |
634 | +{ |
635 | + WindowMenu * menus = NULL; |
636 | + guint32 xid = 0; |
637 | + |
638 | + while (window != NULL && menus == NULL) { |
639 | + xid = bamf_window_get_xid(window); |
640 | + |
641 | + menus = g_hash_table_lookup(iapp->apps, GUINT_TO_POINTER(xid)); |
642 | + |
643 | + /* First look to see if we can get these from the |
644 | + GMenuModel access */ |
645 | + if (menus == NULL) { |
646 | + gchar * uniquename = bamf_window_get_utf8_prop (window, "_GTK_UNIQUE_BUS_NAME"); |
647 | + |
648 | + if (uniquename != NULL) { |
649 | + BamfApplication * app = bamf_matcher_get_application_for_window(iapp->matcher, window); |
650 | + |
651 | + menus = WINDOW_MENU(window_menu_model_new(app, window)); |
652 | + track_menus(iapp, xid, menus); |
653 | + } |
654 | + |
655 | + g_free(uniquename); |
656 | + } |
657 | + |
658 | + if (menus == NULL) { |
659 | + g_debug("Looking for parent window on XID %d", xid); |
660 | + window = bamf_window_get_transient(window); |
661 | + } |
662 | + } |
663 | + |
664 | + return menus; |
665 | +} |
666 | + |
667 | /* Recieve the signal that the window being shown |
668 | has now changed. */ |
669 | static void |
670 | @@ -1000,53 +1070,28 @@ |
671 | |
672 | IndicatorAppmenu * appmenu = INDICATOR_APPMENU(user_data); |
673 | |
674 | + if (window != NULL && appmenu->mode == MODE_UNITY_ALL_MENUS) { |
675 | + ensure_menus(appmenu, window); |
676 | + return; |
677 | + } |
678 | + |
679 | if (window != NULL && bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP) { |
680 | g_debug("Switching to menus from desktop"); |
681 | switch_default_app(appmenu, NULL, NULL); |
682 | return; |
683 | } |
684 | |
685 | - WindowMenu * menus = NULL; |
686 | - guint32 xid = 0; |
687 | - |
688 | - while (window != NULL && menus == NULL) { |
689 | - xid = bamf_window_get_xid(window); |
690 | - |
691 | - menus = g_hash_table_lookup(appmenu->apps, GUINT_TO_POINTER(xid)); |
692 | - |
693 | - /* First look to see if we can get these from the |
694 | - GMenuModel access */ |
695 | - if (menus == NULL) { |
696 | - gchar * uniquename = bamf_window_get_utf8_prop (window, "_GTK_UNIQUE_BUS_NAME"); |
697 | - |
698 | - if (uniquename != NULL) { |
699 | - BamfApplication * app = bamf_matcher_get_application_for_window(matcher, window); |
700 | - |
701 | - menus = WINDOW_MENU(window_menu_model_new(app, window)); |
702 | - |
703 | - g_hash_table_insert(appmenu->apps, GUINT_TO_POINTER(xid), menus); |
704 | - } |
705 | - |
706 | - g_free(uniquename); |
707 | - } |
708 | - |
709 | - if (menus == NULL) { |
710 | - g_debug("Looking for parent window on XID %d", xid); |
711 | - window = bamf_window_get_transient(window); |
712 | - } |
713 | - } |
714 | + WindowMenu * menus = ensure_menus (appmenu, window); |
715 | |
716 | /* Note: We're not using window here, but re-casting the |
717 | newwindow variable. Which means we stay where we were |
718 | but get the menus from parents. */ |
719 | - g_debug("Switching to menus from XID %d", xid); |
720 | + g_debug("Switching to menus from XID %d", newview ? bamf_window_get_xid(BAMF_WINDOW(newview)) : 0); |
721 | if (newview != NULL) { |
722 | switch_default_app(appmenu, menus, BAMF_WINDOW(newview)); |
723 | } else { |
724 | switch_default_app(appmenu, menus, NULL); |
725 | } |
726 | - |
727 | - return; |
728 | } |
729 | |
730 | /* Respond to the menus being destroyed. We need to deregister |
731 | @@ -1056,9 +1101,10 @@ |
732 | { |
733 | gboolean reload_menus = FALSE; |
734 | WindowMenu * wm = g_hash_table_lookup(iapp->apps, GUINT_TO_POINTER(windowid)); |
735 | - g_return_if_fail (wm != NULL); |
736 | + g_return_if_fail (IS_WINDOW_MENU(wm)); |
737 | |
738 | g_hash_table_steal(iapp->apps, GUINT_TO_POINTER(windowid)); |
739 | + g_signal_handlers_disconnect_by_data(wm, iapp); |
740 | |
741 | g_debug("Removing menus for %d", windowid); |
742 | |
743 | @@ -1094,7 +1140,7 @@ |
744 | WindowMenu * wm = WINDOW_MENU(window_menu_dbusmenu_new(windowid, sender, objectpath)); |
745 | g_return_val_if_fail(wm != NULL, FALSE); |
746 | |
747 | - g_hash_table_insert(iapp->apps, GUINT_TO_POINTER(windowid), wm); |
748 | + track_menus(iapp, windowid, wm); |
749 | |
750 | emit_signal(iapp, "WindowRegistered", |
751 | g_variant_new("(uso)", windowid, sender, objectpath)); |
752 | @@ -1271,7 +1317,6 @@ |
753 | { |
754 | entry->parent_object = user_data; |
755 | g_signal_emit_by_name(G_OBJECT(user_data), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED, entry); |
756 | - return; |
757 | } |
758 | |
759 | /* Pass up the entry removed event */ |
760 | @@ -1280,7 +1325,6 @@ |
761 | { |
762 | entry->parent_object = user_data; |
763 | g_signal_emit_by_name(G_OBJECT(user_data), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED, entry); |
764 | - return; |
765 | } |
766 | |
767 | /* Pass up the status changed event */ |
768 | @@ -1296,8 +1340,6 @@ |
769 | IndicatorObjectEntry * entry = (IndicatorObjectEntry *)entries->data; |
770 | g_signal_emit(G_OBJECT(iapp), INDICATOR_OBJECT_SIGNAL_SHOW_NOW_CHANGED_ID, 0, entry, show_now); |
771 | } |
772 | - |
773 | - return; |
774 | } |
775 | |
776 | /* Pass up the show menu event */ |
777 | @@ -1305,7 +1347,6 @@ |
778 | window_show_menu (WindowMenu * mw, IndicatorObjectEntry * entry, guint timestamp, gpointer user_data) |
779 | { |
780 | g_signal_emit_by_name(G_OBJECT(user_data), INDICATOR_OBJECT_SIGNAL_MENU_SHOW, entry, timestamp); |
781 | - return; |
782 | } |
783 | |
784 | /* Pass up the accessible string update */ |
785 | @@ -1313,7 +1354,6 @@ |
786 | window_a11y_update (WindowMenu * mw, IndicatorObjectEntry * entry, gpointer user_data) |
787 | { |
788 | g_signal_emit_by_name(G_OBJECT(user_data), INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE, entry); |
789 | - return; |
790 | } |
791 | |
792 | /********************** |
793 | |
794 | === modified file 'src/window-menu-dbusmenu.c' |
795 | --- src/window-menu-dbusmenu.c 2014-02-06 16:20:23 +0000 |
796 | +++ src/window-menu-dbusmenu.c 2015-02-03 10:10:58 +0000 |
797 | @@ -169,7 +169,7 @@ |
798 | IndicatorObjectEntry * entry; |
799 | entry = g_array_index(priv->entries, IndicatorObjectEntry *, 0); |
800 | g_array_remove_index(priv->entries, 0); |
801 | - if (should_signal) { |
802 | + if (should_signal) { |
803 | g_signal_emit_by_name(object, WINDOW_MENU_SIGNAL_ENTRY_REMOVED, entry, TRUE); |
804 | } |
805 | entry_free(entry); |
806 | @@ -196,15 +196,11 @@ |
807 | } |
808 | |
809 | if (priv->client != NULL) { |
810 | - g_signal_handlers_disconnect_by_func(G_OBJECT(priv->client), G_CALLBACK(root_changed), object); |
811 | - g_signal_handlers_disconnect_by_func(G_OBJECT(priv->client), G_CALLBACK(event_status), object); |
812 | - g_signal_handlers_disconnect_by_func(G_OBJECT(priv->client), G_CALLBACK(item_activate), object); |
813 | - g_signal_handlers_disconnect_by_func(G_OBJECT(priv->client), G_CALLBACK(status_changed), object); |
814 | - |
815 | + g_signal_handlers_disconnect_by_data(priv->client, object); |
816 | g_object_unref(G_OBJECT(priv->client)); |
817 | priv->client = NULL; |
818 | } |
819 | - |
820 | + |
821 | if (priv->props != NULL) { |
822 | g_object_unref(G_OBJECT(priv->props)); |
823 | priv->props = NULL; |
824 | @@ -513,8 +509,8 @@ |
825 | { |
826 | g_signal_handlers_disconnect_by_func(G_OBJECT(mi), G_CALLBACK(menu_entry_realized), user_data); |
827 | g_signal_handlers_disconnect_by_func(G_OBJECT(mi), G_CALLBACK(menu_entry_realized_child_added), user_data); |
828 | - g_signal_handlers_disconnect_matched (mi, G_SIGNAL_MATCH_FUNC, 0, 0, 0, menu_child_realized, NULL); |
829 | - g_signal_handlers_disconnect_matched (mi, G_SIGNAL_MATCH_FUNC, 0, 0, 0, menu_prop_changed, NULL); |
830 | + g_signal_handlers_disconnect_matched(mi, G_SIGNAL_MATCH_FUNC, 0, 0, 0, menu_child_realized, NULL); |
831 | + g_signal_handlers_disconnect_matched(mi, G_SIGNAL_MATCH_FUNC, 0, 0, 0, menu_prop_changed, NULL); |
832 | |
833 | return; |
834 | } |
835 | @@ -531,9 +527,7 @@ |
836 | |
837 | if (priv->root != NULL) { |
838 | dbusmenu_menuitem_foreach(priv->root, remove_menuitem_signals, user_data); |
839 | - |
840 | - g_signal_handlers_disconnect_by_func(G_OBJECT(priv->root), G_CALLBACK(menu_entry_added), user_data); |
841 | - g_signal_handlers_disconnect_by_func(G_OBJECT(priv->root), G_CALLBACK(menu_entry_removed), user_data); |
842 | + g_signal_handlers_disconnect_by_data(priv->root, user_data); |
843 | g_object_unref(priv->root); |
844 | } |
845 | |
846 | @@ -711,6 +705,7 @@ |
847 | WMEntry * wmentry = g_new0(WMEntry, 1); |
848 | wmentry->wm = wm; |
849 | IndicatorObjectEntry * entry = &wmentry->ioentry; |
850 | + entry->parent_window = priv->windowid; |
851 | |
852 | wmentry->mi = newentry; |
853 | g_object_ref(G_OBJECT(wmentry->mi)); |
854 | |
855 | === modified file 'src/window-menu-model.c' |
856 | --- src/window-menu-model.c 2013-11-19 10:20:17 +0000 |
857 | +++ src/window-menu-model.c 2015-02-03 10:10:58 +0000 |
858 | @@ -45,8 +45,6 @@ |
859 | /* Window Menus */ |
860 | GDBusMenuModel * win_menu_model; |
861 | GtkMenuBar * win_menu; |
862 | - gulong win_menu_insert; |
863 | - gulong win_menu_remove; |
864 | }; |
865 | |
866 | #define WINDOW_MENU_MODEL_GET_PRIVATE(o) \ |
867 | @@ -121,19 +119,10 @@ |
868 | g_clear_object(&menu->priv->application_menu.menu); |
869 | |
870 | /* Window Menus */ |
871 | - if (menu->priv->win_menu_insert != 0) { |
872 | - g_signal_handler_disconnect(menu->priv->win_menu, menu->priv->win_menu_insert); |
873 | - menu->priv->win_menu_insert = 0; |
874 | - } |
875 | - |
876 | - if (menu->priv->win_menu_remove != 0) { |
877 | - g_signal_handler_disconnect(menu->priv->win_menu, menu->priv->win_menu_remove); |
878 | - menu->priv->win_menu_remove = 0; |
879 | - } |
880 | - |
881 | g_clear_object(&menu->priv->win_menu_model); |
882 | |
883 | if (menu->priv->win_menu) { |
884 | + g_signal_handlers_disconnect_by_data(menu->priv->win_menu, menu); |
885 | gtk_widget_destroy (GTK_WIDGET (menu->priv->win_menu)); |
886 | g_object_unref (menu->priv->win_menu); |
887 | menu->priv->win_menu = NULL; |
888 | @@ -163,6 +152,7 @@ |
889 | g_return_if_fail(G_IS_MENU_MODEL(model)); |
890 | |
891 | menu->priv->app_menu_model = g_object_ref(model); |
892 | + menu->priv->application_menu.parent_window = menu->priv->xid; |
893 | |
894 | if (appname != NULL) { |
895 | menu->priv->application_menu.label = GTK_LABEL(gtk_label_new(appname)); |
896 | @@ -330,9 +320,7 @@ |
897 | { |
898 | WindowMenuEntry * entry = (WindowMenuEntry *)inentry; |
899 | |
900 | - g_signal_handlers_disconnect_by_func (entry->gmi, entry_label_notify, entry); |
901 | - g_signal_handlers_disconnect_by_func (entry->gmi, entry_sensitive_notify, entry); |
902 | - g_signal_handlers_disconnect_by_func (entry->gmi, entry_visible_notify, entry); |
903 | + g_signal_handlers_disconnect_by_data(entry->gmi, entry); |
904 | |
905 | g_clear_object(&entry->entry.label); |
906 | g_clear_object(&entry->entry.image); |
907 | @@ -350,9 +338,11 @@ |
908 | |
909 | entry->gmi = gmi; |
910 | |
911 | + entry->entry.parent_window = menu->priv->xid; |
912 | entry->entry.label = mi_find_label(GTK_WIDGET(gmi)); |
913 | entry->entry.image = mi_find_icon(GTK_WIDGET(gmi)); |
914 | entry->entry.menu = mi_find_menu(gmi); |
915 | + g_print("%s Setting entry %p paret as %u\n",G_STRFUNC, &entry->entry, entry->entry.parent_window); |
916 | |
917 | if (entry->entry.label == NULL && entry->entry.image == NULL) { |
918 | const gchar * label = gtk_menu_item_get_label(gmi); |
919 | @@ -365,7 +355,6 @@ |
920 | gtk_widget_show(GTK_WIDGET(entry->entry.label)); |
921 | g_signal_connect(G_OBJECT(gmi), "notify::label", G_CALLBACK(entry_label_notify), entry); |
922 | } |
923 | - |
924 | if (entry->entry.label != NULL) { |
925 | g_object_ref_sink(entry->entry.label); |
926 | } |
927 | @@ -430,14 +419,8 @@ |
928 | if (menu->priv->unity_actions) |
929 | gtk_widget_insert_action_group(GTK_WIDGET(menu->priv->win_menu), ACTION_MUX_PREFIX_UNITY, menu->priv->unity_actions); |
930 | |
931 | - menu->priv->win_menu_insert = g_signal_connect(G_OBJECT (menu->priv->win_menu), |
932 | - "insert", |
933 | - G_CALLBACK (item_inserted_cb), |
934 | - menu); |
935 | - menu->priv->win_menu_remove = g_signal_connect (G_OBJECT (menu->priv->win_menu), |
936 | - "remove", |
937 | - G_CALLBACK (item_removed_cb), |
938 | - menu); |
939 | + g_signal_connect(G_OBJECT(menu->priv->win_menu), "insert", G_CALLBACK (item_inserted_cb), menu); |
940 | + g_signal_connect(G_OBJECT(menu->priv->win_menu), "remove", G_CALLBACK (item_removed_cb), menu); |
941 | |
942 | GList * children = gtk_container_get_children(GTK_CONTAINER(menu->priv->win_menu)); |
943 | GList * child; |
FAILED: Continuous integration, rev:264 jenkins. qa.ubuntu. com/job/ indicator- appmenu- ci/23/ jenkins. qa.ubuntu. com/job/ indicator- appmenu- vivid-amd64- ci/1/console jenkins. qa.ubuntu. com/job/ indicator- appmenu- vivid-armhf- ci/1/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/indicator- appmenu- ci/23/rebuild
http://