Perry version: 0.5.1161 (iOS)
Summary
scrollViewSetOffset(scrollView, x, y) ignores the y argument and always uses x, so any caller that does scrollViewSetOffset(sv, 0, savedY) scrolls to 0 (the top) instead of savedY.
Cause
The dispatch table declares 3 args:
// crates/perry-dispatch/src/ui_table.rs
MethodRow { method: "scrollViewSetOffset", runtime: "perry_ui_scrollview_set_offset",
args: &[ArgKind::Widget, ArgKind::F64, ArgKind::F64], ret: ReturnKind::Void },
…but the FFI + impl took a single offset and bound it to the first f64 (the x coordinate):
// crates/perry-ui-ios/src/ffi/widgets_basic.rs
pub extern "C" fn perry_ui_scrollview_set_offset(scroll_handle: i64, offset: f64) { ... }
// crates/perry-ui-ios/src/widgets/scrollview.rs
pub fn set_offset(scroll_handle: i64, offset: f64) {
let point = CGPoint::new(0.0, offset); // offset = x (usually 0) → contentOffset.y = 0
msg_send![scroll_view, setContentOffset: point, animated: true];
}
So setContentOffset got (0, x) and x is almost always 0 → scrolls to top.
Impact
Breaks scroll-position restoration across rebuilds in any immediate-mode/rebuild app: every rebuild that calls scrollViewSetOffset(sv, 0, savedY) snaps the view to the top. (Also surfaced as an apparent "the screen jumps to the top whenever I tap a control" in our app.)
Fix (applied locally, PR-able)
Make the FFI/impl take both coordinates, and don't animate (this is used to restore position):
pub extern "C" fn perry_ui_scrollview_set_offset(scroll_handle: i64, x: f64, y: f64) {
widgets::scrollview::set_offset(scroll_handle, x, y);
}
pub fn set_offset(scroll_handle: i64, x: f64, y: f64) {
let point = CGPoint::new(x, y);
let _: () = msg_send![scroll_view, setContentOffset: point, animated: false];
}
Perry version: 0.5.1161 (iOS)
Summary
scrollViewSetOffset(scrollView, x, y)ignores theyargument and always usesx, so any caller that doesscrollViewSetOffset(sv, 0, savedY)scrolls to 0 (the top) instead ofsavedY.Cause
The dispatch table declares 3 args:
…but the FFI + impl took a single offset and bound it to the first f64 (the x coordinate):
So
setContentOffsetgot(0, x)and x is almost always 0 → scrolls to top.Impact
Breaks scroll-position restoration across rebuilds in any immediate-mode/rebuild app: every rebuild that calls
scrollViewSetOffset(sv, 0, savedY)snaps the view to the top. (Also surfaced as an apparent "the screen jumps to the top whenever I tap a control" in our app.)Fix (applied locally, PR-able)
Make the FFI/impl take both coordinates, and don't animate (this is used to restore position):