Compare commits

..
7 changed files with 87 additions and 153 deletions

View file

@ -47,7 +47,6 @@ M.BarSection {
property M.ProcessList _procs: M.ProcessList { property M.ProcessList _procs: M.ProcessList {
sortBy: "cpu" sortBy: "cpu"
active: root._showPanel active: root._showPanel
onProcessesChanged: hoverPanel.keepOpen(300)
} }
on_AnyHoverChanged: { on_AnyHoverChanged: {

View file

@ -31,7 +31,6 @@ PanelWindow {
// Shared // Shared
required property color accentColor required property color accentColor
property string panelTitle: ""
property string panelNamespace: "nova-panel" property string panelNamespace: "nova-panel"
property real contentWidth: 220 property real contentWidth: 220
@ -50,7 +49,7 @@ PanelWindow {
x: panelContainer.x + panelContainer.width - 28 x: panelContainer.x + panelContainer.width - 28
y: 0 y: 0
width: 28 width: 28
height: 24 height: 28
} }
WlrLayershell.layer: WlrLayer.Overlay 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() { function _show() {
_updatePosition(); _updatePosition();
_winVisible = true; _winVisible = true;
@ -133,7 +114,7 @@ PanelWindow {
Timer { Timer {
id: _hideTimer id: _hideTimer
interval: 150 interval: 150
onTriggered: if (!root.showPanel && !root._grace && !root._pinned && !root._contentBusy) onTriggered: if (!root.showPanel && !root._grace && !root._pinned)
root.dismiss() root.dismiss()
} }
@ -211,7 +192,7 @@ PanelWindow {
x: 0 x: 0
y: -height y: -height
width: root.contentWidth width: root.contentWidth
height: _panelColumn.height height: panelContent.height
opacity: 0 opacity: 0
// Popup mode: eat clicks on panel background so outer dismiss doesn't fire // Popup mode: eat clicks on panel background so outer dismiss doesn't fire
@ -228,74 +209,51 @@ PanelWindow {
} }
Column { Column {
id: _panelColumn id: panelContent
width: root.contentWidth width: root.contentWidth
}
// Header row: title (optional) + pin button hover mode only // Pin button top-right corner, hover mode only
Item { Item {
visible: !root.popupMode visible: !root.popupMode && (root.panelHovered || root._pinned)
width: parent.width x: parent.width - width - 4
height: 24 y: 4
width: 20
height: 20
z: 2
opacity: pinHover.hovered || root._pinned ? 1 : 0.35
Text { Behavior on opacity {
visible: root.panelTitle !== "" NumberAnimation {
anchors.left: parent.left duration: 100
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
}
}
}
} }
} }
Column { HoverHandler {
id: panelContent id: pinHover
width: parent.width }
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
}
}
} }
} }
} }

View file

@ -24,7 +24,6 @@ M.BarSection {
property M.ProcessList _procs: M.ProcessList { property M.ProcessList _procs: M.ProcessList {
sortBy: "mem" sortBy: "mem"
active: root._showPanel active: root._showPanel
onProcessesChanged: hoverPanel.keepOpen(300)
} }
on_AnyHoverChanged: { on_AnyHoverChanged: {

View file

@ -355,63 +355,45 @@ M.BarSection {
} }
// Player switcher // Player switcher
Item { Row {
width: parent.width anchors.horizontalCenter: parent.horizontalCenter
height: _players.length > 1 ? 28 : 0 height: 22
visible: _players.length > 1 spacing: 6
Flickable { Repeater {
id: _switcher model: root._players
anchors.centerIn: parent
width: Math.min(_playerRow.implicitWidth, parent.width - 16)
height: 22
contentWidth: _playerRow.implicitWidth
clip: true
Row { delegate: Rectangle {
id: _playerRow required property var modelData
height: 22 required property int index
spacing: 6
Repeater { readonly property bool _active: index === root._playerIdx
model: root._players
delegate: Rectangle { width: _pLabel.implicitWidth + 12
required property var modelData height: 18
required property int index 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 HoverHandler {
height: 18 id: pHover
radius: 9 cursorShape: Qt.PointingHandCursor
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
Text { TapHandler {
id: _pLabel onTapped: root._playerIdx = index
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);
}
}
}
} }
} }
} }

View file

@ -98,12 +98,12 @@ M.BarSection {
required property var bar required property var bar
readonly property bool _anyHover: root._hovered || networkMenu.panelHovered readonly property bool _anyHover: root._hovered || networkMenu.panelHovered || networkMenu._busy
M.NetworkMenu { M.NetworkMenu {
id: networkMenu id: networkMenu
showPanel: root._anyHover showPanel: root._anyHover
screen: QsWindow.window?.screen ?? null screen: root.bar.screen
anchorItem: root anchorItem: root
accentColor: root.accentColor accentColor: root.accentColor
} }

View file

@ -12,6 +12,8 @@ M.HoverPanel {
onVisibleChanged: if (visible) onVisibleChanged: if (visible)
scanner.running = true scanner.running = true
readonly property bool _busy: connectProc.running || disconnectProc.running || radioProc.running
function triggerRefresh() { function triggerRefresh() {
if (visible) if (visible)
scanner.running = true; scanner.running = true;
@ -83,30 +85,24 @@ M.HoverPanel {
id: radioProc id: radioProc
property string _state: "" property string _state: ""
command: ["nmcli", "radio", "wifi", _state] command: ["nmcli", "radio", "wifi", _state]
onRunningChanged: if (!running) { onRunningChanged: if (!running)
scanner.running = true; scanner.running = true
menuWindow.keepOpen(500);
}
} }
property Process _connectProc: Process { property Process _connectProc: Process {
id: connectProc id: connectProc
property string uuid: "" property string uuid: ""
command: ["nmcli", "connection", "up", uuid] command: ["nmcli", "connection", "up", uuid]
onRunningChanged: if (!running) { onRunningChanged: if (!running)
scanner.running = true; scanner.running = true
menuWindow.keepOpen(500);
}
} }
property Process _disconnectProc: Process { property Process _disconnectProc: Process {
id: disconnectProc id: disconnectProc
property string uuid: "" property string uuid: ""
command: ["nmcli", "connection", "down", uuid] command: ["nmcli", "connection", "down", uuid]
onRunningChanged: if (!running) { onRunningChanged: if (!running)
scanner.running = true; scanner.running = true
menuWindow.keepOpen(500);
}
} }
// Wi-Fi radio toggle header // Wi-Fi radio toggle header

View file

@ -213,7 +213,7 @@ M.BarSection {
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
leftPadding: 12 leftPadding: 12
text: "Output Devices" text: "Output Devices"
color: root.accentColor color: M.Theme.base04
font.pixelSize: M.Theme.fontSize - 1 font.pixelSize: M.Theme.fontSize - 1
font.family: M.Theme.fontFamily font.family: M.Theme.fontFamily
} }
@ -279,7 +279,7 @@ M.BarSection {
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
leftPadding: 12 leftPadding: 12
text: "Applications" text: "Applications"
color: root.accentColor color: M.Theme.base04
font.pixelSize: M.Theme.fontSize - 1 font.pixelSize: M.Theme.fontSize - 1
font.family: M.Theme.fontFamily font.family: M.Theme.fontFamily
} }