From ae9a80c1f012686c1f65fce7ce76fdd1b77b0b71 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Wed, 23 Sep 2026 21:08:35 +0200 Subject: ... --- .../gkleen@skadhi/shell/quickshell/VolumeOSD.qml | 163 +++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 accounts/gkleen@skadhi/shell/quickshell/VolumeOSD.qml (limited to 'accounts/gkleen@skadhi/shell/quickshell/VolumeOSD.qml') diff --git a/accounts/gkleen@skadhi/shell/quickshell/VolumeOSD.qml b/accounts/gkleen@skadhi/shell/quickshell/VolumeOSD.qml new file mode 100644 index 00000000..91dc9591 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/VolumeOSD.qml @@ -0,0 +1,163 @@ +import QtQuick +import QtQuick.Layouts +import Quickshell +import Quickshell.Services.Pipewire +import Quickshell.Widgets + +Scope { + id: root + + property string show: "" + property bool inhibited: true + + PwObjectTracker { + objects: [ Pipewire.defaultAudioSink, Pipewire.defaultAudioSource ] + } + + Connections { + enabled: Pipewire.defaultAudioSink + target: Pipewire.defaultAudioSink?.audio || null + + function onVolumeChanged() { + root.show = "sink"; + hideTimer.restart(); + } + function onMutedChanged() { + root.show = "sink"; + hideTimer.restart(); + } + } + + Connections { + enabled: Pipewire.defaultAudioSource + target: Pipewire.defaultAudioSource?.audio || null + + function onVolumeChanged() { + root.show = "source"; + hideTimer.restart(); + } + function onMutedChanged() { + root.show = "source"; + hideTimer.restart(); + } + } + + onShowChanged: { + if (show) + hideTimer.restart(); + } + + Timer { + id: hideTimer + interval: 1000 + onTriggered: root.show = "" + } + + Timer { + id: startInhibit + interval: 100 + running: true + onTriggered: { + root.show = ""; + root.inhibited = false; + } + } + + LazyLoader { + active: root.show && !root.inhibited + + Variants { + model: Quickshell.screens + + delegate: Scope { + id: screenScope + + required property var modelData + + PanelWindow { + id: window + + screen: screenScope.modelData + + anchors.top: true + margins.top: screen.height / 2 - 50 + 3.5 + exclusiveZone: 0 + exclusionMode: ExclusionMode.Ignore + + implicitWidth: 400 + implicitHeight: 50 + + mask: Region {} + + color: "transparent" + + Rectangle { + anchors.fill: parent + color: Qt.rgba(0, 0, 0, 0.75) + } + + RowLayout { + id: layout + + anchors.centerIn: parent + + height: 50 - 8*2 + width: 400 - 8*2 + + MaterialDesignIcon { + id: volumeIcon + + implicitWidth: parent.height + implicitHeight: parent.height + + icon: { + if (root.show == "sink") { + if (!Pipewire.defaultAudioSink || Pipewire.defaultAudioSink.audio.muted) + return "volume-off"; + if (Pipewire.defaultAudioSink.audio.volume <= 0.33) + return "volume-low"; + if (Pipewire.defaultAudioSink.audio.volume <= 0.67) + return "volume-medium"; + return "volume-high"; + } else if (root.show == "source") { + if (!Pipewire.defaultAudioSource || Pipewire.defaultAudioSource.audio.muted) + return "microphone-off"; + if (Pipewire.defaultAudioSource.audio.volume > 1) + return "microphone-plus"; + return "microphone"; + } + return "volume-high"; + } + } + + Rectangle { + Layout.fillWidth: true + + implicitHeight: 10 + + color: "#50ffffff" + + Rectangle { + anchors { + left: parent.left + top: parent.top + bottom: parent.bottom + } + + color: Pipewire.defaultAudioSink?.audio.muted ? "#70ffffff" : "white" + + implicitWidth: { + if (root.show == "sink") + return parent.width * (Pipewire.defaultAudioSink?.audio.volume ?? 0); + else if (root.show == "source") + return parent.width * Math.min(1, (Pipewire.defaultAudioSource?.audio.volume ?? 0)); + return 0; + } + } + } + } + } + } + } + } +} -- cgit v1.2.3