Keep the grid's place when another screen covers it
Opening Settings, Import or People and coming back landed at the top of the library however deep in it you had been. The grid is gated on an `if` in the markup, so every route away from it destroys the subtree and rebuilds it. A Flickable being destroyed passes its viewport through zero on the way out, and that reaches `on_library_scrolled` looking exactly like the user having flung the grid to the top. The handler already guarded against it -- but on `show-library`, which means "the library rather than develop" and stays true while any of those four screens replaces the window. So the guard covered the develop route and none of the other three: `resume_at` was overwritten with 0 on the way out, and the position was gone before anything could restore it. The condition the `if` is actually spelled with is now computed once, in `app.slint`, and Rust reads that. The two cannot drift apart again because there is only one of them. That fixes the overwrite. The second half is that nothing replayed the position on the way back in: `on_back_to_library` does it by hand, and Settings, Import, People and the launch screen do not go through it. Rather than teaching three more modules to call it, `scroll-to` is now kept current on every scroll. It is read by `seek()`, which runs on a token change and on `init`, so writing it without bumping the token cannot move the grid on screen -- and is exactly what the next grid reads when it is built. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+17
-1
@@ -270,6 +270,22 @@ export component AppWindow inherits Window {
|
||||
// Shown after a library is opened, before an image is chosen. Cells are a
|
||||
// window over the catalog, not the whole of it.
|
||||
in property <bool> show-library: false;
|
||||
/// Whether the grid is actually on screen — the condition the `if` below
|
||||
/// is written with, hoisted so Rust can read the same answer.
|
||||
///
|
||||
/// **`show-library` is not that answer.** It says "the library rather than
|
||||
/// develop", and stays true while Settings, Import, People or the launch
|
||||
/// screen replaces the window. The grid subtree is torn down in all four
|
||||
/// cases, and a Flickable being destroyed passes its viewport through zero
|
||||
/// on the way out — which reaches `on_library_scrolled` as a scroll to the
|
||||
/// top of the library and overwrote the position the user was at. That is
|
||||
/// the "I open Settings and come back to the beginning" report.
|
||||
///
|
||||
/// So the guard has to be this, and the `if` has to be spelled from it, or
|
||||
/// the two can drift apart again.
|
||||
out property <bool> library-visible:
|
||||
!root.show-import && !root.show-settings && !root.show-identity
|
||||
&& !root.show-launch && root.show-library;
|
||||
in-out property <[LibraryCell]> library-cells;
|
||||
in property <int> library-total: 0;
|
||||
// --- background activity (FR-CAT-1, FR-NC-6c) ---
|
||||
@@ -1457,7 +1473,7 @@ in property <bool> panel-visible: true;
|
||||
// has been opened but no image chosen yet. The collections sidebar and the
|
||||
// grid are siblings here rather than the sidebar living inside the grid,
|
||||
// because the drag that connects them has to be owned above both.
|
||||
if !root.show-import && !root.show-settings && !root.show-identity && !root.show-launch && root.show-library: Rectangle {
|
||||
if root.library-visible: Rectangle {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: Theme.ground;
|
||||
|
||||
Reference in New Issue
Block a user