Take input per kind, rather than deciding it once a frame

Reviewing this against the process we agreed: the title claimed per-kind
routing and the code decided it once for the whole frame. A scroll and a
click in the same frame both went to the button, because a widget that
matched any momentary sense consumed everything.

Consumption is now removing an input from the cursor the layers below see.
`CursorSense::take` states what each sense takes -- exhaustively, so a new
sense has to answer the question rather than inherit a default -- and
`is_momentary` is gone with the enumeration it was written on. `should_run`
and consumption share one matcher instead of two copies of the table.

Two tests, each checked to fail without the change: a click and a scroll in
one frame reach different widgets, and leaving a widget still ends its hover.
The second is a regression this review caught in its own first draft, where
the skip condition used `is_off`, which counts `End` -- the one frame a
hover-end handler has to run on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-09-13 19:09:50 -04:00
1 parent f62131eecf
commit 0e7076a01c
3 files changed
+138 -76

No files matched your search

+1 -5
View File
@@ -135,11 +135,7 @@ impl<Rsc: HasEvents + 'static, E: Event> TypeEventManager<Rsc, E> {
));
}
/// The event lists this widget was registered with, without running
/// anything. Asking what a widget would match is a separate question
/// from dispatching to it: input routing needs the first to decide
/// whether a widget consumes an event, and `run_fn` can only answer
/// the second.
/// What this widget registered, without running any of it.
pub fn registered(&self, id: WidgetId) -> impl Iterator<Item = &E> {
self.map.get(&id).into_iter().flatten().map(|(e, _)| e)
}