diff --git a/src/input/pointer/mod.rs b/src/input/pointer/mod.rs index e0101a8f291a..4b91ed62c5d7 100644 --- a/src/input/pointer/mod.rs +++ b/src/input/pointer/mod.rs @@ -141,6 +141,17 @@ where fn gesture_hold_end(&self, seat: &Seat, data: &mut D, event: &GestureHoldEndEvent); /// A pointer of a given seat left this handler fn leave(&self, seat: &Seat, data: &mut D, serial: Serial, time: u32); + /// A pointer of a given seat moved from another handler to this handler + fn replace( + &self, + replaced: ::PointerFocus, + seat: &Seat, + data: &mut D, + event: &MotionEvent, + ) { + PointerTarget::::leave(&replaced, seat, data, event.serial, event.time); + PointerTarget::::enter(self, seat, data, event); + } } impl PointerHandle { @@ -717,42 +728,30 @@ impl PointerInternal { focus: Option<(::PointerFocus, Point)>, event: &MotionEvent, ) { - // do we leave a surface ? - let mut leave = true; self.location = event.location; - if let Some((ref current_focus, _)) = self.focus { - if let Some((ref new_focus, _)) = focus { - if current_focus == new_focus { - leave = false; - } - } - } - if leave { - if let Some((focused, _)) = self.focus.as_mut() { - focused.leave(seat, data, event.serial, event.time); - } - self.focus = None; - data.cursor_image(seat, CursorImageStatus::default_named()); - } - - // do we enter one ? - if let Some((surface, surface_location)) = focus { - let entered = self.focus.is_none(); - // in all cases, update the focus, the coordinates of the surface - // might have changed - self.focus = Some((surface, surface_location)); + if let Some((focus, loc)) = focus { let event = MotionEvent { - location: event.location - surface_location.to_f64(), + location: event.location - loc.to_f64(), serial: event.serial, time: event.time, }; - let (focused, _) = self.focus.as_mut().unwrap(); - if entered { - focused.enter(seat, data, &event); - } else { - // we were on top of a surface and remained on it - focused.motion(seat, data, &event); - } + let old_focus = self.focus.replace((focus.clone(), loc)); + match (focus, old_focus) { + (focus, Some((old_focus, _))) if focus == old_focus => { + // we were on top of a target and remained on it + focus.motion(seat, data, &event); + } + (focus, Some((old_focus, _))) => { + // the target has been replaced + focus.replace(old_focus, seat, data, &event); + } + (focus, None) => { + // we entered a new target + focus.enter(seat, data, &event); + } + }; + } else if let Some((old_focus, _)) = self.focus.take() { + old_focus.leave(seat, data, event.serial, event.time); } }