fix(qt): a backend change only disables gapless when moving TO Alsa

The guard was missing, so EVERY backend change silently turned gapless off —
including switching to PipeWire, where it works perfectly. A user who did not
notice the toggle flip reads that as "alsa breaks gapless", which is exactly how
it was reported.

The reference is conditional: `settings.rs:1232-1237` disables it only for
`backend == AudioBackendType::Alsa`, and that in turn matches Tauri
(`SettingsView.svelte:3409-3416`, "not compatible with ALSA Direct"). Those two
are faithful to each other despite the different wording: in the engine's own
vocabulary `using_alsa_direct` IS `backend_type == Alsa`
(qbz-player/src/player/mod.rs:725-729). Only the Qt port dropped the `if`.

Investigated and RULED OUT while tracing this, recorded so it is not re-derived:
the audio thread's `thread_settings` and the Player's `audio_settings` are the
SAME `Arc<Mutex<AudioSettings>>` (created at mod.rs:1370, cloned into the thread
at :1371, stored on Self at :4067). `reload_settings` therefore does reach the
running audio thread, and no restart is needed for a settings change to land.
The apparent "restart makes gapless stick" is this cascade: the switch persisted
`gapless_enabled = false`, and turning it back on is what fixed it — the restart
was just when that happened.

Whether gapless SHOULD work on Alsa at all is a separate, deliberate rule
inherited from Tauri and left untouched here: the engine's `PlayNext` handler is
backend-agnostic and refuses only on a missing engine, a sample-rate/channel
mismatch or an active streaming source (mod.rs:3553-3586), so the blanket
exclusion may well be broader than the hardware demands. That is a product call
on the PROTECTED bit-perfect path and needs the owner's word plus real testing
on the DAC.

cc
This commit is contained in:
vicrodh committed 2026-07-31 07:41:06 -06:00
1 parent 8f416704a8
commit c8e4f415e7
1 file changed
+15 -1
+15 -1
View File
@@ -1940,7 +1940,21 @@ pub async fn settings_select(runtime: &Arc<AppRuntime<LoggingAdapter>>, key: &st
if backend != AudioBackendType::Alsa {
let _ = with_audio(|s| s.set_exclusive_mode(false));
}
let _ = with_audio(|s| s.set_gapless_enabled(false));
// Gapless off ONLY when moving TO Alsa — `settings.rs:1232-1237`,
// which in turn matches Tauri's `SettingsView.svelte:3409-3416`
// ("not compatible with ALSA Direct"; in the engine's own
// vocabulary `using_alsa_direct` IS `backend_type == Alsa`,
// player/mod.rs:725-729).
//
// This guard was MISSING, so every backend change killed gapless —
// including switching TO PipeWire, where it works perfectly. That
// is the bug behind "gapless works on pipewire, not on alsa": the
// setting was silently turned off by the switch itself, and a user
// who did not notice the toggle flip read it as "alsa breaks
// gapless".
if backend == AudioBackendType::Alsa {
let _ = with_audio(|s| s.set_gapless_enabled(false));
}
let _ = with_audio(|s| s.set_output_device(None));
apply_audio(runtime, Apply::Reinit);
}