Merge branch 'gpui2' into gpui2-ui

Marshall Bowers created

Change summary

crates/gpui3/src/arc_cow.rs             |   0 
crates/gpui3/src/element.rs             |  29 ++
crates/gpui3/src/elements.rs            |   6 
crates/gpui3/src/elements/hoverable.rs  |  10 
crates/gpui3/src/elements/identified.rs |  38 +++
crates/gpui3/src/elements/pressable.rs  | 317 +++++++++++++++++---------
crates/gpui3/src/elements/stateless.rs  |  30 --
crates/gpui3/src/gpui3.rs               |  13 
crates/gpui3/src/window.rs              |  65 ++--
9 files changed, 328 insertions(+), 180 deletions(-)

Detailed changes

crates/gpui3/src/element.rs 🔗

@@ -1,12 +1,16 @@
-use crate::Bounds;
-
-use super::{LayoutId, Pixels, Point, Result, ViewContext};
+use crate::{Bounds, Identified, LayoutId, Pixels, Point, Result, ViewContext};
+use derive_more::{Deref, DerefMut};
 pub(crate) use smallvec::SmallVec;
+use util::arc_cow::ArcCow;
 
 pub trait Element: 'static {
     type State;
     type FrameState;
 
+    fn element_id(&self) -> Option<ElementId> {
+        None
+    }
+
     fn layout(
         &mut self,
         state: &mut Self::State,
@@ -20,8 +24,27 @@ pub trait Element: 'static {
         frame_state: &mut Self::FrameState,
         cx: &mut ViewContext<Self::State>,
     ) -> Result<()>;
+
+    fn id(self, id: ElementId) -> Identified<Self>
+    where
+        Self: Sized,
+    {
+        Identified { element: self, id }
+    }
+}
+
+pub trait StatefulElement: Element {
+    fn element_id(&self) -> ElementId {
+        Element::element_id(self).unwrap()
+    }
 }
 
