62 lines
2.1 KiB
QML
62 lines
2.1 KiB
QML
// modules/BluetoothWidget.qml - ᛒ status / device alias
|
|
// Uses bluetoothctl via a polled Process (no BlueZ QML bindings in QS yet).
|
|
import QtQuick
|
|
import Quickshell.Io
|
|
import ".."
|
|
|
|
Pill {
|
|
id: root
|
|
property string btStatus: "off" // "off" | "on" | "connected"
|
|
property string devAlias: ""
|
|
|
|
readonly property var bgColors: ({
|
|
"off": Qt.rgba(0.565, 0.545, 0.671, 0.3), // alpha(@color3, 0.3)
|
|
"on": Theme.color2,
|
|
"connected": Theme.color4,
|
|
})
|
|
// Override Pill's own color binding
|
|
color: bgColors[btStatus] ?? Theme.pill
|
|
|
|
onClicked: (m) => {
|
|
if (m.button === Qt.LeftButton)
|
|
Exec.run(["blueman-manager"])
|
|
}
|
|
|
|
Text {
|
|
text: {
|
|
var s = root.btStatus
|
|
if (s === "connected") return "ᛒ " + (root.devAlias || "connected")
|
|
if (s === "on") return "ᛒ on"
|
|
return "ᛒ off"
|
|
}
|
|
font { family: Theme.fontSans; pixelSize: Theme.fontSize }
|
|
color: Theme.foreground
|
|
}
|
|
|
|
// Poll bluetoothctl show + info every 5 s
|
|
Process {
|
|
id: btProc
|
|
running: false
|
|
command: ["bash", "-c",
|
|
"bluetoothctl show | grep -E 'Powered|Name'; " +
|
|
"bluetoothctl info 2>/dev/null | grep -E 'Name|Connected'"]
|
|
stdout: SplitParser {
|
|
onRead: (line) => {
|
|
if (/Powered:\s+no/i.test(line)) { root.btStatus = "off"; root.devAlias = "" }
|
|
if (/Powered:\s+yes/i.test(line)) { if (root.btStatus === "off") root.btStatus = "on" }
|
|
if (/Connected:\s+yes/i.test(line)) root.btStatus = "connected"
|
|
if (/Connected:\s+no/i.test(line)) { if (root.btStatus === "connected") { root.btStatus = "on"; root.devAlias = "" } }
|
|
var match = /^\s+Name:\s+(.+)/.exec(line)
|
|
if (match && root.btStatus === "connected") root.devAlias = match[1].trim()
|
|
}
|
|
}
|
|
onExited: btProc.running = false
|
|
}
|
|
|
|
Timer {
|
|
interval: 5000; running: true; repeat: true
|
|
triggeredOnStart: true
|
|
onTriggered: btProc.running = true
|
|
}
|
|
}
|