Route pointer input per kind, so a scroll falls through a hovered button

`run_sensors` decided that a widget had consumed the frame's input from
hover alone: if the cursor was inside its shape, no lower layer saw
anything. So a button sitting over a list swallowed the list's scroll,
having registered nothing but `click()`.

Being in shape still runs a widget -- a hover highlight has to fire on the
topmost thing under the cursor regardless -- but consuming is now judged
per input kind. With nothing momentary happening the behaviour is
unchanged and the topmost widget wins the hover; with a scroll or a press
happening, only a widget that registered a matching momentary sense
consumes it.

`TypeEventManager::registered` is what makes that askable: what a widget
would match is a different question from dispatching to it, and `run_fn`
can only answer the second.

tests/pointer_routing.rs drives `run_sensors` directly, with no GPU and no
window. It fails on the unfixed code with "a scroll over the button must
still reach the list underneath it".
This commit is contained in:
iris committed 2026-09-13 04:01:22 -04:00
1 parent 0f6a28b4dd
commit 028521b419
3 files changed
+170 -1

No files matched your search

+9
View File
@@ -135,6 +135,15 @@ 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.
pub fn registered(&self, id: WidgetId) -> impl Iterator<Item = &E> {
self.map.get(&id).into_iter().flatten().map(|(e, _)| e)
}
pub fn run_fn<'a>(
&mut self,
id: impl IdLike,