+#[derive(Clone, Debug, Eq, PartialEq, Hash)]
+pub struct ElementId(ArcCow<'static, [u8]>);
+
+#[derive(Deref, DerefMut, Default, Clone, Debug)]
+pub(crate) struct GlobalElementId(SmallVec<[ElementId; 8]>);
+
 pub trait ParentElement {
     type State;
 

crates/gpui3/src/elements.rs 🔗

@@ -1,13 +1,15 @@
 mod div;
 mod hoverable;
+mod identified;
 mod img;
-mod stateless;
+mod pressable;
 mod svg;
 mod text;
 
 pub use div::*;
 pub use hoverable::*;
+pub use identified::*;
 pub use img::*;
-pub use stateless::*;
+pub use pressable::*;
 pub use svg::*;
 pub use text::*;

crates/gpui3/src/elements/hoverable.rs 🔗

@@ -1,6 +1,6 @@
 use crate::{
-    AnyElement, Bounds, DispatchPhase, Element, Interactive, MouseEventListeners, MouseMoveEvent,
-    ParentElement, Pixels, Styled, ViewContext,
+    AnyElement, Bounds, DispatchPhase, Element, ElementId, Interactive, MouseEventListeners,
+    MouseMoveEvent, ParentElement, Pixels, StatefulElement, Styled, ViewContext,
 };
 use anyhow::Result;
 use refineable::{CascadeSlot, Refineable, RefinementCascade};
@@ -53,6 +53,10 @@ impl<E: Element + Styled> Element for Hoverable<E> {
     type State = E::State;
     type FrameState = E::FrameState;
 
+    fn element_id(&self) -> Option<ElementId> {
+        self.child.element_id()
+    }
+
     fn layout(
         &mut self,
         state: &mut Self::State,
@@ -95,3 +99,5 @@ impl<E: ParentElement + Styled> ParentElement for Hoverable<E> {
         self.child.children_mut()
     }
 }
+
+impl<E: StatefulElement + Styled> StatefulElement for Hoverable<E> {}

crates/gpui3/src/elements/identified.rs 🔗

@@ -0,0 +1,38 @@
+use crate::{BorrowWindow, Bounds, Element, ElementId, LayoutId, StatefulElement, ViewContext};
+use anyhow::Result;
+
+pub struct Identified<E> {
+    pub(crate) element: E,
+    pub(crate) id: ElementId,
+}
+
+impl<E: Element> Element for Identified<E> {
+    type State = E::State;
+    type FrameState = E::FrameState;
+
+    fn element_id(&self) -> Option<ElementId> {
+        Some(self.id.clone())
+    }
+
+    fn layout(
+        &mut self,
+        state: &mut Self::State,
+        cx: &mut ViewContext<Self::State>,
+    ) -> Result<(LayoutId, Self::FrameState)> {
+        self.element.layout(state, cx)
+    }
+
+    fn paint(
+        &mut self,
+        bounds: Bounds<crate::Pixels>,
+        state: &mut Self::State,
+        frame_state: &mut Self::FrameState,
+        cx: &mut ViewContext<Self::State>,
+    ) -> Result<()> {
+        cx.with_element_id(self.id.clone(), |cx| {
+            self.element.paint(bounds, state, frame_state, cx)
+        })
+    }
+}
+
+impl<E: Element> StatefulElement for Identified<E> {}

crates/gpui3/src/elements/pressable.rs 🔗

@@ -1,106 +1,211 @@
-use crate::{
-    element::{AnyElement, Element, IntoElement, Layout, ParentElement},
-    interactive::{InteractionHandlers, Interactive},
-    style::{Style, StyleHelpers, Styleable},
-    ViewContext,
-};
-use anyhow::Result;
-use gpui::{geometry::vector::Vector2F, platform::MouseButtonEvent, LayoutId};
-use refineable::{CascadeSlot, Refineable, RefinementCascade};
-use smallvec::SmallVec;
-use std::{cell::Cell, rc::Rc};
-
-pub struct Pressable<E: Styleable> {
-    pressed: Rc<Cell<bool>>,
-    pressed_style: <E::Style as Refineable>::Refinement,
-    cascade_slot: CascadeSlot,
-    child: E,
-}
-
-pub fn pressable<E: Styleable>(mut child: E) -> Pressable<E> {
-    Pressable {
-        pressed: Rc::new(Cell::new(false)),
-        pressed_style: Default::default(),
-        cascade_slot: child.style_cascade().reserve(),
-        child,
-    }
-}
-
-impl<E: Styleable> Styleable for Pressable<E> {
-    type Style = E::Style;
-
-    fn declared_style(&mut self) -> &mut <Self::Style as Refineable>::Refinement {
-        &mut self.pressed_style
-    }
-
-    fn style_cascade(&mut self) -> &mut RefinementCascade<E::Style> {
-        self.child.style_cascade()
-    }
-}
-
-impl<V: 'static, E: Element<V> + Styleable> Element<V> for Pressable<E> {
-    type PaintState = E::PaintState;
-
-    fn layout(
-        &mut self,
-        view: &mut V,
-        cx: &mut ViewContext<V>,
-    ) -> Result<(LayoutId, Self::PaintState)>
-    where
-        Self: Sized,
-    {
-        self.child.layout(view, cx)
-    }
-
-    fn paint(
-        &mut self,
-        view: &mut V,
-        parent_origin: Vector2F,
-        layout: &Layout,
-        paint_state: &mut Self::PaintState,
-        cx: &mut ViewContext<V>,
-    ) where
-        Self: Sized,
-    {
-        let slot = self.cascade_slot;
-        let style = self.pressed.get().then_some(self.pressed_style.clone());
-        self.style_cascade().set(slot, style);
-
-        let pressed = self.pressed.clone();
-        let bounds = layout.bounds + parent_origin;
-        cx.on_event(layout.order, move |_view, event: &MouseButtonEvent, cx| {
-            if event.is_down {
-                if bounds.contains_point(event.position) {
-                    pressed.set(true);
-                    cx.repaint();
-                }
-            } else if pressed.get() {
-                pressed.set(false);
-                cx.repaint();
-            }
-        });
-
-        self.child
-            .paint(view, parent_origin, layout, paint_state, cx);
-    }
-}
-
-impl<V: 'static, E: Interactive<V> + Styleable> Interactive<V> for Pressable<E> {
-    fn interaction_handlers(&mut self) -> &mut InteractionHandlers<V> {
-        self.child.interaction_handlers()
-    }
-}
-
-impl<V: 'static, E: ParentElement<V> + Styleable> ParentElement<V> for Pressable<E> {
-    fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
-        self.child.children_mut()
-    }
-}
-
-impl<V: 'static, E: Element<V> + Styleable> IntoElement<V> for Pressable<E> {
-    type Element = Self;
-
-    fn into_element(self) -> Self::Element {
-        self
-    }
-}
+// use crate::{
+//     AnyElement, Bounds, DispatchPhase, Element, Identified, Interactive, MouseDownEvent,
+//     MouseEventListeners, MouseUpEvent, ParentElement, Pixels, Styled, ViewContext,
+// };
+// use anyhow::Result;
+// use refineable::{CascadeSlot, Refineable, RefinementCascade};
+// use smallvec::SmallVec;
+// use std::sync::{
+//     atomic::{AtomicBool, Ordering::SeqCst},
+//     Arc,
+// };
+
+// pub struct Pressable<E: Styled> {
+//     pressed: Arc<AtomicBool>,
+//     cascade_slot: CascadeSlot,
+//     pressed_style: <E::Style as Refineable>::Refinement,
+//     child: E,
+// }
+
+// impl<E: Identified + Styled> Pressable<E> {
+//     pub fn new(mut child: E) -> Self {
+//         Self {
+//             pressed: Arc::new(AtomicBool::new(false)),
+//             cascade_slot: child.style_cascade().reserve(),
+//             pressed_style: Default::default(),
+//             child,
+//         }
+//     }
+// }
+
+// impl<E> Styled for Pressable<E>
+// where
+//     E: Styled,
+// {
+//     type Style = E::Style;
+
+//     fn style_cascade(&mut self) -> &mut RefinementCascade<E::Style> {
+//         self.child.style_cascade()
+//     }
+
+//     fn declared_style(&mut self) -> &mut <Self::Style as refineable::Refineable>::Refinement {
+//         &mut self.pressed_style
+//     }
+// }
+
+// impl<S: 'static + Send + Sync, E: Interactive<S> + Styled> Interactive<S> for Pressable<E> {
+//     fn listeners(&mut self) -> &mut MouseEventListeners<S> {
+//         self.child.listeners()
+//     }
+// }
+
+// impl<E: Element + Identified + Styled> Element for Pressable<E> {
+//     type State = E::State;
+//     type FrameState = E::FrameState;
+
+//     fn layout(
+//         &mut self,
+//         state: &mut Self::State,
+//         cx: &mut ViewContext<Self::State>,
+//     ) -> Result<(crate::LayoutId, Self::FrameState)> {
+//         Ok(self.child.layout(state, cx)?)
+//     }
+
+//     fn paint(
+//         &mut self,
+//         bounds: Bounds<Pixels>,
+//         state: &mut Self::State,
+//         frame_state: &mut Self::FrameState,
+//         cx: &mut ViewContext<Self::State>,
+//     ) -> Result<()> {
+//         let pressed = bounds.contains_point(cx.mouse_position());
+//         let slot = self.cascade_slot;
+//         let style = pressed.then_some(self.pressed_style.clone());
+//         self.style_cascade().set(slot, style);
+//         self.pressed.store(pressed, SeqCst);
+
+//         let hovered = self.pressed.clone();
+//         cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| {
+//             if phase == DispatchPhase::Capture {
+//                 if bounds.contains_point(event.position) != hovered.load(SeqCst) {
+//                     cx.notify();
+//                 }
+//             }
+//         });
+//         cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| {
+//             if phase == DispatchPhase::Capture {
+//                 if bounds.contains_point(event.position) != hovered.load(SeqCst) {
+//                     cx.notify();
+//                 }
+//             }
+//         });
+
+//         self.child.paint(bounds, state, frame_state, cx)?;
+//         Ok(())
+//     }
+// }
+
+// impl<E: ParentElement + Styled> ParentElement for Pressable<E> {
+//     type State = E::State;
+
+//     fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::State>; 2]> {
+//         self.child.children_mut()
+//     }
+// }
+
+// // use crate::{
+// //     element::{AnyElement, Element, IntoElement, Layout, ParentElement},
+// //     interactive::{InteractionHandlers, Interactive},
+// //     style::{Style, StyleHelpers, Styleable},
+// //     ViewContext,
+// // };
+// // use anyhow::Result;
+// // use gpui::{geometry::vector::Vector2F, platform::MouseButtonEvent, LayoutId};
+// // use refineable::{CascadeSlot, Refineable, RefinementCascade};
+// // use smallvec::SmallVec;
+// // use std::{cell::Cell, rc::Rc};
+
+// // pub struct Pressable<E: Styleable> {
+// //     pressed: Rc<Cell<bool>>,
+// //     pressed_style: <E::Style as Refineable>::Refinement,
+// //     cascade_slot: CascadeSlot,
+// //     child: E,
+// // }
+
+// // pub fn pressable<E: Styleable>(mut child: E) -> Pressable<E> {
+// //     Pressable {
+// //         pressed: Rc::new(Cell::new(false)),
+// //         pressed_style: Default::default(),
+// //         cascade_slot: child.style_cascade().reserve(),
+// //         child,
+// //     }
+// // }
+
+// // impl<E: Styleable> Styleable for Pressable<E> {
+// //     type Style = E::Style;
+
+// //     fn declared_style(&mut self) -> &mut <Self::Style as Refineable>::Refinement {
+// //         &mut self.pressed_style
+// //     }
+
+// //     fn style_cascade(&mut self) -> &mut RefinementCascade<E::Style> {
+// //         self.child.style_cascade()
+// //     }
+// // }
+
+// // impl<V: 'static, E: Element<V> + Styleable> Element<V> for Pressable<E> {
+// //     type PaintState = E::PaintState;
+
+// //     fn layout(
+// //         &mut self,
+// //         view: &mut V,
+// //         cx: &mut ViewContext<V>,
+// //     ) -> Result<(LayoutId, Self::PaintState)>
+// //     where
+// //         Self: Sized,
+// //     {
+// //         self.child.layout(view, cx)
+// //     }
+
+// //     fn paint(
+// //         &mut self,
+// //         view: &mut V,
+// //         parent_origin: Vector2F,
+// //         layout: &Layout,
+// //         paint_state: &mut Self::PaintState,
+// //         cx: &mut ViewContext<V>,
+// //     ) where
+// //         Self: Sized,
+// //     {
+// //         let slot = self.cascade_slot;
+// //         let style = self.pressed.get().then_some(self.pressed_style.clone());
+// //         self.style_cascade().set(slot, style);
+
+// //         let pressed = self.pressed.clone();
+// //         let bounds = layout.bounds + parent_origin;
+// //         cx.on_event(layout.order, move |_view, event: &MouseButtonEvent, cx| {
+// //             if event.is_down {
+// //                 if bounds.contains_point(event.position) {
+// //                     pressed.set(true);
+// //                     cx.repaint();
+// //                 }
+// //             } else if pressed.get() {
+// //                 pressed.set(false);
+// //                 cx.repaint();
+// //             }
+// //         });
+
+// //         self.child
+// //             .paint(view, parent_origin, layout, paint_state, cx);
+// //     }
+// // }
+
+// // impl<V: 'static, E: Interactive<V> + Styleable> Interactive<V> for Pressable<E> {
+// //     fn interaction_handlers(&mut self) -> &mut InteractionHandlers<V> {
+// //         self.child.interaction_handlers()
+// //     }
+// // }
+
+// // impl<V: 'static, E: ParentElement<V> + Styleable> ParentElement<V> for Pressable<E> {
+// //     fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
+// //         self.child.children_mut()
+// //     }
+// // }
+
+// // impl<V: 'static, E: Element<V> + Styleable> IntoElement<V> for Pressable<E> {
+// //     type Element = Self;
+
+// //     fn into_element(self) -> Self::Element {
+// //         self
+// //     }
+// // }

