Checkpoint

Antonio Scandurra created

Change summary

crates/gpui3/src/elements/div.rs | 20 ++++++++--------
crates/gpui3/src/events.rs       | 19 +++++++--------
crates/gpui3/src/interactive.rs  | 15 +++++------
crates/gpui3/src/window.rs       | 40 ++++++++++++++++-----------------
4 files changed, 45 insertions(+), 49 deletions(-)

Detailed changes

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<Pixels>,
         pending_click: Arc<Mutex<Option<MouseDownEvent>>>,
         cx: &mut ViewContext<V>,
     ) {
-        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);

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<FocusHandle>,
 }
 
-pub type MouseDownListener<V> = Arc<
+pub type MouseDownListener<V> = Box<
     dyn Fn(&mut V, &MouseDownEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
         + Send
         + Sync
         + 'static,
 >;
-pub type MouseUpListener<V> = Arc<
+pub type MouseUpListener<V> = Box<
     dyn Fn(&mut V, &MouseUpEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
         + Send
         + Sync
         + 'static,
 >;
 pub type MouseClickListener<V> =
-    Arc<dyn Fn(&mut V, &MouseClickEvent, &mut ViewContext<V>) + Send + Sync + 'static>;
+    Box<dyn Fn(&mut V, &MouseClickEvent, &mut ViewContext<V>) + Send + Sync + 'static>;
 
-pub type MouseMoveListener<V> = Arc<
+pub type MouseMoveListener<V> = Box<
     dyn Fn(&mut V, &MouseMoveEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
         + Send
         + Sync
         + 'static,
 >;
 
-pub type ScrollWheelListener<V> = Arc<
+pub type ScrollWheelListener<V> = Box<
     dyn Fn(&mut V, &ScrollWheelEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
         + Send
         + Sync
@@ -239,10 +238,10 @@ pub type ScrollWheelListener<V> = Arc<
 >;
 
 pub type KeyDownListener<V> =
-    Arc<dyn Fn(&mut V, &KeyDownEvent, DispatchPhase, &mut ViewContext<V>) + Send + Sync + 'static>;
+    Box<dyn Fn(&mut V, &KeyDownEvent, DispatchPhase, &mut ViewContext<V>) + Send + Sync + 'static>;
 
 pub type KeyUpListener<V> =
-    Arc<dyn Fn(&mut V, &KeyUpEvent, DispatchPhase, &mut ViewContext<V>) + Send + Sync + 'static>;
+    Box<dyn Fn(&mut V, &KeyUpEvent, DispatchPhase, &mut ViewContext<V>) + Send + Sync + 'static>;
 
 pub struct EventListeners<V: 'static> {
     pub mouse_down: SmallVec<[MouseDownListener<V>; 2]>,

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<Self::ViewState>;
@@ -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
     }
 }

crates/gpui3/src/window.rs 🔗

@@ -40,8 +40,13 @@ pub enum DispatchPhase {
     Capture,
 }
 
-type MouseEventHandler =
-    Arc<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext) + Send + Sync + 'static>;
+type AnyMouseEventListener =
+    Box<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext) + Send + Sync + 'static>;
+type AnyFocusChangeListener = Box<dyn Fn(&FocusEvent, &mut WindowContext) + Send + Sync + 'static>;
+type AnyKeyDownListener =
+    Box<dyn Fn(&KeyDownEvent, DispatchPhase, &mut WindowContext) + Send + Sync + 'static>;
+type AnyKeyUpListener =
+    Box<dyn Fn(&KeyUpEvent, DispatchPhase, &mut WindowContext) + Send + Sync + 'static>;
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub struct FocusId(usize);
@@ -91,16 +96,13 @@ pub struct Window {
     element_states: HashMap<GlobalElementId, AnyBox>,
     z_index_stack: StackingOrder,
     content_mask_stack: Vec<ContentMask<Pixels>>,
-    mouse_listeners: HashMap<TypeId, Vec<(StackingOrder, MouseEventHandler)>>,
+    mouse_listeners: HashMap<TypeId, Vec<(StackingOrder, AnyMouseEventListener)>>,
     focus_stack: Vec<FocusStackFrame>,
     focus_parents_by_child: HashMap<FocusId, FocusId>,
     containing_focus: HashSet<FocusId>,
-    pub(crate) focus_change_listeners:
-        Vec<Arc<dyn Fn(&FocusEvent, &mut WindowContext) + Send + Sync + 'static>>,
-    key_down_listeners:
-        Vec<Arc<dyn Fn(&KeyDownEvent, DispatchPhase, &mut WindowContext) + Send + Sync + 'static>>,
-    key_up_listeners:
-        Vec<Arc<dyn Fn(&KeyUpEvent, DispatchPhase, &mut WindowContext) + Send + Sync + 'static>>,
+    pub(crate) focus_change_listeners: Vec<AnyFocusChangeListener>,
+    key_down_listeners: Vec<AnyKeyDownListener>,
+    key_up_listeners: Vec<AnyKeyUpListener>,
     propagate_event: bool,
     mouse_position: Point<Pixels>,
     scale_factor: f32,
@@ -207,12 +209,8 @@ impl ContentMask<Pixels> {
 
 struct FocusStackFrame {
     handle: FocusHandle,
-    key_down_listeners: SmallVec<
-        [Arc<dyn Fn(&KeyDownEvent, DispatchPhase, &mut WindowContext) + Send + Sync + 'static>; 2],
-    >,
-    key_up_listeners: SmallVec<
-        [Arc<dyn Fn(&KeyUpEvent, DispatchPhase, &mut WindowContext) + Send + Sync + 'static>; 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(..));
             }
         }