Eliminate LayoutContext

Nathan Sobo created

Change summary

crates/collab_ui/src/collab_titlebar_item.rs    |  6 
crates/collab_ui/src/face_pile.rs               |  4 
crates/editor/src/element.rs                    | 20 +--
crates/gpui/examples/corner_radii.rs            |  2 
crates/gpui/src/app.rs                          | 91 +-----------------
crates/gpui/src/app/window.rs                   |  9 -
crates/gpui/src/elements.rs                     | 19 +--
crates/gpui/src/elements/align.rs               |  4 
crates/gpui/src/elements/canvas.rs              |  2 
crates/gpui/src/elements/clipped.rs             |  4 
crates/gpui/src/elements/component.rs           |  6 
crates/gpui/src/elements/constrained_box.rs     | 11 +-
crates/gpui/src/elements/container.rs           |  4 
crates/gpui/src/elements/empty.rs               |  4 
crates/gpui/src/elements/expanded.rs            |  4 
crates/gpui/src/elements/flex.rs                | 12 +-
crates/gpui/src/elements/hook.rs                |  4 
crates/gpui/src/elements/image.rs               |  4 
crates/gpui/src/elements/keystroke_label.rs     |  2 
crates/gpui/src/elements/label.rs               |  4 
crates/gpui/src/elements/list.rs                | 20 +--
crates/gpui/src/elements/mouse_event_handler.rs |  6 
crates/gpui/src/elements/overlay.rs             |  5 
crates/gpui/src/elements/resizable.rs           |  8 
crates/gpui/src/elements/stack.rs               |  4 
crates/gpui/src/elements/svg.rs                 |  4 
crates/gpui/src/elements/text.rs                |  8 -
crates/gpui/src/elements/tooltip.rs             |  5 
crates/gpui/src/elements/uniform_list.rs        |  4 
crates/gpui2/src/adapter.rs                     |  2 
crates/gpui_macros/src/gpui_macros.rs           |  2 
crates/terminal_view/src/terminal_element.rs    |  7 
crates/workspace/src/pane.rs                    |  6 
crates/workspace/src/pane_group.rs              |  8 
crates/workspace/src/status_bar.rs              |  6 
35 files changed, 108 insertions(+), 203 deletions(-)

Detailed changes

crates/collab_ui/src/collab_titlebar_item.rs 🔗

@@ -13,8 +13,8 @@ use gpui::{
     geometry::{rect::RectF, vector::vec2f, PathBuilder},
     json::{self, ToJson},
     platform::{CursorStyle, MouseButton},
-    AppContext, Entity, ImageData, LayoutContext, ModelHandle, PaintContext, Subscription, View,
-    ViewContext, ViewHandle, WeakViewHandle,
+    AppContext, Entity, ImageData, ModelHandle, PaintContext, Subscription, View, ViewContext,
+    ViewHandle, WeakViewHandle,
 };
 use picker::PickerEvent;
 use project::{Project, RepositoryEntry};
@@ -1165,7 +1165,7 @@ impl Element<CollabTitlebarItem> for AvatarRibbon {
         &mut self,
         constraint: gpui::SizeConstraint,
         _: &mut CollabTitlebarItem,
-        _: &mut LayoutContext<CollabTitlebarItem>,
+        _: &mut ViewContext<CollabTitlebarItem>,
     ) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) {
         (constraint.max, ())
     }

crates/collab_ui/src/face_pile.rs 🔗

@@ -7,7 +7,7 @@ use gpui::{
     },
     json::ToJson,
     serde_json::{self, json},
-    AnyElement, Axis, Element, LayoutContext, PaintContext, View, ViewContext,
+    AnyElement, Axis, Element, PaintContext, View, ViewContext,
 };
 
 pub(crate) struct FacePile<V: View> {
@@ -32,7 +32,7 @@ impl<V: View> Element<V> for FacePile<V> {
         &mut self,
         constraint: gpui::SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         debug_assert!(constraint.max_along(Axis::Horizontal) == f32::INFINITY);
 

crates/editor/src/element.rs 🔗

@@ -32,8 +32,8 @@ use gpui::{
     json::{self, ToJson},
     platform::{CursorStyle, Modifiers, MouseButton, MouseButtonEvent, MouseMovedEvent},
     text_layout::{self, Line, RunStyle, TextLayoutCache},
-    AnyElement, Axis, CursorRegion, Element, EventContext, FontCache, LayoutContext, MouseRegion,
-    PaintContext, Quad, SizeConstraint, ViewContext, WindowContext,
+    AnyElement, Axis, CursorRegion, Element, EventContext, FontCache, MouseRegion, PaintContext,
+    Quad, SizeConstraint, ViewContext, WindowContext,
 };
 use itertools::Itertools;
 use json::json;
@@ -1670,7 +1670,7 @@ impl EditorElement {
         style: &EditorStyle,
         line_layouts: &[LineWithInvisibles],
         editor: &mut Editor,
-        cx: &mut LayoutContext<Editor>,
+        cx: &mut ViewContext<Editor>,
     ) -> (f32, Vec<BlockLayout>) {
         let mut block_id = 0;
         let scroll_x = snapshot.scroll_anchor.offset.x();
@@ -2092,7 +2092,7 @@ impl Element<Editor> for EditorElement {
         &mut self,
         constraint: SizeConstraint,
         editor: &mut Editor,
-        cx: &mut LayoutContext<Editor>,
+        cx: &mut ViewContext<Editor>,
     ) -> (Vector2F, Self::LayoutState) {
         let mut size = constraint.max;
         if size.x().is_infinite() {
@@ -3177,11 +3177,10 @@ mod tests {
                     Point::new(5, 6)..Point::new(6, 0),
                 ]);
             });
-            let mut layout_cx = LayoutContext::new(cx);
             element.layout(
                 SizeConstraint::new(vec2f(500., 500.), vec2f(500., 500.)),
                 editor,
-                &mut layout_cx,
+                cx,
             )
         });
         assert_eq!(state.selections.len(), 1);