crates/gpui3/src/elements/stateless.rs 🔗

@@ -1,30 +0,0 @@
-use crate::{Bounds, Element, Pixels};
-use std::marker::PhantomData;
-
-pub struct Stateless<E: Element<State = ()>, S> {
-    element: E,
-    parent_state_type: PhantomData<S>,
-}
-
-impl<E: Element<State = ()>, S: Send + Sync + 'static> Element for Stateless<E, S> {
-    type State = S;
-    type FrameState = E::FrameState;
-
-    fn layout(
-        &mut self,
-        _: &mut Self::State,
-        cx: &mut crate::ViewContext<Self::State>,
-    ) -> anyhow::Result<(crate::LayoutId, Self::FrameState)> {
-        cx.erase_state(|cx| self.element.layout(&mut (), cx))
-    }
-
-    fn paint(
-        &mut self,
-        bounds: Bounds<Pixels>,
-        _: &mut Self::State,
-        frame_state: &mut Self::FrameState,
-        cx: &mut crate::ViewContext<Self::State>,
-    ) -> anyhow::Result<()> {
-        cx.erase_state(|cx| self.element.paint(bounds, &mut (), frame_state, cx))
-    }
-}

crates/gpui3/src/gpui3.rs 🔗

@@ -39,22 +39,23 @@ pub use serde;
 pub use serde_json;
 pub use smallvec;
 pub use smol::Timer;
