e898370bf41f9fca69ca094e3352c3be711e85a8
Building the I3 example (800 rows, some with images, styled with .background(rect(tint))) surfaced a real bug: place()'s Bottom-known branch measured a row at an oversized, fixed-size region and moved it into its final box with reposition -- a pure translation. That is correct for wrapped text, whose reported height doesn't depend on the height it was offered, but Rect (used for every row's background) is is_size_independent because it fills *whatever region it is given*, so it painted at the oversized size and reposition never shrank it back down. The screenshot showed one oversized tinted rectangle covering the whole visible window instead of per-row backgrounds. Fixed by caching each row's height once measured and placing an already-measured row directly at its exact box (one widget_within/ reposition pass, same as any known-size placement) instead of re-measuring every frame. A first-ever appearance still pays a two-draw measurement (draw_twice), and a row whose real height changed since it was cached is corrected the same frame it redraws (not a one-frame lag) via an explicit reposition when the two disagree. Steady-state scroll cost is unaffected: an unchanged row's single placement call still hits draw_inner's existing skip-or-move fast path. Also fixes repair_anchor unconditionally re-snapping a bottom-anchored list's offset to the viewport's edge on every frame snap_end was true -- which discarded a live scroll() call the moment it ran, since snap_end is only recomputed at the end of a layout pass and so still read true from before the scroll. Now only re-snaps when the viewport itself actually resized (tracked via last_viewport_len). Added a_fill_shaped_background_is_not_left_oversized, a direct regression test for the background bug (checks the background rect's own painted pixel size, not just the row's reported extent, which was already correct). cargo test -p iris (26 passed), clippy --all-targets and --benches --release, fmt --all -- --check all clean. Rebenched: all five scenarios still flat across N = 100/1,000/10,000 (numbers in RUST.md's I3 box). Visually verified via run-headless.sh message_list --shot, cropped with a throwaway PNG decoder since no image tooling is installed here. Co-Authored-By: Claude Sonnet <noreply@anthropic.com>
Languages
Rust
53%
Kotlin
44.4%
Shell
2.6%