60 lines
1.9 KiB
QML
60 lines
1.9 KiB
QML
pragma Singleton
|
|
|
|
import Quickshell
|
|
import Quickshell.Services.Pipewire
|
|
import qs.config
|
|
|
|
// The default audio sink. Quickshell talks to pipewire directly, so there is no
|
|
// wpctl or pactl to shell out to and no polling: the properties below change as
|
|
// the graph does, whoever moved them.
|
|
//
|
|
// Everything is expressed against the default sink rather than a remembered
|
|
// one, so switching outputs — plugging in a headset, say — moves the panel with
|
|
// the sound.
|
|
Singleton {
|
|
id: root
|
|
|
|
readonly property PwNode sink: Pipewire.defaultAudioSink
|
|
|
|
// Pipewire objects only carry live properties while something is tracking
|
|
// them, so `audio` is null until the tracker below binds the node.
|
|
readonly property bool available: Config.showVolume && root.sink !== null && root.sink.ready && root.sink.audio !== null
|
|
|
|
// 0-1 for the usable range, though pipewire allows more and another client
|
|
// may well have set more. Reported as-is; the slider is what clamps.
|
|
readonly property real volume: root.available ? root.sink.audio.volume : 0
|
|
readonly property bool muted: root.available ? root.sink.audio.muted : false
|
|
|
|
function setVolume(value: real): void {
|
|
if (!root.available)
|
|
return;
|
|
|
|
root.sink.audio.volume = Math.max(0, Math.min(1, value));
|
|
}
|
|
|
|
// Raising the volume from silence unmutes: a volume key that appears to do
|
|
// nothing is worse than one that does slightly more than it said.
|
|
function step(delta: real): void {
|
|
if (!root.available)
|
|
return;
|
|
|
|
if (delta > 0 && root.muted)
|
|
root.setMuted(false);
|
|
|
|
root.setVolume(root.volume + delta);
|
|
}
|
|
|
|
function setMuted(muted: bool): void {
|
|
if (root.available)
|
|
root.sink.audio.muted = muted;
|
|
}
|
|
|
|
function toggleMute(): void {
|
|
root.setMuted(!root.muted);
|
|
}
|
|
|
|
PwObjectTracker {
|
|
objects: root.sink ? [root.sink] : []
|
|
}
|
|
}
|