-use std::{
-    mem,
-    ops::{Deref, DerefMut},
-    sync::Arc,
-};
 pub use style::*;
 pub use style_helpers::*;
 pub use styled::*;
 pub use svg_renderer::*;
-use taffy::TaffyLayoutEngine;
 pub use taffy::{AvailableSpace, LayoutId};
 pub use text_system::*;
 pub use util::arc_cow::ArcCow;
 pub use view::*;
 pub use window::*;
 
+use std::{
+    mem,
+    ops::{Deref, DerefMut},
+    sync::Arc,
+};
+use taffy::TaffyLayoutEngine;
+
 pub trait Context {
     type EntityContext<'a, 'w, T: 'static + Send + Sync>;
     type Result<T>;

crates/gpui3/src/window.rs 🔗

@@ -1,12 +1,12 @@
 use crate::{
     image_cache::RenderImageParams, px, size, AnyView, AppContext, AsyncWindowContext,
     AvailableSpace, BorrowAppContext, Bounds, BoxShadow, Context, Corners, DevicePixels, DisplayId,
-    Edges, Effect, Element, EntityId, Event, FontId, GlyphId, Handle, Hsla, ImageData, IsZero,
-    LayoutId, MainThread, MainThreadOnly, MonochromeSprite, MouseMoveEvent, Path, Pixels,
-    PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Quad, Reference, RenderGlyphParams,
-    RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style,
-    TaffyLayoutEngine, Task, Underline, UnderlineStyle, WeakHandle, WindowOptions,
-    SUBPIXEL_VARIANTS,
+    Edges, Effect, Element, ElementId, EntityId, Event, FontId, GlobalElementId, GlyphId, Handle,
+    Hsla, ImageData, IsZero, LayoutId, MainThread, MainThreadOnly, MonochromeSprite,
+    MouseMoveEvent, Path, Pixels, PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Quad,
+    Reference, RenderGlyphParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow,
+    SharedString, Size, Style, TaffyLayoutEngine, Task, Underline, UnderlineStyle, WeakHandle,
+    WindowOptions, SUBPIXEL_VARIANTS,
 };
 use anyhow::Result;
 use collections::HashMap;
@@ -51,7 +51,8 @@ pub struct Window {
     content_size: Size<Pixels>,
     layout_engine: TaffyLayoutEngine,
     pub(crate) root_view: Option<AnyView<()>>,
-    current_stacking_order: StackingOrder,
+    pub(crate) element_id_stack: GlobalElementId,
+    z_index_stack: StackingOrder,
     content_mask_stack: Vec<ContentMask<Pixels>>,
     mouse_event_handlers: HashMap<TypeId, Vec<(StackingOrder, MouseEventHandler)>>,
     propagate_event: bool,
@@ -112,7 +113,8 @@ impl Window {
             content_size,
             layout_engine: TaffyLayoutEngine::new(),
             root_view: None,
-            current_stacking_order: StackingOrder(SmallVec::new()),
+            element_id_stack: GlobalElementId::default(),
+            z_index_stack: StackingOrder(SmallVec::new()),
             content_mask_stack: Vec::new(),
             mouse_event_handlers: HashMap::default(),
             propagate_event: true,
@@ -287,7 +289,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
         &mut self,
         handler: impl Fn(&Event, DispatchPhase, &mut WindowContext) + Send + Sync + 'static,
     ) {
-        let order = self.window.current_stacking_order.clone();
+        let order = self.window.z_index_stack.clone();
         self.window
             .mouse_event_handlers
             .entry(TypeId::of::<Event>())
@@ -305,9 +307,9 @@ impl<'a, 'w> WindowContext<'a, 'w> {
     }
 
     pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
-        self.window.current_stacking_order.push(order);
+        self.window.z_index_stack.push(order);
         let result = f(self);
-        self.window.current_stacking_order.pop();
+        self.window.z_index_stack.pop();
         result
     }
 
@@ -325,7 +327,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
             shadow_bounds.origin += shadow.offset;
             shadow_bounds.dilate(shadow.spread_radius);
             window.scene_builder.insert(
-                &window.current_stacking_order,
+                &window.z_index_stack,
                 Shadow {
                     order: 0,
                     bounds: shadow_bounds.scale(scale_factor),
@@ -351,7 +353,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
 
         let window = &mut *self.window;
         window.scene_builder.insert(
-            &window.current_stacking_order,
+            &window.z_index_stack,
             Quad {
                 order: 0,
                 bounds: bounds.scale(scale_factor),
@@ -372,7 +374,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
         let window = &mut *self.window;
         window
             .scene_builder
-            .insert(&window.current_stacking_order, path.scale(scale_factor));
+            .insert(&window.z_index_stack, path.scale(scale_factor));
     }
 
     pub fn paint_underline(
@@ -394,7 +396,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
         let content_mask = self.content_mask();
         let window = &mut *self.window;
         window.scene_builder.insert(
-            &window.current_stacking_order,
+            &window.z_index_stack,
             Underline {
                 order: 0,
                 bounds: bounds.scale(scale_factor),
@@ -446,7 +448,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
             let content_mask = self.content_mask().scale(scale_factor);
             let window = &mut *self.window;
             window.scene_builder.insert(
-                &window.current_stacking_order,
+                &window.z_index_stack,
                 MonochromeSprite {
                     order: 0,
                     bounds,
@@ -495,7 +497,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
             let window = &mut *self.window;
 
             window.scene_builder.insert(
-                &window.current_stacking_order,
+                &window.z_index_stack,
                 PolychromeSprite {
                     order: 0,
                     bounds,
@@ -536,7 +538,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
 
         let window = &mut *self.window;
         window.scene_builder.insert(
-            &window.current_stacking_order,
+            &window.z_index_stack,
             MonochromeSprite {
                 order: 0,
                 bounds,
@@ -571,7 +573,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
 
         let window = &mut *self.window;
         window.scene_builder.insert(
-            &window.current_stacking_order,
+            &window.z_index_stack,
             PolychromeSprite {
                 order: 0,
                 bounds,
@@ -728,6 +730,17 @@ pub trait BorrowWindow: BorrowAppContext {
     fn window(&self) -> &Window;
     fn window_mut(&mut self) -> &mut Window;
 
+    fn with_element_id<R>(
+        &mut self,
+        id: impl Into<ElementId>,
+        f: impl FnOnce(&mut Self) -> R,
+    ) -> R {
+        self.window_mut().element_id_stack.push(id.into());
+        let result = f(self);
+        self.window_mut().element_id_stack.pop();
+        result
+    }
+
     fn with_content_mask<R>(
         &mut self,
         mask: ContentMask<Pixels>,
@@ -824,9 +837,9 @@ impl<'a, 'w, S: Send + Sync + 'static> ViewContext<'a, 'w, S> {
     }
 
     pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
-        self.window.current_stacking_order.push(order);
+        self.window.z_index_stack.push(order);
         let result = f(self);
-        self.window.current_stacking_order.pop();
+        self.window.z_index_stack.pop();
         result
     }
 
@@ -913,16 +926,6 @@ impl<'a, 'w, S: Send + Sync + 'static> ViewContext<'a, 'w, S> {
             })
         });
     }
-
-    pub(crate) fn erase_state<R>(&mut self, f: impl FnOnce(&mut ViewContext<()>) -> R) -> R {
-        let entity_id = self.unit_entity.id;
-        let mut cx = ViewContext::mutable(
-            &mut *self.window_cx.app,
-            &mut *self.window_cx.window,
-            entity_id,
-        );
-        f(&mut cx)
-    }
 }
 
 impl<'a, 'w, S> Context for ViewContext<'a, 'w, S> {