From ba8a565cda09fc020bcfed62628688c58fb1c721 Mon Sep 17 00:00:00 2001 From: thomas Date: Thu, 27 Aug 2026 10:45:50 +0100 Subject: [PATCH] Feature: added scanner indicator --- .../modules/bar/BluetoothIndicator.qml | 71 +++++++++++++++++-- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/dotfiles/.config/quickshell/modules/bar/BluetoothIndicator.qml b/dotfiles/.config/quickshell/modules/bar/BluetoothIndicator.qml index 0b94c16..2f7235f 100644 --- a/dotfiles/.config/quickshell/modules/bar/BluetoothIndicator.qml +++ b/dotfiles/.config/quickshell/modules/bar/BluetoothIndicator.qml @@ -217,6 +217,29 @@ Item { ? Qt.rgba(Colors.primary.r, Colors.primary.g, Colors.primary.b, 0.18) : (rowMouse.containsMouse ? Colors.primary : "transparent") + // Colors.primaryText (used below whenever hovered) assumes a solid + // Colors.primary fill behind it — true for a hovered *disconnected* + // row, but a connected row's background stays the translucent tint + // above even while hovered, so primaryText (dark, meant for a bright + // solid fill) reads poorly against it. This hardcoded near-white + // (same one NetworkIndicator.qml/TailscaleIndicator.qml use for the + // same reason) is used instead for that one case. + readonly property color activeHoverColor: "#c9f0f0f0" + + // Hover-only outline, offset outside the row rather than drawn on + // its own edge — same treatment as NetworkIndicator.qml's NetworkRow. + // The lists this feeds are inset by 3px (see deviceListColumn and + // the Connected section below) so this has room without being + // cropped by deviceListFlick's clip. + Rectangle { + anchors.fill: parent + anchors.margins: -3 + radius: 0 + color: "transparent" + border.color: Colors.foreground + border.width: rowMouse.containsMouse ? 1 : 0 + } + RowLayout { id: rowContent anchors.left: parent.left @@ -234,7 +257,7 @@ Item { font.family: Appearance.iconFontFamilyRounded font.variableAxes: Appearance.iconFontAxes font.pixelSize: 14 - color: rowMouse.containsMouse ? Colors.primaryText : Colors.foreground + color: rowMouse.containsMouse ? (devRow.dev.connected ? devRow.activeHoverColor : Colors.primaryText) : Colors.foreground } ColumnLayout { @@ -248,7 +271,7 @@ Item { font.family: Appearance.fontFamily font.pixelSize: Appearance.fontSize font.bold: devRow.dev.connected - color: rowMouse.containsMouse ? Colors.primaryText : Colors.foreground + color: rowMouse.containsMouse ? (devRow.dev.connected ? devRow.activeHoverColor : Colors.primaryText) : Colors.foreground } Text { readonly property string statusText: { @@ -262,7 +285,7 @@ Item { text: statusText font.family: Appearance.fontFamily font.pixelSize: Appearance.fontSizeSmall - color: rowMouse.containsMouse ? Colors.primaryText : Colors.muted + color: rowMouse.containsMouse ? (devRow.dev.connected ? devRow.activeHoverColor : Colors.primaryText) : Colors.muted } } @@ -273,7 +296,7 @@ Item { font.family: Appearance.iconFontFamilyRounded font.variableAxes: Appearance.iconFontAxes font.pixelSize: 14 - color: rowMouse.containsMouse ? Colors.primaryText : Colors.muted + color: rowMouse.containsMouse ? (devRow.dev.connected ? devRow.activeHoverColor : Colors.primaryText) : Colors.muted } } @@ -374,6 +397,29 @@ Item { color: Colors.foreground } + // Spins continuously while root.adapter.discovering is + // true — a persistent "still searching" cue independent + // of the list itself, unlike the "Scanning for devices…" + // text below (which only shows while the device list is + // still empty). + Text { + id: scanSpinner + visible: root.adapter !== null && root.adapter.discovering + text: "progress_activity" + font.family: Appearance.iconFontFamilyRounded + font.variableAxes: Appearance.iconFontAxes + font.pixelSize: 16 + color: Colors.muted + + RotationAnimation on rotation { + running: scanSpinner.visible + loops: Animation.Infinite + from: 0 + to: 360 + duration: 900 + } + } + ToggleSwitch { visible: root.adapter !== null checked: root.adapter !== null && root.adapter.enabled @@ -413,7 +459,10 @@ Item { color: Colors.muted } Column { - width: parent.width + // Inset 3px on each side to match deviceListColumn + // below, so DeviceRow's hover halo has room here too. + x: 3 + width: parent.width - 6 spacing: 2 Repeater { model: root.connectedRows @@ -451,7 +500,17 @@ Item { Column { id: deviceListColumn - width: deviceListFlick.width + // Inset 3px on every side so DeviceRow's hover halo + // has room without being cropped by deviceListFlick's + // clip. Left/right needs the manual x/width shift + // (children bind width: parent.width, which ignores + // Column's own padding); top/bottom just needs + // padding, since that's along Column's own layout + // axis and Flickable's contentHeight tracks it. + x: 3 + width: deviceListFlick.width - 6 + topPadding: 3 + bottomPadding: 3 spacing: 6 Column {