The last unported row of Settings > Audio. Read-only by design: a Hz
dropdown is the documented root-cause trap, because it promises rates the
app cannot request when Qobuz sells four discrete tiers. The value is
Rust-composed from the probe and the row hides on an empty summary; the
fallback caveat renders only when the probe fell back to the common set.
No new msgids -- both strings already exist, translated, in all 8 catalogs.
Six refresh triggers, one more than the reference: startup, the toggle, a
backend switch, an output-device change, reset-to-defaults, and the device
refresh/release button. That last one is Qt-only and the easiest to miss --
it is the hotplug case, where the hardware behind a "System default"
selection changes without the selection changing.
Ordering is persist -> refresh -> publish, and the refresh goes BEFORE
apply_audio rather than merely before the handler's closing publish:
apply_audio publishes on its own way out, an earlier serialize that would
ship a stale summary. The symptom of getting this wrong is a row that is
only right after reopening Settings.
The boot trigger publishes the snapshot itself after awaiting the refresh.
The boot snapshot is spawned separately and can serialize first, which left
the row absent for a user who already had the toggle on until some
unrelated mutation happened to republish.
A cap change drops the tier-keyed audio cache, symmetric with the streaming
-quality change: the cache is quality-blind, so bytes fetched under the old
tier would keep serving and the feature would be inert on anything already
played. The first refresh of a process is exempt -- see the CapChange
classification, which exists because clearing there wiped the disk cache on
every launch.
cc
Six-step modal (Welcome / Check / DACs / Configure / Test / Done) opened
from Settings > Audio. It probes the audio stack and renders per-distro
remediations, enumerates DACs with a manual node.name escape hatch,
generates the PipeWire / WirePlumber snippets to copy, and plays four
tracks spanning 16/44.1 to 24/192 with a live requested-vs-negotiated
read-back. Read-only: it never writes a system file or runs a command.
The logic was unreachable from Qt — every public function in
qbz-dac-wizard takes a &AppWindow and writes straight into Slint globals.
It is lifted into a new frontend-agnostic crate, qbz-dac-wizard-core,
which returns plain data. qbz-dac-wizard itself is left untouched.
Rust owns everything it computes plus `open`, so the reset and the probe
are one act; QML owns the step navigation and the four progress
checkboxes, which is how the reference splits them too.
Two deliberate divergences from the reference: the row sits at the end of
OUTPUT rather than BIT-PERFECT, and it is offered on every backend
instead of PipeWire only — someone on ALSA direct is exactly who needs
the walkthrough.
The green glyphs use the accent tint, not success: success has no qrc bake
directory, so a degraded tint set would render nothing at all. Every
success-toned text keeps theme.success (#3fae6a verbatim).
Verified by 309 tests, both QML audits and the offscreen smoke, plus a
forced-route probe that mounts Settings and walks the wizard's steps —
the standard smoke only mounts Home, so it is no evidence for a modal.
The modal was also driven and screenshotted over VNC.
cc
The pane was written fast and had drifted both ways: four whole sections were
a placeholder reading "not ported to the Qt frontend yet", and what was there
carried rows and copy Slint does not have — an invented custom-theme info row,
made-up "Restart to apply" descriptions, dividers Integrations never had, and
two buttons forked inline instead of using the shared control.
Every section is real now, in Slint's order and grouping, with Slint's labels
and control types: Audio, Playback, Appearance, Offline, Local Library,
Blacklist, Integrations, Developer, and the sandbox section that only appears
on a Flatpak or Snap install. Local Library brings the folder table and the
Plex panel — 856 lines of Slint with no counterpart here until now — wired to
the Plex store that landed earlier this round. Its PIN auth flow is not ported,
so the manual server-url and token path is what this exposes.
The rule the round was run under: a row whose key is not in settings_qt's
dispatch renders and does nothing, so it is either wired or not shipped.
"Share logs" was exactly that — present since the port began, inert — and now
opens the on-disk log.
The directory is per-section files under a thin composition root rather than
one growing file, and the sub-nav's bottom spacer stops being arithmetic over a
hardcoded row count, which broke the moment anyone added a section.
cc