feat: bar bluetooth devices
This commit is contained in:
parent
a24e6f5b93
commit
169450aa2e
9 changed files with 127 additions and 11 deletions
|
|
@ -35,9 +35,9 @@ Item {
|
||||||
vertical: BarConfig.vertical
|
vertical: BarConfig.vertical
|
||||||
|
|
||||||
anchors.left: root.get(osIcon.right, undefined)
|
anchors.left: root.get(osIcon.right, undefined)
|
||||||
anchors.leftMargin: root.get(Appearance.padding.normal, 0)
|
anchors.leftMargin: root.get(Appearance.padding.large, 0)
|
||||||
anchors.top: root.get(undefined, osIcon.bottom)
|
anchors.top: root.get(undefined, osIcon.bottom)
|
||||||
anchors.topMargin: root.get(0, Appearance.padding.normal)
|
anchors.topMargin: root.get(0, Appearance.padding.large)
|
||||||
|
|
||||||
anchors.horizontalCenter: root.get(undefined, parent.horizontalCenter)
|
anchors.horizontalCenter: root.get(undefined, parent.horizontalCenter)
|
||||||
anchors.verticalCenter: root.get(parent.verticalCenter, undefined)
|
anchors.verticalCenter: root.get(parent.verticalCenter, undefined)
|
||||||
|
|
@ -70,9 +70,9 @@ Item {
|
||||||
|
|
||||||
StatusIcons {
|
StatusIcons {
|
||||||
anchors.left: root.get(clock.right, undefined)
|
anchors.left: root.get(clock.right, undefined)
|
||||||
anchors.leftMargin: root.get(Appearance.padding.normal, 0)
|
anchors.leftMargin: root.get(Appearance.padding.large, 0)
|
||||||
anchors.top: root.get(undefined, clock.bottom)
|
anchors.top: root.get(undefined, clock.bottom)
|
||||||
anchors.topMargin: root.get(0, Appearance.padding.normal)
|
anchors.topMargin: root.get(0, Appearance.padding.large)
|
||||||
|
|
||||||
anchors.horizontalCenter: root.get(undefined, parent.horizontalCenter)
|
anchors.horizontalCenter: root.get(undefined, parent.horizontalCenter)
|
||||||
anchors.verticalCenter: root.get(parent.verticalCenter, undefined)
|
anchors.verticalCenter: root.get(parent.verticalCenter, undefined)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ StyledRect {
|
||||||
prevAnchor: icon
|
prevAnchor: icon
|
||||||
|
|
||||||
horizontalAlignment: StyledText.AlignHCenter
|
horizontalAlignment: StyledText.AlignHCenter
|
||||||
text: root.vertical ? Time.format("hh\nmm") : Time.format("dd/MM/yy hh:mm")
|
text: root.vertical ? Time.format("hh\nmm") : Time.format("hh:mm • dddd, dd MMMM")
|
||||||
font.pointSize: Appearance.font.size.smaller
|
font.pointSize: Appearance.font.size.smaller
|
||||||
font.family: Appearance.font.family.mono
|
font.family: Appearance.font.family.mono
|
||||||
color: root.colour
|
color: root.colour
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import "root:/services"
|
||||||
import "root:/utils"
|
import "root:/utils"
|
||||||
import "root:/config"
|
import "root:/config"
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
id: root
|
id: root
|
||||||
|
|
@ -10,9 +11,44 @@ StyledRect {
|
||||||
readonly property color colour: Appearance.colours.rosewater
|
readonly property color colour: Appearance.colours.rosewater
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
id: icon
|
id: network
|
||||||
|
|
||||||
|
animate: true
|
||||||
text: Icons.getNetworkIcon(Network.active.strength)
|
text: Icons.getNetworkIcon(Network.active.strength)
|
||||||
color: root.colour
|
color: root.colour
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AnchorText {
|
||||||
|
id: bluetooth
|
||||||
|
|
||||||
|
prevAnchor: network
|
||||||
|
|
||||||
|
animate: true
|
||||||
|
text: Bluetooth.powered ? "bluetooth" : "bluetooth_disabled"
|
||||||
|
color: root.colour
|
||||||
|
font.family: Appearance.font.family.material
|
||||||
|
font.pointSize: Appearance.font.size.larger
|
||||||
|
}
|
||||||
|
|
||||||
|
BoxLayout {
|
||||||
|
anchors.left: vertical ? undefined : bluetooth.right
|
||||||
|
anchors.leftMargin: vertical ? 0 : Appearance.padding.smaller
|
||||||
|
anchors.top: vertical ? bluetooth.bottom : undefined
|
||||||
|
anchors.topMargin: vertical ? Appearance.padding.smaller : 0
|
||||||
|
|
||||||
|
anchors.horizontalCenter: vertical ? bluetooth.horizontalCenter : undefined
|
||||||
|
anchors.verticalCenter: vertical ? undefined : bluetooth.verticalCenter
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: Bluetooth.connected
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
required property Bluetooth.Device modelData
|
||||||
|
|
||||||
|
animate: true
|
||||||
|
text: Icons.getBluetoothIcon(modelData.icon)
|
||||||
|
color: root.colour
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
70
services/Bluetooth.qml
Normal file
70
services/Bluetooth.qml
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool powered
|
||||||
|
property bool discovering
|
||||||
|
readonly property list<Device> devices: []
|
||||||
|
readonly property list<Device> connected: devices.filter(d => d.connected)
|
||||||
|
|
||||||
|
Process {
|
||||||
|
running: true
|
||||||
|
command: ["bluetoothctl"]
|
||||||
|
stdout: SplitParser {
|
||||||
|
onRead: getInfo.running = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: getInfo
|
||||||
|
running: true
|
||||||
|
command: ["sh", "-c", "bluetoothctl show | paste -s"]
|
||||||
|
stdout: SplitParser {
|
||||||
|
onRead: data => {
|
||||||
|
root.powered = data.includes("Powered: yes");
|
||||||
|
root.discovering = data.includes("Discovering: yes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: getDevices
|
||||||
|
running: true
|
||||||
|
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`]
|
||||||
|
stdout: SplitParser {
|
||||||
|
onRead: data => {
|
||||||
|
const d = JSON.parse(data);
|
||||||
|
root.devices.push(deviceComp.createObject(root, {
|
||||||
|
name: d.Name,
|
||||||
|
alias: d.Alias,
|
||||||
|
address: d.Address,
|
||||||
|
icon: d.Icon,
|
||||||
|
connected: d.Connected === "yes",
|
||||||
|
paired: d.Paired === "yes",
|
||||||
|
trusted: d.Trusted === "yes"
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component Device: QtObject {
|
||||||
|
property string name
|
||||||
|
property string alias
|
||||||
|
property string address
|
||||||
|
property string icon
|
||||||
|
property bool connected
|
||||||
|
property bool paired
|
||||||
|
property bool trusted
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: deviceComp
|
||||||
|
|
||||||
|
Device {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -39,7 +39,7 @@ Singleton {
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: getClients
|
id: getClients
|
||||||
command: ["bash", "-c", "hyprctl -j clients | jq -c"]
|
command: ["sh", "-c", "hyprctl -j clients | jq -c"]
|
||||||
stdout: SplitParser {
|
stdout: SplitParser {
|
||||||
onRead: data => {
|
onRead: data => {
|
||||||
const clients = JSON.parse(data);
|
const clients = JSON.parse(data);
|
||||||
|
|
@ -58,7 +58,7 @@ Singleton {
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: getActiveClient
|
id: getActiveClient
|
||||||
command: ["bash", "-c", "hyprctl -j activewindow | jq -c"]
|
command: ["sh", "-c", "hyprctl -j activewindow | jq -c"]
|
||||||
stdout: SplitParser {
|
stdout: SplitParser {
|
||||||
onRead: data => {
|
onRead: data => {
|
||||||
const client = JSON.parse(data);
|
const client = JSON.parse(data);
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,16 @@ Singleton {
|
||||||
return "signal_wifi_0_bar";
|
return "signal_wifi_0_bar";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getBluetoothIcon(icon: string): string {
|
||||||
|
if (icon.includes("headset") || icon.includes("headphones"))
|
||||||
|
return "headphones";
|
||||||
|
if (icon.includes("audio"))
|
||||||
|
return "speaker";
|
||||||
|
if (icon.includes("phone"))
|
||||||
|
return "smartphone";
|
||||||
|
return "bluetooth";
|
||||||
|
}
|
||||||
|
|
||||||
FileView {
|
FileView {
|
||||||
path: "/etc/os-release"
|
path: "/etc/os-release"
|
||||||
onLoaded: {
|
onLoaded: {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ StyledText {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property Item prevAnchor
|
required property Item prevAnchor
|
||||||
property bool vertical
|
property bool vertical: parent.vertical ?? false
|
||||||
|
|
||||||
anchors.left: vertical ? undefined : prevAnchor.right
|
anchors.left: vertical ? undefined : prevAnchor.right
|
||||||
anchors.leftMargin: vertical ? 0 : Appearance.padding.smaller
|
anchors.leftMargin: vertical ? 0 : Appearance.padding.smaller
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import "root:/config"
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
property bool vertical: false
|
property bool vertical: parent.vertical ?? false // Propagate from parent
|
||||||
property bool homogenous: false
|
property bool homogenous: false
|
||||||
property int spacing: Appearance.spacing.small
|
property int spacing: Appearance.spacing.small
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ Rectangle {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool animate: false
|
property bool animate: false
|
||||||
property bool vertical: false // Convenience property for propagation to children
|
property bool vertical: parent.vertical ?? false // Convenience property for propagation to children
|
||||||
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
implicitWidth: childrenRect.width
|
implicitWidth: childrenRect.width
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue