fix(audio): skip the Linux stack probes on Windows

A spawn of an image that does not exist fails before a process is created, so
pactl, pw-dump and systemctl were harmless on Windows. sh is not: it exists
wherever Git for Windows is installed, so the five sh -c probes in
audio_stack_health really ran and flashed five console windows past a
GUI-subsystem binary that owns no console.

Scoped to windows / not(windows), NOT to linux / not(linux). macOS and the
BSDs can have a real pactl or pw-dump from Homebrew or ports, and answering
false for them would take away an answer they can give.

qbz-theme needed nothing: its dispatch is by XDG_CURRENT_DESKTOP, so Windows
resolves DesktopEnvironment::Unknown, whose arm returns Err without calling
any desktop probe.

cc
This commit is contained in:
vicrodh committed 2026-08-27 12:44:20 -06:00
1 parent 1503b8236f
commit 249e30766e
3 files changed
+53 -1

No files matched your search

+14
View File
@@ -11,6 +11,8 @@
//! bit-perfect / sample-rate-passthrough path is untouched.
use serde::{Deserialize, Serialize};
// Every target but Windows still runs `pw-dump`.
#[cfg(not(windows))]
use std::process::Command;
/// The DAC's live, negotiated hardware state — what the card is REALLY clocked
@@ -94,6 +96,18 @@ pub fn parse_alsa_card_for_node(json: &str, node_name: &str) -> Option<u32> {
}
/// Resolve the ALSA card number for a sink node by running `pw-dump`.
///
/// W14, Windows only: `pw-dump` does not exist there, so the spawn already
/// failed into this same None. Scoped to Windows rather than `not(linux)` --
/// a macOS or BSD box can have a real `pw-dump`, and this function is not the
/// place to decide it may not speak.
#[cfg(windows)]
fn alsa_card_for_node(_node_name: &str) -> Option<u32> {
None
}
/// Resolve the ALSA card number for a sink node by running `pw-dump`.
#[cfg(not(windows))]
fn alsa_card_for_node(node_name: &str) -> Option<u32> {
let output = Command::new("pw-dump").output().ok()?;
if !output.status.success() {
+29 -1
View File
@@ -5,6 +5,8 @@
//! the check step can show the right `apt`/`dnf`/`pacman` remediation. None of
//! this opens a stream — purely diagnostic.
// Every target but Windows still probes; see `audio_stack_health`.
#[cfg(not(windows))]
use std::process::Command;
/// Result of the audio-stack probes. All best-effort; a failed probe reads as
@@ -32,7 +34,8 @@ impl AudioStackHealth {
}
}
/// True if `sh -c "<probe>"` exits 0.
/// True if `sh -c "<probe>"` exits 0. Windows never probes; see below.
#[cfg(not(windows))]
fn sh_ok(probe: &str) -> bool {
Command::new("sh")
.arg("-c")
@@ -44,6 +47,31 @@ fn sh_ok(probe: &str) -> bool {
/// Run the audio-stack probes. Linux-only meaningfully; elsewhere everything
/// reads false except where trivially true.
///
/// W14: on WINDOWS ONLY the answer is all-false, returned WITHOUT running the
/// probes. `systemctl`, `pactl` and `pw-dump` do not exist there (a spawn of a
/// missing image fails before a process is made, which is harmless), but `sh`
/// DOES exist wherever Git for Windows is installed, so the five `sh -c`
/// probes really run and flash five console windows past a GUI-subsystem
/// binary that owns no console.
///
/// Scoped to Windows, not to `not(linux)`: macOS and the BSDs can have a real
/// `pactl`/`pw-dump` from Homebrew or ports, and answering false for them
/// would be a lie this diff has no business telling.
#[cfg(windows)]
pub fn audio_stack_health() -> AudioStackHealth {
AudioStackHealth {
wireplumber_active: false,
has_pw_dump: false,
cpal_sees_pipewire: false,
has_pactl: false,
any_devices: false,
}
}
/// Run the audio-stack probes. Linux-only meaningfully; elsewhere everything
/// reads false except where trivially true.
#[cfg(not(windows))]
pub fn audio_stack_health() -> AudioStackHealth {
// systemd path first; fall back to a process check so non-systemd inits
// (Gentoo/OpenRC, Void/runit) don't read as "WirePlumber down".
+10
View File
@@ -1163,6 +1163,16 @@ fn collect_output_sinks() -> (Option<String>, Vec<String>, Option<(String, Strin
/// right now (vs the saved "Preferred Sample Rate"). Linux/PipeWire/Pulse only;
/// `None` when pactl is unavailable (a Flatpak/Snap sandbox without it simply
/// degrades to "—", same as the reference). READ-ONLY.
/// W14, Windows only: `pactl` is a Pulse/PipeWire tool and does not exist on
/// Windows, so the row degrades to the same "-" the missing-pactl path already
/// produced -- without the spawn. macOS and the BSDs keep probing: a Homebrew
/// or ports `pactl` there is real and can answer.
#[cfg(windows)]
fn active_sink_format() -> Option<(String, String)> {
None
}
#[cfg(not(windows))]
fn active_sink_format() -> Option<(String, String)> {
use std::process::Command;
let default = Command::new("pactl")