Release the offset borrow before bring_window_to reloads the window

Holding D in develop across the edge of the loaded window panicked with
"RefCell already borrowed" at the first step that had to move it. The
`*ctl.offset.borrow()` written inside the `if let` condition is a
temporary that lives to the end of the `if let` block (edition 2021),
and the block calls `load_window`, which borrows the offset mutably.
The unit tests drive the placement arithmetic, not the RefCells, so
they could not see it; stepping 400 frames in the app did.

The offset is copied out before the test. `follow_open` gets the same
treatment for `image_ids`: the lookup's result is bound first, so no
borrow is held while it writes properties back to the window.
This commit is contained in:
2026-09-25 23:06:24 -04:00
parent a030bfd239
commit 19dd3257e3
2 changed files with 11 additions and 7 deletions
File diff suppressed because one or more lines are too long
+6 -2
View File
@@ -216,7 +216,10 @@ pub(super) fn bring_window_to(
let loaded = ctl.paths.borrow().len();
let size = *ctl.window.borrow();
let total = window.global::<Library>().get_library_total().max(0) as usize;
if let Some(offset) = window_for(at, *ctl.offset.borrow(), loaded, size, total) {
// Copied out first: a `borrow()` written in the `if let` below would live
// to the end of its block, and `load_window` borrows the offset mutably.
let offset = *ctl.offset.borrow();
if let Some(offset) = window_for(at, offset, loaded, size, total) {
*ctl.offset.borrow_mut() = offset;
load_window(window, ctl);
}
@@ -257,7 +260,8 @@ fn follow_open(window: &AppWindow, ctl: &LibraryController, offset: usize) {
return;
};
let index = window.get_index().max(0) as usize;
match locate_open(open, &ctl.image_ids.borrow(), offset, index) {
let found = locate_open(open, &ctl.image_ids.borrow(), offset, index);
match found {
Ok(row) => {
ctl.roll_left.set(false);
window