From af1b0c5ab28a8ee7296bc2d1706dda416c56b7e4 Mon Sep 17 00:00:00 2001 From: iris <2+iris@noreply.localhost> Date: Tue, 8 Sep 2026 13:57:35 -0400 Subject: [PATCH] docs/RUST.md: what the folded-card sanity check found Co-Authored-By: Claude Opus 5 --- docs/RUST.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/docs/RUST.md b/docs/RUST.md index 03106a1..754394d 100644 --- a/docs/RUST.md +++ b/docs/RUST.md @@ -7981,6 +7981,51 @@ is the framework's intended change detection or a way around it, and if iris's change detection is meant to handle "edit the widgets in the context normally", why this screen does not. +#### Worked, 2026-09-08 + +The sanity check she asked for, done by reading `tool.rs` against the +framework and by looking at the fixture running +(`IRIS_TOOLS_EXPANDED=1 iris/run-headless.sh phone --phone --shot`): + +- **`tool.rs`'s framework usage is sound as far as it goes.** A card is a + `WidgetPtr` slot whose content is replaced, the gesture is registered + once on the slot and every rebuild reads the call back out of `Shared`, + and the group's toggle replaces the row's content rather than editing + it. That is the framework's supported way to change a subtree. What it + is *not* is the finer-grained "edit the widget in place and let change + detection notice" Iris has in mind -- opening one card re-shapes every + string in it. Worth revisiting, but it is a cost question, not the + cause of anything she saw. +- **What she saw is much more likely the gesture bug in item 1.** A card's + tap goes through the *same shared* `DragGesture` as the list's pan + (`on_tap` -> `Selection::drag`), and that gesture was being left open + with a stale origin by any capture it lost. In that state a tap on a + card produces `Pan`, not `Tapped`: the list jumps and the card does not + open. "Pretty buggy" is exactly what that looks like. Fixed above; it + wants confirming from her phone. +- **A real defect found and fixed while looking**: a scroll area opened + at the **end** of content it had not measured yet, so a code fence + opened in the middle of a word. `Scroll::content_len` was `0.0` for + both "nothing here" and "not drawn yet", the clamp read `amt == len` as + "at the end" on the first frame, and the second frame jumped there. It + is an `Option` now. Which edge an area opens at is a caller's decision + too: `scrollable_on` starts at the beginning, `scrollable_to_end` pins + to the end for the composer, one `Scroll::new(inner, axis, at_end)` + behind both. Test: + `a_scroll_area_opens_at_the_start_of_content_it_has_not_measured_yet`, + which checks both edges. +- **One of the four IRIS_TODO items is stale**: `scrollable_on(Axis::X)` + on a non-editable `Text` draws fine now, most likely fixed by the + shaped-mask work (`.masked_by`, 38bf630). `raw_block` pans sideways + again instead of clipping, so a long command is readable. Ticked there + with the original symptom kept. +- **Still open, and the one certain thing in her screenshot**: the + chevron. The mark is a font codepoint (U+25B8/25BE/25B4) and the + bundled fonts were removed on 2026-09-07, so the phone draws an empty + box and the desktop draws a dot. It needs a drawn mark -- a texture + generated at the size wanted, since iris has rects, text and textures + and no path primitive. Not done here. + ### 3. "The benchmark scrolling seems like it's at 60fps or something, it's ### way less smooth than me scrolling manually"