From f565fb8750425f8fb38646680fff988055fff468 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Tue, 3 Feb 2026 12:00:22 +0100 Subject: [PATCH] gpui: Make entities no longer implement Element (they go through AnyElement now) (#48217) This reduces e.g. agent_ui's LLVM lines from 1.95m to 1.7m ( -> 56009 -> 50899). git_ui: 1.02 -> 0.917m (30700 functions -> 27496) Overall, anything that implements `Render` should benefit. OTOH `editor` does not, because it has a custom `Element` impl. Release Notes: - N/A --- crates/editor/src/editor_tests.rs | 2 +- crates/editor/src/test.rs | 6 ++-- crates/gpui/src/element.rs | 39 ++++++++++++++------- crates/gpui/src/elements/list.rs | 10 +++--- crates/gpui/src/view.rs | 57 ++----------------------------- 5 files changed, 40 insertions(+), 74 deletions(-) diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 3f938cf3bc89074b0666a784246ea59cb3bcc7c4..c5b17fec42f38eb0eaed82881610bc26790b96a7 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -30563,7 +30563,7 @@ fn test_editor_rendering_when_positioned_above_viewport(cx: &mut TestAppContext) cx.draw( gpui::point(px(0.), px(-10000.)), gpui::size(px(500.), px(3000.)), - |_, _| editor.clone(), + |_, _| editor.clone().into_any_element(), ); // If we get here without hanging, the test passes diff --git a/crates/editor/src/test.rs b/crates/editor/src/test.rs index 92fccf1e0579a79cd891047686d8312bc7541b1e..1c8e117369ec65b7a784d4145891548f1fda8756 100644 --- a/crates/editor/src/test.rs +++ b/crates/editor/src/test.rs @@ -19,7 +19,7 @@ use gpui::{ use multi_buffer::{MultiBufferOffset, ToPoint}; use pretty_assertions::assert_eq; use project::{Project, project_settings::DiagnosticSeverity}; -use ui::{App, BorrowAppContext, px}; +use ui::{App, BorrowAppContext, IntoElement, px}; use util::test::{generate_marked_text, marked_text_offsets, marked_text_ranges}; #[cfg(test)] @@ -193,7 +193,9 @@ pub fn editor_content_with_blocks_and_size( cx: &mut VisualTestContext, ) -> String { cx.simulate_resize(draw_size); - cx.draw(gpui::Point::default(), draw_size, |_, _| editor.clone()); + cx.draw(gpui::Point::default(), draw_size, |_, _| { + editor.clone().into_any_element() + }); let (snapshot, mut lines, blocks) = editor.update_in(cx, |editor, window, cx| { let snapshot = editor.snapshot(window, cx); let text = editor.display_text(cx); diff --git a/crates/gpui/src/element.rs b/crates/gpui/src/element.rs index aaf9869ec7c1490e25f8d40b8b8db272d1702d9d..7b78e9b0ad70631fd52b437dbceb535d35b0b666 100644 --- a/crates/gpui/src/element.rs +++ b/crates/gpui/src/element.rs @@ -33,8 +33,8 @@ use crate::{ App, ArenaBox, AvailableSpace, Bounds, Context, DispatchNodeId, ElementId, FocusHandle, - InspectorElementId, LayoutId, Pixels, Point, Size, Style, Window, util::FluentBuilder, - window::with_element_arena, + InspectorElementId, LayoutId, Pixels, Point, SharedString, Size, Style, Window, + util::FluentBuilder, window::with_element_arena, }; use derive_more::{Deref, DerefMut}; use std::{ @@ -197,8 +197,27 @@ impl Component { } } +fn prepaint_component( + (element, name): &mut (AnyElement, &'static str), + window: &mut Window, + cx: &mut App, +) { + window.with_id(ElementId::Name(SharedString::new_static(name)), |window| { + element.prepaint(window, cx); + }) +} + +fn paint_component( + (element, name): &mut (AnyElement, &'static str), + window: &mut Window, + cx: &mut App, +) { + window.with_id(ElementId::Name(SharedString::new_static(name)), |window| { + element.paint(window, cx); + }) +} impl Element for Component { - type RequestLayoutState = AnyElement; + type RequestLayoutState = (AnyElement, &'static str); type PrepaintState = (); fn id(&self) -> Option { @@ -229,7 +248,7 @@ impl Element for Component { .into_any_element(); let layout_id = element.request_layout(window, cx); - (layout_id, element) + (layout_id, (element, type_name::())) }) } @@ -238,13 +257,11 @@ impl Element for Component { _id: Option<&GlobalElementId>, _inspector_id: Option<&InspectorElementId>, _: Bounds, - element: &mut AnyElement, + state: &mut Self::RequestLayoutState, window: &mut Window, cx: &mut App, ) { - window.with_id(ElementId::Name(type_name::().into()), |window| { - element.prepaint(window, cx); - }) + prepaint_component(state, window, cx); } fn paint( @@ -252,14 +269,12 @@ impl Element for Component { _id: Option<&GlobalElementId>, _inspector_id: Option<&InspectorElementId>, _: Bounds, - element: &mut Self::RequestLayoutState, + state: &mut Self::RequestLayoutState, _: &mut Self::PrepaintState, window: &mut Window, cx: &mut App, ) { - window.with_id(ElementId::Name(type_name::().into()), |window| { - element.paint(window, cx); - }) + paint_component(state, window, cx); } } diff --git a/crates/gpui/src/elements/list.rs b/crates/gpui/src/elements/list.rs index 26cf14a8d39f763d82a5f4070f372e845ace8815..5403bf10eb9a078dfd113462644636b49d1840e4 100644 --- a/crates/gpui/src/elements/list.rs +++ b/crates/gpui/src/elements/list.rs @@ -1285,7 +1285,7 @@ mod test { // Paint cx.draw(point(px(0.), px(0.)), size(px(100.), px(20.)), |_, cx| { - cx.new(|_| TestView(state.clone())) + cx.new(|_| TestView(state.clone())).into_any_element() }); // Reset @@ -1322,7 +1322,7 @@ mod test { // Paint cx.draw(point(px(0.), px(0.)), size(px(100.), px(100.)), |_, cx| { - cx.new(|_| TestView(state.clone())) + cx.new(|_| TestView(state.clone())).into_any_element() }); // Test positive distance: start at item 1, move down 30px @@ -1391,7 +1391,7 @@ mod test { }); cx.draw(point(px(0.), px(0.)), size(px(100.), px(200.)), |_, _| { - view.clone() + view.clone().into_any_element() }); let offset = state.logical_scroll_top(); @@ -1405,7 +1405,9 @@ mod test { item_height.set(50); state.remeasure(); - cx.draw(point(px(0.), px(0.)), size(px(100.), px(200.)), |_, _| view); + cx.draw(point(px(0.), px(0.)), size(px(100.), px(200.)), |_, _| { + view.into_any_element() + }); let offset = state.logical_scroll_top(); assert_eq!(offset.item_ix, 2); diff --git a/crates/gpui/src/view.rs b/crates/gpui/src/view.rs index 217971792ee978307a19f7e40374cb337e38a625..39b87dbb8039e774f2ec25fab660d46e7c72b01e 100644 --- a/crates/gpui/src/view.rs +++ b/crates/gpui/src/view.rs @@ -25,59 +25,6 @@ struct ViewCacheKey { text_style: TextStyle, } -impl Element for Entity { - type RequestLayoutState = AnyElement; - type PrepaintState = (); - - fn id(&self) -> Option { - Some(ElementId::View(self.entity_id())) - } - - fn source_location(&self) -> Option<&'static std::panic::Location<'static>> { - None - } - - fn request_layout( - &mut self, - _id: Option<&GlobalElementId>, - _inspector_id: Option<&InspectorElementId>, - window: &mut Window, - cx: &mut App, - ) -> (LayoutId, Self::RequestLayoutState) { - let mut element = self.update(cx, |view, cx| view.render(window, cx).into_any_element()); - let layout_id = window.with_rendered_view(self.entity_id(), |window| { - element.request_layout(window, cx) - }); - (layout_id, element) - } - - fn prepaint( - &mut self, - _id: Option<&GlobalElementId>, - _inspector_id: Option<&InspectorElementId>, - _: Bounds, - element: &mut Self::RequestLayoutState, - window: &mut Window, - cx: &mut App, - ) { - window.set_view_id(self.entity_id()); - window.with_rendered_view(self.entity_id(), |window| element.prepaint(window, cx)); - } - - fn paint( - &mut self, - _id: Option<&GlobalElementId>, - _inspector_id: Option<&InspectorElementId>, - _: Bounds, - element: &mut Self::RequestLayoutState, - _: &mut Self::PrepaintState, - window: &mut Window, - cx: &mut App, - ) { - window.with_rendered_view(self.entity_id(), |window| element.paint(window, cx)); - } -} - /// A dynamically-typed handle to a view, which can be downcast to a [Entity] for a specific type. #[derive(Clone, Debug)] pub struct AnyView { @@ -294,10 +241,10 @@ impl Element for AnyView { } impl IntoElement for Entity { - type Element = Entity; + type Element = AnyView; fn into_element(self) -> Self::Element { - self + self.into() } }