iris: a Scroll measures and places its content in the same frame
Follows Iris on the previous commit: "nothing in the framework should ever self heal because it should not be drawn incorrectly in the first place. If you need 2 draws to get something into the correct position then that should happen within the same frame. Layout should never be frame dependent, it should be a pure function of the state." So `Scroll::draw` no longer places its child against last frame's content length and asks for a corrective frame. It draws the child once at that length purely to measure it, then places it at the length just measured, with the end-pin and the clamp applied only to the second placement -- the measure-then-place idiom `Span::draw` and `List::place` already use. Last frame's length survives as a hint that keeps the common case cheap: when the content's length did not change the two regions are identical, so the first call is `draw_inner`'s O(1) `mov` and the second returns at its first line. Nothing drawn depends on the hint. Reverts the frame-loop change from the previous commit (a frame that left anything dirty asked for another), which existed only to deliver that corrective frame and would have made any widget marking itself dirty spin at full rate. Knock-on: an end-anchored Scroll now sits at its end on its first drawn frame rather than its second, since the end-pin no longer waits for a length. Two layout tests that scroll down from what they assumed was the top now build their area with `at_end: false`, which is what they meant. `List::clamp_to_content` is the only next-frame correction left. Its comment cited Scroll's lag as precedent, which no longer exists; it now says it is a deviation from the rule, and docs/IRIS_TODO.md carries it. Verified: the layer-1 test draws no settling frame and still passes; on the emulator the caret's bottom is 1509 against a bar edge of 1535, 26px inside a 31px padding. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ba57086361
commit
a00376994e
9 files changed
+181
-131
No files matched your search
@@ -7,6 +7,24 @@ order and what "done" looks like. Tick and date them in place.
|
||||
|
||||
## Fix
|
||||
|
||||
- [ ] **`List::clamp_to_content` still corrects on the next frame
|
||||
(2026-09-08).** Iris's rule, stated while the composer's caret was
|
||||
being fixed: "nothing in the framework should ever self heal because
|
||||
it should not be drawn incorrectly in the first place. If you need 2
|
||||
draws to get something into the correct position then that should
|
||||
happen within the same frame. Layout should never be frame dependent,
|
||||
it should be a pure function of the state." `Scroll::draw` was brought
|
||||
to that rule the same day (it measures its content and places it
|
||||
again in the one frame, IRIS.md's entry). `List::clamp_to_content` is
|
||||
the one place left that has not been: it discovers a fling has run
|
||||
past the content's end, calls `scroll(gap)` and `Painter::draw_again`,
|
||||
and asks its own `RequestRedraw` handle for a frame -- so one frame is
|
||||
drawn with the content past its end and the next one snaps it back.
|
||||
The fix is the same shape as `Scroll`'s: re-place inside the draw that
|
||||
found the gap. Not done in the same change because `List::place` is a
|
||||
larger piece of machinery than `Scroll::draw` and this deserves its
|
||||
own before/after on the phone.
|
||||
|
||||
- [x] **`request_device` asked for compute-shader limits it never uses
|
||||
(2026-09-05).** `Limits::default()` (both `iris/src/android/render.rs`
|
||||
and `iris/src/default/render.rs`) requests desktop-tier compute limits
|
||||
|
||||
Reference in new issue
Block a user