diff --git a/crates/gpui3/src/elements/div.rs b/crates/gpui3/src/elements/div.rs index 3623e44a921bb323fbc4e7f8829f8a0e2917d64c..8bf748568e3e4aa4b248414dba31b5572bd6a86d 100644 --- a/crates/gpui3/src/elements/div.rs +++ b/crates/gpui3/src/elements/div.rs @@ -9,7 +9,7 @@ use collections::HashMap; use parking_lot::Mutex; use refineable::Refineable; use smallvec::SmallVec; -use std::sync::Arc; +use std::{mem, sync::Arc}; #[derive(Default)] pub struct DivState { @@ -263,12 +263,12 @@ where } fn paint_event_listeners( - &self, + &mut self, bounds: Bounds, pending_click: Arc>>, cx: &mut ViewContext, ) { - let click_listeners = self.listeners.mouse_click.clone(); + let click_listeners = mem::take(&mut self.listeners.mouse_click); let mouse_down = pending_click.lock().clone(); if let Some(mouse_down) = mouse_down { cx.on_mouse_event(move |state, event: &MouseUpEvent, phase, cx| { @@ -292,25 +292,25 @@ where }); } - for listener in self.listeners.mouse_down.iter().cloned() { + for listener in mem::take(&mut self.listeners.mouse_down) { cx.on_mouse_event(move |state, event: &MouseDownEvent, phase, cx| { listener(state, event, &bounds, phase, cx); }) } - for listener in self.listeners.mouse_up.iter().cloned() { + for listener in mem::take(&mut self.listeners.mouse_up) { cx.on_mouse_event(move |state, event: &MouseUpEvent, phase, cx| { listener(state, event, &bounds, phase, cx); }) } - for listener in self.listeners.mouse_move.iter().cloned() { + for listener in mem::take(&mut self.listeners.mouse_move) { cx.on_mouse_event(move |state, event: &MouseMoveEvent, phase, cx| { listener(state, event, &bounds, phase, cx); }) } - for listener in self.listeners.scroll_wheel.iter().cloned() { + for listener in mem::take(&mut self.listeners.scroll_wheel) { cx.on_mouse_event(move |state, event: &ScrollWheelEvent, phase, cx| { listener(state, event, &bounds, phase, cx); }) @@ -351,7 +351,7 @@ where + Sync + 'static, ) -> Self { - self.listeners.key_down.push(Arc::new(listener)); + self.listeners.key_down.push(Box::new(listener)); self } } @@ -377,8 +377,8 @@ where ) -> Self::ElementState { cx.with_focus( self.focusability.focus_handle().cloned(), - self.listeners.key_down.clone(), - self.listeners.key_up.clone(), + mem::take(&mut self.listeners.key_down), + mem::take(&mut self.listeners.key_up), |cx| { for child in &mut self.children { child.initialize(view_state, cx); diff --git a/crates/gpui3/src/events.rs b/crates/gpui3/src/events.rs index ee5a1f4fdd5d8763ab878cba9be05f88e36f87ce..624b32bc2035d62dcf9b54b780d990f353fcef77 100644 --- a/crates/gpui3/src/events.rs +++ b/crates/gpui3/src/events.rs @@ -1,9 +1,8 @@ -use smallvec::SmallVec; - use crate::{ point, Bounds, DispatchPhase, FocusHandle, Keystroke, Modifiers, Pixels, Point, ViewContext, }; -use std::{any::Any, ops::Deref, sync::Arc}; +use smallvec::SmallVec; +use std::{any::Any, ops::Deref}; #[derive(Clone, Debug, Eq, PartialEq)] pub struct KeyDownEvent { @@ -209,29 +208,29 @@ pub struct FocusEvent { pub focused: Option, } -pub type MouseDownListener = Arc< +pub type MouseDownListener = Box< dyn Fn(&mut V, &MouseDownEvent, &Bounds, DispatchPhase, &mut ViewContext) + Send + Sync + 'static, >; -pub type MouseUpListener = Arc< +pub type MouseUpListener = Box< dyn Fn(&mut V, &MouseUpEvent, &Bounds, DispatchPhase, &mut ViewContext) + Send + Sync + 'static, >; pub type MouseClickListener = - Arc) + Send + Sync + 'static>; + Box) + Send + Sync + 'static>; -pub type MouseMoveListener = Arc< +pub type MouseMoveListener = Box< dyn Fn(&mut V, &MouseMoveEvent, &Bounds, DispatchPhase, &mut ViewContext) + Send + Sync + 'static, >; -pub type ScrollWheelListener = Arc< +pub type ScrollWheelListener = Box< dyn Fn(&mut V, &ScrollWheelEvent, &Bounds, DispatchPhase, &mut ViewContext) + Send + Sync @@ -239,10 +238,10 @@ pub type ScrollWheelListener = Arc< >; pub type KeyDownListener = - Arc) + Send + Sync + 'static>; + Box) + Send + Sync + 'static>; pub type KeyUpListener = - Arc) + Send + Sync + 'static>; + Box) + Send + Sync + 'static>; pub struct EventListeners { pub mouse_down: SmallVec<[MouseDownListener; 2]>, diff --git a/crates/gpui3/src/interactive.rs b/crates/gpui3/src/interactive.rs index ecaebe7681774f451ce6d5f4b7c9c44ce0683b5b..f328f22cc0606ccc7708a4ab785e479ff7392785 100644 --- a/crates/gpui3/src/interactive.rs +++ b/crates/gpui3/src/interactive.rs @@ -2,7 +2,6 @@ use crate::{ DispatchPhase, Element, EventListeners, MouseButton, MouseClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent, ScrollWheelEvent, ViewContext, }; -use std::sync::Arc; pub trait Interactive: Element { fn listeners(&mut self) -> &mut EventListeners; @@ -20,7 +19,7 @@ pub trait Interactive: Element { { self.listeners() .mouse_down - .push(Arc::new(move |view, event, bounds, phase, cx| { + .push(Box::new(move |view, event, bounds, phase, cx| { if phase == DispatchPhase::Bubble && event.button == button && bounds.contains_point(&event.position) @@ -44,7 +43,7 @@ pub trait Interactive: Element { { self.listeners() .mouse_up - .push(Arc::new(move |view, event, bounds, phase, cx| { + .push(Box::new(move |view, event, bounds, phase, cx| { if phase == DispatchPhase::Bubble && event.button == button && bounds.contains_point(&event.position) @@ -68,7 +67,7 @@ pub trait Interactive: Element { { self.listeners() .mouse_down - .push(Arc::new(move |view, event, bounds, phase, cx| { + .push(Box::new(move |view, event, bounds, phase, cx| { if phase == DispatchPhase::Capture && event.button == button && !bounds.contains_point(&event.position) @@ -92,7 +91,7 @@ pub trait Interactive: Element { { self.listeners() .mouse_up - .push(Arc::new(move |view, event, bounds, phase, cx| { + .push(Box::new(move |view, event, bounds, phase, cx| { if phase == DispatchPhase::Capture && event.button == button && !bounds.contains_point(&event.position) @@ -115,7 +114,7 @@ pub trait Interactive: Element { { self.listeners() .mouse_move - .push(Arc::new(move |view, event, bounds, phase, cx| { + .push(Box::new(move |view, event, bounds, phase, cx| { if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) { handler(view, event, cx); } @@ -135,7 +134,7 @@ pub trait Interactive: Element { { self.listeners() .scroll_wheel - .push(Arc::new(move |view, event, bounds, phase, cx| { + .push(Box::new(move |view, event, bounds, phase, cx| { if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) { handler(view, event, cx); } @@ -157,7 +156,7 @@ pub trait Click: Interactive { { self.listeners() .mouse_click - .push(Arc::new(move |view, event, cx| handler(view, event, cx))); + .push(Box::new(move |view, event, cx| handler(view, event, cx))); self } } diff --git a/crates/gpui3/src/window.rs b/crates/gpui3/src/window.rs index e420a28813c73430c3109c76d5ba992665b8a588..26bbc7df4347267302c8182f6b68f15e36dcd1b7 100644 --- a/crates/gpui3/src/window.rs +++ b/crates/gpui3/src/window.rs @@ -40,8 +40,13 @@ pub enum DispatchPhase { Capture, } -type MouseEventHandler = - Arc; +type AnyMouseEventListener = + Box; +type AnyFocusChangeListener = Box; +type AnyKeyDownListener = + Box; +type AnyKeyUpListener = + Box; #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct FocusId(usize); @@ -91,16 +96,13 @@ pub struct Window { element_states: HashMap, z_index_stack: StackingOrder, content_mask_stack: Vec>, - mouse_listeners: HashMap>, + mouse_listeners: HashMap>, focus_stack: Vec, focus_parents_by_child: HashMap, containing_focus: HashSet, - pub(crate) focus_change_listeners: - Vec>, - key_down_listeners: - Vec>, - key_up_listeners: - Vec>, + pub(crate) focus_change_listeners: Vec, + key_down_listeners: Vec, + key_up_listeners: Vec, propagate_event: bool, mouse_position: Point, scale_factor: f32, @@ -207,12 +209,8 @@ impl ContentMask { struct FocusStackFrame { handle: FocusHandle, - key_down_listeners: SmallVec< - [Arc; 2], - >, - key_up_listeners: SmallVec< - [Arc; 2], - >, + key_down_listeners: SmallVec<[AnyKeyDownListener; 2]>, + key_up_listeners: SmallVec<[AnyKeyUpListener; 2]>, } pub struct WindowContext<'a, 'w> { @@ -402,7 +400,7 @@ impl<'a, 'w> WindowContext<'a, 'w> { .or_default() .push(( order, - Arc::new(move |event: &dyn Any, phase, cx| { + Box::new(move |event: &dyn Any, phase, cx| { handler(event.downcast_ref().unwrap(), phase, cx) }), )) @@ -1136,7 +1134,7 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> { let handle = handle.clone(); frame .key_down_listeners - .push(Arc::new(move |event, phase, cx| { + .push(Box::new(move |event, phase, cx| { handle .update(cx, |view, cx| listener(view, event, phase, cx)) .log_err(); @@ -1146,7 +1144,7 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> { let handle = handle.clone(); frame .key_up_listeners - .push(Arc::new(move |event, phase, cx| { + .push(Box::new(move |event, phase, cx| { handle .update(cx, |view, cx| listener(view, event, phase, cx)) .log_err(); @@ -1156,14 +1154,14 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> { window.focus_stack.push(frame); if Some(focus_handle.id) == window.focus { - for frame in &window.focus_stack { + for frame in &mut window.focus_stack { window.containing_focus.insert(frame.handle.id); window .key_down_listeners - .extend_from_slice(&frame.key_down_listeners); + .extend(frame.key_down_listeners.drain(..)); window .key_up_listeners - .extend_from_slice(&frame.key_up_listeners); + .extend(frame.key_up_listeners.drain(..)); } }