81 lines
2.7 KiB
QML
81 lines
2.7 KiB
QML
pragma Singleton
|
|
|
|
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Bluetooth
|
|
|
|
// Bluetooth via BlueZ. Connection and pairing are driven directly from the
|
|
// popout; `fluxo bt` stays available as a CLI for the existing keybind.
|
|
Singleton {
|
|
id: root
|
|
|
|
readonly property BluetoothAdapter adapter: Bluetooth.defaultAdapter
|
|
readonly property bool available: adapter !== null
|
|
readonly property bool enabled: adapter?.enabled ?? false
|
|
readonly property bool discovering: adapter?.discovering ?? false
|
|
|
|
readonly property var devices: adapter
|
|
? adapter.devices.values.slice().sort((a, b) => {
|
|
if (a.connected !== b.connected) return a.connected ? -1 : 1;
|
|
if (a.paired !== b.paired) return a.paired ? -1 : 1;
|
|
return (a.deviceName || a.name || "").localeCompare(b.deviceName || b.name || "");
|
|
})
|
|
: []
|
|
|
|
readonly property var connected: devices.filter(d => d.connected)
|
|
readonly property BluetoothDevice primary: connected.length > 0 ? connected[0] : null
|
|
|
|
readonly property string label: {
|
|
if (!available) return "No adapter";
|
|
if (!enabled) return "Off";
|
|
if (connected.length === 0) return "Disconnected";
|
|
if (connected.length === 1) return root.deviceLabel(primary);
|
|
return connected.length + " devices";
|
|
}
|
|
|
|
readonly property string icon: {
|
|
if (!available || !enabled) return "";
|
|
if (connected.length > 0) return "";
|
|
return "";
|
|
}
|
|
|
|
function deviceLabel(d: BluetoothDevice): string {
|
|
if (!d) return "";
|
|
return d.deviceName || d.name || d.address;
|
|
}
|
|
|
|
// Nerd Font glyph matching BlueZ's icon hint.
|
|
function deviceIcon(d: BluetoothDevice): string {
|
|
const i = d?.icon || "";
|
|
if (i.includes("headset") || i.includes("headphone")) return "";
|
|
if (i.includes("audio")) return "";
|
|
if (i.includes("phone")) return "";
|
|
if (i.includes("mouse")) return "";
|
|
if (i.includes("keyboard")) return "";
|
|
if (i.includes("computer")) return "";
|
|
if (i.includes("watch")) return "";
|
|
if (i.includes("input-gaming")) return "";
|
|
if (i.includes("printer")) return "";
|
|
return "";
|
|
}
|
|
|
|
function toggle() {
|
|
if (adapter) adapter.enabled = !adapter.enabled;
|
|
}
|
|
|
|
function toggleScan() {
|
|
if (adapter) adapter.discovering = !adapter.discovering;
|
|
}
|
|
|
|
function toggleDevice(d: BluetoothDevice) {
|
|
if (!d) return;
|
|
if (d.connected) {
|
|
d.disconnect();
|
|
} else if (d.paired || d.bonded) {
|
|
d.connect();
|
|
} else {
|
|
d.pair();
|
|
}
|
|
}
|
|
}
|