61
61
GObject parent_instance;
66
GDBusMenuModel *app_menu;
67
GDBusMenuModel *menubar;
63
/* Cancelled on finalize */
64
GCancellable *cancellable;
66
/* GDBus shared session bus and D-Bus name of the app/indicator */
67
GDBusConnection *session;
68
gchar *unique_bus_name;
70
/* If this is an application, is_application will be set and
71
* 'application' and 'window' will contain the two action groups for
72
* the window that we are collecting.
74
* If this is an indicator, is_application will be false and the
75
* (singular) action group for the indicator will be in 'application'.
68
77
GDBusActionGroup *application;
69
78
GDBusActionGroup *window;
71
79
gboolean is_application;
81
/* The GMenuModel for the app menu.
83
* If this is an indicator, the indicator menu is stored here.
85
* app_menu_is_hud_aware is TRUE if we should send HudActiveChanged
86
* calls to app_menu_object_path when our use_count goes above 0.
88
GDBusMenuModel *app_menu;
89
gchar *app_menu_object_path;
90
gboolean app_menu_is_hud_aware;
92
/* Ditto for the menubar.
94
* If this is an indicator then these will all be unset.
96
GDBusMenuModel *menubar;
97
gchar *menubar_object_path;
98
gboolean menubar_is_hud_aware;
100
/* Boring details about the app/indicator we are showing. */
74
102
gchar *desktop_file;
106
/* Each time we see a new menumodel added we add it to 'models', start
107
* watching it for changes and add its contents to 'items', possibly
108
* finding more menumodels to do the same to.
110
* Each time an item is removed, we schedule an idle (in 'refresh_id')
111
* to wipe out all the 'items', disconnect signals from each model in
112
* 'models' and add them all back again.
114
* Searching just iterates over 'items'.
120
/* Keep track of our use_count in order to send signals to HUD-aware
121
* apps and indicators.
477
hud_menu_model_collector_active_changed (HudMenuModelCollector *collector,
480
if (collector->app_menu_is_hud_aware)
481
g_dbus_connection_call (collector->session, collector->unique_bus_name, collector->app_menu_object_path,
482
"com.canonical.hud.Awareness", "HudActiveChanged", g_variant_new ("(b)", active),
483
NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
485
if (collector->menubar_is_hud_aware)
486
g_dbus_connection_call (collector->session, collector->unique_bus_name, collector->app_menu_object_path,
487
"com.canonical.hud.Awareness", "HudActiveChanged", g_variant_new ("(b)", active),
488
NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
435
492
hud_menu_model_collector_use (HudSource *source)
437
494
HudMenuModelCollector *collector = HUD_MENU_MODEL_COLLECTOR (source);
496
if (collector->use_count == 0)
497
hud_menu_model_collector_active_changed (collector, TRUE);
439
499
collector->use_count++;
483
549
g_clear_object (&collector->application);
484
550
g_clear_object (&collector->window);
552
g_object_unref (collector->session);
553
g_free (collector->unique_bus_name);
554
g_free (collector->app_menu_object_path);
555
g_free (collector->menubar_object_path);
486
556
g_free (collector->prefix);
487
557
g_free (collector->desktop_file);
488
558
g_free (collector->icon);
513
584
class->finalize = hud_menu_model_collector_finalize;
588
hud_menu_model_collector_hud_awareness_cb (GObject *source,
589
GAsyncResult *result,
594
/* The goal of this function is to set either the
595
* app_menu_is_hud_aware or menubar_is_hud_aware flag (which we have a
596
* pointer to in user_data) to TRUE in the case that the remote
597
* appears to support the com.canonical.hud.Awareness protocol.
599
* If it supports it, the async call will be successful. In that
600
* case, we want to set *(gboolean *) user_data = TRUE;
602
* There are two cases that we don't want to do that write. The first
603
* is the event that the remote doesn't support the protocol. In that
604
* case, we will see an error when we inspect the result. The other
605
* is the case in which the flag to which user_data points no longer
606
* exists (ie: collector has been finalized). In this case, the
607
* cancellable will have been cancelled and we will also see an error.
609
* Long story short: If we get any error, just do nothing.
612
reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, NULL);
616
*(gboolean *) user_data = TRUE;
617
g_variant_unref (reply);
517
622
* hud_menu_model_collector_get:
518
623
* @window: a #BamfWindow
534
639
HudMenuModelCollector *collector;
535
640
gchar *unique_bus_name;
536
gchar *app_menu_object_path;
537
gchar *menubar_object_path;
538
641
gchar *application_object_path;
539
642
gchar *window_object_path;
540
643
GDBusConnection *session;
645
session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
542
650
unique_bus_name = bamf_window_get_utf8_prop (window, "_GTK_UNIQUE_BUS_NAME");
544
652
if (!unique_bus_name)
548
656
collector = g_object_new (HUD_TYPE_MENU_MODEL_COLLECTOR, NULL);
657
collector->session = session;
658
collector->unique_bus_name = unique_bus_name;
550
app_menu_object_path = bamf_window_get_utf8_prop (window, "_GTK_APP_MENU_OBJECT_PATH");
551
menubar_object_path = bamf_window_get_utf8_prop (window, "_GTK_MENUBAR_OBJECT_PATH");
660
collector->app_menu_object_path = bamf_window_get_utf8_prop (window, "_GTK_APP_MENU_OBJECT_PATH");
661
collector->menubar_object_path = bamf_window_get_utf8_prop (window, "_GTK_MENUBAR_OBJECT_PATH");
552
662
application_object_path = bamf_window_get_utf8_prop (window, "_GTK_APPLICATION_OBJECT_PATH");
553
663
window_object_path = bamf_window_get_utf8_prop (window, "_GTK_WINDOW_OBJECT_PATH");
555
session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
557
if (app_menu_object_path)
665
if (collector->app_menu_object_path)
559
collector->app_menu = g_dbus_menu_model_get (session, unique_bus_name, app_menu_object_path);
667
collector->app_menu = g_dbus_menu_model_get (session, unique_bus_name, collector->app_menu_object_path);
560
668
hud_menu_model_collector_add_model (collector, G_MENU_MODEL (collector->app_menu), NULL, NULL, NULL);
669
g_dbus_connection_call (session, unique_bus_name, collector->app_menu_object_path,
670
"com.canonical.hud.Awareness", "CheckAwareness",
671
NULL, G_VARIANT_TYPE_UNIT, G_DBUS_CALL_FLAGS_NONE, -1, collector->cancellable,
672
hud_menu_model_collector_hud_awareness_cb, &collector->app_menu_is_hud_aware);
563
if (menubar_object_path)
675
if (collector->menubar_object_path)
565
collector->menubar = g_dbus_menu_model_get (session, unique_bus_name, menubar_object_path);
677
collector->menubar = g_dbus_menu_model_get (session, unique_bus_name, collector->menubar_object_path);
566
678
hud_menu_model_collector_add_model (collector, G_MENU_MODEL (collector->menubar), NULL, NULL, NULL);
679
g_dbus_connection_call (session, unique_bus_name, collector->app_menu_object_path,
680
"com.canonical.hud.Awareness", "CheckAwareness",
681
NULL, G_VARIANT_TYPE_UNIT, G_DBUS_CALL_FLAGS_NONE, -1, collector->cancellable,
682
hud_menu_model_collector_hud_awareness_cb, &collector->menubar_is_hud_aware);
569
685
if (application_object_path)