Explicitly push a node in the dispatch tree when painting a new view

Antonio Scandurra created

Change summary

crates/editor/src/element.rs    | 10 +++++-----
crates/gpui/src/key_dispatch.rs |  9 ---------
crates/gpui/src/view.rs         |  6 +++---
crates/gpui/src/window.rs       | 15 +++++++++++++--
4 files changed, 21 insertions(+), 19 deletions(-)

Detailed changes

crates/editor/src/element.rs 🔗

@@ -26,11 +26,11 @@ use git::diff::DiffHunkStatus;
 use gpui::{
     div, fill, outline, overlay, point, px, quad, relative, size, transparent_black, Action,
     AnchorCorner, AnyElement, AvailableSpace, BorrowWindow, Bounds, ContentMask, Corners,
-    CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, Entity, Hsla,
-    InteractiveBounds, InteractiveElement, IntoElement, ModifiersChangedEvent, MouseButton,
-    MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, ScrollDelta,
-    ScrollWheelEvent, ShapedLine, SharedString, Size, StackingOrder, StatefulInteractiveElement,
-    Style, Styled, TextRun, TextStyle, View, ViewContext, WindowContext,
+    CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, Hsla, InteractiveBounds,
+    InteractiveElement, IntoElement, ModifiersChangedEvent, MouseButton, MouseDownEvent,
+    MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, ScrollDelta, ScrollWheelEvent, ShapedLine,
+    SharedString, Size, StackingOrder, StatefulInteractiveElement, Style, Styled, TextRun,
+    TextStyle, View, ViewContext, WindowContext,
 };
 use itertools::Itertools;
 use language::language_settings::ShowWhitespaceSetting;

crates/gpui/src/key_dispatch.rs 🔗

@@ -73,15 +73,6 @@ impl DispatchTree {
         focus_id: Option<FocusId>,
         view_id: Option<EntityId>,
     ) {
-        // Associate a view id to this only if it is the root node for the view.
-        let view_id = view_id.and_then(|view_id| {
-            if self.view_node_ids.contains_key(&view_id) {
-                None
-            } else {
-                Some(view_id)
-            }
-        });
-
         let parent = self.node_stack.last().copied();
         let node_id = DispatchNodeId(self.nodes.len());
         self.nodes.push(DispatchNode {

crates/gpui/src/view.rs 🔗

@@ -97,7 +97,7 @@ impl<V: Render> Element for View<V> {
     }
 
     fn paint(&mut self, _: Bounds<Pixels>, element: &mut Self::State, cx: &mut WindowContext) {
-        cx.with_view_id(self.entity_id(), |cx| element.take().unwrap().paint(cx));
+        cx.paint_view(self.entity_id(), |cx| element.take().unwrap().paint(cx));
     }
 }
 
@@ -230,7 +230,7 @@ impl AnyView {
         available_space: Size<AvailableSpace>,
         cx: &mut WindowContext,
     ) {
-        cx.with_view_id(self.entity_id(), |cx| {
+        cx.paint_view(self.entity_id(), |cx| {
             cx.with_absolute_element_offset(origin, |cx| {
                 let (layout_id, mut rendered_element) = (self.request_layout)(self, cx);
                 cx.compute_layout(layout_id, available_space);
@@ -278,7 +278,7 @@ impl Element for AnyView {
     }
 
     fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut WindowContext) {
-        cx.with_view_id(self.entity_id(), |cx| {
+        cx.paint_view(self.entity_id(), |cx| {
             if !self.cache {
                 state.element.take().unwrap().paint(cx);
                 return;

crates/gpui/src/window.rs 🔗

@@ -1942,13 +1942,12 @@ impl<'a> WindowContext<'a> {
         focus_handle: Option<FocusHandle>,
         f: impl FnOnce(Option<FocusHandle>, &mut Self) -> R,
     ) -> R {
-        let parent_view_id = self.parent_view_id();
         let window = &mut self.window;
         let focus_id = focus_handle.as_ref().map(|handle| handle.id);
         window
             .next_frame
             .dispatch_tree
-            .push_node(context.clone(), focus_id, parent_view_id);
+            .push_node(context.clone(), focus_id, None);
 
         let result = f(focus_handle, self);
 
@@ -1968,6 +1967,18 @@ impl<'a> WindowContext<'a> {
         result
     }
 
+    pub(crate) fn paint_view<R>(&mut self, view_id: EntityId, f: impl FnOnce(&mut Self) -> R) -> R {
+        self.with_view_id(view_id, |cx| {
+            cx.window
+                .next_frame
+                .dispatch_tree
+                .push_node(None, None, Some(view_id));
+            let result = f(cx);
+            cx.window.next_frame.dispatch_tree.pop_node();
+            result
+        })
+    }
+
     /// Update or initialize state for an element with the given id that lives across multiple
     /// frames. If an element with this id existed in the rendered frame, its state will be passed
     /// to the given closure. The state returned by the closure will be stored so it can be referenced