From f9b0c926d9d14c05145fe50e6dd588824ec96840 Mon Sep 17 00:00:00 2001 From: xarvic Date: Fri, 25 Nov 2022 18:53:09 +0100 Subject: [PATCH 1/4] - change WidgetPod::event to only send follow up events when ctx.set_handled is called - add event.is_pointer_event() --- druid/src/core.rs | 10 +++++----- druid/src/event.rs | 7 +++++++ druid/src/widget/z_stack.rs | 26 +++++++++++++------------- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/druid/src/core.rs b/druid/src/core.rs index 4f32aa701c..ad31b9174c 100644 --- a/druid/src/core.rs +++ b/druid/src/core.rs @@ -666,11 +666,11 @@ impl> WidgetPod { } // TODO: factor as much logic as possible into monomorphic functions. - if ctx.is_handled - && !matches!( - event, - Event::MouseDown(_) | Event::MouseUp(_) | Event::MouseMove(_) | Event::Wheel(_) - ) + // a follow_up event should reach the widget which handled the first event. + // in this case we dont discard events when ctx.is_handled is set but just dont set our hot + // state to true + let follow_up_event = event.is_pointer_event() && self.state.has_active; + if ctx.is_handled && !follow_up_event { // This function is called by containers to propagate an event from // containers to children. Non-recurse events will be invoked directly diff --git a/druid/src/event.rs b/druid/src/event.rs index e45df871e3..3b48dd8ebb 100644 --- a/druid/src/event.rs +++ b/druid/src/event.rs @@ -448,6 +448,13 @@ impl Event { | Event::Zoom(_) => false, } } + + pub fn is_pointer_event(&self) -> bool { + matches!( + event, + Event::MouseDown(_) | Event::MouseUp(_) | Event::MouseMove(_) + ) + } } impl LifeCycle { diff --git a/druid/src/widget/z_stack.rs b/druid/src/widget/z_stack.rs index 8f1d721895..945c8b46ed 100644 --- a/druid/src/widget/z_stack.rs +++ b/druid/src/widget/z_stack.rs @@ -1,7 +1,4 @@ -use crate::{ - BoxConstraints, Data, Env, Event, EventCtx, LayoutCtx, LifeCycle, LifeCycleCtx, PaintCtx, - Point, Rect, Size, UnitPoint, UpdateCtx, Vec2, Widget, WidgetExt, WidgetPod, -}; +use crate::{BoxConstraints, Data, Env, Event, EventCtx, InternalEvent, LayoutCtx, LifeCycle, LifeCycleCtx, PaintCtx, Point, Rect, Size, UnitPoint, UpdateCtx, Vec2, Widget, WidgetExt, WidgetPod}; /// A container that stacks its children on top of each other. /// @@ -94,17 +91,20 @@ impl ZStack { impl Widget for ZStack { fn event(&mut self, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) { - let is_pointer_event = matches!( - event, - Event::MouseDown(_) | Event::MouseMove(_) | Event::MouseUp(_) | Event::Wheel(_) - ); - + let mut previous_hot = false; for layer in self.layers.iter_mut() { - layer.child.event(ctx, event, data, env); - - if is_pointer_event && layer.child.is_hot() { - ctx.set_handled(); + if event.is_pointer_event() && previous_hot { + if layer.child.is_active() { + ctx.set_handled(); + layer.child.event(ctx, event, data, env); + } else { + layer.child.event(ctx, &Event::Internal(InternalEvent::MouseLeave), data, env); + } + } else { + layer.child.event(ctx, event, data, env); } + + previous_hot |= layer.child.is_hot(); } } From eabccefd42d38d691e1e9d9176267b0dbe8c72c6 Mon Sep 17 00:00:00 2001 From: xarvic Date: Fri, 25 Nov 2022 19:54:32 +0100 Subject: [PATCH 2/4] clippy --- druid/src/core.rs | 3 +-- druid/src/event.rs | 6 +++--- druid/src/widget/z_stack.rs | 4 +++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/druid/src/core.rs b/druid/src/core.rs index ad31b9174c..44121fca9e 100644 --- a/druid/src/core.rs +++ b/druid/src/core.rs @@ -670,8 +670,7 @@ impl> WidgetPod { // in this case we dont discard events when ctx.is_handled is set but just dont set our hot // state to true let follow_up_event = event.is_pointer_event() && self.state.has_active; - if ctx.is_handled && !follow_up_event - { + if ctx.is_handled && !follow_up_event { // This function is called by containers to propagate an event from // containers to children. Non-recurse events will be invoked directly // from other points in the library. diff --git a/druid/src/event.rs b/druid/src/event.rs index 3b48dd8ebb..ab965ae8b7 100644 --- a/druid/src/event.rs +++ b/druid/src/event.rs @@ -451,9 +451,9 @@ impl Event { pub fn is_pointer_event(&self) -> bool { matches!( - event, - Event::MouseDown(_) | Event::MouseUp(_) | Event::MouseMove(_) - ) + event, + Event::MouseDown(_) | Event::MouseUp(_) | Event::MouseMove(_) + ) } } diff --git a/druid/src/widget/z_stack.rs b/druid/src/widget/z_stack.rs index 945c8b46ed..f8a21a7bf8 100644 --- a/druid/src/widget/z_stack.rs +++ b/druid/src/widget/z_stack.rs @@ -98,7 +98,9 @@ impl Widget for ZStack { ctx.set_handled(); layer.child.event(ctx, event, data, env); } else { - layer.child.event(ctx, &Event::Internal(InternalEvent::MouseLeave), data, env); + layer + .child + .event(ctx, &Event::Internal(InternalEvent::MouseLeave), data, env); } } else { layer.child.event(ctx, event, data, env); From 8648a217d022d0dce25bf01fbf16035a7a6f6b8d Mon Sep 17 00:00:00 2001 From: xarvic Date: Mon, 28 Nov 2022 21:27:31 +0100 Subject: [PATCH 3/4] change is_pointer_event() --- druid/src/event.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/druid/src/event.rs b/druid/src/event.rs index ab965ae8b7..4ff6765661 100644 --- a/druid/src/event.rs +++ b/druid/src/event.rs @@ -449,10 +449,13 @@ impl Event { } } + /// Returns true if the event involves a cursor. + /// + /// These events interact with the hot state and pub fn is_pointer_event(&self) -> bool { matches!( - event, - Event::MouseDown(_) | Event::MouseUp(_) | Event::MouseMove(_) + self, + Event::MouseDown(_) | Event::MouseUp(_) | Event::MouseMove(_) | Event::Wheel(_) ) } } From 42bc5f0c9f58971525b42841a9895b899f344231 Mon Sep 17 00:00:00 2001 From: xarvic Date: Mon, 28 Nov 2022 21:44:11 +0100 Subject: [PATCH 4/4] fmt --- druid/src/widget/z_stack.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/druid/src/widget/z_stack.rs b/druid/src/widget/z_stack.rs index f8a21a7bf8..d0bbd16718 100644 --- a/druid/src/widget/z_stack.rs +++ b/druid/src/widget/z_stack.rs @@ -1,4 +1,7 @@ -use crate::{BoxConstraints, Data, Env, Event, EventCtx, InternalEvent, LayoutCtx, LifeCycle, LifeCycleCtx, PaintCtx, Point, Rect, Size, UnitPoint, UpdateCtx, Vec2, Widget, WidgetExt, WidgetPod}; +use crate::{ + BoxConstraints, Data, Env, Event, EventCtx, InternalEvent, LayoutCtx, LifeCycle, LifeCycleCtx, + PaintCtx, Point, Rect, Size, UnitPoint, UpdateCtx, Vec2, Widget, WidgetExt, WidgetPod, +}; /// A container that stacks its children on top of each other. ///