@@ -3262,11 +3261,10 @@ mod tests {
                     DisplayPoint::new(10, 0)..DisplayPoint::new(13, 0),
                 ]);
             });
-            let mut layout_cx = LayoutContext::new(cx);
             element.layout(
                 SizeConstraint::new(vec2f(500., 500.), vec2f(500., 500.)),
                 editor,
-                &mut layout_cx,
+                cx,
             )
         });
 
@@ -3322,11 +3320,10 @@ mod tests {
 
         let mut element = EditorElement::new(editor.read_with(cx, |editor, cx| editor.style(cx)));
         let (size, mut state) = editor.update(cx, |editor, cx| {
-            let mut layout_cx = LayoutContext::new(cx);
             element.layout(
                 SizeConstraint::new(vec2f(500., 500.), vec2f(500., 500.)),
                 editor,
-                &mut layout_cx,
+                cx,
             )
         });
 
@@ -3517,11 +3514,10 @@ mod tests {
             editor.set_soft_wrap_mode(language_settings::SoftWrap::EditorWidth, cx);
             editor.set_wrap_width(Some(editor_width), cx);
 
-            let mut layout_cx = LayoutContext::new(cx);
             element.layout(
                 SizeConstraint::new(vec2f(editor_width, 500.), vec2f(editor_width, 500.)),
                 editor,
-                &mut layout_cx,
+                cx,
             )
         });
 

crates/gpui/examples/corner_radii.rs 🔗

@@ -42,7 +42,7 @@ impl<V: View> gpui::Element<V> for CornersElement {
         &mut self,
         constraint: gpui::SizeConstraint,
         _: &mut V,
-        _: &mut gpui::LayoutContext<V>,
+        _: &mut gpui::ViewContext<V>,
     ) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) {
         (constraint.max, ())
     }

crates/gpui/src/app.rs 🔗

@@ -3495,75 +3495,6 @@ impl<V> BorrowWindowContext for ViewContext<'_, '_, V> {
     }
 }
 
-pub struct LayoutContext<'a, 'b, 'c, V> {
-    // Nathan: Making this is public while I work on gpui2.
-    pub view_context: &'c mut ViewContext<'a, 'b, V>,
-}
-
-impl<'a, 'b, 'c, V> LayoutContext<'a, 'b, 'c, V> {
-    pub fn new(view_context: &'c mut ViewContext<'a, 'b, V>) -> Self {
-        Self { view_context }
-    }
-
-    pub fn view_context(&mut self) -> &mut ViewContext<'a, 'b, V> {
-        self.view_context
-    }
-}
-
-impl<'a, 'b, 'c, V> Deref for LayoutContext<'a, 'b, 'c, V> {
-    type Target = ViewContext<'a, 'b, V>;
-
-    fn deref(&self) -> &Self::Target {
-        &self.view_context
-    }
-}
-
-impl<V> DerefMut for LayoutContext<'_, '_, '_, V> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        &mut self.view_context
-    }
-}
-
-impl<V> BorrowAppContext for LayoutContext<'_, '_, '_, V> {
-    fn read_with<T, F: FnOnce(&AppContext) -> T>(&self, f: F) -> T {
-        BorrowAppContext::read_with(&*self.view_context, f)
-    }
-
-    fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, f: F) -> T {
-        BorrowAppContext::update(&mut *self.view_context, f)
-    }
-}
-
-impl<V> BorrowWindowContext for LayoutContext<'_, '_, '_, V> {
-    type Result<T> = T;
-
-    fn read_window<T, F: FnOnce(&WindowContext) -> T>(&self, window: AnyWindowHandle, f: F) -> T {
-        BorrowWindowContext::read_window(&*self.view_context, window, f)
-    }
-
-    fn read_window_optional<T, F>(&self, window: AnyWindowHandle, f: F) -> Option<T>
-    where
-        F: FnOnce(&WindowContext) -> Option<T>,
-    {
-        BorrowWindowContext::read_window_optional(&*self.view_context, window, f)
-    }
-
-    fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
-        &mut self,
-        window: AnyWindowHandle,
-        f: F,
-    ) -> T {
-        BorrowWindowContext::update_window(&mut *self.view_context, window, f)
-    }
-
-    fn update_window_optional<T, F>(&mut self, window: AnyWindowHandle, f: F) -> Option<T>
-    where
-        F: FnOnce(&mut WindowContext) -> Option<T>,
-    {
-        BorrowWindowContext::update_window_optional(&mut *self.view_context, window, f)
-    }
-}
-
 pub struct PaintContext<'a, 'b, 'c, V> {
     pub view_context: &'c mut ViewContext<'a, 'b, V>,
 }
