fix(audio): bump generation on paused device reopen to stop spurious audio:ended

Third defence for #1094: on a device change while paused/stopped,
reopen_output_stream stopped the old sink without bumping the engine
generation (the bump only happened on a successful internal resume). The
still-running progress task could then flip done_flag and emit a spurious
audio:ended, which the frontend turns into a restart. Bump the generation
before sink.stop() in the non-playing case so the progress task bails out;
the active-playback path keeps bumping inside try_resume_after_device_change.

(cherry picked from commit 9034882bf6)
This commit is contained in:
Psychotoxical
2026-06-16 14:49:49 +02:00
committed by cucadmuh
parent 997e697a53
commit 42dcbb9323
@@ -82,6 +82,15 @@ pub(crate) async fn reopen_output_stream(
if !opened {
return false;
}
// When we're not actively playing (paused/stopped), bump the generation
// before stopping the old sink so the still-running progress task sees the
// mismatch and bails out instead of emitting a spurious `audio:ended` —
// which would otherwise trigger a frontend restart of paused playback
// (#1094). The active-playback path bumps inside
// `try_resume_after_device_change`, so only guard the non-playing case here.
if !snapshot.is_playing {
engine.generation.fetch_add(1, Ordering::SeqCst);
}
if let Some(s) = current.lock().unwrap().sink.take() {
s.stop();
}