diff --git a/crates/gpui2/src/geometry.rs b/crates/gpui2/src/geometry.rs index b472d77f57..95fa6c2353 100644 --- a/crates/gpui2/src/geometry.rs +++ b/crates/gpui2/src/geometry.rs @@ -7,9 +7,7 @@ use std::{ ops::{Add, Div, Mul, MulAssign, Sub}, }; -#[derive( - Refineable, Default, Add, AddAssign, Sub, SubAssign, Copy, Debug, PartialEq, Eq, Hash, -)] +#[derive(Refineable, Default, Add, AddAssign, Sub, SubAssign, Copy, Debug, PartialEq, Eq, Hash)] #[refineable(debug)] #[repr(C)] pub struct Point { @@ -41,6 +39,10 @@ impl Point { y: self.y.scale(factor), } } + + pub fn magnitude(&self) -> f64 { + ((self.x.0.powi(2) + self.y.0.powi(2)) as f64).sqrt() + } } impl Mul for Point diff --git a/crates/gpui2/src/interactive.rs b/crates/gpui2/src/interactive.rs index 0479d49f74..a078efff30 100644 --- a/crates/gpui2/src/interactive.rs +++ b/crates/gpui2/src/interactive.rs @@ -16,6 +16,8 @@ use std::{ sync::Arc, }; +const DRAG_THRESHOLD: f64 = 2.; + pub trait StatelessInteractive: Element { fn stateless_interactivity(&mut self) -> &mut StatelessInteraction; @@ -531,6 +533,7 @@ pub trait ElementInteraction: 'static + Send + Sync { if let Some(mouse_down) = mouse_down { if let Some(drag_listener) = drag_listener { let active_state = element_state.active_state.clone(); + cx.on_mouse_event(move |view_state, event: &MouseMoveEvent, phase, cx| { if cx.active_drag.is_some() { if phase == DispatchPhase::Capture { @@ -538,6 +541,8 @@ pub trait ElementInteraction: 'static + Send + Sync { } } else if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) + && (event.position - mouse_down.position).magnitude() + > DRAG_THRESHOLD { let cursor_offset = event.position - bounds.origin; let any_drag = drag_listener(view_state, cursor_offset, cx);