Files
ai-app/IRIS_TODO.md
T
irisandClaude Sonnet 643daf5637 iris: route pointer input per kind, so scroll falls through a hovered button
IRIS_TODO.md's "Input does not fall through by input type": run_sensors
treated "the cursor is over this widget" and "this widget consumed the
event" as the same check, so a widget registered only for click() still
blocked a Scroll meant for a list underneath it. Fixed by judging
consumption per input kind -- with nothing momentary happening this
frame the topmost hovered widget still wins (unchanged), but once a
scroll or a press/release is actually happening, only a widget whose
registered senses include a matching non-hover one (via the new
TypeEventManager::registered, which lists a widget's registrations
without running anything) can consume it.

iris/src/sense_tests.rs builds a button-over-a-list Stack with a plain
HasEvents impl (no GPU or window) and checks both directions: a scroll
over the button reaches the list, and a real click still reaches the
button. Confirmed to fail on the pre-fix code and pass after.

Co-Authored-By: Claude Sonnet <noreply@anthropic.com>
2026-09-04 23:52:37 -04:00

3.8 KiB

iris: known problems and things still to build

Iris's own list for the library, recorded 2026-09-04 in her words where it matters, so the agents working through RUST.md pick these up in a sensible order rather than rediscovering them. Each item says where it sits in the order and what "done" looks like. Tick and date them in place.

Fix

  • Input does not fall through by input type (2026-09-04). SensorUi::run_sensors (src/default/sense.rs) used to set "consumed, stop checking lower layers" from mere hover — a widget registered for nothing but click() blocked a Scroll meant for whatever was behind it, since "the cursor is over this widget" and "this widget handled the event" were the same check. Fixed by judging consumption per input kind: with no button transition and no scroll happening this frame ("momentary" activity), the topmost hovered widget still wins, same as before; when something momentary is happening, only a widget whose registered senses actually include a matching non-hover one (checked via a new TypeEventManager::registered, which lists what a widget registered without running anything) consumes it, so a widget with only Hovering/click handlers can no longer block a scroll from reaching a list underneath. iris/src/sense_tests.rs builds a button-over-a-list Stack with a plain HasEvents impl (no GPU or window) and checks both directions: a scroll over the button reaches the list, and a real click still reaches the button — confirmed to fail on the pre-fix code and pass after.

Build

  • Benchmarks, not unit tests, run on demand (a benches/ or a script under iris/, never in cargo test). The scenario that matters most is a message list — chat apps and this app's transcript alike — stressed with many messages and many images. One case in particular: resizing an input box (typing enough text to grow it) that pushes a long list of messages above it must stay very fast and recalculate almost nothing — a move of everything above, not a re-layout. That is exactly the O(1) move chain in LAYOUT.md; the benchmark is what proves it. Done when the numbers are in this file with the command, and the input-box case reports draws re-run, not just frame time.
  • Masks defined relative to each other. Wanted: mask A multiplies by something and also applies mask B — a mask can reference a parent mask, the way the move chain references a parent offset. Today masks are independent regions. Design it beside the move chain (same shape: a parent index and a bounded walk in the shader); do it when a real widget needs it, not before.
  • Positions as a single float per scroll. Iris raised, and half rejected, letting a scroll update one float rather than positions: input handling cares about most elements in a list, so absolute positions must be computed on the CPU anyway. LAYOUT.md's design already lands here (GPU walks the chain, CPU resolves on demand for hit tests). Keep the CPU resolution lazy and per query; do not materialise every row's absolute position per frame.
  • Animations, last. Cosmetic, so after everything above. Must be modular — a piece of the library rather than a core part forced into everything, the same way input is. Whatever the mechanism, a widget that does not animate must pay nothing and import nothing for it.

Reconsider

  • WidgetView. Iris is unsure of it: what she wants is an easy way to compose a widget from others (a button is the main case). With sizing folded into draw, composing may be easy enough that View is redundant. Decide after the layout change lands, by writing a button both ways and keeping the one that is shorter to explain; delete the other rather than keeping two ways.