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>
67 lines
3.8 KiB
Markdown
67 lines
3.8 KiB
Markdown
# 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
|
|
|
|
- [x] **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.
|