@@ -6489,25 +6420,21 @@ mod tests {
         view_1.update(cx, |_, cx| {
             view_2.update(cx, |_, cx| {
                 // Sanity check
-                let mut layout_cx = LayoutContext::new(cx);
                 assert_eq!(
-                    layout_cx
-                        .keystrokes_for_action(view_1_id, &Action1)
+                    cx.keystrokes_for_action(view_1_id, &Action1)
                         .unwrap()
                         .as_slice(),
                     &[Keystroke::parse("a").unwrap()]
                 );
                 assert_eq!(
-                    layout_cx
-                        .keystrokes_for_action(view_2.id(), &Action2)
+                    cx.keystrokes_for_action(view_2.id(), &Action2)
                         .unwrap()
                         .as_slice(),
                     &[Keystroke::parse("b").unwrap()]
                 );
-                assert_eq!(layout_cx.keystrokes_for_action(view_1.id(), &Action3), None);
+                assert_eq!(cx.keystrokes_for_action(view_1.id(), &Action3), None);
                 assert_eq!(
-                    layout_cx
-                        .keystrokes_for_action(view_2.id(), &Action3)
+                    cx.keystrokes_for_action(view_2.id(), &Action3)
                         .unwrap()
                         .as_slice(),
                     &[Keystroke::parse("c").unwrap()]
@@ -6516,21 +6443,17 @@ mod tests {
                 // The 'a' keystroke propagates up the view tree from view_2
                 // to view_1. The action, Action1, is handled by view_1.
                 assert_eq!(
-                    layout_cx
-                        .keystrokes_for_action(view_2.id(), &Action1)
+                    cx.keystrokes_for_action(view_2.id(), &Action1)
                         .unwrap()
                         .as_slice(),
                     &[Keystroke::parse("a").unwrap()]
                 );
 
                 // Actions that are handled below the current view don't have bindings
-                assert_eq!(layout_cx.keystrokes_for_action(view_1_id, &Action2), None);
+                assert_eq!(cx.keystrokes_for_action(view_1_id, &Action2), None);
 
                 // Actions that are handled in other branches of the tree should not have a binding
-                assert_eq!(
-                    layout_cx.keystrokes_for_action(view_2.id(), &GlobalAction),
-                    None
-                );
+                assert_eq!(cx.keystrokes_for_action(view_2.id(), &GlobalAction), None);
             });
         });
 

crates/gpui/src/app/window.rs 🔗

@@ -16,9 +16,8 @@ use crate::{
     text_layout::TextLayoutCache,
     util::post_inc,
     Action, AnyView, AnyViewHandle, AnyWindowHandle, AppContext, BorrowAppContext,
-    BorrowWindowContext, Effect, Element, Entity, Handle, LayoutContext, MouseRegion,
-    MouseRegionId, PaintContext, SceneBuilder, Subscription, View, ViewContext, ViewHandle,
-    WindowInvalidation,
+    BorrowWindowContext, Effect, Element, Entity, Handle, MouseRegion, MouseRegionId, PaintContext,
+    SceneBuilder, Subscription, View, ViewContext, ViewHandle, WindowInvalidation,
 };
 use anyhow::{anyhow, bail, Result};
 use collections::{HashMap, HashSet};
@@ -1677,13 +1676,13 @@ impl<V: 'static> Element<V> for ChildView {
         &mut self,
         constraint: SizeConstraint,
         _: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         if let Some(mut rendered_view) = cx.window.rendered_views.remove(&self.view_id) {
             let parent_id = cx.view_id();
             cx.window.new_parents.insert(self.view_id, parent_id);
             let size = rendered_view
-                .layout(constraint, cx.view_context)
+                .layout(constraint, cx)
                 .log_err()
                 .unwrap_or(Vector2F::zero());
             cx.window.rendered_views.insert(self.view_id, rendered_view);

crates/gpui/src/elements.rs 🔗

@@ -34,8 +34,8 @@ use crate::{
         rect::RectF,
         vector::{vec2f, Vector2F},
     },
-    json, Action, Entity, LayoutContext, PaintContext, SizeConstraint, TypeTag, View, ViewContext,
-    WeakViewHandle, WindowContext,
+    json, Action, Entity, PaintContext, SizeConstraint, TypeTag, View, ViewContext, WeakViewHandle,
+    WindowContext,
 };
 use anyhow::{anyhow, Result};
 use core::panic;
@@ -59,7 +59,7 @@ pub trait Element<V: 'static>: 'static {
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState);
 
     fn paint(
@@ -259,7 +259,7 @@ trait AnyElementState<V> {
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> Vector2F;
 
     fn paint(
@@ -310,7 +310,7 @@ impl<V, E: Element<V>> AnyElementState<V> for ElementState<V, E> {
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> Vector2F {
         let result;
         *self = match mem::take(self) {
@@ -510,7 +510,7 @@ impl<V> AnyElement<V> {
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> Vector2F {
         self.state.layout(constraint, view, cx)
     }
@@ -570,7 +570,7 @@ impl<V: 'static> Element<V> for AnyElement<V> {
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         let size = self.layout(constraint, view, cx);
         (size, ())
@@ -659,10 +659,7 @@ impl<V: View> AnyRootElement for RootElement<V> {
             .view
             .upgrade(cx)
             .ok_or_else(|| anyhow!("layout called on a root element for a dropped view"))?;
-        view.update(cx, |view, cx| {
-            let mut cx = LayoutContext::new(cx);
-            Ok(self.element.layout(constraint, view, &mut cx))
-        })
+        view.update(cx, |view, cx| Ok(self.element.layout(constraint, view, cx)))
     }
 
     fn paint(

crates/gpui/src/elements/align.rs 🔗

@@ -1,6 +1,6 @@
 use crate::{
     geometry::{rect::RectF, vector::Vector2F},
-    json, AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext,
+    json, AnyElement, Element, PaintContext, SizeConstraint, ViewContext,
 };
 use json::ToJson;
 
@@ -48,7 +48,7 @@ impl<V: 'static> Element<V> for Align<V> {
         &mut self,
         mut constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         let mut size = constraint.max;
         constraint.min = Vector2F::zero();

crates/gpui/src/elements/canvas.rs 🔗

@@ -33,7 +33,7 @@ where
         &mut self,
         constraint: crate::SizeConstraint,
         _: &mut V,
-        _: &mut crate::LayoutContext<V>,
+        _: &mut crate::ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         let x = if constraint.max.x().is_finite() {
             constraint.max.x()

crates/gpui/src/elements/clipped.rs 🔗

@@ -3,7 +3,7 @@ use std::ops::Range;
 use pathfinder_geometry::{rect::RectF, vector::Vector2F};
 use serde_json::json;
 
-use crate::{json, AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext};
+use crate::{json, AnyElement, Element, PaintContext, SizeConstraint, ViewContext};
 
 pub struct Clipped<V> {
     child: AnyElement<V>,
@@ -23,7 +23,7 @@ impl<V: 'static> Element<V> for Clipped<V> {
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         (self.child.layout(constraint, view, cx), ())
     }

crates/gpui/src/elements/component.rs 🔗

@@ -2,7 +2,7 @@ use std::{any::Any, marker::PhantomData};
 
 use pathfinder_geometry::{rect::RectF, vector::Vector2F};
 
-use crate::{AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext};
+use crate::{AnyElement, Element, PaintContext, SizeConstraint, ViewContext};
 
 use super::Empty;
 
@@ -282,14 +282,14 @@ impl<V: 'static, C: StatefulComponent<V> + 'static> Element<V> for ComponentAdap
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         if self.element.is_none() {
             let element = self
                 .component
                 .take()
                 .expect("Component can only be rendered once")
-                .render(view, cx.view_context());
+                .render(view, cx);
             self.element = Some(element);
         }
         let constraint = self.element.as_mut().unwrap().layout(constraint, view, cx);

crates/gpui/src/elements/constrained_box.rs 🔗

@@ -5,7 +5,7 @@ use serde_json::json;
 
 use crate::{
     geometry::{rect::RectF, vector::Vector2F},
-    json, AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext,
+    json, AnyElement, Element, PaintContext, SizeConstraint, ViewContext,
 };
 
 pub struct ConstrainedBox<V> {
@@ -15,7 +15,7 @@ pub struct ConstrainedBox<V> {
 
 pub enum Constraint<V> {
     Static(SizeConstraint),
-    Dynamic(Box<dyn FnMut(SizeConstraint, &mut V, &mut LayoutContext<V>) -> SizeConstraint>),
+    Dynamic(Box<dyn FnMut(SizeConstraint, &mut V, &mut ViewContext<V>) -> SizeConstraint>),
 }
 
 impl<V> ToJson for Constraint<V> {
@@ -37,8 +37,7 @@ impl<V: 'static> ConstrainedBox<V> {
 
     pub fn dynamically(
         mut self,
-        constraint: impl 'static
-            + FnMut(SizeConstraint, &mut V, &mut LayoutContext<V>) -> SizeConstraint,
+        constraint: impl 'static + FnMut(SizeConstraint, &mut V, &mut ViewContext<V>) -> SizeConstraint,
     ) -> Self {
         self.constraint = Constraint::Dynamic(Box::new(constraint));
         self
@@ -120,7 +119,7 @@ impl<V: 'static> ConstrainedBox<V> {
         &mut self,
         input_constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> SizeConstraint {
         match &mut self.constraint {
             Constraint::Static(constraint) => *constraint,
@@ -139,7 +138,7 @@ impl<V: 'static> Element<V> for ConstrainedBox<V> {
         &mut self,
         mut parent_constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         let constraint = self.constraint(parent_constraint, view, cx);
         parent_constraint.min = parent_constraint.min.max(constraint.min);

crates/gpui/src/elements/container.rs 🔗

@@ -10,7 +10,7 @@ use crate::{
     json::ToJson,
     platform::CursorStyle,
     scene::{self, CornerRadii, CursorRegion, Quad},
-    AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext,
+    AnyElement, Element, PaintContext, SizeConstraint, ViewContext,
 };
 use schemars::JsonSchema;
 use serde::Deserialize;
@@ -371,7 +371,7 @@ impl<V: 'static> Element<V> for Container<V> {
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         let mut size_buffer = self.margin_size() + self.padding_size();
         if !self.style.border.overlay {

crates/gpui/src/elements/empty.rs 🔗

@@ -6,7 +6,7 @@ use crate::{
         vector::{vec2f, Vector2F},
     },
     json::{json, ToJson},
-    LayoutContext, PaintContext, ViewContext,
+    PaintContext, ViewContext,
 };
 use crate::{Element, SizeConstraint};
 
@@ -34,7 +34,7 @@ impl<V: 'static> Element<V> for Empty {
         &mut self,
         constraint: SizeConstraint,
         _: &mut V,
-        _: &mut LayoutContext<V>,
+        _: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         let x = if constraint.max.x().is_finite() && !self.collapsed {
             constraint.max.x()

crates/gpui/src/elements/expanded.rs 🔗

@@ -2,7 +2,7 @@ use std::ops::Range;
 
 use crate::{
     geometry::{rect::RectF, vector::Vector2F},
-    json, AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext,
+    json, AnyElement, Element, PaintContext, SizeConstraint, ViewContext,
 };
 use serde_json::json;
 
@@ -42,7 +42,7 @@ impl<V: 'static> Element<V> for Expanded<V> {
         &mut self,
         mut constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         if self.full_width {
             constraint.min.set_x(constraint.max.x());

crates/gpui/src/elements/flex.rs 🔗

@@ -2,8 +2,8 @@ use std::{any::Any, cell::Cell, f32::INFINITY, ops::Range, rc::Rc};
 
 use crate::{
     json::{self, ToJson, Value},
-    AnyElement, Axis, Element, ElementStateHandle, LayoutContext, PaintContext, SizeConstraint,
-    Vector2FExt, ViewContext,
+    AnyElement, Axis, Element, ElementStateHandle, PaintContext, SizeConstraint, Vector2FExt,
+    ViewContext,
 };
 use pathfinder_geometry::{
     rect::RectF,
@@ -85,7 +85,7 @@ impl<V: 'static> Flex<V> {
         remaining_flex: &mut f32,
         cross_axis_max: &mut f32,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) {
         let cross_axis = self.axis.invert();
         for child in self.children.iter_mut() {
@@ -136,7 +136,7 @@ impl<V: 'static> Element<V> for Flex<V> {
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         let mut total_flex = None;
         let mut fixed_space = self.children.len().saturating_sub(1) as f32 * self.spacing;
@@ -225,7 +225,7 @@ impl<V: 'static> Element<V> for Flex<V> {
         }
 
         if let Some(scroll_state) = self.scroll_state.as_ref() {
-            scroll_state.0.update(cx.view_context(), |scroll_state, _| {
+            scroll_state.0.update(cx, |scroll_state, _| {
                 if let Some(scroll_to) = scroll_state.scroll_to.take() {
                     let visible_start = scroll_state.scroll_position.get();
                     let visible_end = visible_start + size.along(self.axis);
@@ -442,7 +442,7 @@ impl<V: 'static> Element<V> for FlexItem<V> {
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         let size = self.child.layout(constraint, view, cx);
         (size, ())

crates/gpui/src/elements/hook.rs 🔗

@@ -3,7 +3,7 @@ use std::ops::Range;
 use crate::{
     geometry::{rect::RectF, vector::Vector2F},
     json::json,
-    AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext,
+    AnyElement, Element, PaintContext, SizeConstraint, ViewContext,
 };
 
 pub struct Hook<V> {
@@ -36,7 +36,7 @@ impl<V: 'static> Element<V> for Hook<V> {
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         let size = self.child.layout(constraint, view, cx);
         if let Some(handler) = self.after_layout.as_mut() {

crates/gpui/src/elements/image.rs 🔗

@@ -5,7 +5,7 @@ use crate::{
         vector::{vec2f, Vector2F},
     },
     json::{json, ToJson},
-    scene, Element, ImageData, LayoutContext, PaintContext, SizeConstraint, ViewContext,
+    scene, Element, ImageData, PaintContext, SizeConstraint, ViewContext,
 };
 use schemars::JsonSchema;
 use serde::Deserialize;
@@ -64,7 +64,7 @@ impl<V: 'static> Element<V> for Image {
         &mut self,
         constraint: SizeConstraint,
         _: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         let data = match &self.source {
             ImageSource::Path(path) => match cx.asset_cache.png(path) {

crates/gpui/src/elements/keystroke_label.rs 🔗

@@ -39,7 +39,7 @@ impl<V: 'static> Element<V> for KeystrokeLabel {
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, AnyElement<V>) {
         let mut element = if let Some(keystrokes) =
             cx.keystrokes_for_action(self.view_id, self.action.as_ref())

crates/gpui/src/elements/label.rs 🔗

@@ -8,7 +8,7 @@ use crate::{
     },
     json::{ToJson, Value},
     text_layout::{Line, RunStyle},
-    Element, LayoutContext, PaintContext, SizeConstraint, ViewContext,
+    Element, PaintContext, SizeConstraint, ViewContext,
 };
 use schemars::JsonSchema;
 use serde::Deserialize;
@@ -136,7 +136,7 @@ impl<V: 'static> Element<V> for Label {
         &mut self,
         constraint: SizeConstraint,
         _: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         let runs = self.compute_runs();
         let line = cx.text_layout_cache().layout_str(

crates/gpui/src/elements/list.rs 🔗

@@ -4,7 +4,7 @@ use crate::{
         vector::{vec2f, Vector2F},
     },
     json::json,
-    AnyElement, Element, LayoutContext, MouseRegion, PaintContext, SizeConstraint, ViewContext,
+    AnyElement, Element, MouseRegion, PaintContext, SizeConstraint, ViewContext,
 };
 use std::{cell::RefCell, collections::VecDeque, fmt::Debug, ops::Range, rc::Rc};
 use sum_tree::{Bias, SumTree};
@@ -99,7 +99,7 @@ impl<V: 'static> Element<V> for List<V> {
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         let state = &mut *self.state.0.borrow_mut();
         let size = constraint.max;
@@ -449,7 +449,7 @@ impl<V: 'static> StateInner<V> {
         existing_element: Option<&ListItem<V>>,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> Option<Rc<RefCell<AnyElement<V>>>> {
         if let Some(ListItem::Rendered(element)) = existing_element {
             Some(element.clone())
@@ -662,8 +662,7 @@ mod tests {
             });
 
             let mut list = List::new(state.clone());
-            let mut layout_cx = LayoutContext::new(cx);
-            let (size, _) = list.layout(constraint, &mut view, &mut layout_cx);
+            let (size, _) = list.layout(constraint, &mut view, cx);
             assert_eq!(size, vec2f(100., 40.));
             assert_eq!(
                 state.0.borrow().items.summary().clone(),
@@ -687,8 +686,7 @@ mod tests {
                 cx,
             );
 
-            let mut layout_cx = LayoutContext::new(cx);
-            let (_, logical_scroll_top) = list.layout(constraint, &mut view, &mut layout_cx);
+            let (_, logical_scroll_top) = list.layout(constraint, &mut view, cx);
             assert_eq!(
                 logical_scroll_top,
                 ListOffset {
@@ -712,8 +710,7 @@ mod tests {
                 }
             );
 
-            let mut layout_cx = LayoutContext::new(cx);
-            let (size, logical_scroll_top) = list.layout(constraint, &mut view, &mut layout_cx);
+            let (size, logical_scroll_top) = list.layout(constraint, &mut view, cx);
             assert_eq!(size, vec2f(100., 40.));
             assert_eq!(
                 state.0.borrow().items.summary().clone(),
@@ -831,11 +828,10 @@ mod tests {
 
                 let mut list = List::new(state.clone());
                 let window_size = vec2f(width, height);
-                let mut layout_cx = LayoutContext::new(cx);
                 let (size, logical_scroll_top) = list.layout(
                     SizeConstraint::new(vec2f(0., 0.), window_size),
                     &mut view,
-                    &mut layout_cx,
+                    cx,
                 );
                 assert_eq!(size, window_size);
                 last_logical_scroll_top = Some(logical_scroll_top);
@@ -948,7 +944,7 @@ mod tests {
             &mut self,
             _: SizeConstraint,
             _: &mut V,
-            _: &mut LayoutContext<V>,
+            _: &mut ViewContext<V>,
         ) -> (Vector2F, ()) {
             (self.size, ())
         }

crates/gpui/src/elements/mouse_event_handler.rs 🔗

@@ -10,8 +10,8 @@ use crate::{
         CursorRegion, HandlerSet, MouseClick, MouseClickOut, MouseDown, MouseDownOut, MouseDrag,
         MouseHover, MouseMove, MouseMoveOut, MouseScrollWheel, MouseUp, MouseUpOut,
     },
-    AnyElement, Element, EventContext, LayoutContext, MouseRegion, MouseState, PaintContext,
-    SizeConstraint, TypeTag, ViewContext,
+    AnyElement, Element, EventContext, MouseRegion, MouseState, PaintContext, SizeConstraint,
+    TypeTag, ViewContext,
 };
 use serde_json::json;
 use std::ops::Range;
@@ -270,7 +270,7 @@ impl<V: 'static> Element<V> for MouseEventHandler<V> {
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         (self.child.layout(constraint, view, cx), ())
     }

crates/gpui/src/elements/overlay.rs 🔗

@@ -3,8 +3,7 @@ use std::ops::Range;
 use crate::{
     geometry::{rect::RectF, vector::Vector2F},
     json::ToJson,
-    AnyElement, Axis, Element, LayoutContext, MouseRegion, PaintContext, SizeConstraint,
-    ViewContext,
+    AnyElement, Axis, Element, MouseRegion, PaintContext, SizeConstraint, ViewContext,
 };
 use serde_json::json;
 
@@ -125,7 +124,7 @@ impl<V: 'static> Element<V> for Overlay<V> {
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         let constraint = if self.anchor_position.is_some() {
             SizeConstraint::new(Vector2F::zero(), cx.window_size())

crates/gpui/src/elements/resizable.rs 🔗

@@ -7,8 +7,8 @@ use serde_json::json;
 use crate::{
     geometry::rect::RectF,
     platform::{CursorStyle, MouseButton},
-    AnyElement, AppContext, Axis, Element, LayoutContext, MouseRegion, PaintContext,
-    SizeConstraint, TypeTag, View, ViewContext,
+    AnyElement, AppContext, Axis, Element, MouseRegion, PaintContext, SizeConstraint, TypeTag,
+    View, ViewContext,
 };
 
 #[derive(Copy, Clone, Debug)]
@@ -105,7 +105,7 @@ impl<V: 'static> Element<V> for Resizable<V> {
         &mut self,
         constraint: crate::SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         (self.child.layout(constraint, view, cx), constraint)
     }
@@ -241,7 +241,7 @@ impl<V: View, P: 'static> Element<V> for BoundsProvider<V, P> {
         &mut self,
         constraint: crate::SizeConstraint,
         view: &mut V,
-        cx: &mut crate::LayoutContext<V>,
+        cx: &mut crate::ViewContext<V>,
     ) -> (pathfinder_geometry::vector::Vector2F, Self::LayoutState) {
         (self.child.layout(constraint, view, cx), ())
     }

crates/gpui/src/elements/stack.rs 🔗

@@ -3,7 +3,7 @@ use std::ops::Range;
 use crate::{
     geometry::{rect::RectF, vector::Vector2F},
     json::{self, json, ToJson},
-    AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext,
+    AnyElement, Element, PaintContext, SizeConstraint, ViewContext,
 };
 
 /// Element which renders it's children in a stack on top of each other.
@@ -34,7 +34,7 @@ impl<V: 'static> Element<V> for Stack<V> {
         &mut self,
         mut constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         let mut size = constraint.min;
         let mut children = self.children.iter_mut();

crates/gpui/src/elements/svg.rs 🔗

@@ -7,7 +7,7 @@ use crate::{
         rect::RectF,
         vector::{vec2f, Vector2F},
     },
-    scene, Element, LayoutContext, SizeConstraint, ViewContext,
+    scene, Element, SizeConstraint, ViewContext,
 };
 use schemars::JsonSchema;
 use serde_derive::Deserialize;
@@ -49,7 +49,7 @@ impl<V: 'static> Element<V> for Svg {
         &mut self,
         constraint: SizeConstraint,
         _: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         match cx.asset_cache.svg(&self.path) {
             Ok(tree) => {

crates/gpui/src/elements/text.rs 🔗

@@ -7,8 +7,7 @@ use crate::{
     },
     json::{ToJson, Value},
     text_layout::{Line, RunStyle, ShapedBoundary},
-    Element, FontCache, LayoutContext, PaintContext, SizeConstraint, TextLayoutCache, ViewContext,
-    WindowContext,
+    Element, FontCache, PaintContext, SizeConstraint, TextLayoutCache, ViewContext, WindowContext,
 };
 use log::warn;
 use serde_json::json;
@@ -78,7 +77,7 @@ impl<V: 'static> Element<V> for Text {
         &mut self,
         constraint: SizeConstraint,
         _: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         // Convert the string and highlight ranges into an iterator of highlighted chunks.
 
@@ -409,11 +408,10 @@ mod tests {
             let mut view = TestView;
             fonts::with_font_cache(cx.font_cache().clone(), || {
                 let mut text = Text::new("Hello\r\n", Default::default()).with_soft_wrap(true);
-                let mut layout_cx = LayoutContext::new(cx);
                 let (_, state) = text.layout(
                     SizeConstraint::new(Default::default(), vec2f(f32::INFINITY, f32::INFINITY)),
                     &mut view,
-                    &mut layout_cx,
+                    cx,
                 );
                 assert_eq!(state.shaped_lines.len(), 2);
                 assert_eq!(state.wrap_boundaries.len(), 2);

crates/gpui/src/elements/tooltip.rs 🔗

@@ -6,8 +6,7 @@ use crate::{
     fonts::TextStyle,
     geometry::{rect::RectF, vector::Vector2F},
     json::json,
-    Action, Axis, ElementStateHandle, LayoutContext, PaintContext, SizeConstraint, Task, TypeTag,
-    ViewContext,
+    Action, Axis, ElementStateHandle, PaintContext, SizeConstraint, Task, TypeTag, ViewContext,
 };
 use schemars::JsonSchema;
 use serde::Deserialize;
@@ -189,7 +188,7 @@ impl<V: 'static> Element<V> for Tooltip<V> {
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         let size = self.child.layout(constraint, view, cx);
         if let Some(tooltip) = self.tooltip.as_mut() {

crates/gpui/src/elements/uniform_list.rs 🔗

@@ -6,7 +6,7 @@ use crate::{
     },
     json::{self, json},
     platform::ScrollWheelEvent,
-    AnyElement, LayoutContext, MouseRegion, PaintContext, ViewContext,
+    AnyElement, MouseRegion, PaintContext, ViewContext,
 };
 use json::ToJson;
 use std::{cell::RefCell, cmp, ops::Range, rc::Rc};
@@ -158,7 +158,7 @@ impl<V: 'static> Element<V> for UniformList<V> {
         &mut self,
         constraint: SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         if constraint.max.y().is_infinite() {
             unimplemented!(

crates/gpui2/src/adapter.rs 🔗

@@ -13,7 +13,7 @@ impl<V: 'static> gpui::Element<V> for AdapterElement<V> {
         &mut self,
         constraint: gpui::SizeConstraint,
         view: &mut V,
-        cx: &mut gpui::LayoutContext<V>,
+        cx: &mut gpui::ViewContext<V>,
     ) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) {
         cx.push_layout_engine(LayoutEngine::new());
 

crates/gpui_macros/src/gpui_macros.rs 🔗

@@ -329,7 +329,7 @@ pub fn element_derive(input: TokenStream) -> TokenStream {
                 &mut self,
                 constraint: gpui::SizeConstraint,
                 view: &mut V,
-                cx: &mut gpui::LayoutContext<V>,
+                cx: &mut gpui::ViewContext<V>,
             ) -> (gpui::geometry::vector::Vector2F, gpui::elements::AnyElement<V>) {
                 let mut element = self.render(view, cx).into_any();
                 let size = element.layout(constraint, view, cx);

crates/terminal_view/src/terminal_element.rs 🔗

@@ -10,9 +10,8 @@ use gpui::{
     platform::{CursorStyle, MouseButton},
     serde_json::json,
     text_layout::{Line, RunStyle},
-    AnyElement, Element, EventContext, FontCache, LayoutContext, ModelContext, MouseRegion,
-    PaintContext, Quad, SizeConstraint, TextLayoutCache, ViewContext, WeakModelHandle,
-    WindowContext,
+    AnyElement, Element, EventContext, FontCache, ModelContext, MouseRegion, PaintContext, Quad,
+    SizeConstraint, TextLayoutCache, ViewContext, WeakModelHandle, WindowContext,
 };
 use itertools::Itertools;
 use language::CursorShape;
@@ -527,7 +526,7 @@ impl Element<TerminalView> for TerminalElement {
         &mut self,
         constraint: gpui::SizeConstraint,
         view: &mut TerminalView,
-        cx: &mut LayoutContext<TerminalView>,
+        cx: &mut ViewContext<TerminalView>,
     ) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) {
         let settings = settings::get::<ThemeSettings>(cx);
         let terminal_settings = settings::get::<TerminalSettings>(cx);

crates/workspace/src/pane.rs 🔗

@@ -25,8 +25,8 @@ use gpui::{
     keymap_matcher::KeymapContext,
     platform::{CursorStyle, MouseButton, NavigationDirection, PromptLevel},
     Action, AnyViewHandle, AnyWeakViewHandle, AppContext, AsyncAppContext, Entity, EventContext,
-    LayoutContext, ModelHandle, MouseRegion, PaintContext, Quad, Task, View, ViewContext,
-    ViewHandle, WeakViewHandle, WindowContext,
+    ModelHandle, MouseRegion, PaintContext, Quad, Task, View, ViewContext, ViewHandle,
+    WeakViewHandle, WindowContext,
 };
 use project::{Project, ProjectEntryId, ProjectPath};
 use serde::Deserialize;
@@ -1999,7 +1999,7 @@ impl<V: 'static> Element<V> for PaneBackdrop<V> {
         &mut self,
         constraint: gpui::SizeConstraint,
         view: &mut V,
-        cx: &mut LayoutContext<V>,
+        cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         let size = self.child.layout(constraint, view, cx);
         (size, ())

crates/workspace/src/pane_group.rs 🔗

@@ -594,8 +594,8 @@ mod element {
         json::{self, ToJson},
         platform::{CursorStyle, MouseButton},
         scene::MouseDrag,
-        AnyElement, Axis, CursorRegion, Element, EventContext, LayoutContext, MouseRegion,
-        PaintContext, RectFExt, SizeConstraint, Vector2FExt, ViewContext,
+        AnyElement, Axis, CursorRegion, Element, EventContext, MouseRegion, PaintContext, RectFExt,
+        SizeConstraint, Vector2FExt, ViewContext,
     };
 
     use crate::{
@@ -641,7 +641,7 @@ mod element {
             remaining_flex: &mut f32,
             cross_axis_max: &mut f32,
             view: &mut Workspace,
-            cx: &mut LayoutContext<Workspace>,
+            cx: &mut ViewContext<Workspace>,
         ) {
             let flexes = self.flexes.borrow();
             let cross_axis = self.axis.invert();
@@ -789,7 +789,7 @@ mod element {
             &mut self,
             constraint: SizeConstraint,
             view: &mut Workspace,
-            cx: &mut LayoutContext<Workspace>,
+            cx: &mut ViewContext<Workspace>,
         ) -> (Vector2F, Self::LayoutState) {
             debug_assert!(self.children.len() == self.flexes.borrow().len());
 

crates/workspace/src/status_bar.rs 🔗

@@ -8,8 +8,8 @@ use gpui::{
         vector::{vec2f, Vector2F},
     },
     json::{json, ToJson},
-    AnyElement, AnyViewHandle, Entity, LayoutContext, PaintContext, SizeConstraint, Subscription,
-    View, ViewContext, ViewHandle, WindowContext,
+    AnyElement, AnyViewHandle, Entity, PaintContext, SizeConstraint, Subscription, View,
+    ViewContext, ViewHandle, WindowContext,
 };
 
 pub trait StatusItemView: View {
@@ -208,7 +208,7 @@ impl Element<StatusBar> for StatusBarElement {
         &mut self,
         mut constraint: SizeConstraint,
         view: &mut StatusBar,
-        cx: &mut LayoutContext<StatusBar>,
+        cx: &mut ViewContext<StatusBar>,
     ) -> (Vector2F, Self::LayoutState) {
         let max_width = constraint.max.x();
         constraint.min = vec2f(0., constraint.min.y());