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

This commit is contained in:
Antonio Scandurra 2024-01-11 12:48:05 +01:00
parent 142a8b68c8
commit d088ace404
4 changed files with 21 additions and 19 deletions

View file

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

View file

@ -73,15 +73,6 @@ impl DispatchTree {
focus_id: Option<FocusId>, focus_id: Option<FocusId>,
view_id: Option<EntityId>, 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 parent = self.node_stack.last().copied();
let node_id = DispatchNodeId(self.nodes.len()); let node_id = DispatchNodeId(self.nodes.len());
self.nodes.push(DispatchNode { self.nodes.push(DispatchNode {

View file

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

View file

@ -1942,13 +1942,12 @@ impl<'a> WindowContext<'a> {
focus_handle: Option<FocusHandle>, focus_handle: Option<FocusHandle>,
f: impl FnOnce(Option<FocusHandle>, &mut Self) -> R, f: impl FnOnce(Option<FocusHandle>, &mut Self) -> R,
) -> R { ) -> R {
let parent_view_id = self.parent_view_id();
let window = &mut self.window; let window = &mut self.window;
let focus_id = focus_handle.as_ref().map(|handle| handle.id); let focus_id = focus_handle.as_ref().map(|handle| handle.id);
window window
.next_frame .next_frame
.dispatch_tree .dispatch_tree
.push_node(context.clone(), focus_id, parent_view_id); .push_node(context.clone(), focus_id, None);
let result = f(focus_handle, self); let result = f(focus_handle, self);
@ -1968,6 +1967,18 @@ impl<'a> WindowContext<'a> {
result 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 /// 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 /// 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 /// to the given closure. The state returned by the closure will be stored so it can be referenced