Bluetooth.qml
1 pragma Singleton 2 3 import Quickshell 4 import Quickshell.Io 5 import QtQuick 6 7 Singleton { 8 id: root 9 10 property bool powered 11 property bool discovering 12 readonly property list<Device> devices: [] 13 14 Process { 15 running: true 16 command: ["bluetoothctl"] 17 stdout: SplitParser { 18 onRead: { 19 getInfo.running = true; 20 getDevices.running = true; 21 } 22 } 23 } 24 25 Process { 26 id: getInfo 27 running: true 28 command: ["sh", "-c", "bluetoothctl show | paste -s"] 29 stdout: SplitParser { 30 onRead: data => { 31 root.powered = data.includes("Powered: yes"); 32 root.discovering = data.includes("Discovering: yes"); 33 } 34 } 35 } 36 37 Process { 38 id: getDevices 39 running: true 40 command: ["fish", "-c", `for a in (bluetoothctl devices | cut -d ' ' -f 2); bluetoothctl info $a | jq -R 'reduce (inputs / ":") as [$key, $value] ({}; .[$key | ltrimstr("\t")] = ($value | ltrimstr(" ")))' | jq -c --arg addr $a '.Address = $addr'; end | jq -sc`] 41 stdout: SplitParser { 42 onRead: data => { 43 const devices = JSON.parse(data).filter(d => d.Name); 44 const rDevices = root.devices; 45 46 const destroyed = rDevices.filter(rd => !devices.find(d => d.Address === rd.address)); 47 for (const device of destroyed) 48 rDevices.splice(rDevices.indexOf(device), 1).forEach(d => d.destroy()); 49 50 for (const device of devices) { 51 const match = rDevices.find(d => d.address === device.Address); 52 if (match) { 53 match.lastIpcObject = device; 54 } else { 55 rDevices.push(deviceComp.createObject(root, { 56 lastIpcObject: device 57 })); 58 } 59 } 60 } 61 } 62 } 63 64 component Device: QtObject { 65 required property var lastIpcObject 66 readonly property string name: lastIpcObject.Name 67 readonly property string alias: lastIpcObject.Alias 68 readonly property string address: lastIpcObject.Address 69 readonly property string icon: lastIpcObject.Icon 70 readonly property bool connected: lastIpcObject.Connected === "yes" 71 readonly property bool paired: lastIpcObject.Paired === "yes" 72 readonly property bool trusted: lastIpcObject.Trusted === "yes" 73 } 74 75 Component { 76 id: deviceComp 77 78 Device {} 79 } 80 }