diff --git a/crates/context_menu/src/context_menu.rs b/crates/context_menu/src/context_menu.rs index de78b51e9c071aadd28750c8f45b5d039c502a33..9bdf146da47e4f8e882cabbf0fd116b7f5676b7f 100644 --- a/crates/context_menu/src/context_menu.rs +++ b/crates/context_menu/src/context_menu.rs @@ -301,18 +301,23 @@ impl ContextMenu { cx: &mut ViewContext, ) { let mut items = items.into_iter().peekable(); - if items.peek().is_some() { - self.items = items.collect(); - self.anchor_position = anchor_position; - self.anchor_corner = anchor_corner; - self.visible = true; - self.show_count += 1; - if !cx.is_self_focused() { - self.previously_focused_view_id = cx.focused_view_id(); - } - cx.focus_self(); - } else { + dbg!(self.visible); + if (self.visible) { self.visible = false; + } else { + if items.peek().is_some() { + self.items = items.collect(); + self.anchor_position = anchor_position; + self.anchor_corner = anchor_corner; + self.visible = true; + self.show_count += 1; + if !cx.is_self_focused() { + self.previously_focused_view_id = cx.focused_view_id(); + } + cx.focus_self(); + } else { + self.visible = false; + } } cx.notify(); } diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index cffce6c3a6c646094f7247683def5d148c550138..cc6778c930c0fb7b8740738ca0c202be8a4d8fd2 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -9,7 +9,7 @@ use crate::{ }, scene::{ CursorRegion, MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseEvent, MouseHover, - MouseMove, MouseMoveOut, MouseScrollWheel, MouseUp, MouseUpOut, Scene, + MouseMove, MouseMoveOut, MouseScrollWheel, MouseUp, MouseUpOut, Scene, MouseClickOut, }, text_layout::TextLayoutCache, util::post_inc, @@ -524,6 +524,10 @@ impl<'a> WindowContext<'a> { region: Default::default(), platform_event: e.clone(), })); + mouse_events.push(MouseEvent::ClickOut(MouseClickOut { + region: Default::default(), + platform_event: e.clone(), + })); } Event::MouseMoved( diff --git a/crates/gpui/src/scene/mouse_event.rs b/crates/gpui/src/scene/mouse_event.rs index cf0a08f33ed50ead5e5f4619cbb024603de780a9..a492da771b848574e29411e91d8876873ead4917 100644 --- a/crates/gpui/src/scene/mouse_event.rs +++ b/crates/gpui/src/scene/mouse_event.rs @@ -99,6 +99,20 @@ impl Deref for MouseClick { } } +#[derive(Debug, Default, Clone)] +pub struct MouseClickOut { + pub region: RectF, + pub platform_event: MouseButtonEvent, +} + +impl Deref for MouseClickOut { + type Target = MouseButtonEvent; + + fn deref(&self) -> &Self::Target { + &self.platform_event + } +} + #[derive(Debug, Default, Clone)] pub struct MouseDownOut { pub region: RectF, @@ -150,6 +164,7 @@ pub enum MouseEvent { Down(MouseDown), Up(MouseUp), Click(MouseClick), + ClickOut(MouseClickOut), DownOut(MouseDownOut), UpOut(MouseUpOut), ScrollWheel(MouseScrollWheel), @@ -165,6 +180,7 @@ impl MouseEvent { MouseEvent::Down(r) => r.region = region, MouseEvent::Up(r) => r.region = region, MouseEvent::Click(r) => r.region = region, + MouseEvent::ClickOut(r) => r.region = region, MouseEvent::DownOut(r) => r.region = region, MouseEvent::UpOut(r) => r.region = region, MouseEvent::ScrollWheel(r) => r.region = region, @@ -182,6 +198,7 @@ impl MouseEvent { MouseEvent::Down(_) => true, MouseEvent::Up(_) => true, MouseEvent::Click(_) => true, + MouseEvent::ClickOut(_) => true, MouseEvent::DownOut(_) => false, MouseEvent::UpOut(_) => false, MouseEvent::ScrollWheel(_) => true, @@ -222,6 +239,10 @@ impl MouseEvent { discriminant(&MouseEvent::Click(Default::default())) } + pub fn click_out_disc() -> Discriminant { + discriminant(&MouseEvent::ClickOut(Default::default())) + } + pub fn down_out_disc() -> Discriminant { discriminant(&MouseEvent::DownOut(Default::default())) } @@ -239,6 +260,7 @@ impl MouseEvent { MouseEvent::Down(e) => HandlerKey::new(Self::down_disc(), Some(e.button)), MouseEvent::Up(e) => HandlerKey::new(Self::up_disc(), Some(e.button)), MouseEvent::Click(e) => HandlerKey::new(Self::click_disc(), Some(e.button)), + MouseEvent::ClickOut(e) => HandlerKey::new(Self::click_out_disc(), Some(e.button)), MouseEvent::UpOut(e) => HandlerKey::new(Self::up_out_disc(), Some(e.button)), MouseEvent::DownOut(e) => HandlerKey::new(Self::down_out_disc(), Some(e.button)), MouseEvent::ScrollWheel(_) => HandlerKey::new(Self::scroll_wheel_disc(), None), diff --git a/crates/gpui/src/scene/mouse_region.rs b/crates/gpui/src/scene/mouse_region.rs index 0efc794148868c537eae37f4027ae8f23afa177c..7e1d5d6e1e4f12c0162607d3c4460fe37092a348 100644 --- a/crates/gpui/src/scene/mouse_region.rs +++ b/crates/gpui/src/scene/mouse_region.rs @@ -14,7 +14,7 @@ use super::{ MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseEvent, MouseHover, MouseMove, MouseUp, MouseUpOut, }, - MouseMoveOut, MouseScrollWheel, + MouseMoveOut, MouseScrollWheel, MouseClickOut, }; #[derive(Clone)] @@ -89,6 +89,15 @@ impl MouseRegion { self } + pub fn on_click_out(mut self, button: MouseButton, handler: F) -> Self + where + V: View, + F: Fn(MouseClickOut, &mut V, &mut EventContext) + 'static, + { + self.handlers = self.handlers.on_click(button, handler); + self + } + pub fn on_down_out(mut self, button: MouseButton, handler: F) -> Self where V: View, @@ -405,6 +414,28 @@ impl HandlerSet { self } + pub fn on_click_out(mut self, button: MouseButton, handler: F) -> Self + where + V: View, + F: Fn(MouseClickOut, &mut V, &mut EventContext) + 'static, + { + self.insert(MouseEvent::click_out_disc(), Some(button), + Rc::new(move |region_event, view, cx, view_id| { + if let MouseEvent::ClickOut(e) = region_event { + let view = view.downcast_mut().unwrap(); + let mut cx = ViewContext::mutable(cx, view_id); + let mut cx = EventContext::new(&mut cx); + handler(e, view, &mut cx); + cx.handled + } else { + panic!( + "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::ClickOut, found {:?}", + region_event); + } + })); + self + } + pub fn on_down_out(mut self, button: MouseButton, handler: F) -> Self where V: View,