Report consumption from run_event
`Event::consumes` says whether having run uses up what triggered it, defaulting to no. `run_fn` already calls `should_run` per registration, so it ors that across everything that ran and hands it back through `run_event`. `CursorSenses` answers it with the sense it matched: a press or a scroll is used up, hovering is not. That drops `TypeEventManager::registered` and the second pass over a widget's senses -- the match that decides consumption is now the same one that decides whether the handler runs. A cursor that is only resting still stops at the layer it is over, which `run_event` cannot report because nothing need answer for it to be true. It must not stop at a widget it has merely left, though, or ending a hover above blocks the hover below: `leaving_a_widget_does_not_block_the_layer_below` is that case, and it fails on `main` too.
This commit is contained in:
1 parent
e53ce585e6
commit
827d317f41
5 files changed
+57
-26
No files matched your search
+12
-19
@@ -37,19 +37,11 @@ impl Event for CursorSenses {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CursorSenses {
|
||||
/// Whether a widget with these senses stops the input reaching the layer
|
||||
/// below it. A cursor that is only somewhere stops at the first layer it
|
||||
/// is over. A cursor doing something -- a press, a scroll -- stops only
|
||||
/// where something answers to it, so a button drawn over a list does not
|
||||
/// swallow the list's scrolling.
|
||||
fn consumes(&self, cursor: &CursorState, hover: ActivationState) -> bool {
|
||||
if cursor.position_only() {
|
||||
return true;
|
||||
}
|
||||
should_run(self, cursor, hover).is_some_and(|sense| !sense.position_only())
|
||||
/// A press or a scroll is used up by whatever answered it, so it stops
|
||||
/// there. Hovering is not: a cursor resting somewhere goes on resting.
|
||||
fn consumes(&self, data: &Self::Data<'_>) -> bool {
|
||||
!data.sense.position_only()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,6 +182,7 @@ impl SensorUi for UiRenderState {
|
||||
// state like thing, but local to render state, and is passed to UiRsc events so you can
|
||||
// update it there?
|
||||
let mut active = std::mem::take(&mut rsc.events_mut().get_type::<CursorSense>().active);
|
||||
let resting = cursor.position_only();
|
||||
for layer in self.layers.indices().rev() {
|
||||
let mut consumed = false;
|
||||
for (id, sensor) in active.get_mut(&layer).into_flat_iter() {
|
||||
@@ -200,12 +193,6 @@ impl SensorUi for UiRenderState {
|
||||
if sensor.hover == ActivationState::Off {
|
||||
continue;
|
||||
}
|
||||
consumed |= rsc
|
||||
.events_mut()
|
||||
.get_type::<CursorSense>()
|
||||
.registered(*id)
|
||||
.any(|senses| senses.consumes(&cursor, sensor.hover));
|
||||
|
||||
let cursor = cursor.clone();
|
||||
|
||||
let data = CursorData {
|
||||
@@ -219,7 +206,13 @@ impl SensorUi for UiRenderState {
|
||||
sense: CursorSense::Hovering,
|
||||
render: self,
|
||||
};
|
||||
rsc.run_event::<CursorSense>(*id, data, state);
|
||||
// A cursor that is only resting stops at the layer it is
|
||||
// over, answered or not -- but not at a widget it has just
|
||||
// left, which is here only to end its hover. An action stops
|
||||
// where something answered it, so a button over a list does
|
||||
// not swallow the list's scrolling.
|
||||
let answered = rsc.run_event::<CursorSense>(*id, data, state);
|
||||
consumed |= answered || (resting && in_shape);
|
||||
}
|
||||
if consumed {
|
||||
break;
|
||||
|
||||
Reference in new issue
Block a user