From c517997922d7ed7917e9cd64cc6a41c49759145b Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Mon, 18 May 2026 20:47:30 +0200 Subject: [PATCH] Spinning when scanning --- shell/Ui/PillButton.qml | 12 +++- shell/plugins/bar/widgets/bluetoothPanel.qml | 11 +--- shell/plugins/bar/widgets/networkPanel.qml | 59 +++++++++++--------- 3 files changed, 45 insertions(+), 37 deletions(-) diff --git a/shell/Ui/PillButton.qml b/shell/Ui/PillButton.qml index cf5bdc49..34b81f08 100644 --- a/shell/Ui/PillButton.qml +++ b/shell/Ui/PillButton.qml @@ -18,6 +18,7 @@ Rectangle { property real fontSize: 12 property real iconSize: 14 property real iconRotation: 0 + property bool iconSpinning: false property real horizontalPadding: 10 property real verticalPadding: 6 property bool active: false @@ -112,14 +113,23 @@ Rectangle { spacing: 8 Text { + id: iconLabel visible: root.iconText !== "" text: root.iconText color: root.foreground font.family: root.fontFamily font.pixelSize: root.iconSize - rotation: root.iconRotation + rotation: root.iconSpinning ? 0 : root.iconRotation transformOrigin: Item.Center anchors.verticalCenter: parent.verticalCenter + + RotationAnimation on rotation { + from: 0 + to: 360 + duration: 900 + loops: Animation.Infinite + running: root.iconSpinning + } } Text { diff --git a/shell/plugins/bar/widgets/bluetoothPanel.qml b/shell/plugins/bar/widgets/bluetoothPanel.qml index 51986fae..a5e10c6c 100644 --- a/shell/plugins/bar/widgets/bluetoothPanel.qml +++ b/shell/plugins/bar/widgets/bluetoothPanel.qml @@ -415,21 +415,12 @@ Item { HeaderPill { pillIndex: 0 - property real scanRotation: 0 iconText: "󰑐" - iconRotation: root.adapter && root.adapter.discovering ? scanRotation : 0 + iconSpinning: root.adapter && root.adapter.discovering tooltipText: !root.adapter ? "" : !root.adapter.enabled ? "Bluetooth is off" : root.adapter.discovering ? "Stop scanning" : "Scan for devices" pillEnabled: root.adapter !== null && root.adapter.enabled onActivated: if (root.adapter) root.adapter.discovering = !root.adapter.discovering - - NumberAnimation on scanRotation { - from: 0 - to: 360 - duration: 900 - loops: Animation.Infinite - running: root.adapter && root.adapter.discovering - } } HeaderPill { diff --git a/shell/plugins/bar/widgets/networkPanel.qml b/shell/plugins/bar/widgets/networkPanel.qml index 3c3a9762..6617526f 100644 --- a/shell/plugins/bar/widgets/networkPanel.qml +++ b/shell/plugins/bar/widgets/networkPanel.qml @@ -77,7 +77,7 @@ Item { // — OnDemand only grants focus on click/hover. onPopupOpenChanged: { if (popupOpen) { - refresh() + refresh(true) selectedIndex = wifiNetworks.length > 0 ? 0 : -1 focusSection = "dns" var idx = dnsProviders.indexOf(dnsProvider) @@ -215,7 +215,8 @@ iwctl known-networks list 2>/dev/null \\ return "󰤮" } - function refresh() { + function refresh(scanWifi) { + if (scanWifi === undefined) scanWifi = false if (!detailsProc.running) detailsProc.running = true if (!dnsProc.running) { dnsProc.command = ["bash", "-lc", root.dnsCommand("")] @@ -223,10 +224,38 @@ iwctl known-networks list 2>/dev/null \\ } if (!wifiProc.running) { scanning = true + wifiProc.command = ["bash", "-c", root.wifiScanScript(scanWifi)] wifiProc.running = true } } + function wifiScanScript(scanWifi) { + return ` +station=$(iwctl station list 2>/dev/null | sed -e 's/\\x1b\\[[0-9;]*m//g' | awk '/^[[:space:]]*wl/ { print $1; exit }') +[[ -z $station ]] && exit 0 +echo STATION_AVAILABLE +${scanWifi ? 'iwctl station "$station" scan >/dev/null 2>&1 || true' : ''} +iwctl station "$station" get-networks rssi-dbms 2>/dev/null \\ + | sed -e 's/\\x1b\\[[0-9;]*m//g' \\ + | awk ' + NR <= 4 { next } + /^[[:space:]]*$/ { next } + { + connected = (substr($0, 1, 4) ~ />/) ? 1 : 0 + line = $0 + sub(/^[[:space:]]*>?[[:space:]]+/, "", line) + sub(/[[:space:]]+$/, "", line) + n = split(line, parts, /[[:space:]]{2,}/) + if (n < 3) next + ssid = parts[1] + security = parts[n-1] + dbm = parts[n] / 100 + signal = (dbm >= -50) ? 100 : (dbm <= -100) ? 0 : int(2 * (dbm + 100)) + printf "%d\\t%s\\t%d\\t%s\\n", connected, ssid, signal, security + }' +` + } + function formatSpeed(mbps) { var v = parseInt(mbps, 10) if (!v || v < 0) return "" @@ -454,29 +483,6 @@ fi // iwctl's table layout starts each row with one, which breaks naive parsing. Process { id: wifiProc - command: ["bash", "-c", ` -station=$(iwctl station list 2>/dev/null | sed -e 's/\\x1b\\[[0-9;]*m//g' | awk '/^[[:space:]]*wl/ { print $1; exit }') -[[ -z $station ]] && exit 0 -echo STATION_AVAILABLE -iwctl station "$station" get-networks rssi-dbms 2>/dev/null \\ - | sed -e 's/\\x1b\\[[0-9;]*m//g' \\ - | awk ' - NR <= 4 { next } - /^[[:space:]]*$/ { next } - { - connected = (substr($0, 1, 4) ~ />/) ? 1 : 0 - line = $0 - sub(/^[[:space:]]*>?[[:space:]]+/, "", line) - sub(/[[:space:]]+$/, "", line) - n = split(line, parts, /[[:space:]]{2,}/) - if (n < 3) next - ssid = parts[1] - security = parts[n-1] - dbm = parts[n] / 100 - signal = (dbm >= -50) ? 100 : (dbm <= -100) ? 0 : int(2 * (dbm + 100)) - printf "%d\\t%s\\t%d\\t%s\\n", connected, ssid, signal, security - }' -`] stdout: StdioCollector { waitForEnd: true onStreamFinished: root.updateWifi(text) @@ -701,6 +707,7 @@ iwctl station "$station" get-networks rssi-dbms 2>/dev/null \\ anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter iconText: "󰑐" + iconSpinning: root.scanning tooltipText: "Refresh" tooltipBackground: root.bar.background tooltipForeground: root.bar.foreground @@ -709,7 +716,7 @@ iwctl station "$station" get-networks rssi-dbms 2>/dev/null \\ verticalPadding: 4 iconSize: 14 active: root.scanning - onClicked: root.refresh() + onClicked: root.refresh(true) } }