[network-manager-applet] applet: Work around appindicator "show"/"hide" signals quirk



commit b9b256a0f668d5e9f00b514cb034b0c4973c41df
Author: Andrew Zaborowski <andrew zaborowski intel com>
Date:   Sat Nov 7 23:12:34 2020 +0100

    applet: Work around appindicator "show"/"hide" signals quirk
    
    The ubuntu version of libappindicator (also available on some other
    distros like arch) doesn't emit the "show" and "hide" signals as the
    code expects.  This results in issue #4.  Use one of the workarounds
    documented in
    https://bugs.launchpad.net/ubuntu/+source/libappindicator/+bug/522152 to
    at least get a signal when the menu pops up and request a single Wi-Fi
    scan to make up for the missing periodic scans.
    
    This commit includes a fix by @thaller ([1]).
    
    [1] https://gitlab.gnome.org/GNOME/network-manager-applet/-/merge_requests/89#note_964843
    
    https://gitlab.gnome.org/GNOME/network-manager-applet/-/merge_requests/89

 src/applet.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 src/applet.h |  1 +
 2 files changed, 44 insertions(+)
---
diff --git a/src/applet.c b/src/applet.c
index 88f4c9d19..c94adb5f6 100644
--- a/src/applet.c
+++ b/src/applet.c
@@ -82,6 +82,46 @@ applet_stop_wifi_scan (NMApplet *applet, gpointer unused)
        nm_clear_g_source (&applet->wifi_scan_id);
 }
 
+#ifdef WITH_APPINDICATOR
+/* Work around ubuntu libappindicator not emitting the "show"/"hide" signals,
+ * see https://bugs.launchpad.net/ubuntu/+source/libappindicator/+bug/522152.
+ * There will be no periodic Wi-Fi access point updates but at least there
+ * will be one each time the menu is opened.
+ */
+static void
+applet_menu_about_to_show_cb (NMApplet *applet, gpointer unused)
+{
+       applet_request_wifi_scan (applet);
+}
+
+static void
+applet_workaround_show_cb (NMApplet *applet, gpointer unused)
+{
+       GObject *menu_server;
+       GObject *root_menu_item;
+
+       g_object_get (applet->app_indicator, "dbus-menu-server", &menu_server, NULL);
+       g_object_get (menu_server, "root-node", &root_menu_item, NULL);
+
+       /* If libappindicator doesn't emit "show" and "hide" signals when the
+        * menu is opened/closed, there will be exactly one "show" signal when
+        * the menu is constructed.  Subscribe to DBusmenuMenuItem's
+        * "about-to-show" signal to work around this.  If we're receiving the
+        * "show" signal for the second time the workaround wasn't needed and
+        * we can undo it.
+        */
+       if (!applet->app_indicator_show_signal_received) {
+               applet->app_indicator_show_signal_received = TRUE;
+               g_signal_connect_swapped (root_menu_item, "about-to-show", G_CALLBACK 
(applet_menu_about_to_show_cb), applet);
+       } else {
+               GtkMenu *menu = app_indicator_get_menu (applet->app_indicator);
+
+               g_signal_handlers_disconnect_by_func (root_menu_item, applet_menu_about_to_show_cb, applet);
+               g_signal_handlers_disconnect_by_func (menu, applet_workaround_show_cb, applet);
+       }
+}
+#endif
+
 static inline NMADeviceClass *
 get_device_class (NMDevice *device, NMApplet *applet)
 {
@@ -1992,6 +2032,9 @@ applet_update_menu (gpointer user_data)
                        app_indicator_set_menu (applet->app_indicator, menu);
                        g_signal_connect_swapped (menu, "show", G_CALLBACK (applet_start_wifi_scan), applet);
                        g_signal_connect_swapped (menu, "hide", G_CALLBACK (applet_stop_wifi_scan), applet);
+
+                       /* Work around ubuntu libappindicator not emitting the above signals in runtime */
+                       g_signal_connect_swapped (menu, "show", G_CALLBACK (applet_workaround_show_cb), 
applet);
                }
 #else
                g_return_val_if_reached (G_SOURCE_REMOVE);
diff --git a/src/applet.h b/src/applet.h
index ebc775a5e..81327f699 100644
--- a/src/applet.h
+++ b/src/applet.h
@@ -115,6 +115,7 @@ typedef struct {
        /* Direct UI elements */
 #ifdef WITH_APPINDICATOR
        AppIndicator *  app_indicator;
+       bool            app_indicator_show_signal_received;
 #endif
        guint           update_menu_id;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]