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>
This commit is contained in:
Florian Müllner 2022-08-06 05:01:20 +02:00 committed by Marge Bot
parent 81eb7db5a0
commit 84c33157a2

View File

@ -8,6 +8,7 @@ const MessageTray = imports.ui.messageTray;
const ModemManager = imports.misc.modemManager; const ModemManager = imports.misc.modemManager;
const Util = imports.misc.util; const Util = imports.misc.util;
const {Spinner} = imports.ui.animation;
const {QuickMenuToggle, SystemIndicator} = imports.ui.quickSettings; const {QuickMenuToggle, SystemIndicator} = imports.ui.quickSettings;
const {loadInterfaceXML} = imports.misc.fileUtils; const {loadInterfaceXML} = imports.misc.fileUtils;
@ -16,7 +17,9 @@ const {registerDestroyableType} = imports.misc.signalTracker;
Gio._promisify(Gio.DBusConnection.prototype, 'call'); Gio._promisify(Gio.DBusConnection.prototype, 'call');
Gio._promisify(NM.Client, 'new_async'); Gio._promisify(NM.Client, 'new_async');
Gio._promisify(NM.Client.prototype, 'check_connectivity_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; const MAX_VISIBLE_NETWORKS = 8;
// small optimization, to avoid using [] all the time // small optimization, to avoid using [] all the time
@ -1698,7 +1701,17 @@ class NMWirelessToggle extends NMDeviceToggle {
this, 'menu-enabled', this, 'menu-enabled',
GObject.BindingFlags.INVERT_BOOLEAN); 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', _('WiFi')); this.menu.setHeader('network-wireless-symbolic', _('WiFi'));
this.menu.addHeaderSuffix(this._scanningSpinner);
this.menu.addSettingsAction(_('All Networks'), this.menu.addSettingsAction(_('All Networks'),
'gnome-wifi-panel.desktop'); 'gnome-wifi-panel.desktop');
} }
@ -1722,6 +1735,51 @@ class NMWirelessToggle extends NMDeviceToggle {
this._client.wireless_enabled = !this._client.wireless_enabled; 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) { _createDeviceMenuItem(device) {
return new NMWirelessDeviceItem(this._client, device); return new NMWirelessDeviceItem(this._client, device);
} }