[gnome-shell] status/network: Request scans while wireless menu is open



commit 84c33157a29d6d406fe91822504a1e38e8419925
Author: Florian Müllner <fmuellner gnome org>
Date:   Sat Aug 6 05:01:20 2022 +0200

    status/network: Request scans while wireless menu is open
    
    We want the list to keep updating, so periodically request scans
    from NetworkManager. The code follows what Settings does in its
    wifi panel, including the used interval.
    
    There's a cute little spinner in the menu header now, to indicate
    an ongoing scan.
    
    Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2408>

 js/ui/status/network.js | 58 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)
---
diff --git a/js/ui/status/network.js b/js/ui/status/network.js
index 098727f910..aef2373fb8 100644
--- a/js/ui/status/network.js
+++ b/js/ui/status/network.js
@@ -8,6 +8,7 @@ const MessageTray = imports.ui.messageTray;
 const ModemManager = imports.misc.modemManager;
 const Util = imports.misc.util;
 
+const {Spinner} = imports.ui.animation;
 const {QuickMenuToggle, SystemIndicator} = imports.ui.quickSettings;
 
 const {loadInterfaceXML} = imports.misc.fileUtils;
@@ -16,7 +17,9 @@ const {registerDestroyableType} = imports.misc.signalTracker;
 Gio._promisify(Gio.DBusConnection.prototype, 'call');
 Gio._promisify(NM.Client, 'new_async');
 Gio._promisify(NM.Client.prototype, 'check_connectivity_async');
+Gio._promisify(NM.DeviceWifi.prototype, 'request_scan_async');
 
+const WIFI_SCAN_FREQUENCY = 15;
 const MAX_VISIBLE_NETWORKS = 8;
 
 // small optimization, to avoid using [] all the time
@@ -1698,7 +1701,17 @@ class NMWirelessToggle extends NMDeviceToggle {
             this, 'menu-enabled',
             GObject.BindingFlags.INVERT_BOOLEAN);
 
+        this._scanningSpinner = new Spinner(16);
+
+        this.menu.connectObject('open-state-changed', (m, isOpen) => {
+            if (isOpen)
+                this._startScanning();
+            else
+                this._stopScanning();
+        });
+
         this.menu.setHeader('network-wireless-symbolic', _('Wi–Fi'));
+        this.menu.addHeaderSuffix(this._scanningSpinner);
         this.menu.addSettingsAction(_('All Networks'),
             'gnome-wifi-panel.desktop');
     }
@@ -1722,6 +1735,51 @@ class NMWirelessToggle extends NMDeviceToggle {
             this._client.wireless_enabled = !this._client.wireless_enabled;
     }
 
+    async _scanDevice(device) {
+        const {lastScan} = device;
+        await device.request_scan_async(null);
+
+        // Wait for the lastScan property to update, which
+        // indicates the end of the scan
+        return new Promise(resolve => {
+            GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1500, () => {
+                if (device.lastScan === lastScan)
+                    return GLib.SOURCE_CONTINUE;
+
+                resolve();
+                return GLib.SOURCE_REMOVE;
+            });
+        });
+    }
+
+    async _scanDevices() {
+        if (!this._client.wireless_enabled)
+            return;
+
+        this._scanningSpinner.play();
+
+        const devices = [...this._items.keys()];
+        await Promise.all(
+            devices.map(d => this._scanDevice(d)));
+
+        this._scanningSpinner.stop();
+    }
+
+    _startScanning() {
+        this._scanTimeoutId = GLib.timeout_add_seconds(
+            GLib.PRIORITY_DEFAULT, WIFI_SCAN_FREQUENCY, () => {
+                this._scanDevices().catch(logError);
+                return GLib.SOURCE_CONTINUE;
+            });
+        this._scanDevices().catch(logError);
+    }
+
+    _stopScanning() {
+        if (this._scanTimeoutId)
+            GLib.source_remove(this._scanTimeoutId);
+        delete this._scanTimeoutId;
+    }
+
     _createDeviceMenuItem(device) {
         return new NMWirelessDeviceItem(this._client, device);
     }


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