host/audio: emit initial app_audio "lost" at strict capture start (A23 P2/F1)
In strict per-app mode the default-sink loopback is suppressed, so until the chosen app's first stream routes the viewer hears silence. Previously no event fired for an app that never routed (`lost` only fires on an N→0 transition after a prior route), so peerspeak couldn't warn — the share looked normal but was silent. Emit a `lost` at capture start (lazy, on first viewer) when, and only when, `--app` + `--strict-audio` are both set; whole-desktop and best-effort modes keep audio flowing via the loopback and emit nothing. Factored the emit decision into the pure, unit-tested `initial_app_audio_state`; derive Debug/PartialEq/Eq on AppAudioState so it can be asserted on. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -535,4 +535,20 @@ mod tests {
|
||||
);
|
||||
assert_eq!(capture_summary(&opts(None, true)), "fullscreen + system-audio");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn initial_app_audio_is_lost_only_in_strict_app_mode() {
|
||||
use crate::common::output::AppAudioState;
|
||||
use crate::host::audio::initial_app_audio_state;
|
||||
// Strict + app: announce silence up front (loopback suppressed).
|
||||
assert_eq!(
|
||||
initial_app_audio_state(&opts(Some("Firefox"), true)),
|
||||
Some(AppAudioState::Lost)
|
||||
);
|
||||
// Best-effort app (no strict): loopback covers the gap → no initial event.
|
||||
assert_eq!(initial_app_audio_state(&opts(Some("Firefox"), false)), None);
|
||||
// Whole-desktop (strict is ignored without --app): no per-app events.
|
||||
assert_eq!(initial_app_audio_state(&opts(None, true)), None);
|
||||
assert_eq!(initial_app_audio_state(&opts(None, false)), None);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user