Merge lp:~3v1n0/indicator-appmenu/all-menus-mode into lp:indicator-appmenu/15.04

Proposed by Marco Trevisan (Treviño)
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
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.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
265. By Marco Trevisan (Treviño)

gcov.m4: add more lcov supported versions

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
266. By Marco Trevisan (Treviño)

Bump version to 15.02

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
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.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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;

Subscribers

People subscribed via source and target branches