Krolyxon
Commit 071f97f

Branches

Refs →

aurora.configquickshellauroraOsd.qml

110 lines · 3.5 KB · QML

1import QtQuick
2import Quickshell
3import Quickshell.Wayland
4import Quickshell.Services.Pipewire
5
6// Volume / mic / brightness popup: bottom-centre, click-through, auto-hides.
7// Volume + mute changes are picked up natively from Pipewire (any source: keys, wpctl, panel).
8// Brightness is pushed in via show() from the `bright` IPC call.
9PanelWindow {
10 id: win
11 property bool suppressed: false // hidden while the control panel is open
12 property bool shown: false
13 property string icon: ""
14 property real value: 0
15 property bool muted: false
16 property string valueText: ""
17
18 function show(icon, value, muted, valueText) {
19 win.icon = icon
20 win.value = value
21 win.muted = muted
22 win.valueText = valueText !== undefined ? valueText : Math.round(value * 100) + "%"
23 shown = true
24 hide.restart()
25 }
26
27 visible: shown && !suppressed
28 anchors.bottom: true
29 margins.bottom: 80
30 implicitWidth: 280
31 implicitHeight: 40
32 exclusiveZone: 0
33 color: "transparent"
34 mask: Region {}
35 WlrLayershell.layer: WlrLayer.Overlay
36 WlrLayershell.namespace: "aurora-osd"
37 WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
38
39 Timer { id: hide; interval: Settings.osdTimeout; onTriggered: win.shown = false }
40
41 // ---- pipewire watchers ----
42 // ignore the burst of change signals on startup and when the default device switches
43 property bool armed: false
44 Timer { id: arm; interval: 1000; running: true; onTriggered: win.armed = true }
45 function rearm() { armed = false; arm.restart() }
46
47 readonly property var sink: Pipewire.defaultAudioSink
48 readonly property var source: Pipewire.defaultAudioSource
49 onSinkChanged: rearm()
50 onSourceChanged: rearm()
51
52 function showVol() {
53 var a = sink ? sink.audio : null
54 if (!armed || !a) return
55 show(Theme.volIcon(a.volume, a.muted), a.volume, a.muted)
56 }
57 Connections {
58 target: win.sink ? win.sink.audio : null
59 function onVolumeChanged() { win.showVol() }
60 function onMutedChanged() { win.showVol() }
61 }
62 Connections {
63 target: win.source ? win.source.audio : null
64 function onMutedChanged() {
65 var a = win.source.audio
66 if (!win.armed) return
67 win.show(a.muted ? Theme.iMicOff : Theme.iMic, a.volume, a.muted, a.muted ? "muted" : "on")
68 }
69 }
70
71 // ---- ui ----
72 Rectangle {
73 anchors.fill: parent
74 color: Theme.bgA
75 border.width: 1
76 border.color: Theme.accent
77
78 Row {
79 anchors.fill: parent
80 anchors.leftMargin: 12
81 anchors.rightMargin: 12
82 spacing: 10
83
84 Text {
85 anchors.verticalCenter: parent.verticalCenter
86 width: 20
87 text: win.icon
88 color: win.muted ? Theme.dim : Theme.fg
89 font.family: Theme.font
90 font.pixelSize: 16
91 }
92 BarSlider {
93 anchors.verticalCenter: parent.verticalCenter
94 width: parent.width - 20 - 44 - parent.spacing * 2
95 value: win.value
96 muted: win.muted
97 }
98 Text {
99 anchors.verticalCenter: parent.verticalCenter
100 width: 44
101 horizontalAlignment: Text.AlignRight
102 text: win.valueText
103 color: win.muted ? Theme.dim : Theme.fg
104 font.family: Theme.font
105 font.pixelSize: Theme.fontSize
106 font.bold: true
107 }
108 }
109 }
110}