diff --git a/modules/Bluetooth.qml b/modules/Bluetooth.qml index 68181dc..f991349 100644 --- a/modules/Bluetooth.qml +++ b/modules/Bluetooth.qml @@ -63,14 +63,6 @@ M.BarSection { onTriggered: proc.running = true } - Process { - id: toggle - property string cmd: "" - command: ["bluetoothctl", "power", cmd] - onRunningChanged: if (!running && cmd !== "") - proc.running = true - } - M.BarIcon { icon: "\uF294" color: root.state === "off" ? M.Theme.base04 : root.accentColor @@ -84,31 +76,13 @@ M.BarSection { required property var bar - TapHandler { - acceptedButtons: Qt.LeftButton - cursorShape: Qt.PointingHandCursor - onTapped: { - menuLoader.active = !menuLoader.active; - M.FlyoutState.visible = false; - } - } + readonly property bool _anyHover: root._hovered || bluetoothMenu.panelHovered - TapHandler { - acceptedButtons: Qt.RightButton - onTapped: { - toggle.cmd = root.state === "off" ? "on" : "off"; - toggle.running = true; - } - } - - LazyLoader { - id: menuLoader - active: false - M.BluetoothMenu { - accentColor: root.accentColor - screen: root.bar.screen - anchorX: root.mapToGlobal(root.width / 2, 0).x - (QsWindow.window?.screen?.x ?? 0) - onDismissed: menuLoader.active = false - } + M.BluetoothMenu { + id: bluetoothMenu + showPanel: root._anyHover + screen: root.bar.screen + anchorItem: root + accentColor: root.accentColor } } diff --git a/modules/BluetoothMenu.qml b/modules/BluetoothMenu.qml index b6b97d3..565baf9 100644 --- a/modules/BluetoothMenu.qml +++ b/modules/BluetoothMenu.qml @@ -6,15 +6,18 @@ import "." as M M.HoverPanel { id: menuWindow - popupMode: true contentWidth: 250 + panelNamespace: "nova-bluetooth" + + onVisibleChanged: if (visible) + scanner.running = true property var _devices: [] property bool _btEnabled: true property Process _scanner: Process { id: scanner - running: true + running: false command: ["sh", "-c", "bluetoothctl show 2>/dev/null | awk '/Powered:/{print $2; exit}';" + "echo '---DEVICES---';" + "bluetoothctl devices Paired 2>/dev/null | while read -r _ mac name; do " + "info=$(bluetoothctl info \"$mac\" 2>/dev/null); " + "conn=$(echo \"$info\" | grep -c 'Connected: yes'); " + "bat=$(echo \"$info\" | awk -F'[(): ]' '/Battery Percentage/{for(i=1;i<=NF;i++) if($i+0==$i && $i!=\"\") print $i}'); " + "echo \"$mac:$conn:${bat:-}:$name\"; " + "done"] stdout: StdioCollector { onStreamFinished: { diff --git a/modules/Clock.qml b/modules/Clock.qml index 9ceeb6e..6506124 100644 --- a/modules/Clock.qml +++ b/modules/Clock.qml @@ -10,6 +10,5 @@ M.BarLabel { font.pixelSize: M.Theme.fontSize + 1 label: Qt.formatDateTime(clock.date, "ddd, dd. MMM HH:mm") - minText: "Mi., 00. Sep. 00:00" tooltip: Qt.formatDateTime(clock.date, "dddd, dd. MMMM yyyy\nHH:mm:ss") } diff --git a/modules/Volume.qml b/modules/Volume.qml index ed4088b..3283ed7 100644 --- a/modules/Volume.qml +++ b/modules/Volume.qml @@ -195,65 +195,70 @@ M.BarSection { id: deviceList width: parent.width - // Output devices - Rectangle { - width: parent.width - 16 - height: 1 - anchors.horizontalCenter: parent.horizontalCenter - color: M.Theme.base03 - } - - Text { + // Output devices — only shown when more than one exists + Column { + visible: root._sinkList.length > 1 width: parent.width - height: 24 - verticalAlignment: Text.AlignVCenter - leftPadding: 12 - text: "Output Devices" - color: M.Theme.base04 - font.pixelSize: M.Theme.fontSize - 1 - font.family: M.Theme.fontFamily - } - Repeater { - model: root._sinkList + Rectangle { + width: parent.width - 16 + height: 1 + anchors.horizontalCenter: parent.horizontalCenter + color: M.Theme.base03 + } - delegate: Item { - required property var modelData + Text { + width: parent.width + height: 24 + verticalAlignment: Text.AlignVCenter + leftPadding: 12 + text: "Output Devices" + color: M.Theme.base04 + font.pixelSize: M.Theme.fontSize - 1 + font.family: M.Theme.fontFamily + } - width: deviceList.width - height: 28 + Repeater { + model: root._sinkList - readonly property bool _active: modelData === root.sink + delegate: Item { + required property var modelData - Rectangle { - anchors.fill: parent - anchors.leftMargin: 4 - anchors.rightMargin: 4 - color: deviceHover.hovered ? M.Theme.base02 : "transparent" - radius: M.Theme.radius - } + width: deviceList.width + height: 28 - Text { - anchors.left: parent.left - anchors.leftMargin: 12 - anchors.right: parent.right - anchors.rightMargin: 12 - anchors.verticalCenter: parent.verticalCenter - text: modelData.description || modelData.name || "Unknown" - color: parent._active ? root.accentColor : M.Theme.base05 - font.pixelSize: M.Theme.fontSize - font.family: M.Theme.fontFamily - font.bold: parent._active - elide: Text.ElideRight - } + readonly property bool _active: modelData === root.sink - HoverHandler { - id: deviceHover - cursorShape: Qt.PointingHandCursor - } + Rectangle { + anchors.fill: parent + anchors.leftMargin: 4 + anchors.rightMargin: 4 + color: deviceHover.hovered ? M.Theme.base02 : "transparent" + radius: M.Theme.radius + } - TapHandler { - onTapped: Pipewire.preferredDefaultAudioSink = modelData + Text { + anchors.left: parent.left + anchors.leftMargin: 12 + anchors.right: parent.right + anchors.rightMargin: 12 + anchors.verticalCenter: parent.verticalCenter + text: modelData.description || modelData.name || "Unknown" + color: parent._active ? root.accentColor : M.Theme.base05 + font.pixelSize: M.Theme.fontSize + font.family: M.Theme.fontFamily + font.bold: parent._active + elide: Text.ElideRight + } + + HoverHandler { + id: deviceHover + cursorShape: Qt.PointingHandCursor + } + + TapHandler { + onTapped: Pipewire.preferredDefaultAudioSink = modelData + } } } }