feat(qt): remember where each page was scrolled, across back and forward
The port of the block Slint repeats in 27 views (NavState.restore-scope /
scroll-restore / report-scroll). A .slint file cannot hand a component a
reference to a Flickable, which is why the reference inlines it; QML can, so
controls/ScrollMemory.qml exists once and 31 containers mount it.
Two divergences from the reference, both forced by the same fact — tabs are not
history entries in this port:
1. THE SCOPE IS NAMED BY THE VIEW, not derived from the entry by a scope_for
table. Slint can derive it because its entries carry the tab
(Favorites { tab }); here an entry is a bare route id, so a derived scope
would read "library" for all five Library tabs and pour the Albums grid's
offset into whatever tab mounted. Letting the reporter name its own scope
buys tab granularity for free, and the mismatch case degrades the right way:
an unmatched scope restores NOTHING instead of restoring the wrong thing.
2. THE RESTORE RE-ASSERTS instead of firing once. A Qt item view resets
contentY to 0 whenever its model is replaced, and several pages assign their
model from a binding whose inputs arrive over the network after the mount —
the album page rebuilds listCells from three deferred rails, so it hands its
ListView a new array up to four times in its first seconds and snaps back to
the top over a restore that already ran correctly. The offset is held and
re-applied until a 2.5 s deadline, or until the user takes over (a wheel, a
drag or a flick raises `moving`, and from then the position is theirs).
Diagnostics are off by default: QT_LOGGING_RULES="qbz.nav.scroll.info=true" for
the QML half, RUST_LOG=qbz=debug for the stamp/arm half.
cc
This commit is contained in:
36 files changed
+581
-22
No files matched your search
@@ -31,6 +31,9 @@ Item {
|
||||
/// instances of this component can be alive at once (Albums, Folders-flat,
|
||||
/// the Artists detail grid), and they must not share a slot.
|
||||
property string surface: "collection"
|
||||
/// Scroll-memory scope for this list ("local:albums" / "local:folders"),
|
||||
/// empty when the host is not the page (the artist detail pane).
|
||||
property string scrollScope: ""
|
||||
/// Flat album rows (already searched/sorted/filtered by the host).
|
||||
property var rows: []
|
||||
/// [{ letter, items: [...] }] — only read when `grouped`.
|
||||
@@ -485,6 +488,12 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
// Back/forward scroll memory — OPT-IN, because this component is mounted
|
||||
// by three different hosts (the Albums tab, the Folders tab and the artist
|
||||
// detail pane) and only the two that ARE the page should own a scroll
|
||||
// scope. The default "" leaves the third inert.
|
||||
ScrollMemory { target: list; scope: root.scrollScope }
|
||||
|
||||
QbzScrollBar {
|
||||
anchors.right: parent.right
|
||||
// Negative when the host insets its content — the bar overhangs to
|
||||
|
||||
Reference in new issue
Block a user