Anchor the delete on what the view was showing, not on the window's start
Build and test / Desktop (Linux) (push) Failing after 2m33s
Build and test / Layer separation (push) Successful in 23s
Traceability / Requirement traces (push) Successful in 22s
🐳 Android image / Build and push (push) Successful in 1s
Build and test / android-image (push) Successful in 2s
Build and test / Android (aarch64) (push) Failing after 6s

The grid still jumped. Anchoring on `offset` was wrong for a reason this file
already states, a few hundred lines away: "the first *visible* ordinal, not the
window's start: the loaded window deliberately begins a quarter of a screen
above the view, so its first cell is one the user cannot see."

Two things made `offset` the wrong number. It is a screen-quarter above what is
being looked at, and by the point this runs it has already been re-clamped
against the new, smaller total — so seeking to it moved the view somewhere the
photographer had not been. A smaller jump than the original, and the same fault.

`resume_at` is what the grid last reported as its first visible image, which is
the photograph the person is actually looking at.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-23 19:38:27 +02:00
co-authored by Claude Opus 5
parent cd64166b15
commit 6b5ffc6a93
2 changed files with 27 additions and 14 deletions
+16 -3
View File
@@ -3948,7 +3948,18 @@ pub fn restore_position(window: &AppWindow, ctl: &Rc<LibraryController>) {
if total == 0 {
return;
}
let anchor = (*ctl.offset.borrow()).min(total - 1);
// The first *visible* ordinal, not the loaded window's start.
//
// Anchoring on `offset` was the first attempt and it still jumped, because
// the two are deliberately different: the window begins about a quarter of
// a screen above the view so scrolling up has rows ready, and by this point
// in `load_window` it has also been re-clamped against the new, smaller
// total. Seeking to it therefore moved the view to somewhere the user was
// not — a smaller jump than before, but the same fault.
//
// `resume_at` is what the grid last reported as its first visible image,
// which is the thing the photographer is actually looking at.
let anchor = ctl.resume_at.get().min(total - 1);
window.set_library_scroll_to(anchor as i32);
window.set_library_scroll_token(window.get_library_scroll_token() + 1);
}
@@ -5555,8 +5566,10 @@ mod tests {
/// view left pointing past the end of the content — or appeared to jump,
/// the same scroll position now addressing different photographs.
///
/// The anchor is the offset clamped into what is left: the ordinal the view
/// was showing, or the last one there is if it was near the end.
/// The anchor is the last *visible* ordinal the grid reported, clamped into
/// what is left — not the loaded window's `offset`, which sits about a
/// quarter of a screen above the view and is itself re-clamped by the
/// delete. Anchoring on that was the first attempt and still jumped.
#[test]
fn a_shorter_library_anchors_the_view_instead_of_losing_it() {
// The rule `restore_position` applies, stated where it can be checked.