diff options
| author | bh <qn+git@epicurus.dev> | 2026-03-08 15:17:45 +0800 |
|---|---|---|
| committer | bh <qn+git@epicurus.dev> | 2026-03-08 15:17:45 +0800 |
| commit | 36c1b38b514ab74f1c48ce5ab2b8738c80321281 (patch) | |
| tree | ec5b45701a9232984290e120787e8f7f2ba01169 | |
| parent | 7ce9aa173d7d1ecd9dec8eed31980a16c0f14202 (diff) | |
Replace volume polling with reactive Pipewire bindings
| -rw-r--r-- | quickshell/.config/quickshell/shell.qml | 59 |
1 files changed, 17 insertions, 42 deletions
diff --git a/quickshell/.config/quickshell/shell.qml b/quickshell/.config/quickshell/shell.qml index 95ac87f..a58b7b0 100644 --- a/quickshell/.config/quickshell/shell.qml +++ b/quickshell/.config/quickshell/shell.qml @@ -5,6 +5,7 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls import Quickshell.Services.SystemTray +import Quickshell.Services.Pipewire PanelWindow { id: root @@ -361,7 +362,9 @@ PanelWindow { color: "transparent" property bool showing: false - property real currentVol: 0 + property var sink: Pipewire.defaultAudioSink + property real currentVol: sink && sink.audio ? Math.round(sink.audio.volume * 100) : 0 + property bool isMuted: sink && sink.audio ? sink.audio.muted : false HyprlandFocusGrab { id: volGrab @@ -393,7 +396,7 @@ PanelWindow { ColumnLayout { anchors.fill: parent anchors.margins: 12 - spacing: 2 + spacing: 0 opacity: volPopup.showing ? 1.0 : 0.0 Behavior on opacity { @@ -408,7 +411,7 @@ PanelWindow { id: volPopupIcon color: root.fg font.family: "Symbols Nerd Font" - font.pixelSize: 14 + font.pixelSize: 18 text: volSlider.value === 0 ? "" : volSlider.value <= 50 ? "" : "" } @@ -416,7 +419,7 @@ PanelWindow { id: volSliderLabel color: "#FFC500" font.family: "Source Code Pro" - font.pixelSize: 13 + font.pixelSize: 17 font.bold: true text: Math.round(volSlider.value) + "%" } @@ -464,36 +467,13 @@ PanelWindow { var ratio = Math.max(0, Math.min(1, mouse.x / width)) var vol = Math.round(ratio * 300) volSlider.value = vol - volSetProc.command = ["wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", (vol / 100).toFixed(2)] - volSetProc.running = true + if (volPopup.sink && volPopup.sink.audio) + volPopup.sink.audio.volume = vol / 100 } } } } - Process { - id: volSetProc - } - - Timer { - interval: 200 - running: volPopup.visible - repeat: true - triggeredOnStart: true - onTriggered: volReadProc.running = true - } - - Process { - id: volReadProc - command: ["sh", "-c", "wpctl get-volume @DEFAULT_AUDIO_SINK@ | awk '{printf \"%.0f\", $2*100}'"] - stdout: StdioCollector { - onStreamFinished: { - var val = parseInt(this.text.trim()) - if (!isNaN(val) && !volSlider.pressed) - volPopup.currentVol = val - } - } - } } RowLayout { @@ -517,21 +497,16 @@ PanelWindow { } } - Timer { - interval: 1000 - running: true - repeat: true - triggeredOnStart: true - onTriggered: volProc.running = true - } + property var sink: Pipewire.defaultAudioSink + property real volPercent: sink && sink.audio ? Math.round(sink.audio.volume * 100) : 0 + property bool isMuted: sink && sink.audio ? sink.audio.muted : false - Process { - id: volProc - command: ["sh", "-c", "wpctl get-volume @DEFAULT_AUDIO_SINK@ | awk '{if (/MUTED/) print \"MUTED\"; else printf \"%.0f%%\", $2*100}'"] - stdout: StdioCollector { - onStreamFinished: { var out = this.text.trim(); var muted = (out === "MUTED"); volText.text = out; volIcon.text = muted ? "" : "" } - } + PwObjectTracker { + objects: [ Pipewire.defaultAudioSink ] } + + Binding { target: volText; property: "text"; value: volModule.isMuted ? "MUTED" : volModule.volPercent + "%" } + Binding { target: volIcon; property: "text"; value: volModule.isMuted ? "" : "" } } // Powerline separator: bg1 -> bg2 |
