fix(qt): persist the player volume, so a launch stops starting at 100%

PARITY-DEBT #3 — the cheapest AUDIBLE row in the inventory. Volume was never
written and never restored: `setVolume` reached the engine and stopped there.
Set it to 15%, quit, relaunch, and playback came back at full scale. On an
exclusive-mode DAC at night that is not a cosmetic default.

1:1 with the Slint: persist on drag-END only (`NowPlayingState.persist-volume`,
PlayerBar.slint:864-866 -> qbz/src/main.rs:14413-14417), restore at shell entry
(qbz/src/main.rs:220-227), and let the poll loop mirror the engine back onto the
slider so nothing else has to publish it.

Drag-end matters here rather than being a nicety: ui_prefs.json is co-owned with
the running Slint app and both processes do a whole-document read-modify-write,
so a write per drag tick is a write per pixel into a shared file. `QbzSlider`
only had `changed`, which fires on every tick, so it gains a `released` signal
carrying the settled value — both now-playing bars use it.

Two supporting bits: `QbzPlayer.persistVolume` (the engine setter stays
per-tick, only the persist is debounced by the signal), and
`settings_qt::read_pref_f32` — the crate had no public ui_prefs reader, theme_qt
kept a private one, and a third private copy is exactly what the write
discipline at the top of settings_qt exists to prevent.

Verified the key name against the live file: `volume` is already present in the
shared ui_prefs.json alongside 60 other keys, so this reads and writes what the
Slint build reads and writes.

cc
This commit is contained in:
vicrodh committed 2026-07-30 09:46:19 -06:00
1 parent 424c2ea552
commit b8b493bd59
6 files changed
+45 -1

No files matched your search

@@ -402,6 +402,8 @@ Rectangle {
maximum: 1000
value: Math.round(QbzPlayer.npVolume * 1000)
onChanged: function (v) { QbzPlayer.setVolume(v / 1000.0) }
// Persist only the settled value, like the full bar.
onReleased: function (v) { QbzPlayer.persistVolume(v / 1000.0) }
}
Item { width: 4; height: 1 }
+2
View File
@@ -433,6 +433,8 @@ Rectangle {
maximum: 1000
value: Math.round(QbzPlayer.npVolume * 1000)
onChanged: function (v) { QbzPlayer.setVolume(v / 1000.0) }
// Persist only the settled value (PlayerBar.slint:864-866).
onReleased: function (v) { QbzPlayer.persistVolume(v / 1000.0) }
}
QbzIconButton {
visible: root.showVolumeSteppers