fix(audio): detect PipeWire via runtime socket so the backend is not hidden without pactl (#466)

is_pipewire_available() shelled out to `pactl info`, which lives in
pulseaudio-utils and is absent on PipeWire-only systems — hiding the PipeWire
backend even though PipeWire was running. Detect via the
$XDG_RUNTIME_DIR/pipewire-0 socket first (no extra package required), with
pw-cli and pactl as fallbacks.

cc
This commit is contained in:
vicrodh committed 2026-05-22 23:16:53 -06:00
1 parent f5de06aeef
commit 3a09ce7fe7
1 file changed
+20 -3
+20 -3
View File
@@ -350,9 +350,26 @@ impl BackendManager {
#[cfg(target_os = "linux")]
fn is_pipewire_available() -> bool {
// Check if PipeWire/PulseAudio is available using pactl
// PipeWire provides PulseAudio compatibility, so pactl works for both
// This is more reliable than pw-cli, especially in sandboxed environments (Flatpak)
// Detect PipeWire via its runtime socket ($XDG_RUNTIME_DIR/pipewire-0),
// which exists whenever PipeWire is running. Unlike `pactl`, this does
// NOT require pulseaudio-utils to be installed — PipeWire-only systems
// frequently lack it, which used to hide the PipeWire backend entirely
// (issue #466). pw-cli / pactl remain as fallbacks for unusual setups
// (e.g. a non-default socket name, or Flatpak where the socket path
// differs but the pulse shim is bridged).
if let Some(runtime_dir) = std::env::var_os("XDG_RUNTIME_DIR") {
if std::path::Path::new(&runtime_dir).join("pipewire-0").exists() {
return true;
}
}
if std::process::Command::new("pw-cli")
.args(["info", "0"])
.output()
.map(|o| o.status.success())
.unwrap_or(false)
{
return true;
}
std::process::Command::new("pactl")
.arg("info")
.output()