diff --git a/shell/applets/BatteryApplet.qml b/shell/applets/BatteryApplet.qml index f71e3c2..da0fe2a 100644 --- a/shell/applets/BatteryApplet.qml +++ b/shell/applets/BatteryApplet.qml @@ -201,7 +201,13 @@ Column { } } - Separator {} + // Separator + Rectangle { + width: parent.width - 16 + height: 1 + anchors.horizontalCenter: parent.horizontalCenter + color: S.Theme.base03 + } // Rate row InfoRow { diff --git a/shell/applets/BluetoothApplet.qml b/shell/applets/BluetoothApplet.qml index 1f7eeb4..64d2584 100644 --- a/shell/applets/BluetoothApplet.qml +++ b/shell/applets/BluetoothApplet.qml @@ -9,13 +9,24 @@ Column { Repeater { model: S.BluetoothService.devices - delegate: HoverableListItem { + delegate: Item { id: entry required property var modelData required property int index readonly property bool _pending: S.BluetoothService.pendingMac === entry.modelData.mac + width: root.width + height: 32 + + Rectangle { + anchors.fill: parent + anchors.leftMargin: 4 + anchors.rightMargin: 4 + color: entryHover.hovered ? S.Theme.base02 : "transparent" + radius: S.Theme.radius + } + Text { id: btIcon anchors.left: parent.left @@ -72,9 +83,15 @@ Column { entry.opacity = 1 } - onTapped: { - if (!entry._pending) - S.BluetoothService.toggleDevice(entry.modelData.mac, !entry.modelData.connected); + HoverHandler { + id: entryHover + cursorShape: Qt.PointingHandCursor + } + TapHandler { + onTapped: { + if (!entry._pending) + S.BluetoothService.toggleDevice(entry.modelData.mac, !entry.modelData.connected); + } } } } diff --git a/shell/applets/CpuApplet.qml b/shell/applets/CpuApplet.qml index ca14fc5..d6e590a 100644 --- a/shell/applets/CpuApplet.qml +++ b/shell/applets/CpuApplet.qml @@ -149,7 +149,13 @@ Column { } } - Separator {} + // Process list separator + Rectangle { + width: root.width - 16 + height: 1 + anchors.horizontalCenter: parent.horizontalCenter + color: S.Theme.base03 + } Item { width: root.width diff --git a/shell/applets/GpuApplet.qml b/shell/applets/GpuApplet.qml index cf5b739..29fb82e 100644 --- a/shell/applets/GpuApplet.qml +++ b/shell/applets/GpuApplet.qml @@ -113,7 +113,12 @@ Column { } // VRAM section - Separator {} + Rectangle { + width: parent.width - 16 + height: 1 + anchors.horizontalCenter: parent.horizontalCenter + color: S.Theme.base03 + } Item { width: parent.width diff --git a/shell/applets/HoverableListItem.qml b/shell/applets/HoverableListItem.qml deleted file mode 100644 index 2bb7262..0000000 --- a/shell/applets/HoverableListItem.qml +++ /dev/null @@ -1,30 +0,0 @@ -import QtQuick -import "../services" as S - -Item { - id: root - - readonly property bool hovered: _hover.hovered - signal tapped - - width: parent?.width ?? 0 - height: 32 - - Rectangle { - anchors.fill: parent - anchors.leftMargin: 4 - anchors.rightMargin: 4 - color: root.hovered ? S.Theme.base02 : "transparent" - radius: S.Theme.radius - z: -1 - } - - HoverHandler { - id: _hover - cursorShape: Qt.PointingHandCursor - } - - TapHandler { - onTapped: root.tapped() - } -} diff --git a/shell/applets/MemoryApplet.qml b/shell/applets/MemoryApplet.qml index 61bca81..d62add2 100644 --- a/shell/applets/MemoryApplet.qml +++ b/shell/applets/MemoryApplet.qml @@ -115,7 +115,13 @@ Column { InfoRow { label: "Available"; value: root._fmt(root.availGb) } InfoRow { label: "Total"; value: root._fmt(root.totalGb) } - Separator {} + // Process list separator + Rectangle { + width: root.width - 16 + height: 1 + anchors.horizontalCenter: parent.horizontalCenter + color: S.Theme.base03 + } Item { width: root.width diff --git a/shell/applets/NetworkApplet.qml b/shell/applets/NetworkApplet.qml index 2344e7d..c2aa8e7 100644 --- a/shell/applets/NetworkApplet.qml +++ b/shell/applets/NetworkApplet.qml @@ -9,11 +9,22 @@ Column { Repeater { model: S.NetworkService.networks - delegate: HoverableListItem { + delegate: Item { id: entry required property var modelData required property int index + width: root.width + height: 32 + + Rectangle { + anchors.fill: parent + anchors.leftMargin: 4 + anchors.rightMargin: 4 + color: entryHover.hovered ? S.Theme.base02 : "transparent" + radius: S.Theme.radius + } + Text { id: netIcon anchors.left: parent.left @@ -51,11 +62,17 @@ Column { width: entry.modelData.signal >= 0 ? implicitWidth : 0 } - onTapped: { - if (entry.modelData.active) - S.NetworkService.disconnectNetwork(entry.modelData.uuid); - else - S.NetworkService.connectNetwork(entry.modelData.uuid); + HoverHandler { + id: entryHover + cursorShape: Qt.PointingHandCursor + } + TapHandler { + onTapped: { + if (entry.modelData.active) + S.NetworkService.disconnectNetwork(entry.modelData.uuid); + else + S.NetworkService.connectNetwork(entry.modelData.uuid); + } } } } diff --git a/shell/applets/Separator.qml b/shell/applets/Separator.qml deleted file mode 100644 index 365b9fc..0000000 --- a/shell/applets/Separator.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick -import "../services" as S - -Rectangle { - width: (parent?.width ?? 16) - 16 - height: 1 - anchors.horizontalCenter: parent?.horizontalCenter - color: S.Theme.base03 -} diff --git a/shell/applets/TemperatureApplet.qml b/shell/applets/TemperatureApplet.qml index 5216580..7ff7e44 100644 --- a/shell/applets/TemperatureApplet.qml +++ b/shell/applets/TemperatureApplet.qml @@ -200,7 +200,11 @@ Column { } // Per-device breakdown - Separator { + Rectangle { + width: root.width - 16 + height: 1 + anchors.horizontalCenter: parent.horizontalCenter + color: S.Theme.base03 visible: root.devices.length > 0 } diff --git a/shell/applets/VolumeApplet.qml b/shell/applets/VolumeApplet.qml index ec06e85..739f9d8 100644 --- a/shell/applets/VolumeApplet.qml +++ b/shell/applets/VolumeApplet.qml @@ -105,7 +105,12 @@ Column { visible: root.sinkList.length > 1 width: parent.width - Separator {} + Rectangle { + width: parent.width - 16 + height: 1 + anchors.horizontalCenter: parent.horizontalCenter + color: S.Theme.base03 + } Text { width: parent.width @@ -121,13 +126,22 @@ Column { Repeater { model: root.sinkList - delegate: HoverableListItem { + delegate: Item { required property var modelData + width: root.width height: 28 readonly property bool _active: modelData === root.sink + Rectangle { + anchors.fill: parent + anchors.leftMargin: 4 + anchors.rightMargin: 4 + color: deviceHover.hovered ? S.Theme.base02 : "transparent" + radius: S.Theme.radius + } + Text { anchors.left: parent.left anchors.leftMargin: 12 @@ -142,14 +156,25 @@ Column { elide: Text.ElideRight } - onTapped: Pipewire.preferredDefaultAudioSink = modelData + HoverHandler { + id: deviceHover + cursorShape: Qt.PointingHandCursor + } + + TapHandler { + onTapped: Pipewire.preferredDefaultAudioSink = modelData + } } } } // Streams section - Separator { + Rectangle { visible: root.streamList.length > 0 + width: parent.width - 16 + height: visible ? 1 : 0 + anchors.horizontalCenter: parent.horizontalCenter + color: S.Theme.base03 } Text { diff --git a/shell/applets/qmldir b/shell/applets/qmldir index caee41f..17b1759 100644 --- a/shell/applets/qmldir +++ b/shell/applets/qmldir @@ -7,12 +7,10 @@ CpuApplet 1.0 CpuApplet.qml DiskApplet 1.0 DiskApplet.qml GpuApplet 1.0 GpuApplet.qml HexWaveBackground 1.0 HexWaveBackground.qml -HoverableListItem 1.0 HoverableListItem.qml InfoRow 1.0 InfoRow.qml MemoryApplet 1.0 MemoryApplet.qml MprisApplet 1.0 MprisApplet.qml NetworkApplet 1.0 NetworkApplet.qml -Separator 1.0 Separator.qml NotifApplet 1.0 NotifApplet.qml TemperatureApplet 1.0 TemperatureApplet.qml VolumeApplet 1.0 VolumeApplet.qml diff --git a/shell/modules/BacklightModule.qml b/shell/modules/BacklightModule.qml index d3e0b5b..67ab22f 100644 --- a/shell/modules/BacklightModule.qml +++ b/shell/modules/BacklightModule.qml @@ -4,15 +4,17 @@ import "." as M import "../services" as S import "../applets" as C -M.OsdSection { +M.BarSection { id: root spacing: S.Theme.moduleSpacing opacity: S.Modules.backlight.enable && S.BacklightService.available ? 1 : 0 visible: opacity > 0 - _panelHovered: hoverPanel.panelHovered + tooltip: "" property int percent: S.BacklightService.percent + property bool _osdActive: false property bool _percentInit: false + readonly property bool _showPanel: root._hovered || hoverPanel.panelHovered || _osdActive onPercentChanged: { if (!_percentInit) { @@ -20,7 +22,18 @@ M.OsdSection { return; } if (percent > 0) - flashPanel(); + _flashPanel(); + } + + function _flashPanel() { + _osdActive = true; + _osdTimer.restart(); + } + + Timer { + id: _osdTimer + interval: 1500 + onTriggered: root._osdActive = false } WheelHandler { diff --git a/shell/modules/OsdSection.qml b/shell/modules/OsdSection.qml deleted file mode 100644 index bfddde8..0000000 --- a/shell/modules/OsdSection.qml +++ /dev/null @@ -1,25 +0,0 @@ -import QtQuick - -// Base component for bar modules with OSD flash behavior (Volume, Backlight). -// Panel shows on hover or when flashPanel() is called, auto-dismisses after 1.5s. -// Modules bind _panelHovered to their HoverPanel's panelHovered property. -BarSection { - id: root - tooltip: "" - - property bool _panelHovered: false - property bool _osdActive: false - readonly property bool _anyHover: root._hovered || _panelHovered - readonly property bool _showPanel: _anyHover || _osdActive - - function flashPanel() { - _osdActive = true; - _osdTimer.restart(); - } - - Timer { - id: _osdTimer - interval: 1500 - onTriggered: root._osdActive = false - } -} diff --git a/shell/modules/VolumeModule.qml b/shell/modules/VolumeModule.qml index ed193bc..8ce6ac8 100644 --- a/shell/modules/VolumeModule.qml +++ b/shell/modules/VolumeModule.qml @@ -5,10 +5,10 @@ import "." as M import "../services" as S import "../applets" as C -M.OsdSection { +M.BarSection { id: root spacing: S.Theme.moduleSpacing - _panelHovered: hoverPanel.panelHovered + tooltip: "" PwObjectTracker { objects: [Pipewire.defaultAudioSink, ...root._streamList] @@ -40,22 +40,36 @@ M.OsdSection { return streams; } + property bool _osdActive: false property bool _volumeInit: false property bool _mutedInit: false + readonly property bool _anyHover: root._hovered || hoverPanel.panelHovered + readonly property bool _showPanel: _anyHover || _osdActive onVolumeChanged: { if (!_volumeInit) { _volumeInit = true; return; } - flashPanel(); + _flashPanel(); } onMutedChanged: { if (!_mutedInit) { _mutedInit = true; return; } - flashPanel(); + _flashPanel(); + } + + function _flashPanel() { + _osdActive = true; + _osdTimer.restart(); + } + + Timer { + id: _osdTimer + interval: 1500 + onTriggered: root._osdActive = false } M.BarIcon { diff --git a/shell/modules/qmldir b/shell/modules/qmldir index a7934b5..8d09375 100644 --- a/shell/modules/qmldir +++ b/shell/modules/qmldir @@ -22,7 +22,6 @@ NetworkModule 1.0 NetworkModule.qml NotifCard 1.0 NotifCard.qml NotifPopup 1.0 NotifPopup.qml NotificationsModule 1.0 NotificationsModule.qml -OsdSection 1.0 OsdSection.qml OverviewBackdrop 1.0 OverviewBackdrop.qml PinnableSection 1.0 PinnableSection.qml PopupBackground 1.0 PopupBackground.qml