aboutsummaryrefslogtreecommitdiff
path: root/modules/system/quickshell/VolumeOSD.qml
diff options
context:
space:
mode:
Diffstat (limited to 'modules/system/quickshell/VolumeOSD.qml')
-rw-r--r--modules/system/quickshell/VolumeOSD.qml90
1 files changed, 90 insertions, 0 deletions
diff --git a/modules/system/quickshell/VolumeOSD.qml b/modules/system/quickshell/VolumeOSD.qml
new file mode 100644
index 0000000..8efe305
--- /dev/null
+++ b/modules/system/quickshell/VolumeOSD.qml
@@ -0,0 +1,90 @@
+import QtQuick
+import QtQuick.Layouts
+import Quickshell
+import Quickshell.Services.Pipewire
+import Quickshell.Wayland
+
+// Volume OSD that appears on volume change, styled to match the system menus.
+Scope {
+ id: root
+
+ readonly property PwNode sink: Pipewire.defaultAudioSink
+ property bool visible: false
+
+ PwObjectTracker {
+ objects: root.sink ? [root.sink] : []
+ }
+
+ Connections {
+ target: root.sink && root.sink.audio ? root.sink.audio : null
+ ignoreUnknownSignals: true
+
+ function onVolumeChanged() {
+ root.visible = true
+ hideTimer.restart()
+ }
+ function onMutedChanged() {
+ root.visible = true
+ hideTimer.restart()
+ }
+ }
+
+ Timer {
+ id: hideTimer
+ interval: 2000
+ onTriggered: root.visible = false
+ }
+
+ PanelWindow {
+ visible: root.visible
+
+ // Compositor centers horizontally if only bottom anchor is set
+ anchors.bottom: true
+ margins.bottom: 100
+ exclusiveZone: 0
+
+ implicitWidth: 240
+ implicitHeight: 64
+
+ WlrLayershell.layer: WlrLayer.Overlay
+ exclusionMode: ExclusionMode.Ignore
+ color: Theme.transparent
+ mask: Region {} // Pass-through clicks
+
+ Squircle {
+ id: card
+ anchors.fill: parent
+ fillColor: Theme.bg
+ strokeColor: Theme.border
+ strokeWidth: 1
+ cornerRadius: 16
+
+ RowLayout {
+ anchors {
+ fill: parent
+ margins: 16
+ }
+ spacing: 12
+
+ IconCircle {
+ size: 32
+ source: {
+ if (root.sink?.audio?.muted) return "audio-volume-muted"
+ const vol = root.sink?.audio?.volume ?? 0
+ if (vol <= 0) return "audio-volume-low"
+ if (vol <= 0.33) return "audio-volume-low"
+ if (vol <= 0.66) return "audio-volume-medium"
+ return "audio-volume-high"
+ }
+ active: !(root.sink?.audio?.muted ?? true)
+ }
+
+ PillSlider {
+ Layout.fillWidth: true
+ value: root.sink?.audio?.volume ?? 0
+ enabled: false // OSD is for display only
+ }
+ }
+ }
+ }
+}