diff --git a/modules/Cpu.qml b/modules/Cpu.qml index 8159533..58d41e7 100644 --- a/modules/Cpu.qml +++ b/modules/Cpu.qml @@ -47,7 +47,6 @@ M.BarSection { property M.ProcessList _procs: M.ProcessList { sortBy: "cpu" active: root._showPanel - onProcessesChanged: hoverPanel.keepOpen(300) } on_AnyHoverChanged: { diff --git a/modules/HoverPanel.qml b/modules/HoverPanel.qml index 47f6dc3..d511214 100644 --- a/modules/HoverPanel.qml +++ b/modules/HoverPanel.qml @@ -31,7 +31,6 @@ PanelWindow { // Shared required property color accentColor - property string panelTitle: "" property string panelNamespace: "nova-panel" property real contentWidth: 220 @@ -50,7 +49,7 @@ PanelWindow { x: panelContainer.x + panelContainer.width - 28 y: 0 width: 28 - height: 24 + height: 28 } WlrLayershell.layer: WlrLayer.Overlay @@ -92,24 +91,6 @@ PanelWindow { } } - // Content-change grace: call keepOpen(ms) when panel content is about to - // resize/rebuild (session switch, device list change, etc.) to prevent the - // hover-drop-on-resize from closing the panel. - property bool _contentBusy: false - Timer { - id: _contentBusyTimer - onTriggered: { - root._contentBusy = false; - if (!root.showPanel && !root._grace && !root._pinned) - root._hideTimer.restart(); - } - } - function keepOpen(ms) { - _contentBusy = true; - _contentBusyTimer.interval = ms ?? 400; - _contentBusyTimer.restart(); - } - function _show() { _updatePosition(); _winVisible = true; @@ -133,7 +114,7 @@ PanelWindow { Timer { id: _hideTimer interval: 150 - onTriggered: if (!root.showPanel && !root._grace && !root._pinned && !root._contentBusy) + onTriggered: if (!root.showPanel && !root._grace && !root._pinned) root.dismiss() } @@ -211,7 +192,7 @@ PanelWindow { x: 0 y: -height width: root.contentWidth - height: _panelColumn.height + height: panelContent.height opacity: 0 // Popup mode: eat clicks on panel background so outer dismiss doesn't fire @@ -228,74 +209,51 @@ PanelWindow { } Column { - id: _panelColumn + id: panelContent width: root.contentWidth + } - // Header row: title (optional) + pin button — hover mode only - Item { - visible: !root.popupMode - width: parent.width - height: 24 + // Pin button — top-right corner, hover mode only + Item { + visible: !root.popupMode && (root.panelHovered || root._pinned) + x: parent.width - width - 4 + y: 4 + width: 20 + height: 20 + z: 2 + opacity: pinHover.hovered || root._pinned ? 1 : 0.35 - Text { - visible: root.panelTitle !== "" - anchors.left: parent.left - anchors.leftMargin: 12 - anchors.verticalCenter: parent.verticalCenter - text: root.panelTitle - color: root.accentColor - font.pixelSize: M.Theme.fontSize - 1 - font.bold: true - font.family: M.Theme.fontFamily - } - - Item { - visible: root.panelHovered || root._pinned - anchors.right: parent.right - anchors.rightMargin: 4 - anchors.verticalCenter: parent.verticalCenter - width: 20 - height: 20 - opacity: pinHover.hovered || root._pinned ? 1 : 0.35 - - Behavior on opacity { - NumberAnimation { - duration: 100 - } - } - - HoverHandler { - id: pinHover - } - - TapHandler { - cursorShape: Qt.PointingHandCursor - onTapped: { - root._pinned = !root._pinned; - if (!root._pinned && !root.showPanel) - root.dismiss(); - } - } - - Text { - anchors.centerIn: parent - text: root._pinned ? "\uDB81\uDC03" : "\uDB82\uDD31" - color: root._pinned ? root.accentColor : M.Theme.base04 - font.pixelSize: M.Theme.fontSize - 1 - font.family: M.Theme.iconFontFamily - - Behavior on color { - ColorAnimation { - duration: 100 - } - } - } + Behavior on opacity { + NumberAnimation { + duration: 100 } } - Column { - id: panelContent - width: parent.width + HoverHandler { + id: pinHover + } + + TapHandler { + cursorShape: Qt.PointingHandCursor + onTapped: { + root._pinned = !root._pinned; + if (!root._pinned && !root.showPanel) + root.dismiss(); + } + } + + Text { + anchors.centerIn: parent + text: root._pinned ? "\uDB81\uDC03" : "\uDB82\uDD31" + color: root._pinned ? root.accentColor : M.Theme.base04 + font.pixelSize: M.Theme.fontSize - 1 + font.family: M.Theme.iconFontFamily + + Behavior on color { + ColorAnimation { + duration: 100 + } + } } } } diff --git a/modules/Memory.qml b/modules/Memory.qml index c9df8bc..5d8b7a0 100644 --- a/modules/Memory.qml +++ b/modules/Memory.qml @@ -24,7 +24,6 @@ M.BarSection { property M.ProcessList _procs: M.ProcessList { sortBy: "mem" active: root._showPanel - onProcessesChanged: hoverPanel.keepOpen(300) } on_AnyHoverChanged: { diff --git a/modules/Mpris.qml b/modules/Mpris.qml index 4fd58ef..d24c39e 100644 --- a/modules/Mpris.qml +++ b/modules/Mpris.qml @@ -355,63 +355,45 @@ M.BarSection { } // Player switcher - Item { - width: parent.width - height: _players.length > 1 ? 28 : 0 - visible: _players.length > 1 + Row { + anchors.horizontalCenter: parent.horizontalCenter + height: 22 + spacing: 6 - Flickable { - id: _switcher - anchors.centerIn: parent - width: Math.min(_playerRow.implicitWidth, parent.width - 16) - height: 22 - contentWidth: _playerRow.implicitWidth - clip: true + Repeater { + model: root._players - Row { - id: _playerRow - height: 22 - spacing: 6 + delegate: Rectangle { + required property var modelData + required property int index - Repeater { - model: root._players + readonly property bool _active: index === root._playerIdx - delegate: Rectangle { - required property var modelData - required property int index + width: _pLabel.implicitWidth + 12 + height: 18 + radius: 9 + color: _active ? M.Theme.base02 : (pHover.hovered ? M.Theme.base02 : "transparent") + border.color: _active ? root.accentColor : M.Theme.base03 + border.width: _active ? 1 : 0 + anchors.verticalCenter: parent.verticalCenter - readonly property bool _active: index === root._playerIdx + Text { + id: _pLabel + anchors.centerIn: parent + text: modelData.identity ?? "Player" + color: _active ? root.accentColor : M.Theme.base04 + font.pixelSize: M.Theme.fontSize - 2 + font.family: M.Theme.fontFamily + font.bold: _active + } - width: _pLabel.implicitWidth + 12 - height: 18 - radius: 9 - color: _active ? M.Theme.base02 : (pHover.hovered ? M.Theme.base02 : "transparent") - border.color: _active ? root.accentColor : M.Theme.base03 - border.width: _active ? 1 : 0 - anchors.verticalCenter: parent.verticalCenter + HoverHandler { + id: pHover + cursorShape: Qt.PointingHandCursor + } - Text { - id: _pLabel - anchors.centerIn: parent - text: modelData.identity ?? "Player" - color: _active ? root.accentColor : M.Theme.base04 - font.pixelSize: M.Theme.fontSize - 2 - font.family: M.Theme.fontFamily - font.bold: _active - } - - HoverHandler { - id: pHover - cursorShape: Qt.PointingHandCursor - } - - TapHandler { - onTapped: { - root._playerIdx = index; - hoverPanel.keepOpen(400); - } - } - } + TapHandler { + onTapped: root._playerIdx = index } } } diff --git a/modules/Network.qml b/modules/Network.qml index 033c0ab..f0d3865 100644 --- a/modules/Network.qml +++ b/modules/Network.qml @@ -98,12 +98,12 @@ M.BarSection { required property var bar - readonly property bool _anyHover: root._hovered || networkMenu.panelHovered + readonly property bool _anyHover: root._hovered || networkMenu.panelHovered || networkMenu._busy M.NetworkMenu { id: networkMenu showPanel: root._anyHover - screen: QsWindow.window?.screen ?? null + screen: root.bar.screen anchorItem: root accentColor: root.accentColor } diff --git a/modules/NetworkMenu.qml b/modules/NetworkMenu.qml index 529458e..ad493a2 100644 --- a/modules/NetworkMenu.qml +++ b/modules/NetworkMenu.qml @@ -12,6 +12,8 @@ M.HoverPanel { onVisibleChanged: if (visible) scanner.running = true + readonly property bool _busy: connectProc.running || disconnectProc.running || radioProc.running + function triggerRefresh() { if (visible) scanner.running = true; @@ -83,30 +85,24 @@ M.HoverPanel { id: radioProc property string _state: "" command: ["nmcli", "radio", "wifi", _state] - onRunningChanged: if (!running) { - scanner.running = true; - menuWindow.keepOpen(500); - } + onRunningChanged: if (!running) + scanner.running = true } property Process _connectProc: Process { id: connectProc property string uuid: "" command: ["nmcli", "connection", "up", uuid] - onRunningChanged: if (!running) { - scanner.running = true; - menuWindow.keepOpen(500); - } + onRunningChanged: if (!running) + scanner.running = true } property Process _disconnectProc: Process { id: disconnectProc property string uuid: "" command: ["nmcli", "connection", "down", uuid] - onRunningChanged: if (!running) { - scanner.running = true; - menuWindow.keepOpen(500); - } + onRunningChanged: if (!running) + scanner.running = true } // Wi-Fi radio toggle header diff --git a/modules/Volume.qml b/modules/Volume.qml index 7166207..3283ed7 100644 --- a/modules/Volume.qml +++ b/modules/Volume.qml @@ -213,7 +213,7 @@ M.BarSection { verticalAlignment: Text.AlignVCenter leftPadding: 12 text: "Output Devices" - color: root.accentColor + color: M.Theme.base04 font.pixelSize: M.Theme.fontSize - 1 font.family: M.Theme.fontFamily } @@ -279,7 +279,7 @@ M.BarSection { verticalAlignment: Text.AlignVCenter leftPadding: 12 text: "Applications" - color: root.accentColor + color: M.Theme.base04 font.pixelSize: M.Theme.fontSize - 1 font.family: M.Theme.fontFamily }