WIP

Nathan Sobo created

Change summary

crates/activity_indicator/src/activity_indicator.rs          |   2 
crates/auto_update/src/update_notification.rs                |   4 
crates/breadcrumbs/src/breadcrumbs.rs                        |   2 
crates/collab_ui/src/collab_titlebar_item.rs                 |  32 
crates/collab_ui/src/collaborator_list_popover.rs            |   4 
crates/collab_ui/src/contact_finder.rs                       |   4 
crates/collab_ui/src/contact_list.rs                         |  16 
crates/collab_ui/src/contact_notification.rs                 |   2 
crates/collab_ui/src/contacts_popover.rs                     |   2 
crates/collab_ui/src/face_pile.rs                            |  10 
crates/collab_ui/src/incoming_call_notification.rs           |   8 
crates/collab_ui/src/notifications.rs                        |   4 
crates/collab_ui/src/project_shared_notification.rs          |   6 
crates/collab_ui/src/sharing_status_indicator.rs             |   4 
crates/command_palette/src/command_palette.rs                |   6 
crates/context_menu/src/context_menu.rs                      |  13 
crates/copilot/src/sign_in.rs                                |  15 
crates/copilot_button/src/copilot_button.rs                  |   4 
crates/diagnostics/src/diagnostics.rs                        |   6 
crates/diagnostics/src/items.rs                              |   2 
crates/drag_and_drop/src/drag_and_drop.rs                    |  12 
crates/editor/src/display_map/block_map.rs                   |  10 
crates/editor/src/editor.rs                                  |  18 
crates/editor/src/element.rs                                 |  14 
crates/editor/src/hover_popover.rs                           |   8 
crates/editor/src/items.rs                                   |  31 
crates/feedback/src/deploy_feedback_button.rs                |   2 
crates/feedback/src/feedback_editor.rs                       |   6 
crates/feedback/src/feedback_info_text.rs                    |   4 
crates/feedback/src/submit_feedback_button.rs                |   4 
crates/file_finder/src/file_finder.rs                        |   4 
crates/go_to_line/src/go_to_line.rs                          |   2 
crates/gpui/examples/text.rs                                 |   6 
crates/gpui/src/app.rs                                       |  60 +
crates/gpui/src/app/window.rs                                | 141 +---
crates/gpui/src/elements.rs                                  | 179 +++++
crates/gpui/src/elements/align.rs                            |   8 
crates/gpui/src/elements/canvas.rs                           |   4 
crates/gpui/src/elements/clipped.rs                          |   8 
crates/gpui/src/elements/constrained_box.rs                  |   8 
crates/gpui/src/elements/container.rs                        |   8 
crates/gpui/src/elements/empty.rs                            |   4 
crates/gpui/src/elements/expanded.rs                         |   8 
crates/gpui/src/elements/flex.rs                             |  16 
crates/gpui/src/elements/hook.rs                             |   8 
crates/gpui/src/elements/image.rs                            |   4 
crates/gpui/src/elements/keystroke_label.rs                  |  12 
crates/gpui/src/elements/label.rs                            |   4 
crates/gpui/src/elements/list.rs                             |  18 
crates/gpui/src/elements/mouse_event_handler.rs              |  10 
crates/gpui/src/elements/overlay.rs                          |   8 
crates/gpui/src/elements/resizable.rs                        |   8 
crates/gpui/src/elements/stack.rs                            |  10 
crates/gpui/src/elements/svg.rs                              |   4 
crates/gpui/src/elements/text.rs                             |   8 
crates/gpui/src/elements/tooltip.rs                          |  12 
crates/gpui/src/elements/uniform_list.rs                     |  12 
crates/gpui/src/gpui.rs                                      |   2 
crates/gpui/src/test.rs                                      |   8 
crates/gpui/src/views/select.rs                              |   6 
crates/language_selector/src/active_buffer_language.rs       |   2 
crates/language_selector/src/language_selector.rs            |   4 
crates/outline/src/outline.rs                                |   4 
crates/picker/src/picker.rs                                  |   6 
crates/project_panel/src/project_panel.rs                    |   8 
crates/project_symbols/src/project_symbols.rs                |   4 
crates/recent_projects/src/highlighted_workspace_location.rs |   4 
crates/recent_projects/src/recent_projects.rs                |   6 
crates/search/src/buffer_search.rs                           |   8 
crates/search/src/project_search.rs                          |  20 
crates/terminal_view/src/terminal_button.rs                  |   4 
crates/terminal_view/src/terminal_element.rs                 |   6 
crates/terminal_view/src/terminal_view.rs                    |  26 
crates/theme/src/ui.rs                                       |  10 
crates/theme_selector/src/theme_selector.rs                  |   8 
crates/theme_testbench/src/theme_testbench.rs                |  17 
crates/welcome/src/base_keymap_picker.rs                     |   6 
crates/welcome/src/welcome.rs                                |   6 
crates/workspace/src/dock.rs                                 |   4 
crates/workspace/src/dock/toggle_dock_button.rs              |   4 
crates/workspace/src/item.rs                                 |  22 
crates/workspace/src/notifications.rs                        |   4 
crates/workspace/src/pane.rs                                 |  18 
crates/workspace/src/pane/dragged_item_receiver.rs           |   4 
crates/workspace/src/pane_group.rs                           |   6 
crates/workspace/src/shared_screen.rs                        |   4 
crates/workspace/src/sidebar.rs                              |   4 
crates/workspace/src/status_bar.rs                           |  10 
crates/workspace/src/toolbar.rs                              |   6 
crates/workspace/src/workspace.rs                            |   8 
90 files changed, 587 insertions(+), 501 deletions(-)

Detailed changes

crates/activity_indicator/src/activity_indicator.rs 🔗

@@ -314,7 +314,7 @@ impl View for ActivityIndicator {
         "ActivityIndicator"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let Content {
             icon,
             message,

crates/auto_update/src/update_notification.rs 🔗

@@ -2,7 +2,7 @@ use crate::ViewReleaseNotes;
 use gpui::{
     elements::{Flex, MouseEventHandler, Padding, ParentElement, Svg, Text},
     platform::{AppVersion, CursorStyle, MouseButton},
-    Element, Entity, View, ViewContext,
+    Drawable, Entity, View, ViewContext,
 };
 use menu::Cancel;
 use settings::Settings;
@@ -26,7 +26,7 @@ impl View for UpdateNotification {
         "UpdateNotification"
     }
 
-    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::ElementBox<Self> {
+    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::Element<Self> {
         let theme = cx.global::<Settings>().theme.clone();
         let theme = &theme.update_notification;
 

crates/breadcrumbs/src/breadcrumbs.rs 🔗

@@ -41,7 +41,7 @@ impl View for Breadcrumbs {
         "Breadcrumbs"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let active_item = match &self.active_item {
             Some(active_item) => active_item,
             None => return Empty::new().boxed(),

crates/collab_ui/src/collab_titlebar_item.rs 🔗

@@ -68,7 +68,7 @@ impl View for CollabTitlebarItem {
         "CollabTitlebarItem"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let workspace = if let Some(workspace) = self.workspace.upgrade(cx) {
             workspace
         } else {
@@ -326,7 +326,7 @@ impl CollabTitlebarItem {
         &self,
         theme: &Theme,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         let titlebar = &theme.workspace.titlebar;
 
         let badge = if self
@@ -391,7 +391,7 @@ impl CollabTitlebarItem {
         theme: &Theme,
         room: &ModelHandle<Room>,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         let icon;
         let tooltip;
         if room.read(cx).is_screen_sharing() {
@@ -437,7 +437,7 @@ impl CollabTitlebarItem {
         workspace: &ViewHandle<Workspace>,
         theme: &Theme,
         cx: &mut ViewContext<Self>,
-    ) -> Option<ElementBox<Self>> {
+    ) -> Option<Element<Self>> {
         let project = workspace.read(cx).project();
         if project.read(cx).is_remote() {
             return None;
@@ -491,11 +491,7 @@ impl CollabTitlebarItem {
         )
     }
 
-    fn render_user_menu_button(
-        &self,
-        theme: &Theme,
-        cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    fn render_user_menu_button(&self, theme: &Theme, cx: &mut ViewContext<Self>) -> Element<Self> {
         let titlebar = &theme.workspace.titlebar;
 
         Stack::new()
@@ -539,7 +535,7 @@ impl CollabTitlebarItem {
             .boxed()
     }
 
-    fn render_sign_in_button(&self, theme: &Theme, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render_sign_in_button(&self, theme: &Theme, cx: &mut ViewContext<Self>) -> Element<Self> {
         let titlebar = &theme.workspace.titlebar;
         MouseEventHandler::<SignIn, Self>::new(0, cx, |state, _| {
             let style = titlebar.sign_in_prompt.style_for(state, false);
@@ -559,7 +555,7 @@ impl CollabTitlebarItem {
         &'a self,
         _theme: &'a theme::Titlebar,
         cx: &'a ViewContext<Self>,
-    ) -> Option<ElementBox<Self>> {
+    ) -> Option<Element<Self>> {
         self.contacts_popover.as_ref().map(|popover| {
             Overlay::new(ChildView::new(popover, cx).boxed())
                 .with_fit_mode(OverlayFitMode::SwitchAnchor)
@@ -578,7 +574,7 @@ impl CollabTitlebarItem {
         theme: &Theme,
         room: &ModelHandle<Room>,
         cx: &mut ViewContext<Self>,
-    ) -> Vec<ElementBox<Self>> {
+    ) -> Vec<Element<Self>> {
         let mut participants = room
             .read(cx)
             .remote_participants()
@@ -620,7 +616,7 @@ impl CollabTitlebarItem {
         user: &Arc<User>,
         peer_id: PeerId,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         let replica_id = workspace.read(cx).project().read(cx).replica_id();
         Container::new(self.render_face_pile(
             user,
@@ -644,7 +640,7 @@ impl CollabTitlebarItem {
         workspace: &ViewHandle<Workspace>,
         theme: &Theme,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         let project_id = workspace.read(cx).project().read(cx).remote_id();
         let room = ActiveCall::global(cx).read(cx).room();
         let is_being_followed = workspace.read(cx).is_being_followed(peer_id);
@@ -824,11 +820,11 @@ impl CollabTitlebarItem {
         style
     }
 
-    fn render_face(
+    fn render_face<V: View>(
         avatar: Arc<ImageData>,
         avatar_style: AvatarStyle,
         background_color: Color,
-    ) -> ElementBox<Self> {
+    ) -> Element<V> {
         Image::from_data(avatar)
             .with_style(avatar_style.image)
             .aligned()
@@ -846,7 +842,7 @@ impl CollabTitlebarItem {
         &self,
         status: &client::Status,
         cx: &mut ViewContext<Self>,
-    ) -> Option<ElementBox<Self>> {
+    ) -> Option<Element<Self>> {
         enum ConnectionStatusButton {}
 
         let theme = &cx.global::<Settings>().theme.clone();
@@ -903,7 +899,7 @@ impl AvatarRibbon {
     }
 }
 
-impl Element<CollabTitlebarItem> for AvatarRibbon {
+impl Drawable<CollabTitlebarItem> for AvatarRibbon {
     type LayoutState = ();
 
     type PaintState = ();

crates/collab_ui/src/collaborator_list_popover.rs 🔗

@@ -30,7 +30,7 @@ impl View for CollaboratorListPopover {
         "CollaboratorListPopover"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let theme = cx.global::<Settings>().theme.clone();
 
         MouseEventHandler::<Self, Self>::new(0, cx, |_, _| {
@@ -117,7 +117,7 @@ fn render_collaborator_list_entry<UA: Action + Clone, IA: Action + Clone>(
     icon_action: IA,
     icon_tooltip: String,
     cx: &mut ViewContext<CollaboratorListPopover>,
-) -> ElementBox<CollaboratorListPopover> {
+) -> Element<CollaboratorListPopover> {
     enum Username {}
     enum UsernameTooltip {}
     enum Icon {}

crates/collab_ui/src/contact_finder.rs 🔗

@@ -32,7 +32,7 @@ impl View for ContactFinder {
         "ContactFinder"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         ChildView::new(&self.picker, cx).boxed()
     }
 
@@ -104,7 +104,7 @@ impl PickerDelegate for ContactFinder {
         mouse_state: &mut MouseState,
         selected: bool,
         cx: &gpui::AppContext,
-    ) -> ElementBox<Picker<Self>> {
+    ) -> Element<Picker<Self>> {
         let theme = &cx.global::<Settings>().theme;
         let user = &self.potential_contacts[ix];
         let request_status = self.user_store.read(cx).contact_request_status(user);

crates/collab_ui/src/contact_list.rs 🔗

@@ -748,7 +748,7 @@ impl ContactList {
         is_pending: bool,
         is_selected: bool,
         theme: &theme::ContactList,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         Flex::row()
             .with_children(user.avatar.clone().map(|avatar| {
                 Image::from_data(avatar)
@@ -800,7 +800,7 @@ impl ContactList {
         is_selected: bool,
         theme: &theme::ContactList,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         let font_cache = cx.font_cache();
         let host_avatar_height = theme
             .contact_avatar
@@ -899,7 +899,7 @@ impl ContactList {
         is_selected: bool,
         theme: &theme::ContactList,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         let font_cache = cx.font_cache();
         let host_avatar_height = theme
             .contact_avatar
@@ -1000,7 +1000,7 @@ impl ContactList {
         is_selected: bool,
         is_collapsed: bool,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         enum Header {}
         enum LeaveCallContactList {}
 
@@ -1078,7 +1078,7 @@ impl ContactList {
         theme: &theme::ContactList,
         is_selected: bool,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         let online = contact.online;
         let busy = contact.busy || calling;
         let user_id = contact.user.id;
@@ -1195,7 +1195,7 @@ impl ContactList {
         is_incoming: bool,
         is_selected: bool,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         enum Decline {}
         enum Accept {}
         enum Cancel {}
@@ -1331,7 +1331,7 @@ impl View for ContactList {
         cx
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         enum AddContact {}
         let theme = cx.global::<Settings>().theme.clone();
 
@@ -1387,7 +1387,7 @@ impl View for ContactList {
     }
 }
 
-fn render_icon_button(style: &IconButton, svg_path: &'static str) -> impl Element<ContactList> {
+fn render_icon_button(style: &IconButton, svg_path: &'static str) -> impl Drawable<ContactList> {
     Svg::new(svg_path)
         .with_color(style.color)
         .constrained()

crates/collab_ui/src/contact_notification.rs 🔗

@@ -42,7 +42,7 @@ impl View for ContactNotification {
         "ContactNotification"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         match self.kind {
             ContactEventKind::Requested => render_user_notification(
                 self.user.clone(),

crates/collab_ui/src/contacts_popover.rs 🔗

@@ -91,7 +91,7 @@ impl View for ContactsPopover {
         "ContactsPopover"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let theme = cx.global::<Settings>().theme.clone();
         let child = match &self.child {
             Child::ContactList(child) => ChildView::new(child, cx),

crates/collab_ui/src/face_pile.rs 🔗

@@ -7,14 +7,14 @@ use gpui::{
     },
     json::ToJson,
     serde_json::{self, json},
-    Axis, Element, ElementBox, SceneBuilder, ViewContext,
+    Axis, Drawable, Element, SceneBuilder, ViewContext,
 };
 
 use crate::CollabTitlebarItem;
 
 pub(crate) struct FacePile {
     overlap: f32,
-    faces: Vec<ElementBox<CollabTitlebarItem>>,
+    faces: Vec<Element<CollabTitlebarItem>>,
 }
 
 impl FacePile {
@@ -26,7 +26,7 @@ impl FacePile {
     }
 }
 
-impl Element<CollabTitlebarItem> for FacePile {
+impl Drawable<CollabTitlebarItem> for FacePile {
     type LayoutState = ();
     type PaintState = ();
 
@@ -101,8 +101,8 @@ impl Element<CollabTitlebarItem> for FacePile {
     }
 }
 
-impl Extend<ElementBox<CollabTitlebarItem>> for FacePile {
-    fn extend<T: IntoIterator<Item = ElementBox<CollabTitlebarItem>>>(&mut self, children: T) {
+impl Extend<Element<CollabTitlebarItem>> for FacePile {
+    fn extend<T: IntoIterator<Item = Element<CollabTitlebarItem>>>(&mut self, children: T) {
         self.faces.extend(children);
     }
 }

crates/collab_ui/src/incoming_call_notification.rs 🔗

@@ -6,7 +6,7 @@ use gpui::{
     geometry::{rect::RectF, vector::vec2f},
     impl_internal_actions,
     platform::{CursorStyle, MouseButton, WindowBounds, WindowKind, WindowOptions},
-    AppContext, ElementBox, Entity, View, ViewContext,
+    AppContext, Element, Entity, View, ViewContext,
 };
 use settings::Settings;
 use util::ResultExt;
@@ -99,7 +99,7 @@ impl IncomingCallNotification {
         }
     }
 
-    fn render_caller(&self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render_caller(&self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let theme = &cx.global::<Settings>().theme.incoming_call_notification;
         let default_project = proto::ParticipantProject::default();
         let initial_project = self
@@ -165,7 +165,7 @@ impl IncomingCallNotification {
             .boxed()
     }
 
-    fn render_buttons(&self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render_buttons(&self, cx: &mut ViewContext<Self>) -> Element<Self> {
         enum Accept {}
         enum Decline {}
 
@@ -222,7 +222,7 @@ impl View for IncomingCallNotification {
         "IncomingCallNotification"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let background = cx
             .global::<Settings>()
             .theme

crates/collab_ui/src/notifications.rs 🔗

@@ -2,7 +2,7 @@ use client::User;
 use gpui::{
     elements::*,
     platform::{CursorStyle, MouseButton},
-    Action, Element, ElementBox, View, ViewContext,
+    Action, Drawable, Element, View, ViewContext,
 };
 use settings::Settings;
 use std::sync::Arc;
@@ -17,7 +17,7 @@ pub fn render_user_notification<V: View, A: Action + Clone>(
     dismiss_action: A,
     buttons: Vec<(&'static str, Box<dyn Action>)>,
     cx: &mut ViewContext<V>,
-) -> ElementBox<V> {
+) -> Element<V> {
     let theme = cx.global::<Settings>().theme.clone();
     let theme = &theme.contact_notification;
 

crates/collab_ui/src/project_shared_notification.rs 🔗

@@ -104,7 +104,7 @@ impl ProjectSharedNotification {
         cx.remove_window(window_id);
     }
 
-    fn render_owner(&self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render_owner(&self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let theme = &cx.global::<Settings>().theme.project_shared_notification;
         Flex::row()
             .with_children(self.owner.avatar.clone().map(|avatar| {
@@ -164,7 +164,7 @@ impl ProjectSharedNotification {
             .boxed()
     }
 
-    fn render_buttons(&self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render_buttons(&self, cx: &mut ViewContext<Self>) -> Element<Self> {
         enum Open {}
         enum Dismiss {}
 
@@ -227,7 +227,7 @@ impl View for ProjectSharedNotification {
         "ProjectSharedNotification"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> gpui::ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> gpui::Element<Self> {
         let background = cx
             .global::<Settings>()
             .theme

crates/collab_ui/src/sharing_status_indicator.rs 🔗

@@ -3,7 +3,7 @@ use gpui::{
     color::Color,
     elements::{MouseEventHandler, Svg},
     platform::{Appearance, MouseButton},
-    AppContext, Element, ElementBox, Entity, View, ViewContext,
+    AppContext, Drawable, Element, Entity, View, ViewContext,
 };
 use settings::Settings;
 
@@ -40,7 +40,7 @@ impl View for SharingStatusIndicator {
         "SharingStatusIndicator"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let color = match cx.window_appearance() {
             Appearance::Light | Appearance::VibrantLight => Color::black(),
             Appearance::Dark | Appearance::VibrantDark => Color::white(),

crates/command_palette/src/command_palette.rs 🔗

@@ -1,7 +1,7 @@
 use collections::CommandPaletteFilter;
 use fuzzy::{StringMatch, StringMatchCandidate};
 use gpui::{
-    actions, elements::*, keymap_matcher::Keystroke, Action, AnyViewHandle, AppContext, Element,
+    actions, elements::*, keymap_matcher::Keystroke, Action, AnyViewHandle, AppContext, Drawable,
     Entity, MouseState, View, ViewContext, ViewHandle,
 };
 use picker::{Picker, PickerDelegate};
@@ -119,7 +119,7 @@ impl View for CommandPalette {
         "CommandPalette"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         ChildView::new(&self.picker, cx).boxed()
     }
 
@@ -215,7 +215,7 @@ impl PickerDelegate for CommandPalette {
         mouse_state: &mut MouseState,
         selected: bool,
         cx: &gpui::AppContext,
-    ) -> ElementBox<Picker<Self>> {
+    ) -> Element<Picker<Self>> {
         let mat = &self.matches[ix];
         let command = &self.actions[mat.candidate_id];
         let settings = cx.global::<Settings>();

crates/context_menu/src/context_menu.rs 🔗

@@ -26,10 +26,10 @@ pub fn init(cx: &mut AppContext) {
     cx.add_action(ContextMenu::cancel);
 }
 
-pub type StaticItem = Box<dyn Fn(&mut AppContext) -> ElementBox<ContextMenu>>;
+pub type StaticItem = Box<dyn Fn(&mut AppContext) -> Element<ContextMenu>>;
 
 type ContextMenuItemBuilder =
-    Box<dyn Fn(&mut MouseState, &theme::ContextMenuItem) -> ElementBox<ContextMenu>>;
+    Box<dyn Fn(&mut MouseState, &theme::ContextMenuItem) -> Element<ContextMenu>>;
 
 pub enum ContextMenuItemLabel {
     String(Cow<'static, str>),
@@ -142,7 +142,7 @@ impl View for ContextMenu {
         cx
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         if !self.visible {
             return Empty::new().boxed();
         }
@@ -328,7 +328,10 @@ impl ContextMenu {
         self.position_mode = mode;
     }
 
-    fn render_menu_for_measurement(&self, cx: &mut ViewContext<Self>) -> impl Element<ContextMenu> {
+    fn render_menu_for_measurement(
+        &self,
+        cx: &mut ViewContext<Self>,
+    ) -> impl Drawable<ContextMenu> {
         let window_id = cx.window_id();
         let style = cx.global::<Settings>().theme.context_menu.clone();
         Flex::row()
@@ -415,7 +418,7 @@ impl ContextMenu {
             .with_style(style.container)
     }
 
-    fn render_menu(&self, cx: &mut ViewContext<Self>) -> impl Element<ContextMenu> {
+    fn render_menu(&self, cx: &mut ViewContext<Self>) -> impl Drawable<ContextMenu> {
         enum Menu {}
         enum MenuItem {}
 

crates/copilot/src/sign_in.rs 🔗

@@ -3,7 +3,7 @@ use gpui::{
     elements::*,
     geometry::rect::RectF,
     platform::{WindowBounds, WindowKind, WindowOptions},
-    AnyViewHandle, AppContext, ClipboardItem, Element, ElementBox, Entity, View, ViewContext,
+    AnyViewHandle, AppContext, ClipboardItem, Drawable, Element, Entity, View, ViewContext,
     ViewHandle,
 };
 use settings::Settings;
@@ -98,7 +98,7 @@ impl CopilotCodeVerification {
         data: &PromptUserDeviceFlow,
         style: &theme::Copilot,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         let copied = cx
             .read_from_clipboard()
             .map(|item| item.text() == &data.user_code)
@@ -147,7 +147,7 @@ impl CopilotCodeVerification {
         data: &PromptUserDeviceFlow,
         style: &theme::Copilot,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         enum ConnectButton {}
 
         Flex::column()
@@ -206,10 +206,7 @@ impl CopilotCodeVerification {
             .align_children_center()
             .boxed()
     }
-    fn render_enabled_modal(
-        style: &theme::Copilot,
-        cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    fn render_enabled_modal(style: &theme::Copilot, cx: &mut ViewContext<Self>) -> Element<Self> {
         enum DoneButton {}
 
         let enabled_style = &style.auth.authorized;
@@ -260,7 +257,7 @@ impl CopilotCodeVerification {
     fn render_unauthorized_modal(
         style: &theme::Copilot,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         let unauthorized_style = &style.auth.not_authorized;
 
         Flex::column()
@@ -338,7 +335,7 @@ impl View for CopilotCodeVerification {
         cx.notify()
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         enum ConnectModal {}
 
         let style = cx.global::<Settings>().theme.clone();

crates/copilot_button/src/copilot_button.rs 🔗

@@ -6,7 +6,7 @@ use gpui::{
     elements::*,
     impl_internal_actions,
     platform::{CursorStyle, MouseButton},
-    AppContext, Element, ElementBox, Entity, MouseState, Subscription, View, ViewContext,
+    AppContext, Drawable, Element, Entity, MouseState, Subscription, View, ViewContext,
     ViewHandle,
 };
 use settings::{settings_file::SettingsFile, Settings};
@@ -91,7 +91,7 @@ impl View for CopilotButton {
         "CopilotButton"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let settings = cx.global::<Settings>();
 
         if !settings.enable_copilot_integration {

crates/diagnostics/src/diagnostics.rs 🔗

@@ -86,7 +86,7 @@ impl View for ProjectDiagnosticsEditor {
         "ProjectDiagnosticsEditor"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         if self.path_states.is_empty() {
             let theme = &cx.global::<Settings>().theme.project_diagnostics;
             Label::new("No problems in workspace", theme.empty_message.clone())
@@ -509,7 +509,7 @@ impl Item for ProjectDiagnosticsEditor {
         _detail: Option<usize>,
         style: &theme::Tab,
         cx: &AppContext,
-    ) -> ElementBox<Pane> {
+    ) -> Element<Pane> {
         render_summary(
             &self.summary,
             &style.label.text,
@@ -691,7 +691,7 @@ pub(crate) fn render_summary(
     summary: &DiagnosticSummary,
     text_style: &TextStyle,
     theme: &theme::ProjectDiagnostics,
-) -> ElementBox<Pane> {
+) -> Element<Pane> {
     if summary.error_count == 0 && summary.warning_count == 0 {
         Label::new("No problems", text_style.clone()).boxed()
     } else {

crates/diagnostics/src/items.rs 🔗

@@ -84,7 +84,7 @@ impl View for DiagnosticIndicator {
         "DiagnosticIndicator"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         enum Summary {}
         enum Message {}
 

crates/drag_and_drop/src/drag_and_drop.rs 🔗

@@ -6,7 +6,7 @@ use gpui::{
     geometry::{rect::RectF, vector::Vector2F},
     platform::{CursorStyle, MouseButton},
     scene::{MouseDown, MouseDrag},
-    AppContext, Element, ElementBox, View, ViewContext, WeakViewHandle,
+    AppContext, Drawable, Element, View, ViewContext, WeakViewHandle,
 };
 
 const DEAD_ZONE: f32 = 4.;
@@ -26,7 +26,7 @@ enum State<V: View> {
         region_offset: Vector2F,
         region: RectF,
         payload: Rc<dyn Any + 'static>,
-        render: Rc<dyn Fn(Rc<dyn Any>, &mut ViewContext<V>) -> ElementBox<V>>,
+        render: Rc<dyn Fn(Rc<dyn Any>, &mut ViewContext<V>) -> Element<V>>,
     },
     Canceled,
 }
@@ -124,7 +124,7 @@ impl<V: View> DragAndDrop<V> {
         event: MouseDrag,
         payload: Rc<T>,
         cx: &mut ViewContext<V>,
-        render: Rc<impl 'static + Fn(&T, &mut ViewContext<V>) -> ElementBox<V>>,
+        render: Rc<impl 'static + Fn(&T, &mut ViewContext<V>) -> Element<V>>,
     ) {
         let window_id = cx.window_id();
         cx.update_global(|this: &mut Self, cx| {
@@ -178,7 +178,7 @@ impl<V: View> DragAndDrop<V> {
         });
     }
 
-    pub fn render(cx: &mut ViewContext<V>) -> Option<ElementBox<V>> {
+    pub fn render(cx: &mut ViewContext<V>) -> Option<Element<V>> {
         enum DraggedElementHandler {}
         cx.global::<Self>()
             .currently_dragged
@@ -300,7 +300,7 @@ pub trait Draggable<V: View> {
     fn as_draggable<P: Any>(
         self,
         payload: P,
-        render: impl 'static + Fn(&P, &mut ViewContext<V>) -> ElementBox<V>,
+        render: impl 'static + Fn(&P, &mut ViewContext<V>) -> Element<V>,
     ) -> Self
     where
         Self: Sized;
@@ -310,7 +310,7 @@ impl<Tag, V: View> Draggable<V> for MouseEventHandler<Tag, V> {
     fn as_draggable<P: Any>(
         self,
         payload: P,
-        render: impl 'static + Fn(&P, &mut ViewContext<V>) -> ElementBox<V>,
+        render: impl 'static + Fn(&P, &mut ViewContext<V>) -> Element<V>,
     ) -> Self
     where
         Self: Sized,

crates/editor/src/display_map/block_map.rs 🔗

@@ -4,7 +4,7 @@ use super::{
 };
 use crate::{Anchor, Editor, ExcerptId, ExcerptRange, ToPoint as _};
 use collections::{Bound, HashMap, HashSet};
-use gpui::{fonts::HighlightStyle, ElementBox, ViewContext};
+use gpui::{fonts::HighlightStyle, Element, ViewContext};
 use language::{BufferSnapshot, Chunk, Patch, Point};
 use parking_lot::Mutex;
 use std::{
@@ -50,7 +50,7 @@ struct BlockRow(u32);
 #[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)]
 struct WrapRow(u32);
 
-pub type RenderBlock = Arc<dyn Fn(&mut BlockContext) -> ElementBox<Editor>>;
+pub type RenderBlock = Arc<dyn Fn(&mut BlockContext) -> Element<Editor>>;
 
 pub struct Block {
     id: BlockId,
@@ -69,7 +69,7 @@ where
     pub position: P,
     pub height: u8,
     pub style: BlockStyle,
-    pub render: Arc<dyn Fn(&mut BlockContext) -> ElementBox<Editor>>,
+    pub render: Arc<dyn Fn(&mut BlockContext) -> Element<Editor>>,
     pub disposition: BlockDisposition,
 }
 
@@ -947,7 +947,7 @@ impl DerefMut for BlockContext<'_, '_, '_, '_> {
 }
 
 impl Block {
-    pub fn render(&self, cx: &mut BlockContext) -> ElementBox<Editor> {
+    pub fn render(&self, cx: &mut BlockContext) -> Element<Editor> {
         self.render.lock()(cx)
     }
 
@@ -994,7 +994,7 @@ mod tests {
     use crate::display_map::suggestion_map::SuggestionMap;
     use crate::display_map::{fold_map::FoldMap, tab_map::TabMap, wrap_map::WrapMap};
     use crate::multi_buffer::MultiBuffer;
-    use gpui::{elements::Empty, Element};
+    use gpui::{elements::Empty, Drawable};
     use rand::prelude::*;
     use settings::Settings;
     use std::env;

crates/editor/src/editor.rs 🔗

@@ -41,7 +41,7 @@ use gpui::{
     keymap_matcher::KeymapContext,
     platform::{CursorStyle, MouseButton},
     serde_json::{self, json},
-    AnyViewHandle, AppContext, AsyncAppContext, ClipboardItem, Element, ElementBox, Entity,
+    AnyViewHandle, AppContext, AsyncAppContext, ClipboardItem, Drawable, Element, Entity,
     ModelHandle, Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle,
 };
 use highlight_matching_bracket::refresh_matching_bracket_highlights;
@@ -722,7 +722,7 @@ impl ContextMenu {
         cursor_position: DisplayPoint,
         style: EditorStyle,
         cx: &mut ViewContext<Editor>,
-    ) -> (DisplayPoint, ElementBox<Editor>) {
+    ) -> (DisplayPoint, Element<Editor>) {
         match self {
             ContextMenu::Completions(menu) => (cursor_position, menu.render(style, cx)),
             ContextMenu::CodeActions(menu) => menu.render(cursor_position, style, cx),
@@ -774,7 +774,7 @@ impl CompletionsMenu {
         !self.matches.is_empty()
     }
 
-    fn render(&self, style: EditorStyle, cx: &mut ViewContext<Editor>) -> ElementBox<Editor> {
+    fn render(&self, style: EditorStyle, cx: &mut ViewContext<Editor>) -> Element<Editor> {
         enum CompletionTag {}
 
         let completions = self.completions.clone();
@@ -951,7 +951,7 @@ impl CodeActionsMenu {
         mut cursor_position: DisplayPoint,
         style: EditorStyle,
         cx: &mut ViewContext<Editor>,
-    ) -> (DisplayPoint, ElementBox<Editor>) {
+    ) -> (DisplayPoint, Element<Editor>) {
         enum ActionTag {}
 
         let container_style = style.autocomplete.container;
@@ -2929,7 +2929,7 @@ impl Editor {
         style: &EditorStyle,
         active: bool,
         cx: &mut ViewContext<Self>,
-    ) -> Option<ElementBox<Self>> {
+    ) -> Option<Element<Self>> {
         if self.available_code_actions.is_some() {
             enum CodeActions {}
             Some(
@@ -2960,7 +2960,7 @@ impl Editor {
         line_height: f32,
         gutter_margin: f32,
         cx: &mut ViewContext<Self>,
-    ) -> Vec<Option<ElementBox<Self>>> {
+    ) -> Vec<Option<Element<Self>>> {
         enum FoldIndicators {}
 
         let style = style.folds.clone();
@@ -2975,7 +2975,7 @@ impl Editor {
                             MouseEventHandler::<FoldIndicators, _>::new(
                                 ix as usize,
                                 cx,
-                                |mouse_state, _| -> ElementBox<Editor> {
+                                |mouse_state, _| -> Element<Editor> {
                                     Svg::new(match fold_status {
                                         FoldStatus::Folded => style.folded_icon.clone(),
                                         FoldStatus::Foldable => style.foldable_icon.clone(),
@@ -3028,7 +3028,7 @@ impl Editor {
         cursor_position: DisplayPoint,
         style: EditorStyle,
         cx: &mut ViewContext<Editor>,
-    ) -> Option<(DisplayPoint, ElementBox<Editor>)> {
+    ) -> Option<(DisplayPoint, Element<Editor>)> {
         self.context_menu
             .as_ref()
             .map(|menu| menu.render(cursor_position, style, cx))
@@ -6795,7 +6795,7 @@ impl Entity for Editor {
 }
 
 impl View for Editor {
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let style = self.style(cx);
         let font_changed = self.display_map.update(cx, |map, cx| {
             map.set_fold_ellipses_color(style.folds.ellipses.text_color);

crates/editor/src/element.rs 🔗

@@ -31,7 +31,7 @@ use gpui::{
     json::{self, ToJson},
     platform::{CursorStyle, Modifiers, MouseButton, MouseButtonEvent, MouseMovedEvent},
     text_layout::{self, Line, RunStyle, TextLayoutCache},
-    AppContext, Axis, Border, CursorRegion, Element, ElementBox, EventContext, MouseRegion, Quad,
+    AppContext, Axis, Border, CursorRegion, Drawable, Element, EventContext, MouseRegion, Quad,
     SceneBuilder, SizeConstraint, ViewContext, WeakViewHandle, WindowContext,
 };
 use itertools::Itertools;
@@ -1611,7 +1611,7 @@ impl EditorElement {
     }
 }
 
-impl Element<Editor> for EditorElement {
+impl Drawable<Editor> for EditorElement {
     type LayoutState = LayoutState;
     type PaintState = ();
 
@@ -2172,10 +2172,10 @@ pub struct LayoutState {
     scrollbar_row_range: Range<f32>,
     show_scrollbars: bool,
     max_row: u32,
-    context_menu: Option<(DisplayPoint, ElementBox<Editor>)>,
-    code_actions_indicator: Option<(u32, ElementBox<Editor>)>,
-    hover_popovers: Option<(DisplayPoint, Vec<ElementBox<Editor>>)>,
-    fold_indicators: Vec<Option<ElementBox<Editor>>>,
+    context_menu: Option<(DisplayPoint, Element<Editor>)>,
+    code_actions_indicator: Option<(u32, Element<Editor>)>,
+    hover_popovers: Option<(DisplayPoint, Vec<Element<Editor>>)>,
+    fold_indicators: Vec<Option<Element<Editor>>>,
 }
 
 pub struct PositionMap {
@@ -2226,7 +2226,7 @@ impl PositionMap {
 
 struct BlockLayout {
     row: u32,
-    element: ElementBox<Editor>,
+    element: Element<Editor>,
     style: BlockStyle,
 }
 

crates/editor/src/hover_popover.rs 🔗

@@ -4,7 +4,7 @@ use gpui::{
     elements::{Flex, MouseEventHandler, Padding, Text},
     impl_internal_actions,
     platform::{CursorStyle, MouseButton},
-    AppContext, Axis, Element, ElementBox, ModelHandle, Task, ViewContext,
+    AppContext, Axis, Drawable, Element, ModelHandle, Task, ViewContext,
 };
 use language::{Bias, DiagnosticEntry, DiagnosticSeverity};
 use project::{HoverBlock, Project};
@@ -283,7 +283,7 @@ impl HoverState {
         style: &EditorStyle,
         visible_rows: Range<u32>,
         cx: &mut ViewContext<Editor>,
-    ) -> Option<(DisplayPoint, Vec<ElementBox<Editor>>)> {
+    ) -> Option<(DisplayPoint, Vec<Element<Editor>>)> {
         // If there is a diagnostic, position the popovers based on that.
         // Otherwise use the start of the hover range
         let anchor = self
@@ -323,7 +323,7 @@ pub struct InfoPopover {
 }
 
 impl InfoPopover {
-    pub fn render(&self, style: &EditorStyle, cx: &mut ViewContext<Editor>) -> ElementBox<Editor> {
+    pub fn render(&self, style: &EditorStyle, cx: &mut ViewContext<Editor>) -> Element<Editor> {
         MouseEventHandler::<InfoPopover, _>::new(0, cx, |_, cx| {
             let mut flex = Flex::new(Axis::Vertical).scrollable::<HoverBlock>(1, None, cx);
             flex.extend(self.contents.iter().map(|content| {
@@ -378,7 +378,7 @@ pub struct DiagnosticPopover {
 }
 
 impl DiagnosticPopover {
-    pub fn render(&self, style: &EditorStyle, cx: &mut ViewContext<Editor>) -> ElementBox<Editor> {
+    pub fn render(&self, style: &EditorStyle, cx: &mut ViewContext<Editor>) -> Element<Editor> {
         enum PrimaryDiagnostic {}
 
         let mut text_style = style.hover_popover.prose.clone();

crates/editor/src/items.rs 🔗

@@ -7,8 +7,8 @@ use anyhow::{anyhow, Context, Result};
 use collections::HashSet;
 use futures::future::try_join_all;
 use gpui::{
-    elements::*, geometry::vector::vec2f, AppContext, Entity, ModelHandle, Subscription, Task,
-    View, ViewContext, ViewHandle, WeakViewHandle,
+    elements::*, geometry::vector::vec2f, AppContext, Entity, ModelHandle, RenderedView,
+    Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle,
 };
 use language::{
     proto::serialize_anchor as serialize_text_anchor, Bias, Buffer, OffsetRangeExt, Point,
@@ -526,7 +526,7 @@ impl Item for Editor {
         detail: Option<usize>,
         style: &theme::Tab,
         cx: &AppContext,
-    ) -> ElementBox<Pane> {
+    ) -> Element<Pane> {
         Flex::row()
             .with_child(
                 Label::new(self.title(cx).to_string(), style.label.clone())
@@ -727,7 +727,11 @@ impl Item for Editor {
         ToolbarItemLocation::PrimaryLeft { flex: None }
     }
 
-    fn breadcrumbs(&self, theme: &theme::Theme, cx: &AppContext) -> Option<Vec<ElementBox<Pane>>> {
+    fn breadcrumbs(
+        &self,
+        theme: &theme::Theme,
+        cx: &AppContext,
+    ) -> Option<Vec<Box<dyn RenderedView>>> {
         let cursor = self.selections.newest_anchor().head();
         let multibuffer = &self.buffer().read(cx);
         let (buffer_id, symbols) =
@@ -748,14 +752,17 @@ impl Item for Editor {
             .unwrap_or_else(|| "untitled".to_string());
 
         let filename_label = Label::new(filename, theme.workspace.breadcrumbs.default.text.clone());
-        let mut breadcrumbs = vec![filename_label.boxed()];
+        let mut breadcrumbs =
+            vec![Box::new(filename_label.boxed() as Element<Editor>) as Box<dyn RenderedView>];
         breadcrumbs.extend(symbols.into_iter().map(|symbol| {
-            Text::new(
-                symbol.text,
-                theme.workspace.breadcrumbs.default.text.clone(),
-            )
-            .with_highlights(symbol.highlight_ranges)
-            .boxed()
+            Box::new(
+                Text::new(
+                    symbol.text,
+                    theme.workspace.breadcrumbs.default.text.clone(),
+                )
+                .with_highlights(symbol.highlight_ranges)
+                .boxed() as Element<Editor>,
+            ) as Box<dyn RenderedView>
         }));
         Some(breadcrumbs)
     }
@@ -1078,7 +1085,7 @@ impl View for CursorPosition {
         "CursorPosition"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         if let Some(position) = self.position {
             let theme = &cx.global::<Settings>().theme.workspace.status_bar;
             let mut text = format!("{},{}", position.row + 1, position.column + 1);

crates/feedback/src/deploy_feedback_button.rs 🔗

@@ -27,7 +27,7 @@ impl View for DeployFeedbackButton {
         "DeployFeedbackButton"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let active = self.active;
         let theme = cx.global::<Settings>().theme.clone();
         Stack::new()

crates/feedback/src/feedback_editor.rs 🔗

@@ -12,7 +12,7 @@ use gpui::{
     actions,
     elements::{ChildView, Flex, Label, ParentElement, Svg},
     platform::PromptLevel,
-    serde_json, AnyViewHandle, AppContext, Element, ElementBox, Entity, ModelHandle, Task, View,
+    serde_json, AnyViewHandle, AppContext, Drawable, Element, Entity, ModelHandle, Task, View,
     ViewContext, ViewHandle,
 };
 use isahc::Request;
@@ -232,7 +232,7 @@ impl View for FeedbackEditor {
         "FeedbackEditor"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         ChildView::new(&self.editor, cx).boxed()
     }
 
@@ -253,7 +253,7 @@ impl Item for FeedbackEditor {
         _: Option<usize>,
         style: &theme::Tab,
         _: &AppContext,
-    ) -> ElementBox<Pane> {
+    ) -> Element<Pane> {
         Flex::row()
             .with_child(
                 Svg::new("icons/feedback_16.svg")

crates/feedback/src/feedback_info_text.rs 🔗

@@ -1,7 +1,7 @@
 use gpui::{
     elements::{Flex, Label, MouseEventHandler, ParentElement, Text},
     platform::{CursorStyle, MouseButton},
-    Element, ElementBox, Entity, View, ViewContext, ViewHandle,
+    Drawable, Element, Entity, View, ViewContext, ViewHandle,
 };
 use settings::Settings;
 use workspace::{item::ItemHandle, ToolbarItemLocation, ToolbarItemView};
@@ -29,7 +29,7 @@ impl View for FeedbackInfoText {
         "FeedbackInfoText"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let theme = cx.global::<Settings>().theme.clone();
 
         Flex::row()

crates/feedback/src/submit_feedback_button.rs 🔗

@@ -1,7 +1,7 @@
 use gpui::{
     elements::{Label, MouseEventHandler},
     platform::{CursorStyle, MouseButton},
-    Element, ElementBox, Entity, View, ViewContext, ViewHandle,
+    Drawable, Element, Entity, View, ViewContext, ViewHandle,
 };
 use settings::Settings;
 use workspace::{item::ItemHandle, ToolbarItemLocation, ToolbarItemView};
@@ -29,7 +29,7 @@ impl View for SubmitFeedbackButton {
         "SubmitFeedbackButton"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let theme = cx.global::<Settings>().theme.clone();
         enum SubmitFeedbackButton {}
         MouseEventHandler::<SubmitFeedbackButton, Self>::new(0, cx, |state, _| {

crates/file_finder/src/file_finder.rs 🔗

@@ -50,7 +50,7 @@ impl View for FileFinder {
         "FileFinder"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         ChildView::new(&self.picker, cx).boxed()
     }
 
@@ -267,7 +267,7 @@ impl PickerDelegate for FileFinder {
         mouse_state: &mut MouseState,
         selected: bool,
         cx: &AppContext,
-    ) -> ElementBox<Picker<Self>> {
+    ) -> Element<Picker<Self>> {
         let path_match = &self.matches[ix];
         let settings = cx.global::<Settings>();
         let style = settings.theme.picker.item.style_for(mouse_state, selected);

crates/go_to_line/src/go_to_line.rs 🔗

@@ -156,7 +156,7 @@ impl View for GoToLine {
         "GoToLine"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let theme = &cx.global::<Settings>().theme.picker;
 
         let label = format!(

crates/gpui/examples/text.rs 🔗

@@ -2,7 +2,7 @@ use gpui::{
     color::Color,
     fonts::{Properties, Weight},
     text_layout::RunStyle,
-    Element, ElementBox, Quad, SceneBuilder, View, ViewContext,
+    Drawable, Element, Quad, SceneBuilder, View, ViewContext,
 };
 use log::LevelFilter;
 use pathfinder_geometry::rect::RectF;
@@ -30,12 +30,12 @@ impl gpui::View for TextView {
         "View"
     }
 
-    fn render(&mut self, _: &mut gpui::ViewContext<Self>) -> ElementBox<TextView> {
+    fn render(&mut self, _: &mut gpui::ViewContext<Self>) -> Element<TextView> {
         TextElement.boxed()
     }
 }
 
-impl<V: View> Element<V> for TextElement {
+impl<V: View> Drawable<V> for TextElement {
     type LayoutState = ();
 
     type PaintState = ();

crates/gpui/src/app.rs 🔗

@@ -41,7 +41,7 @@ pub use test_app_context::{ContextHandle, TestAppContext};
 use window_input_handler::WindowInputHandler;
 
 use crate::{
-    elements::ElementBox,
+    elements::{AnyRootElement, Element, RootElement},
     executor::{self, Task},
     keymap_matcher::{self, Binding, KeymapContext, KeymapMatcher, Keystroke, MatchResult},
     platform::{
@@ -53,7 +53,7 @@ use crate::{
     AssetCache, AssetSource, ClipboardItem, FontCache, MouseRegionId,
 };
 
-use self::{ref_counts::RefCounts, window::RenderedView};
+use self::ref_counts::RefCounts;
 
 pub trait Entity: 'static {
     type Event;
@@ -69,7 +69,7 @@ pub trait Entity: 'static {
 
 pub trait View: Entity + Sized {
     fn ui_name() -> &'static str;
-    fn render(&mut self, cx: &mut ViewContext<'_, '_, '_, Self>) -> ElementBox<Self>;
+    fn render(&mut self, cx: &mut ViewContext<'_, '_, '_, Self>) -> Element<Self>;
     fn focus_in(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
     fn focus_out(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
     fn key_down(&mut self, _: &KeyDownEvent, _: &mut ViewContext<Self>) -> bool {
@@ -871,7 +871,7 @@ impl AppContext {
         self.active_labeled_tasks.values().cloned()
     }
 
-    pub fn render_view(&mut self, params: RenderParams) -> Result<Box<dyn RenderedView>> {
+    pub fn render_view(&mut self, params: RenderParams) -> Result<Box<dyn AnyRootElement>> {
         todo!()
         // let window_id = params.window_id;
         // let view_id = params.view_id;
@@ -889,7 +889,7 @@ impl AppContext {
         window_id: usize,
         titlebar_height: f32,
         appearance: Appearance,
-    ) -> HashMap<usize, Box<dyn RenderedView>> {
+    ) -> HashMap<usize, Box<dyn AnyRootElement>> {
         todo!()
         // self.start_frame();
         // #[allow(clippy::needless_collect)]
@@ -2838,7 +2838,7 @@ pub trait AnyView {
         cx: &mut AppContext,
     ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
     fn ui_name(&self) -> &'static str;
-    fn render(&mut self, params: RenderParams, cx: &mut WindowContext) -> Box<dyn RenderedView>;
+    fn render(&mut self, cx: &mut WindowContext, view_id: usize) -> Box<dyn AnyRootElement>;
     fn focus_in<'a, 'b>(
         &mut self,
         focused_id: usize,
@@ -2886,9 +2886,9 @@ pub trait AnyView {
     }
 }
 
-impl<T> AnyView for T
+impl<V> AnyView for V
 where
-    T: View,
+    V: View,
 {
     fn as_any(&self) -> &dyn Any {
         self
@@ -2910,12 +2910,14 @@ where
     }
 
     fn ui_name(&self) -> &'static str {
-        T::ui_name()
+        V::ui_name()
     }
 
-    fn render(&mut self, params: RenderParams, cx: &mut WindowContext) -> Box<dyn RenderedView> {
-        todo!()
-        // Box::new(View::render(self, &mut ViewContext::new(params.view_id, cx)))
+    fn render(&mut self, cx: &mut WindowContext, view_id: usize) -> Box<dyn AnyRootElement> {
+        let mut view_context = ViewContext::mutable(cx, view_id);
+        let element = V::render(self, &mut view_context);
+        let view = WeakViewHandle::new(cx.window_id, view_id);
+        Box::new(RootElement::new(element, view))
     }
 
     fn focus_in(&mut self, focused_id: usize, cx: &mut WindowContext, view_id: usize) {
@@ -5017,7 +5019,7 @@ mod tests {
         }
 
         impl super::View for View {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
                 post_inc(&mut self.render_count);
                 Empty::new().boxed()
             }
@@ -5070,7 +5072,7 @@ mod tests {
         }
 
         impl super::View for View {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
                 Empty::new().boxed()
             }
 
@@ -5134,7 +5136,7 @@ mod tests {
         }
 
         impl super::View for View {
-            fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+            fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
                 enum Handler {}
                 let mouse_down_count = self.mouse_down_count.clone();
                 MouseEventHandler::<Handler, _>::new(0, cx, |_, _| Empty::new().boxed())
@@ -5200,7 +5202,7 @@ mod tests {
                 "View"
             }
 
-            fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
                 Empty::new().boxed()
             }
         }
@@ -5718,7 +5720,7 @@ mod tests {
         }
 
         impl super::View for View {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
                 Empty::new().boxed()
             }
 
@@ -5783,7 +5785,7 @@ mod tests {
         }
 
         impl super::View for View {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
                 Empty::new().boxed()
             }
 
@@ -5959,7 +5961,7 @@ mod tests {
         }
 
         impl View for ViewA {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
                 Empty::new().boxed()
             }
 
@@ -5977,7 +5979,7 @@ mod tests {
         }
 
         impl View for ViewB {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
                 Empty::new().boxed()
             }
 
@@ -6129,7 +6131,7 @@ mod tests {
         }
 
         impl super::View for View {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
                 Empty::new().boxed()
             }
 
@@ -6256,7 +6258,7 @@ mod tests {
         }
 
         impl super::View for View1 {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
                 Empty::new().boxed()
             }
             fn ui_name() -> &'static str {
@@ -6264,7 +6266,7 @@ mod tests {
             }
         }
         impl super::View for View2 {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
                 Empty::new().boxed()
             }
             fn ui_name() -> &'static str {
@@ -6439,7 +6441,7 @@ mod tests {
                 "test view"
             }
 
-            fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
                 Empty::new().boxed()
             }
         }
@@ -6501,7 +6503,7 @@ mod tests {
                 "test view"
             }
 
-            fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
                 Empty::new().named(format!("render count: {}", post_inc(&mut self.0)))
             }
         }
@@ -6590,7 +6592,7 @@ mod tests {
                 "test view"
             }
 
-            fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
                 Empty::new().boxed()
             }
         }
@@ -6670,7 +6672,7 @@ mod tests {
                 "child view"
             }
 
-            fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
                 self.rendered.set(true);
                 Empty::new().boxed()
             }
@@ -6695,7 +6697,7 @@ mod tests {
                 "parent view"
             }
 
-            fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+            fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
                 if let Some(child) = self.child.as_ref() {
                     ChildView::new(child, cx).boxed()
                 } else {
@@ -6737,7 +6739,7 @@ mod tests {
             "TestView"
         }
 
-        fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+        fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
             Empty::new().boxed()
         }
     }

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

@@ -1,4 +1,5 @@
 use crate::{
+    elements::AnyRootElement,
     geometry::rect::RectF,
     json::{self, ToJson},
     keymap_matcher::{Keystroke, MatchResult},
@@ -12,9 +13,9 @@ use crate::{
     },
     text_layout::TextLayoutCache,
     util::post_inc,
-    AnyView, AnyViewHandle, AnyWeakViewHandle, AppContext, Element, ElementBox, Entity,
-    ModelContext, ModelHandle, MouseRegion, MouseRegionId, ParentId, ReadView, RenderParams,
-    SceneBuilder, UpdateModel, UpgradeViewHandle, View, ViewContext, ViewHandle, WeakViewHandle,
+    AnyView, AnyViewHandle, AnyWeakViewHandle, AppContext, Drawable, Entity, ModelContext,
+    ModelHandle, MouseRegion, MouseRegionId, ParentId, ReadView, RenderParams, SceneBuilder,
+    UpdateModel, UpdateView, UpgradeViewHandle, View, ViewContext, ViewHandle, WeakViewHandle,
     WindowInvalidation,
 };
 use anyhow::bail;
@@ -28,6 +29,7 @@ use sqlez::{
     statement::Statement,
 };
 use std::ops::{Deref, DerefMut, Range};
+use util::ResultExt;
 use uuid::Uuid;
 
 use super::Reference;
@@ -39,7 +41,7 @@ pub struct Window {
     pub(crate) is_fullscreen: bool,
     pub(crate) invalidation: Option<WindowInvalidation>,
     pub(crate) platform_window: Box<dyn platform::Window>,
-    pub(crate) rendered_views: HashMap<usize, Box<dyn RenderedView>>,
+    pub(crate) rendered_views: HashMap<usize, Box<dyn AnyRootElement>>,
     titlebar_height: f32,
     appearance: Appearance,
     cursor_regions: Vec<CursorRegion>,
@@ -139,6 +141,19 @@ impl ReadView for WindowContext<'_, '_> {
     }
 }
 
+impl UpdateView for WindowContext<'_, '_> {
+    fn update_view<T, S>(
+        &mut self,
+        handle: &ViewHandle<T>,
+        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
+    ) -> S
+    where
+        T: View,
+    {
+        self.app_context.update_view(handle, update)
+    }
+}
+
 impl UpgradeViewHandle for WindowContext<'_, '_> {
     fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
         self.app_context.upgrade_view_handle(handle)
@@ -727,7 +742,7 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
 
         let root_view_id = self.window.root_view().id();
         let mut rendered_root = self.window.rendered_views.remove(&root_view_id).unwrap();
-        rendered_root.layout(SizeConstraint::strict(window_size), self, root_view_id);
+        rendered_root.layout(SizeConstraint::strict(window_size), self);
 
         let mut scene_builder = SceneBuilder::new(scale_factor);
         rendered_root.paint(
@@ -735,7 +750,6 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
             Vector2F::zero(),
             RectF::from_points(Vector2F::zero(), window_size),
             self,
-            root_view_id,
         );
 
         self.window.text_layout_cache.finish_frame();
@@ -757,7 +771,9 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
         self.window
             .rendered_views
             .get(&root_view_id)?
-            .rect_for_text_range(range_utf16, self, root_view_id)
+            .rect_for_text_range(range_utf16, self)
+            .log_err()
+            .flatten()
     }
 
     pub fn debug_elements(&self) -> Option<json::Value> {
@@ -765,8 +781,8 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
         Some(json!({
             "root_view": view.debug_json(self),
             "root_element": self.window.rendered_views.get(&view.id())
-                .map(|root_element| {
-                    root_element.debug(self, view.id())
+                .and_then(|root_element| {
+                    root_element.debug(self).log_err()
                 })
         }))
     }
@@ -907,95 +923,6 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
     }
 }
 
-pub trait RenderedView {
-    fn layout(
-        &mut self,
-        constraint: SizeConstraint,
-        cx: &mut WindowContext,
-        view_id: usize,
-    ) -> Vector2F;
-    fn paint(
-        &mut self,
-        scene: &mut SceneBuilder,
-        origin: Vector2F,
-        visible_bounds: RectF,
-        cx: &mut WindowContext,
-        view_id: usize,
-    );
-    fn rect_for_text_range(
-        &self,
-        range_utf16: Range<usize>,
-        cx: &WindowContext,
-        view_id: usize,
-    ) -> Option<RectF>;
-    fn debug(&self, cx: &WindowContext, view_id: usize) -> serde_json::Value;
-    fn name(&self) -> Option<&str>;
-}
-
-impl<V: View> RenderedView for ElementBox<V> {
-    fn layout(
-        &mut self,
-        constraint: SizeConstraint,
-        cx: &mut WindowContext,
-        view_id: usize,
-    ) -> Vector2F {
-        cx.update_any_view(view_id, |view, cx| {
-            let view = view.as_any_mut().downcast_mut::<V>().unwrap();
-            let mut cx = ViewContext::mutable(cx, view_id);
-            ElementBox::layout(self, constraint, view, &mut cx)
-        })
-        .unwrap()
-    }
-
-    fn paint(
-        &mut self,
-        scene: &mut SceneBuilder,
-        origin: Vector2F,
-        visible_bounds: RectF,
-        cx: &mut WindowContext,
-        view_id: usize,
-    ) {
-        cx.update_any_view(view_id, |view, cx| {
-            let view = view.as_any_mut().downcast_mut::<V>().unwrap();
-            let mut cx = ViewContext::mutable(cx, view_id);
-            ElementBox::paint(self, scene, origin, visible_bounds, view, &mut cx)
-        });
-    }
-
-    fn rect_for_text_range(
-        &self,
-        range_utf16: Range<usize>,
-        cx: &WindowContext,
-        view_id: usize,
-    ) -> Option<RectF> {
-        let view = cx
-            .views
-            .get(&(cx.window_id, view_id))
-            .unwrap()
-            .as_any()
-            .downcast_ref::<V>()
-            .unwrap();
-        let cx = ViewContext::immutable(cx, view_id);
-        ElementBox::rect_for_text_range(self, range_utf16, view, &cx)
-    }
-
-    fn debug(&self, cx: &WindowContext, view_id: usize) -> serde_json::Value {
-        let view = cx
-            .views
-            .get(&(cx.window_id, view_id))
-            .unwrap()
-            .as_any()
-            .downcast_ref::<V>()
-            .unwrap();
-        let cx = ViewContext::immutable(cx, view_id);
-        ElementBox::debug(self, view, &cx)
-    }
-
-    fn name(&self) -> Option<&str> {
-        ElementBox::name(self)
-    }
-}
-
 #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
 pub enum Axis {
     #[default]
@@ -1153,7 +1080,7 @@ impl ChildView {
     }
 }
 
-impl<V: View> Element<V> for ChildView {
+impl<V: View> Drawable<V> for ChildView {
     type LayoutState = ();
     type PaintState = ();
 
@@ -1164,7 +1091,10 @@ impl<V: View> Element<V> for ChildView {
         cx: &mut ViewContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
         if let Some(mut rendered_view) = cx.window.rendered_views.remove(&self.view_id) {
-            let size = rendered_view.layout(constraint, cx, self.view_id);
+            let size = rendered_view
+                .layout(constraint, cx)
+                .log_err()
+                .unwrap_or(Vector2F::zero());
             cx.window.rendered_views.insert(self.view_id, rendered_view);
             (size, ())
         } else {
@@ -1187,7 +1117,9 @@ impl<V: View> Element<V> for ChildView {
         cx: &mut ViewContext<V>,
     ) {
         if let Some(mut rendered_view) = cx.window.rendered_views.remove(&self.view_id) {
-            rendered_view.paint(scene, bounds.origin(), visible_bounds, cx, self.view_id);
+            rendered_view
+                .paint(scene, bounds.origin(), visible_bounds, cx)
+                .log_err();
             cx.window.rendered_views.insert(self.view_id, rendered_view);
         } else {
             log::error!(
@@ -1209,7 +1141,10 @@ impl<V: View> Element<V> for ChildView {
         cx: &ViewContext<V>,
     ) -> Option<RectF> {
         if let Some(rendered_view) = cx.window.rendered_views.get(&self.view_id) {
-            rendered_view.rect_for_text_range(range_utf16, &cx.window_context, self.view_id)
+            rendered_view
+                .rect_for_text_range(range_utf16, &cx.window_context)
+                .log_err()
+                .flatten()
         } else {
             log::error!(
                 "rect_for_text_range called on a ChildView element whose underlying view was dropped (view_id: {}, name: {:?})",
@@ -1238,7 +1173,7 @@ impl<V: View> Element<V> for ChildView {
                 json!(null)
             },
             "child": if let Some(element) = cx.window.rendered_views.get(&self.view_id) {
-                element.debug(&cx.window_context, self.view_id)
+                element.debug(&cx.window_context).log_err().unwrap_or_else(|| json!(null))
             } else {
                 json!(null)
             }

crates/gpui/src/elements.rs 🔗

@@ -33,13 +33,15 @@ use crate::{
         rect::RectF,
         vector::{vec2f, Vector2F},
     },
-    json, Action, SceneBuilder, SizeConstraint, View, ViewContext,
+    json, Action, SceneBuilder, SizeConstraint, View, ViewContext, WeakViewHandle, WindowContext,
 };
+use anyhow::{anyhow, Result};
 use core::panic;
 use json::ToJson;
 use std::{any::Any, borrow::Cow, marker::PhantomData, mem, ops::Range};
+use util::ResultExt;
 
-trait AnyElement<V: View> {
+trait AnyDrawable<V: View> {
     fn layout(
         &mut self,
         constraint: SizeConstraint,
@@ -70,7 +72,7 @@ trait AnyElement<V: View> {
     fn metadata(&self) -> Option<&dyn Any>;
 }
 
-pub trait Element<V: View> {
+pub trait Drawable<V: View> {
     type LayoutState;
     type PaintState;
 
@@ -115,22 +117,22 @@ pub trait Element<V: View> {
         cx: &ViewContext<V>,
     ) -> serde_json::Value;
 
-    fn boxed(self) -> ElementBox<V>
+    fn boxed(self) -> Element<V>
     where
         Self: 'static + Sized,
     {
-        ElementBox {
+        Element {
             element: Box::new(Lifecycle::Init { element: self }),
             view_type: PhantomData,
             name: None,
         }
     }
 
-    fn named(self, name: impl Into<Cow<'static, str>>) -> ElementBox<V>
+    fn named(self, name: impl Into<Cow<'static, str>>) -> Element<V>
     where
         Self: 'static + Sized,
     {
-        ElementBox {
+        Element {
             element: Box::new(Lifecycle::Init { element: self }),
             view_type: PhantomData,
             name: Some(name.into()),
@@ -222,7 +224,7 @@ pub trait Element<V: View> {
     }
 }
 
-pub enum Lifecycle<V: View, E: Element<V>> {
+pub enum Lifecycle<V: View, E: Drawable<V>> {
     Empty,
     Init {
         element: E,
@@ -243,7 +245,7 @@ pub enum Lifecycle<V: View, E: Element<V>> {
     },
 }
 
-impl<V: View, E: Element<V>> AnyElement<V> for Lifecycle<V, E> {
+impl<V: View, E: Drawable<V>> AnyDrawable<V> for Lifecycle<V, E> {
     fn layout(
         &mut self,
         constraint: SizeConstraint,
@@ -401,19 +403,19 @@ impl<V: View, E: Element<V>> AnyElement<V> for Lifecycle<V, E> {
     }
 }
 
-impl<V: View, E: Element<V>> Default for Lifecycle<V, E> {
+impl<V: View, E: Drawable<V>> Default for Lifecycle<V, E> {
     fn default() -> Self {
         Self::Empty
     }
 }
 
-pub struct ElementBox<V: View> {
-    element: Box<dyn AnyElement<V>>,
+pub struct Element<V: View> {
+    element: Box<dyn AnyDrawable<V>>,
     view_type: PhantomData<V>,
     name: Option<Cow<'static, str>>,
 }
 
-impl<V: View> ElementBox<V> {
+impl<V: View> Element<V> {
     pub fn name(&self) -> Option<&str> {
         self.name.as_deref()
     }
@@ -481,26 +483,165 @@ impl<V: View> ElementBox<V> {
     }
 }
 
-pub trait ParentElement<'a, V: View>: Extend<ElementBox<V>> + Sized {
-    fn add_children(&mut self, children: impl IntoIterator<Item = ElementBox<V>>) {
+pub struct RootElement<V: View> {
+    element: Element<V>,
+    view: WeakViewHandle<V>,
+}
+
+impl<V: View> RootElement<V> {
+    pub fn new(element: Element<V>, view: WeakViewHandle<V>) -> Self {
+        Self { element, view }
+    }
+}
+
+pub trait AnyRootElement {
+    fn layout(&mut self, constraint: SizeConstraint, cx: &mut WindowContext) -> Result<Vector2F>;
+    fn paint(
+        &mut self,
+        scene: &mut SceneBuilder,
+        origin: Vector2F,
+        visible_bounds: RectF,
+        cx: &mut WindowContext,
+    ) -> Result<()>;
+    fn rect_for_text_range(
+        &self,
+        range_utf16: Range<usize>,
+        cx: &WindowContext,
+    ) -> Result<Option<RectF>>;
+    fn debug(&self, cx: &WindowContext) -> Result<serde_json::Value>;
+    fn name(&self) -> Option<&str>;
+}
+
+impl<V: View> AnyRootElement for RootElement<V> {
+    fn layout(&mut self, constraint: SizeConstraint, cx: &mut WindowContext) -> Result<Vector2F> {
+        let view = self
+            .view
+            .upgrade(cx)
+            .ok_or_else(|| anyhow!("layout called on a root element for a dropped view"))?;
+        view.update(cx, |view, cx| Ok(self.element.layout(constraint, view, cx)))
+    }
+
+    fn paint(
+        &mut self,
+        scene: &mut SceneBuilder,
+        origin: Vector2F,
+        visible_bounds: RectF,
+        cx: &mut WindowContext,
+    ) -> Result<()> {
+        let view = self
+            .view
+            .upgrade(cx)
+            .ok_or_else(|| anyhow!("paint called on a root element for a dropped view"))?;
+
+        view.update(cx, |view, cx| {
+            self.element.paint(scene, origin, visible_bounds, view, cx);
+            Ok(())
+        })
+    }
+
+    fn rect_for_text_range(
+        &self,
+        range_utf16: Range<usize>,
+        cx: &WindowContext,
+    ) -> Result<Option<RectF>> {
+        let view = self.view.upgrade(cx).ok_or_else(|| {
+            anyhow!("rect_for_text_range called on a root element for a dropped view")
+        })?;
+        let view = view.read(cx);
+        let view_context = ViewContext::immutable(cx, self.view.id());
+        Ok(self
+            .element
+            .rect_for_text_range(range_utf16, view, &view_context))
+    }
+
+    fn debug(&self, cx: &WindowContext) -> Result<serde_json::Value> {
+        let view = self
+            .view
+            .upgrade(cx)
+            .ok_or_else(|| anyhow!("debug called on a root element for a dropped view"))?;
+        let view = view.read(cx);
+        let view_context = ViewContext::immutable(cx, self.view.id());
+        Ok(self.element.debug(view, &view_context))
+    }
+
+    fn name(&self) -> Option<&str> {
+        self.element.name()
+    }
+}
+
+impl<V: View, R: View> Drawable<V> for RootElement<R> {
+    type LayoutState = ();
+    type PaintState = ();
+
+    fn layout(
+        &mut self,
+        constraint: SizeConstraint,
+        view: &mut V,
+        cx: &mut ViewContext<V>,
+    ) -> (Vector2F, Self::LayoutState) {
+        let size = AnyRootElement::layout(self, constraint, cx)
+            .log_err()
+            .unwrap_or_else(|| Vector2F::zero());
+        (size, ())
+    }
+
+    fn paint(
+        &mut self,
+        scene: &mut SceneBuilder,
+        bounds: RectF,
+        visible_bounds: RectF,
+        layout: &mut Self::LayoutState,
+        view: &mut V,
+        cx: &mut ViewContext<V>,
+    ) -> Self::PaintState {
+        todo!()
+    }
+
+    fn rect_for_text_range(
+        &self,
+        range_utf16: Range<usize>,
+        bounds: RectF,
+        visible_bounds: RectF,
+        layout: &Self::LayoutState,
+        paint: &Self::PaintState,
+        view: &V,
+        cx: &ViewContext<V>,
+    ) -> Option<RectF> {
+        todo!()
+    }
+
+    fn debug(
+        &self,
+        bounds: RectF,
+        layout: &Self::LayoutState,
+        paint: &Self::PaintState,
+        view: &V,
+        cx: &ViewContext<V>,
+    ) -> serde_json::Value {
+        todo!()
+    }
+}
+
+pub trait ParentElement<'a, V: View>: Extend<Element<V>> + Sized {
+    fn add_children(&mut self, children: impl IntoIterator<Item = Element<V>>) {
         self.extend(children);
     }
 
-    fn add_child(&mut self, child: ElementBox<V>) {
+    fn add_child(&mut self, child: Element<V>) {
         self.add_children(Some(child));
     }
 
-    fn with_children(mut self, children: impl IntoIterator<Item = ElementBox<V>>) -> Self {
+    fn with_children(mut self, children: impl IntoIterator<Item = Element<V>>) -> Self {
         self.add_children(children);
         self
     }
 
-    fn with_child(self, child: ElementBox<V>) -> Self {
+    fn with_child(self, child: Element<V>) -> Self {
         self.with_children(Some(child))
     }
 }
 
-impl<'a, V: View, T> ParentElement<'a, V> for T where T: Extend<ElementBox<V>> {}
+impl<'a, V: View, T> ParentElement<'a, V> for T where T: Extend<Element<V>> {}
 
 pub fn constrain_size_preserving_aspect_ratio(max_size: Vector2F, size: Vector2F) -> Vector2F {
     if max_size.x().is_infinite() && max_size.y().is_infinite() {

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

@@ -1,18 +1,18 @@
 use crate::{
     geometry::{rect::RectF, vector::Vector2F},
-    json, Element, ElementBox, SceneBuilder, SizeConstraint, View, ViewContext,
+    json, Drawable, Element, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 use json::ToJson;
 
 use serde_json::json;
 
 pub struct Align<V: View> {
-    child: ElementBox<V>,
+    child: Element<V>,
     alignment: Vector2F,
 }
 
 impl<V: View> Align<V> {
-    pub fn new(child: ElementBox<V>) -> Self {
+    pub fn new(child: Element<V>) -> Self {
         Self {
             child,
             alignment: Vector2F::zero(),
@@ -40,7 +40,7 @@ impl<V: View> Align<V> {
     }
 }
 
-impl<V: View> Element<V> for Align<V> {
+impl<V: View> Drawable<V> for Align<V> {
     type LayoutState = ();
     type PaintState = ();
 

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

@@ -1,6 +1,6 @@
 use std::marker::PhantomData;
 
-use super::Element;
+use super::Drawable;
 use crate::{
     json::{self, json},
     SceneBuilder, View, ViewContext,
@@ -23,7 +23,7 @@ where
     }
 }
 
-impl<V: View, F> Element<V> for Canvas<V, F>
+impl<V: View, F> Drawable<V> for Canvas<V, F>
 where
     F: FnMut(&mut SceneBuilder, RectF, RectF, &mut V, &mut ViewContext<V>),
 {

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

@@ -3,19 +3,19 @@ use std::ops::Range;
 use pathfinder_geometry::{rect::RectF, vector::Vector2F};
 use serde_json::json;
 
-use crate::{json, Element, ElementBox, SceneBuilder, SizeConstraint, View, ViewContext};
+use crate::{json, Drawable, Element, SceneBuilder, SizeConstraint, View, ViewContext};
 
 pub struct Clipped<V: View> {
-    child: ElementBox<V>,
+    child: Element<V>,
 }
 
 impl<V: View> Clipped<V> {
-    pub fn new(child: ElementBox<V>) -> Self {
+    pub fn new(child: Element<V>) -> Self {
         Self { child }
     }
 }
 
-impl<V: View> Element<V> for Clipped<V> {
+impl<V: View> Drawable<V> for Clipped<V> {
     type LayoutState = ();
     type PaintState = ();
 

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

@@ -5,11 +5,11 @@ use serde_json::json;
 
 use crate::{
     geometry::{rect::RectF, vector::Vector2F},
-    json, Element, ElementBox, SceneBuilder, SizeConstraint, View, ViewContext,
+    json, Drawable, Element, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 
 pub struct ConstrainedBox<V: View> {
-    child: ElementBox<V>,
+    child: Element<V>,
     constraint: Constraint<V>,
 }
 
@@ -28,7 +28,7 @@ impl<V: View> ToJson for Constraint<V> {
 }
 
 impl<V: View> ConstrainedBox<V> {
-    pub fn new(child: ElementBox<V>) -> Self {
+    pub fn new(child: Element<V>) -> Self {
         Self {
             child,
             constraint: Constraint::Static(Default::default()),
@@ -130,7 +130,7 @@ impl<V: View> ConstrainedBox<V> {
     }
 }
 
-impl<V: View> Element<V> for ConstrainedBox<V> {
+impl<V: View> Drawable<V> for ConstrainedBox<V> {
     type LayoutState = ();
     type PaintState = ();
 

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

@@ -10,7 +10,7 @@ use crate::{
     json::ToJson,
     platform::CursorStyle,
     scene::{self, Border, CursorRegion, Quad},
-    Element, ElementBox, SceneBuilder, SizeConstraint, View, ViewContext,
+    Drawable, Element, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 use serde::Deserialize;
 use serde_json::json;
@@ -36,12 +36,12 @@ pub struct ContainerStyle {
 }
 
 pub struct Container<V: View> {
-    child: ElementBox<V>,
+    child: Element<V>,
     style: ContainerStyle,
 }
 
 impl<V: View> Container<V> {
-    pub fn new(child: ElementBox<V>) -> Self {
+    pub fn new(child: Element<V>) -> Self {
         Self {
             child,
             style: Default::default(),
@@ -184,7 +184,7 @@ impl<V: View> Container<V> {
     }
 }
 
-impl<V: View> Element<V> for Container<V> {
+impl<V: View> Drawable<V> for Container<V> {
     type LayoutState = ();
     type PaintState = ();
 

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

@@ -8,7 +8,7 @@ use crate::{
     json::{json, ToJson},
     SceneBuilder, View, ViewContext,
 };
-use crate::{Element, SizeConstraint};
+use crate::{Drawable, SizeConstraint};
 
 #[derive(Default)]
 pub struct Empty {
@@ -26,7 +26,7 @@ impl Empty {
     }
 }
 
-impl<V: View> Element<V> for Empty {
+impl<V: View> Drawable<V> for Empty {
     type LayoutState = ();
     type PaintState = ();
 

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

@@ -2,18 +2,18 @@ use std::ops::Range;
 
 use crate::{
     geometry::{rect::RectF, vector::Vector2F},
-    json, Element, ElementBox, SceneBuilder, SizeConstraint, View, ViewContext,
+    json, Drawable, Element, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 use serde_json::json;
 
 pub struct Expanded<V: View> {
-    child: ElementBox<V>,
+    child: Element<V>,
     full_width: bool,
     full_height: bool,
 }
 
 impl<V: View> Expanded<V> {
-    pub fn new(child: ElementBox<V>) -> Self {
+    pub fn new(child: Element<V>) -> Self {
         Self {
             child,
             full_width: true,
@@ -34,7 +34,7 @@ impl<V: View> Expanded<V> {
     }
 }
 
-impl<V: View> Element<V> for Expanded<V> {
+impl<V: View> Drawable<V> for Expanded<V> {
     type LayoutState = ();
     type PaintState = ();
 

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

@@ -2,7 +2,7 @@ use std::{any::Any, cell::Cell, f32::INFINITY, ops::Range, rc::Rc};
 
 use crate::{
     json::{self, ToJson, Value},
-    Axis, Element, ElementBox, ElementStateHandle, SceneBuilder, SizeConstraint, Vector2FExt, View,
+    Axis, Drawable, Element, ElementStateHandle, SceneBuilder, SizeConstraint, Vector2FExt, View,
     ViewContext,
 };
 use pathfinder_geometry::{
@@ -19,7 +19,7 @@ struct ScrollState {
 
 pub struct Flex<V: View> {
     axis: Axis,
-    children: Vec<ElementBox<V>>,
+    children: Vec<Element<V>>,
     scroll_state: Option<(ElementStateHandle<Rc<ScrollState>>, usize)>,
     child_alignment: f32,
 }
@@ -111,13 +111,13 @@ impl<V: View> Flex<V> {
     }
 }
 
-impl<V: View> Extend<ElementBox<V>> for Flex<V> {
-    fn extend<T: IntoIterator<Item = ElementBox<V>>>(&mut self, children: T) {
+impl<V: View> Extend<Element<V>> for Flex<V> {
+    fn extend<T: IntoIterator<Item = Element<V>>>(&mut self, children: T) {
         self.children.extend(children);
     }
 }
 
-impl<V: View> Element<V> for Flex<V> {
+impl<V: View> Drawable<V> for Flex<V> {
     type LayoutState = f32;
     type PaintState = ();
 
@@ -399,11 +399,11 @@ struct FlexParentData {
 
 pub struct FlexItem<V: View> {
     metadata: FlexParentData,
-    child: ElementBox<V>,
+    child: Element<V>,
 }
 
 impl<V: View> FlexItem<V> {
-    pub fn new(child: ElementBox<V>) -> Self {
+    pub fn new(child: Element<V>) -> Self {
         FlexItem {
             metadata: FlexParentData {
                 flex: None,
@@ -424,7 +424,7 @@ impl<V: View> FlexItem<V> {
     }
 }
 
-impl<V: View> Element<V> for FlexItem<V> {
+impl<V: View> Drawable<V> for FlexItem<V> {
     type LayoutState = ();
     type PaintState = ();
 

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

@@ -3,16 +3,16 @@ use std::ops::Range;
 use crate::{
     geometry::{rect::RectF, vector::Vector2F},
     json::json,
-    Element, ElementBox, SceneBuilder, SizeConstraint, View, ViewContext,
+    Drawable, Element, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 
 pub struct Hook<V: View> {
-    child: ElementBox<V>,
+    child: Element<V>,
     after_layout: Option<Box<dyn FnMut(Vector2F, &mut ViewContext<V>)>>,
 }
 
 impl<V: View> Hook<V> {
-    pub fn new(child: ElementBox<V>) -> Self {
+    pub fn new(child: Element<V>) -> Self {
         Self {
             child,
             after_layout: None,
@@ -28,7 +28,7 @@ impl<V: View> Hook<V> {
     }
 }
 
-impl<V: View> Element<V> for Hook<V> {
+impl<V: View> Drawable<V> for Hook<V> {
     type LayoutState = ();
     type PaintState = ();
 

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

@@ -5,7 +5,7 @@ use crate::{
         vector::{vec2f, Vector2F},
     },
     json::{json, ToJson},
-    scene, Border, Element, ImageData, SceneBuilder, SizeConstraint, View, ViewContext,
+    scene, Border, Drawable, ImageData, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 use serde::Deserialize;
 use std::{ops::Range, sync::Arc};
@@ -55,7 +55,7 @@ impl Image {
     }
 }
 
-impl<V: View> Element<V> for Image {
+impl<V: View> Drawable<V> for Image {
     type LayoutState = Option<Arc<ImageData>>;
     type PaintState = ();
 

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

@@ -2,7 +2,7 @@ use crate::{
     elements::*,
     fonts::TextStyle,
     geometry::{rect::RectF, vector::Vector2F},
-    Action, ElementBox, SizeConstraint,
+    Action, Element, SizeConstraint,
 };
 use serde_json::json;
 
@@ -34,8 +34,8 @@ impl KeystrokeLabel {
     }
 }
 
-impl<V: View> Element<V> for KeystrokeLabel {
-    type LayoutState = ElementBox<V>;
+impl<V: View> Drawable<V> for KeystrokeLabel {
+    type LayoutState = Element<V>;
     type PaintState = ();
 
     fn layout(
@@ -43,7 +43,7 @@ impl<V: View> Element<V> for KeystrokeLabel {
         constraint: SizeConstraint,
         view: &mut V,
         cx: &mut ViewContext<V>,
-    ) -> (Vector2F, ElementBox<V>) {
+    ) -> (Vector2F, Element<V>) {
         let mut element = if let Some(keystrokes) =
             cx.keystrokes_for_action(self.window_id, self.view_id, self.action.as_ref())
         {
@@ -68,7 +68,7 @@ impl<V: View> Element<V> for KeystrokeLabel {
         scene: &mut SceneBuilder,
         bounds: RectF,
         visible_bounds: RectF,
-        element: &mut ElementBox<V>,
+        element: &mut Element<V>,
         view: &mut V,
         cx: &mut ViewContext<V>,
     ) {
@@ -91,7 +91,7 @@ impl<V: View> Element<V> for KeystrokeLabel {
     fn debug(
         &self,
         _: RectF,
-        element: &ElementBox<V>,
+        element: &Element<V>,
         _: &(),
         view: &V,
         cx: &ViewContext<V>,

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

@@ -8,7 +8,7 @@ use crate::{
     },
     json::{ToJson, Value},
     text_layout::{Line, RunStyle},
-    Element, SceneBuilder, SizeConstraint, View, ViewContext,
+    Drawable, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 use serde::Deserialize;
 use serde_json::json;
@@ -127,7 +127,7 @@ impl Label {
     }
 }
 
-impl<V: View> Element<V> for Label {
+impl<V: View> Drawable<V> for Label {
     type LayoutState = Line;
     type PaintState = ();
 

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

@@ -4,7 +4,7 @@ use crate::{
         vector::{vec2f, Vector2F},
     },
     json::json,
-    Element, ElementBox, MouseRegion, SceneBuilder, SizeConstraint, View, ViewContext,
+    Drawable, Element, MouseRegion, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 use std::{cell::RefCell, collections::VecDeque, fmt::Debug, ops::Range, rc::Rc};
 use sum_tree::{Bias, SumTree};
@@ -23,7 +23,7 @@ pub enum Orientation {
 
 struct StateInner<V: View> {
     last_layout_width: Option<f32>,
-    render_item: Box<dyn FnMut(&mut V, usize, &mut ViewContext<V>) -> ElementBox<V>>,
+    render_item: Box<dyn FnMut(&mut V, usize, &mut ViewContext<V>) -> Element<V>>,
     rendered_range: Range<usize>,
     items: SumTree<ListItem<V>>,
     logical_scroll_top: Option<ListOffset>,
@@ -41,7 +41,7 @@ pub struct ListOffset {
 
 enum ListItem<V: View> {
     Unrendered,
-    Rendered(Rc<RefCell<ElementBox<V>>>),
+    Rendered(Rc<RefCell<Element<V>>>),
     Removed(f32),
 }
 
@@ -91,7 +91,7 @@ impl<V: View> List<V> {
     }
 }
 
-impl<V: View> Element<V> for List<V> {
+impl<V: View> Drawable<V> for List<V> {
     type LayoutState = ListOffset;
     type PaintState = ();
 
@@ -355,7 +355,7 @@ impl<V: View> ListState<V> {
     ) -> Self
     where
         V: View,
-        F: 'static + FnMut(&mut V, usize, &mut ViewContext<V>) -> ElementBox<V>,
+        F: 'static + FnMut(&mut V, usize, &mut ViewContext<V>) -> Element<V>,
     {
         let mut items = SumTree::new();
         items.extend((0..element_count).map(|_| ListItem::Unrendered), &());
@@ -453,7 +453,7 @@ impl<V: View> StateInner<V> {
         constraint: SizeConstraint,
         view: &mut V,
         cx: &mut ViewContext<V>,
-    ) -> Option<Rc<RefCell<ElementBox<V>>>> {
+    ) -> Option<Rc<RefCell<Element<V>>>> {
         if let Some(ListItem::Rendered(element)) = existing_element {
             Some(element.clone())
         } else {
@@ -475,7 +475,7 @@ impl<V: View> StateInner<V> {
         &'a self,
         bounds: RectF,
         scroll_top: &ListOffset,
-    ) -> impl Iterator<Item = (Rc<RefCell<ElementBox<V>>>, Vector2F)> + 'a {
+    ) -> impl Iterator<Item = (Rc<RefCell<Element<V>>>, Vector2F)> + 'a {
         let mut item_origin = bounds.origin() - vec2f(0., scroll_top.offset_in_item);
         let mut cursor = self.items.cursor::<Count>();
         cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &());
@@ -922,7 +922,7 @@ mod tests {
             "TestView"
         }
 
-        fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+        fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
             Empty::new().boxed()
         }
     }
@@ -941,7 +941,7 @@ mod tests {
         }
     }
 
-    impl<V: View> Element<V> for TestElement {
+    impl<V: View> Drawable<V> for TestElement {
         type LayoutState = ();
         type PaintState = ();
 

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

@@ -10,14 +10,14 @@ use crate::{
         CursorRegion, HandlerSet, MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseHover,
         MouseMove, MouseMoveOut, MouseScrollWheel, MouseUp, MouseUpOut,
     },
-    Element, ElementBox, EventContext, MouseRegion, MouseState, SceneBuilder, SizeConstraint, View,
+    Drawable, Element, EventContext, MouseRegion, MouseState, SceneBuilder, SizeConstraint, View,
     ViewContext,
 };
 use serde_json::json;
 use std::{marker::PhantomData, ops::Range};
 
 pub struct MouseEventHandler<Tag: 'static, V: View> {
-    child: ElementBox<V>,
+    child: Element<V>,
     region_id: usize,
     cursor_style: Option<CursorStyle>,
     handlers: HandlerSet,
@@ -35,7 +35,7 @@ impl<Tag, V: View> MouseEventHandler<Tag, V> {
     pub fn new<F>(region_id: usize, cx: &mut ViewContext<V>, render_child: F) -> Self
     where
         V: View,
-        F: FnOnce(&mut MouseState, &mut ViewContext<V>) -> ElementBox<V>,
+        F: FnOnce(&mut MouseState, &mut ViewContext<V>) -> Element<V>,
     {
         let mut mouse_state = cx.mouse_state::<Tag>(region_id);
         let child = render_child(&mut mouse_state, cx);
@@ -61,7 +61,7 @@ impl<Tag, V: View> MouseEventHandler<Tag, V> {
     pub fn above<F>(region_id: usize, cx: &mut ViewContext<V>, render_child: F) -> Self
     where
         V: View,
-        F: FnOnce(&mut MouseState, &mut ViewContext<V>) -> ElementBox<V>,
+        F: FnOnce(&mut MouseState, &mut ViewContext<V>) -> Element<V>,
     {
         let mut handler = Self::new(region_id, cx, render_child);
         handler.above = true;
@@ -212,7 +212,7 @@ impl<Tag, V: View> MouseEventHandler<Tag, V> {
     }
 }
 
-impl<Tag, V: View> Element<V> for MouseEventHandler<Tag, V> {
+impl<Tag, V: View> Drawable<V> for MouseEventHandler<Tag, V> {
     type LayoutState = ();
     type PaintState = ();
 

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

@@ -3,12 +3,12 @@ use std::ops::Range;
 use crate::{
     geometry::{rect::RectF, vector::Vector2F},
     json::ToJson,
-    Axis, Element, ElementBox, MouseRegion, SceneBuilder, SizeConstraint, View, ViewContext,
+    Axis, Drawable, Element, MouseRegion, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 use serde_json::json;
 
 pub struct Overlay<V: View> {
-    child: ElementBox<V>,
+    child: Element<V>,
     anchor_position: Option<Vector2F>,
     anchor_corner: AnchorCorner,
     fit_mode: OverlayFitMode,
@@ -73,7 +73,7 @@ impl AnchorCorner {
 }
 
 impl<V: View> Overlay<V> {
-    pub fn new(child: ElementBox<V>) -> Self {
+    pub fn new(child: Element<V>) -> Self {
         Self {
             child,
             anchor_position: None,
@@ -116,7 +116,7 @@ impl<V: View> Overlay<V> {
     }
 }
 
-impl<V: View> Element<V> for Overlay<V> {
+impl<V: View> Drawable<V> for Overlay<V> {
     type LayoutState = Vector2F;
     type PaintState = ();
 

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

@@ -7,7 +7,7 @@ use crate::{
     geometry::rect::RectF,
     platform::{CursorStyle, MouseButton},
     scene::MouseDrag,
-    Axis, Element, ElementBox, ElementStateHandle, MouseRegion, SceneBuilder, View, ViewContext,
+    Axis, Drawable, Element, ElementStateHandle, MouseRegion, SceneBuilder, View, ViewContext,
 };
 
 use super::{ConstrainedBox, Hook};
@@ -78,14 +78,14 @@ struct ResizeHandleState {
 pub struct Resizable<V: View> {
     side: Side,
     handle_size: f32,
-    child: ElementBox<V>,
+    child: Element<V>,
     state: Rc<ResizeHandleState>,
     _state_handle: ElementStateHandle<Rc<ResizeHandleState>>,
 }
 
 impl<V: View> Resizable<V> {
     pub fn new<Tag: 'static, T: View>(
-        child: ElementBox<V>,
+        child: Element<V>,
         element_id: usize,
         side: Side,
         handle_size: f32,
@@ -132,7 +132,7 @@ impl<V: View> Resizable<V> {
     }
 }
 
-impl<V: View> Element<V> for Resizable<V> {
+impl<V: View> Drawable<V> for Resizable<V> {
     type LayoutState = ();
     type PaintState = ();
 

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

@@ -3,13 +3,13 @@ use std::ops::Range;
 use crate::{
     geometry::{rect::RectF, vector::Vector2F},
     json::{self, json, ToJson},
-    Element, ElementBox, SceneBuilder, SizeConstraint, View, ViewContext,
+    Drawable, Element, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 
 /// Element which renders it's children in a stack on top of each other.
 /// The first child determines the size of the others.
 pub struct Stack<V: View> {
-    children: Vec<ElementBox<V>>,
+    children: Vec<Element<V>>,
 }
 
 impl<V: View> Default for Stack<V> {
@@ -26,7 +26,7 @@ impl<V: View> Stack<V> {
     }
 }
 
-impl<V: View> Element<V> for Stack<V> {
+impl<V: View> Drawable<V> for Stack<V> {
     type LayoutState = ();
     type PaintState = ();
 
@@ -98,8 +98,8 @@ impl<V: View> Element<V> for Stack<V> {
     }
 }
 
-impl<V: View> Extend<ElementBox<V>> for Stack<V> {
-    fn extend<T: IntoIterator<Item = ElementBox<V>>>(&mut self, children: T) {
+impl<V: View> Extend<Element<V>> for Stack<V> {
+    fn extend<T: IntoIterator<Item = Element<V>>>(&mut self, children: T) {
         self.children.extend(children)
     }
 }

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

@@ -8,7 +8,7 @@ use crate::{
         rect::RectF,
         vector::{vec2f, Vector2F},
     },
-    scene, Element, SceneBuilder, SizeConstraint, View, ViewContext,
+    scene, Drawable, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 
 pub struct Svg {
@@ -30,7 +30,7 @@ impl Svg {
     }
 }
 
-impl<V: View> Element<V> for Svg {
+impl<V: View> Drawable<V> for Svg {
     type LayoutState = Option<usvg::Tree>;
     type PaintState = ();
 

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

@@ -7,7 +7,7 @@ use crate::{
     },
     json::{ToJson, Value},
     text_layout::{Line, RunStyle, ShapedBoundary},
-    Element, FontCache, SceneBuilder, SizeConstraint, TextLayoutCache, View, ViewContext,
+    Drawable, FontCache, SceneBuilder, SizeConstraint, TextLayoutCache, View, ViewContext,
 };
 use log::warn;
 use serde_json::json;
@@ -52,7 +52,7 @@ impl Text {
     }
 }
 
-impl<V: View> Element<V> for Text {
+impl<V: View> Drawable<V> for Text {
     type LayoutState = LayoutState;
     type PaintState = ();
 
@@ -276,7 +276,7 @@ pub fn layout_highlighted_chunks<'a>(
 #[cfg(test)]
 mod tests {
     use super::*;
-    use crate::{elements::Empty, fonts, AppContext, ElementBox, Entity, View, ViewContext};
+    use crate::{elements::Empty, fonts, AppContext, Element, Entity, View, ViewContext};
 
     #[crate::test(self)]
     fn test_soft_wrapping_with_carriage_returns(cx: &mut AppContext) {
@@ -306,7 +306,7 @@ mod tests {
             "TestView"
         }
 
-        fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+        fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
             Empty::new().boxed()
         }
     }

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

@@ -1,5 +1,5 @@
 use super::{
-    ContainerStyle, Element, ElementBox, Flex, KeystrokeLabel, MouseEventHandler, Overlay,
+    ContainerStyle, Drawable, Element, Flex, KeystrokeLabel, MouseEventHandler, Overlay,
     OverlayFitMode, ParentElement, Text,
 };
 use crate::{
@@ -19,8 +19,8 @@ use std::{
 const DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(500);
 
 pub struct Tooltip<V: View> {
-    child: ElementBox<V>,
-    tooltip: Option<ElementBox<V>>,
+    child: Element<V>,
+    tooltip: Option<Element<V>>,
     _state: ElementStateHandle<Rc<TooltipState>>,
 }
 
@@ -54,7 +54,7 @@ impl<V: View> Tooltip<V> {
         text: String,
         action: Option<Box<dyn Action>>,
         style: TooltipStyle,
-        child: ElementBox<V>,
+        child: Element<V>,
         cx: &mut ViewContext<V>,
     ) -> Self {
         struct ElementState<Tag>(Tag);
@@ -134,7 +134,7 @@ impl<V: View> Tooltip<V> {
         style: TooltipStyle,
         action: Option<Box<dyn Action>>,
         measure: bool,
-    ) -> impl Element<V> {
+    ) -> impl Drawable<V> {
         Flex::row()
             .with_child({
                 let text = Text::new(text, style.text)
@@ -165,7 +165,7 @@ impl<V: View> Tooltip<V> {
     }
 }
 
-impl<V: View> Element<V> for Tooltip<V> {
+impl<V: View> Drawable<V> for Tooltip<V> {
     type LayoutState = ();
     type PaintState = ();
 

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

@@ -1,4 +1,4 @@
-use super::{Element, SizeConstraint};
+use super::{Drawable, SizeConstraint};
 use crate::{
     geometry::{
         rect::RectF,
@@ -6,7 +6,7 @@ use crate::{
     },
     json::{self, json},
     platform::ScrollWheelEvent,
-    ElementBox, MouseRegion, SceneBuilder, View, ViewContext,
+    Element, MouseRegion, SceneBuilder, View, ViewContext,
 };
 use json::ToJson;
 use std::{cell::RefCell, cmp, ops::Range, rc::Rc};
@@ -39,14 +39,14 @@ struct StateInner {
 pub struct LayoutState<V: View> {
     scroll_max: f32,
     item_height: f32,
-    items: Vec<ElementBox<V>>,
+    items: Vec<Element<V>>,
 }
 
 pub struct UniformList<V: View> {
     state: UniformListState,
     item_count: usize,
     #[allow(clippy::type_complexity)]
-    append_items: Box<dyn Fn(&mut V, Range<usize>, &mut Vec<ElementBox<V>>, &mut ViewContext<V>)>,
+    append_items: Box<dyn Fn(&mut V, Range<usize>, &mut Vec<Element<V>>, &mut ViewContext<V>)>,
     padding_top: f32,
     padding_bottom: f32,
     get_width_from_item: Option<usize>,
@@ -62,7 +62,7 @@ impl<V: View> UniformList<V> {
     ) -> Self
     where
         V: View,
-        F: 'static + Fn(&mut V, Range<usize>, &mut Vec<ElementBox<V>>, &mut ViewContext<V>),
+        F: 'static + Fn(&mut V, Range<usize>, &mut Vec<Element<V>>, &mut ViewContext<V>),
     {
         Self {
             state,
@@ -151,7 +151,7 @@ impl<V: View> UniformList<V> {
     }
 }
 
-impl<V: View> Element<V> for UniformList<V> {
+impl<V: View> Drawable<V> for UniformList<V> {
     type LayoutState = LayoutState<V>;
     type PaintState = ();
 

crates/gpui/src/gpui.rs 🔗

@@ -19,7 +19,7 @@ pub use scene::{Border, CursorRegion, MouseRegion, MouseRegionId, Quad, Scene, S
 pub mod text_layout;
 pub use text_layout::TextLayoutCache;
 mod util;
-pub use elements::{Element, ElementBox};
+pub use elements::{Drawable, Element};
 pub mod executor;
 pub use executor::Task;
 pub mod color;

crates/gpui/src/test.rs 🔗

@@ -19,8 +19,8 @@ use crate::{
     platform,
     platform::Platform,
     util::CwdBacktrace,
-    AppContext, Element, ElementBox, Entity, FontCache, Handle, Subscription, TestAppContext, View,
-    ViewContext,
+    AppContext, Drawable, Element, Entity, FontCache, Handle, Subscription, TestAppContext,
+    View, ViewContext,
 };
 
 #[cfg(test)]
@@ -240,7 +240,7 @@ impl View for EmptyView {
         "empty view"
     }
 
-    fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
-        Element::boxed(Empty::new())
+    fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
+        Drawable::boxed(Empty::new())
     }
 }

crates/gpui/src/views/select.rs 🔗

@@ -7,7 +7,7 @@ use crate::{
 
 pub struct Select {
     handle: WeakViewHandle<Self>,
-    render_item: Box<dyn Fn(usize, ItemType, bool, &AppContext) -> ElementBox<Self>>,
+    render_item: Box<dyn Fn(usize, ItemType, bool, &AppContext) -> Element<Self>>,
     selected_item_ix: usize,
     item_count: usize,
     is_open: bool,
@@ -41,7 +41,7 @@ pub fn init(cx: &mut AppContext) {
 }
 
 impl Select {
-    pub fn new<F: 'static + Fn(usize, ItemType, bool, &AppContext) -> ElementBox<Self>>(
+    pub fn new<F: 'static + Fn(usize, ItemType, bool, &AppContext) -> Element<Self>>(
         item_count: usize,
         cx: &mut ViewContext<Self>,
         render_item: F,
@@ -92,7 +92,7 @@ impl View for Select {
         "Select"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         if self.item_count == 0 {
             return Empty::new().boxed();
         }

crates/language_selector/src/active_buffer_language.rs 🔗

@@ -50,7 +50,7 @@ impl View for ActiveBufferLanguage {
         "ActiveBufferLanguage"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         if let Some(active_language) = self.active_language.as_ref() {
             let active_language_text = if let Some(active_language_text) = active_language {
                 active_language_text.to_string()

crates/language_selector/src/language_selector.rs 🔗

@@ -120,7 +120,7 @@ impl View for LanguageSelector {
         "LanguageSelector"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         ChildView::new(&self.picker, cx).boxed()
     }
 
@@ -210,7 +210,7 @@ impl PickerDelegate for LanguageSelector {
         mouse_state: &mut MouseState,
         selected: bool,
         cx: &AppContext,
-    ) -> ElementBox<Picker<Self>> {
+    ) -> Element<Picker<Self>> {
         let settings = cx.global::<Settings>();
         let theme = &settings.theme;
         let mat = &self.matches[ix];

crates/outline/src/outline.rs 🔗

@@ -48,7 +48,7 @@ impl View for OutlineView {
         "OutlineView"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         ChildView::new(&self.picker, cx).boxed()
     }
 
@@ -238,7 +238,7 @@ impl PickerDelegate for OutlineView {
         mouse_state: &mut MouseState,
         selected: bool,
         cx: &AppContext,
-    ) -> ElementBox<Picker<Self>> {
+    ) -> Element<Picker<Self>> {
         let settings = cx.global::<Settings>();
         let string_match = &self.matches[ix];
         let style = settings.theme.picker.item.style_for(mouse_state, selected);

crates/picker/src/picker.rs 🔗

@@ -4,7 +4,7 @@ use gpui::{
     geometry::vector::{vec2f, Vector2F},
     keymap_matcher::KeymapContext,
     platform::{CursorStyle, MouseButton},
-    AnyViewHandle, AppContext, Axis, ElementBox, Entity, MouseState, Task, View, ViewContext,
+    AnyViewHandle, AppContext, Axis, Element, Entity, MouseState, Task, View, ViewContext,
     ViewHandle, WeakViewHandle,
 };
 use menu::{Cancel, Confirm, SelectFirst, SelectIndex, SelectLast, SelectNext, SelectPrev};
@@ -33,7 +33,7 @@ pub trait PickerDelegate: View {
         state: &mut MouseState,
         selected: bool,
         cx: &AppContext,
-    ) -> ElementBox<Picker<Self>>;
+    ) -> Element<Picker<Self>>;
     fn center_selection_after_match_updates(&self) -> bool {
         false
     }
@@ -48,7 +48,7 @@ impl<D: PickerDelegate> View for Picker<D> {
         "Picker"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let theme = (self.theme.lock())(&cx.global::<settings::Settings>().theme);
         let query = self.query(cx);
         let delegate = self.delegate.clone();

crates/project_panel/src/project_panel.rs 🔗

@@ -13,7 +13,7 @@ use gpui::{
     impl_internal_actions,
     keymap_matcher::KeymapContext,
     platform::{CursorStyle, MouseButton, PromptLevel},
-    AppContext, ClipboardItem, Element, ElementBox, Entity, ModelHandle, Task, View, ViewContext,
+    AppContext, ClipboardItem, Drawable, Element, Entity, ModelHandle, Task, View, ViewContext,
     ViewHandle,
 };
 use menu::{Confirm, SelectNext, SelectPrev};
@@ -1098,7 +1098,7 @@ impl ProjectPanel {
         row_container_style: ContainerStyle,
         style: &ProjectPanelEntry,
         cx: &mut ViewContext<V>,
-    ) -> ElementBox<V> {
+    ) -> Element<V> {
         let kind = details.kind;
         let show_editor = details.is_editing && !details.is_processing;
 
@@ -1155,7 +1155,7 @@ impl ProjectPanel {
         dragged_entry_destination: &mut Option<Arc<Path>>,
         theme: &theme::ProjectPanel,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         let this = cx.handle().downgrade();
         let kind = details.kind;
         let path = details.path.clone();
@@ -1273,7 +1273,7 @@ impl View for ProjectPanel {
         "ProjectPanel"
     }
 
-    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::ElementBox<Self> {
+    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::Element<Self> {
         enum ProjectPanel {}
         let theme = &cx.global::<Settings>().theme.project_panel;
         let mut container_style = theme.container;

crates/project_symbols/src/project_symbols.rs 🔗

@@ -48,7 +48,7 @@ impl View for ProjectSymbolsView {
         "ProjectSymbolsView"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         ChildView::new(&self.picker, cx).boxed()
     }
 
@@ -238,7 +238,7 @@ impl PickerDelegate for ProjectSymbolsView {
         mouse_state: &mut MouseState,
         selected: bool,
         cx: &AppContext,
-    ) -> ElementBox<Picker<Self>> {
+    ) -> Element<Picker<Self>> {
         let string_match = &self.matches[ix];
         let settings = cx.global::<Settings>();
         let style = &settings.theme.picker.item;

crates/recent_projects/src/highlighted_workspace_location.rs 🔗

@@ -3,7 +3,7 @@ use std::path::Path;
 use fuzzy::StringMatch;
 use gpui::{
     elements::{Label, LabelStyle},
-    Element, ElementBox, View,
+    Drawable, Element, View,
 };
 use workspace::WorkspaceLocation;
 
@@ -42,7 +42,7 @@ impl HighlightedText {
         }
     }
 
-    pub fn render<V: View>(self, style: impl Into<LabelStyle>) -> ElementBox<V> {
+    pub fn render<V: View>(self, style: impl Into<LabelStyle>) -> Element<V> {
         Label::new(self.text, style)
             .with_highlights(self.highlight_positions)
             .boxed()

crates/recent_projects/src/recent_projects.rs 🔗

@@ -4,7 +4,7 @@ use fuzzy::{StringMatch, StringMatchCandidate};
 use gpui::{
     actions,
     elements::{ChildView, Flex, ParentElement},
-    AnyViewHandle, AppContext, Element, ElementBox, Entity, Task, View, ViewContext, ViewHandle,
+    AnyViewHandle, AppContext, Drawable, Element, Entity, Task, View, ViewContext, ViewHandle,
 };
 use highlighted_workspace_location::HighlightedWorkspaceLocation;
 use ordered_float::OrderedFloat;
@@ -101,7 +101,7 @@ impl View for RecentProjectsView {
         "RecentProjectsView"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         ChildView::new(&self.picker, cx).boxed()
     }
 
@@ -183,7 +183,7 @@ impl PickerDelegate for RecentProjectsView {
         mouse_state: &mut gpui::MouseState,
         selected: bool,
         cx: &gpui::AppContext,
-    ) -> ElementBox<Picker<Self>> {
+    ) -> Element<Picker<Self>> {
         let settings = cx.global::<Settings>();
         let string_match = &self.matches[ix];
         let style = settings.theme.picker.item.style_for(mouse_state, selected);

crates/search/src/buffer_search.rs 🔗

@@ -91,7 +91,7 @@ impl View for BufferSearchBar {
         }
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let theme = cx.global::<Settings>().theme.clone();
         let editor_container = if self.query_contains_error {
             theme.search.invalid_editor
@@ -324,7 +324,7 @@ impl BufferSearchBar {
         icon: &'static str,
         option: SearchOption,
         cx: &mut ViewContext<Self>,
-    ) -> Option<ElementBox<Self>> {
+    ) -> Option<Element<Self>> {
         if !option_supported {
             return None;
         }
@@ -364,7 +364,7 @@ impl BufferSearchBar {
         icon: &'static str,
         direction: Direction,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         let action: Box<dyn Action>;
         let tooltip;
         match direction {
@@ -411,7 +411,7 @@ impl BufferSearchBar {
         &self,
         theme: &theme::Search,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         let action = Box::new(Dismiss);
         let tooltip = "Dismiss Buffer Search";
         let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();

crates/search/src/project_search.rs 🔗

@@ -12,8 +12,8 @@ use gpui::{
     actions,
     elements::*,
     platform::{CursorStyle, MouseButton},
-    Action, AnyViewHandle, AppContext, ElementBox, Entity, ModelContext, ModelHandle, Subscription,
-    Task, View, ViewContext, ViewHandle, WeakModelHandle, WeakViewHandle,
+    Action, AnyViewHandle, AppContext, Element, Entity, ModelContext, ModelHandle, RenderedView,
+    Subscription, Task, View, ViewContext, ViewHandle, WeakModelHandle, WeakViewHandle,
 };
 use menu::Confirm;
 use project::{search::SearchQuery, Project};
@@ -177,7 +177,7 @@ impl View for ProjectSearchView {
         "ProjectSearchView"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let model = &self.model.read(cx);
         if model.match_ranges.is_empty() {
             enum Status {}
@@ -249,7 +249,7 @@ impl Item for ProjectSearchView {
         _detail: Option<usize>,
         tab_theme: &theme::Tab,
         cx: &AppContext,
-    ) -> ElementBox<Pane> {
+    ) -> Element<Pane> {
         Flex::row()
             .with_child(
                 Svg::new("icons/magnifying_glass_12.svg")
@@ -364,7 +364,11 @@ impl Item for ProjectSearchView {
         }
     }
 
-    fn breadcrumbs(&self, theme: &theme::Theme, cx: &AppContext) -> Option<Vec<ElementBox<Pane>>> {
+    fn breadcrumbs(
+        &self,
+        theme: &theme::Theme,
+        cx: &AppContext,
+    ) -> Option<Vec<Box<dyn RenderedView>>> {
         self.results_editor.breadcrumbs(theme, cx)
     }
 
@@ -747,7 +751,7 @@ impl ProjectSearchBar {
         icon: &'static str,
         direction: Direction,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         let action: Box<dyn Action>;
         let tooltip;
         match direction {
@@ -795,7 +799,7 @@ impl ProjectSearchBar {
         icon: &'static str,
         option: SearchOption,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
         let is_active = self.is_option_enabled(option, cx);
         MouseEventHandler::<Self, _>::new(option as usize, cx, |state, cx| {
@@ -847,7 +851,7 @@ impl View for ProjectSearchBar {
         "ProjectSearchBar"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         if let Some(search) = self.active_project_search.as_ref() {
             let search = search.read(cx);
             let theme = cx.global::<Settings>().theme.clone();

crates/terminal_view/src/terminal_button.rs 🔗

@@ -3,7 +3,7 @@ use gpui::{
     elements::*,
     impl_internal_actions,
     platform::{CursorStyle, MouseButton},
-    AppContext, Element, ElementBox, Entity, View, ViewContext, ViewHandle, WeakModelHandle,
+    AppContext, Drawable, Element, Entity, View, ViewContext, ViewHandle, WeakModelHandle,
     WeakViewHandle,
 };
 use settings::Settings;
@@ -42,7 +42,7 @@ impl View for TerminalButton {
         "TerminalButton"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let workspace = self.workspace.upgrade(cx);
         let project = match workspace {
             Some(workspace) => workspace.read(cx).project().read(cx),

crates/terminal_view/src/terminal_element.rs 🔗

@@ -10,7 +10,7 @@ use gpui::{
     platform::{CursorStyle, MouseButton},
     serde_json::json,
     text_layout::{Line, RunStyle},
-    Element, ElementBox, EventContext, FontCache, ModelContext, MouseRegion, Quad, SceneBuilder,
+    Drawable, Element, EventContext, FontCache, ModelContext, MouseRegion, Quad, SceneBuilder,
     SizeConstraint, TextLayoutCache, ViewContext, WeakModelHandle, WeakViewHandle,
 };
 use itertools::Itertools;
@@ -45,7 +45,7 @@ pub struct LayoutState {
     size: TerminalSize,
     mode: TermMode,
     display_offset: usize,
-    hyperlink_tooltip: Option<ElementBox<TerminalView>>,
+    hyperlink_tooltip: Option<Element<TerminalView>>,
 }
 
 ///Helper struct for converting data between alacritty's cursor points, and displayed cursor points
@@ -555,7 +555,7 @@ impl TerminalElement {
     }
 }
 
-impl Element<TerminalView> for TerminalElement {
+impl Drawable<TerminalView> for TerminalElement {
     type LayoutState = LayoutState;
     type PaintState = ();
 

crates/terminal_view/src/terminal_view.rs 🔗

@@ -17,8 +17,8 @@ use gpui::{
     impl_actions, impl_internal_actions,
     keymap_matcher::{KeymapContext, Keystroke},
     platform::KeyDownEvent,
-    AnyViewHandle, AppContext, Element, ElementBox, Entity, ModelHandle, Task, View, ViewContext,
-    ViewHandle, WeakViewHandle,
+    AnyViewHandle, AppContext, Drawable, Element, Entity, ModelHandle, RenderedView, Task, View,
+    ViewContext, ViewHandle, WeakViewHandle,
 };
 use project::{LocalWorktree, Project};
 use serde::Deserialize;
@@ -384,7 +384,7 @@ impl View for TerminalView {
         "Terminal"
     }
 
-    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Element<Self> {
         let terminal_handle = self.terminal.clone().downgrade();
 
         let self_id = cx.view_id();
@@ -544,7 +544,7 @@ impl Item for TerminalView {
         _detail: Option<usize>,
         tab_theme: &theme::Tab,
         cx: &gpui::AppContext,
-    ) -> ElementBox<Pane> {
+    ) -> Element<Pane> {
         let title = self.terminal().read(cx).title();
 
         Flex::row()
@@ -606,12 +606,18 @@ impl Item for TerminalView {
         ToolbarItemLocation::PrimaryLeft { flex: None }
     }
 
-    fn breadcrumbs(&self, theme: &theme::Theme, cx: &AppContext) -> Option<Vec<ElementBox<Pane>>> {
-        Some(vec![Text::new(
-            self.terminal().read(cx).breadcrumb_text.clone(),
-            theme.workspace.breadcrumbs.default.text.clone(),
-        )
-        .boxed()])
+    fn breadcrumbs(
+        &self,
+        theme: &theme::Theme,
+        cx: &AppContext,
+    ) -> Option<Vec<Box<dyn RenderedView>>> {
+        Some(vec![Box::new(
+            Text::new(
+                self.terminal().read(cx).breadcrumb_text.clone(),
+                theme.workspace.breadcrumbs.default.text.clone(),
+            )
+            .boxed() as Element<TerminalView>,
+        )])
     }
 
     fn serialized_item_kind() -> Option<&'static str> {

crates/theme/src/ui.rs 🔗

@@ -11,7 +11,7 @@ use gpui::{
     platform,
     platform::MouseButton,
     scene::MouseClick,
-    Action, Element, ElementBox, EventContext, MouseState, View, ViewContext,
+    Action, Drawable, Element, EventContext, MouseState, View, ViewContext,
 };
 use serde::Deserialize;
 
@@ -43,7 +43,7 @@ pub fn checkbox<Tag: 'static, V: View>(
 }
 
 pub fn checkbox_with_label<Tag: 'static, V: View>(
-    label: ElementBox<V>,
+    label: Element<V>,
     style: &CheckboxStyle,
     checked: bool,
     cx: &mut ViewContext<V>,
@@ -181,7 +181,7 @@ pub fn cta_button<L, A, V>(
     max_width: f32,
     style: &ButtonStyle,
     cx: &mut ViewContext<V>,
-) -> ElementBox<V>
+) -> Element<V>
 where
     L: Into<Cow<'static, str>>,
     A: 'static + Action + Clone,
@@ -240,12 +240,12 @@ pub fn modal<Tag, V, I, F>(
     style: &ModalStyle,
     cx: &mut ViewContext<V>,
     build_modal: F,
-) -> ElementBox<V>
+) -> Element<V>
 where
     Tag: 'static,
     V: View,
     I: Into<Cow<'static, str>>,
-    F: FnOnce(&mut gpui::ViewContext<V>) -> ElementBox<V>,
+    F: FnOnce(&mut gpui::ViewContext<V>) -> Element<V>,
 {
     const TITLEBAR_HEIGHT: f32 = 28.;
     // let active = cx.window_is_active(cx.window_id());

crates/theme_selector/src/theme_selector.rs 🔗

@@ -1,7 +1,7 @@
 use fuzzy::{match_strings, StringMatch, StringMatchCandidate};
 use gpui::{
-    actions, elements::*, AnyViewHandle, AppContext, Element, ElementBox, Entity, MouseState, View,
-    ViewContext, ViewHandle,
+    actions, elements::*, AnyViewHandle, AppContext, Drawable, Element, Entity, MouseState,
+    View, ViewContext, ViewHandle,
 };
 use picker::{Picker, PickerDelegate};
 use settings::{settings_file::SettingsFile, Settings};
@@ -226,7 +226,7 @@ impl PickerDelegate for ThemeSelector {
         mouse_state: &mut MouseState,
         selected: bool,
         cx: &AppContext,
-    ) -> ElementBox<Picker<Self>> {
+    ) -> Element<Picker<Self>> {
         let settings = cx.global::<Settings>();
         let theme = &settings.theme;
         let theme_match = &self.matches[ix];
@@ -255,7 +255,7 @@ impl View for ThemeSelector {
         "ThemeSelector"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         ChildView::new(&self.picker, cx).boxed()
     }
 

crates/theme_testbench/src/theme_testbench.rs 🔗

@@ -2,11 +2,11 @@ use gpui::{
     actions,
     color::Color,
     elements::{
-        Canvas, Container, ContainerStyle, ElementBox, Flex, Label, Margin, MouseEventHandler,
+        Canvas, Container, ContainerStyle, Element, Flex, Label, Margin, MouseEventHandler,
         Padding, ParentElement,
     },
     fonts::TextStyle,
-    AppContext, Border, Element, Entity, ModelHandle, Quad, Task, View, ViewContext, ViewHandle,
+    AppContext, Border, Drawable, Entity, ModelHandle, Quad, Task, View, ViewContext, ViewHandle,
     WeakViewHandle,
 };
 use project::Project;
@@ -35,7 +35,7 @@ impl ThemeTestbench {
     }
 
     fn render_ramps(color_scheme: &ColorScheme) -> Flex<Self> {
-        fn display_ramp(ramp: &Vec<Color>) -> ElementBox<ThemeTestbench> {
+        fn display_ramp(ramp: &Vec<Color>) -> Element<ThemeTestbench> {
             Flex::row()
                 .with_children(ramp.iter().cloned().map(|color| {
                     Canvas::new(move |scene, bounds, _, _, _| {
@@ -183,7 +183,7 @@ impl ThemeTestbench {
         style_set: &StyleSet,
         style_override: Option<fn(&StyleSet) -> &Style>,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         enum TestBenchButton {}
         MouseEventHandler::<TestBenchButton, _>::new(layer_index + button_index, cx, |state, cx| {
             let style = if let Some(style_override) = style_override {
@@ -262,7 +262,7 @@ impl View for ThemeTestbench {
         "ThemeTestbench"
     }
 
-    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Element<Self> {
         let color_scheme = &cx.global::<Settings>().theme.clone().color_scheme;
 
         Flex::row()
@@ -298,12 +298,7 @@ impl View for ThemeTestbench {
 }
 
 impl Item for ThemeTestbench {
-    fn tab_content(
-        &self,
-        _: Option<usize>,
-        style: &theme::Tab,
-        _: &AppContext,
-    ) -> ElementBox<Pane> {
+    fn tab_content(&self, _: Option<usize>, style: &theme::Tab, _: &AppContext) -> Element<Pane> {
         Label::new("Theme Testbench", style.label.clone())
             .aligned()
             .contained()

crates/welcome/src/base_keymap_picker.rs 🔗

@@ -1,7 +1,7 @@
 use fuzzy::{match_strings, StringMatch, StringMatchCandidate};
 use gpui::{
     actions,
-    elements::{ChildView, Element as _, Label},
+    elements::{ChildView, Drawable as _, Label},
     AnyViewHandle, AppContext, Entity, View, ViewContext, ViewHandle,
 };
 use picker::{Picker, PickerDelegate};
@@ -74,7 +74,7 @@ impl View for BaseKeymapSelector {
         "BaseKeymapSelector"
     }
 
-    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::ElementBox<Self> {
+    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::Element<Self> {
         ChildView::new(&self.picker, cx).boxed()
     }
 
@@ -161,7 +161,7 @@ impl PickerDelegate for BaseKeymapSelector {
         mouse_state: &mut gpui::MouseState,
         selected: bool,
         cx: &gpui::AppContext,
-    ) -> gpui::ElementBox<Picker<Self>> {
+    ) -> gpui::Element<Picker<Self>> {
         let theme = &cx.global::<Settings>().theme;
         let keymap_match = &self.matches[ix];
         let style = theme.picker.item.style_for(mouse_state, selected);

crates/welcome/src/welcome.rs 🔗

@@ -5,7 +5,7 @@ use std::sync::Arc;
 use db::kvp::KEY_VALUE_STORE;
 use gpui::{
     elements::{Flex, Label, ParentElement},
-    AppContext, Element, ElementBox, Entity, Subscription, View, ViewContext,
+    AppContext, Drawable, Element, Entity, Subscription, View, ViewContext,
 };
 use settings::{settings_file::SettingsFile, Settings};
 
@@ -55,7 +55,7 @@ impl View for WelcomePage {
         "WelcomePage"
     }
 
-    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Element<Self> {
         let self_handle = cx.handle();
         let settings = cx.global::<Settings>();
         let theme = settings.theme.clone();
@@ -203,7 +203,7 @@ impl Item for WelcomePage {
         _detail: Option<usize>,
         style: &theme::Tab,
         _cx: &gpui::AppContext,
-    ) -> ElementBox<Pane> {
+    ) -> Element<Pane> {
         Flex::row()
             .with_child(
                 Label::new("Welcome to Zed!", style.label.clone())

crates/workspace/src/dock.rs 🔗

@@ -9,7 +9,7 @@ use gpui::{
     geometry::vector::Vector2F,
     impl_internal_actions,
     platform::{CursorStyle, MouseButton},
-    AppContext, Border, Element, ElementBox, SizeConstraint, ViewContext, ViewHandle,
+    AppContext, Border, Drawable, Element, SizeConstraint, ViewContext, ViewHandle,
 };
 use settings::{DockAnchor, Settings};
 use theme::Theme;
@@ -315,7 +315,7 @@ impl Dock {
         theme: &Theme,
         anchor: DockAnchor,
         cx: &mut ViewContext<Workspace>,
-    ) -> Option<ElementBox<Workspace>> {
+    ) -> Option<Element<Workspace>> {
         let style = &theme.workspace.dock;
 
         self.position

crates/workspace/src/dock/toggle_dock_button.rs 🔗

@@ -2,7 +2,7 @@ use gpui::{
     elements::{Empty, MouseEventHandler, Svg},
     platform::CursorStyle,
     platform::MouseButton,
-    Element, ElementBox, Entity, View, ViewContext, ViewHandle, WeakViewHandle,
+    Drawable, Element, Entity, View, ViewContext, ViewHandle, WeakViewHandle,
 };
 use settings::Settings;
 
@@ -34,7 +34,7 @@ impl View for ToggleDockButton {
         "Dock Toggle"
     }
 
-    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Element<Self> {
         let workspace = self.workspace.upgrade(cx);
 
         if workspace.is_none() {

crates/workspace/src/item.rs 🔗

@@ -15,8 +15,8 @@ use std::{
 use anyhow::Result;
 use client::{proto, Client};
 use gpui::{
-    AnyViewHandle, AppContext, ElementBox, ModelHandle, Task, View, ViewContext, ViewHandle,
-    WeakViewHandle,
+    AnyViewHandle, AppContext, Element, ModelHandle, RenderedView, Task, View, ViewContext,
+    ViewHandle, WeakViewHandle,
 };
 use project::{Project, ProjectEntryId, ProjectPath};
 use settings::{Autosave, Settings};
@@ -52,7 +52,7 @@ pub trait Item: View {
         detail: Option<usize>,
         style: &theme::Tab,
         cx: &AppContext,
-    ) -> ElementBox<Pane>;
+    ) -> Element<Pane>;
     fn for_each_project_item(&self, _: &AppContext, _: &mut dyn FnMut(usize, &dyn project::Item)) {}
     fn is_singleton(&self, _cx: &AppContext) -> bool {
         false
@@ -134,7 +134,7 @@ pub trait Item: View {
         ToolbarItemLocation::Hidden
     }
 
-    fn breadcrumbs(&self, _theme: &Theme, _cx: &AppContext) -> Option<Vec<ElementBox<Pane>>> {
+    fn breadcrumbs(&self, _theme: &Theme, _cx: &AppContext) -> Option<Vec<Box<dyn RenderedView>>> {
         None
     }
 
@@ -172,7 +172,7 @@ pub trait ItemHandle: 'static + fmt::Debug {
         detail: Option<usize>,
         style: &theme::Tab,
         cx: &AppContext,
-    ) -> ElementBox<Pane>;
+    ) -> Element<Pane>;
     fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
     fn project_entry_ids(&self, cx: &AppContext) -> SmallVec<[ProjectEntryId; 3]>;
     fn project_item_model_ids(&self, cx: &AppContext) -> SmallVec<[usize; 3]>;
@@ -221,7 +221,7 @@ pub trait ItemHandle: 'static + fmt::Debug {
     ) -> gpui::Subscription;
     fn to_searchable_item_handle(&self, cx: &AppContext) -> Option<Box<dyn SearchableItemHandle>>;
     fn breadcrumb_location(&self, cx: &AppContext) -> ToolbarItemLocation;
-    fn breadcrumbs(&self, theme: &Theme, cx: &AppContext) -> Option<Vec<ElementBox<Pane>>>;
+    fn breadcrumbs(&self, theme: &Theme, cx: &AppContext) -> Option<Vec<Box<dyn RenderedView>>>;
     fn serialized_item_kind(&self) -> Option<&'static str>;
     fn show_toolbar(&self, cx: &AppContext) -> bool;
 }
@@ -265,7 +265,7 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
         detail: Option<usize>,
         style: &theme::Tab,
         cx: &AppContext,
-    ) -> ElementBox<Pane> {
+    ) -> Element<Pane> {
         self.read(cx).tab_content(detail, style, cx)
     }
 
@@ -591,7 +591,7 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
         self.read(cx).breadcrumb_location()
     }
 
-    fn breadcrumbs(&self, theme: &Theme, cx: &AppContext) -> Option<Vec<ElementBox<Pane>>> {
+    fn breadcrumbs(&self, theme: &Theme, cx: &AppContext) -> Option<Vec<Box<dyn RenderedView>>> {
         self.read(cx).breadcrumbs(theme, cx)
     }
 
@@ -748,7 +748,7 @@ pub(crate) mod test {
     use super::{Item, ItemEvent};
     use crate::{sidebar::SidebarItem, ItemId, ItemNavHistory, Pane, Workspace, WorkspaceId};
     use gpui::{
-        elements::Empty, AppContext, Element, ElementBox, Entity, ModelHandle, Task, View,
+        elements::Empty, AppContext, Drawable, Element, Entity, ModelHandle, Task, View,
         ViewContext, ViewHandle, WeakViewHandle,
     };
     use project::{Project, ProjectEntryId, ProjectPath, WorktreeId};
@@ -907,7 +907,7 @@ pub(crate) mod test {
             "TestItem"
         }
 
-        fn render(&mut self, _: &mut ViewContext<Self>) -> ElementBox<Self> {
+        fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
             Empty::new().boxed()
         }
     }
@@ -925,7 +925,7 @@ pub(crate) mod test {
             detail: Option<usize>,
             _: &theme::Tab,
             _: &AppContext,
-        ) -> ElementBox<Pane> {
+        ) -> Element<Pane> {
             self.tab_detail.set(detail);
             Empty::new().boxed()
         }

crates/workspace/src/notifications.rs 🔗

@@ -140,7 +140,7 @@ pub mod simple_message_notification {
         elements::{Flex, MouseEventHandler, Padding, ParentElement, Svg, Text},
         impl_actions,
         platform::{CursorStyle, MouseButton},
-        Action, AppContext, Element, Entity, View, ViewContext,
+        Action, AppContext, Drawable, Entity, View, ViewContext,
     };
     use menu::Cancel;
     use serde::Deserialize;
@@ -229,7 +229,7 @@ pub mod simple_message_notification {
             "MessageNotification"
         }
 
-        fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::ElementBox<Self> {
+        fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::Element<Self> {
             let theme = cx.global::<Settings>().theme.clone();
             let theme = &theme.simple_message_notification;
 

crates/workspace/src/pane.rs 🔗

@@ -1220,7 +1220,7 @@ impl Pane {
         });
     }
 
-    fn render_tabs(&mut self, cx: &mut ViewContext<Self>) -> impl Element<Self> {
+    fn render_tabs(&mut self, cx: &mut ViewContext<Self>) -> impl Drawable<Self> {
         let theme = cx.global::<Settings>().theme.clone();
 
         let pane = cx.handle().downgrade();
@@ -1384,7 +1384,7 @@ impl Pane {
         hovered: bool,
         tab_style: &theme::Tab,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         let title = item.tab_content(detail, &tab_style, cx);
         let mut container = tab_style.container.clone();
         if first {
@@ -1483,7 +1483,7 @@ impl Pane {
         &mut self,
         theme: &Theme,
         cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         Flex::row()
             // New menu
             .with_child(render_tab_bar_button(
@@ -1536,7 +1536,7 @@ impl Pane {
         &mut self,
         theme: &Theme,
         _cx: &mut ViewContext<Self>,
-    ) -> ElementBox<Self> {
+    ) -> Element<Self> {
         let background = theme.workspace.background;
         Empty::new()
             .contained()
@@ -1554,7 +1554,7 @@ impl View for Pane {
         "Pane"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let this = cx.handle().downgrade();
 
         enum MouseNavigationHandler {}
@@ -1719,7 +1719,7 @@ fn render_tab_bar_button<A: Action + Clone>(
     cx: &mut ViewContext<Pane>,
     action: A,
     context_menu: Option<ViewHandle<ContextMenu>>,
-) -> ElementBox<Pane> {
+) -> Element<Pane> {
     enum TabBarButton {}
 
     Stack::new()
@@ -1853,11 +1853,11 @@ impl NavHistory {
 
 pub struct PaneBackdrop<V: View> {
     child_view: usize,
-    child: ElementBox<V>,
+    child: Element<V>,
 }
 
 impl<V: View> PaneBackdrop<V> {
-    pub fn new(pane_item_view: usize, child: ElementBox<V>) -> Self {
+    pub fn new(pane_item_view: usize, child: Element<V>) -> Self {
         PaneBackdrop {
             child,
             child_view: pane_item_view,
@@ -1865,7 +1865,7 @@ impl<V: View> PaneBackdrop<V> {
     }
 }
 
-impl<V: View> Element<V> for PaneBackdrop<V> {
+impl<V: View> Drawable<V> for PaneBackdrop<V> {
     type LayoutState = ();
 
     type PaintState = ();

crates/workspace/src/pane/dragged_item_receiver.rs 🔗

@@ -5,7 +5,7 @@ use gpui::{
     geometry::{rect::RectF, vector::Vector2F},
     platform::MouseButton,
     scene::MouseUp,
-    AppContext, Element, ElementBox, EventContext, MouseState, Quad, View, ViewContext,
+    AppContext, Drawable, Element, EventContext, MouseState, Quad, View, ViewContext,
     WeakViewHandle,
 };
 use project::ProjectEntryId;
@@ -28,7 +28,7 @@ pub fn dragged_item_receiver<Tag, F>(
 ) -> MouseEventHandler<Tag, Pane>
 where
     Tag: 'static,
-    F: FnOnce(&mut MouseState, &mut ViewContext<Pane>) -> ElementBox<Pane>,
+    F: FnOnce(&mut MouseState, &mut ViewContext<Pane>) -> Element<Pane>,
 {
     MouseEventHandler::<Tag, _>::above(region_id, cx, |state, cx| {
         // Observing hovered will cause a render when the mouse enters regardless

crates/workspace/src/pane_group.rs 🔗

@@ -71,7 +71,7 @@ impl PaneGroup {
         active_call: Option<&ModelHandle<ActiveCall>>,
         active_pane: &ViewHandle<Pane>,
         cx: &mut ViewContext<Workspace>,
-    ) -> ElementBox<Workspace> {
+    ) -> Element<Workspace> {
         self.root.render(
             project,
             theme,
@@ -132,7 +132,7 @@ impl Member {
         active_call: Option<&ModelHandle<ActiveCall>>,
         active_pane: &ViewHandle<Pane>,
         cx: &mut ViewContext<Workspace>,
-    ) -> ElementBox<Workspace> {
+    ) -> Element<Workspace> {
         enum FollowIntoExternalProject {}
 
         match self {
@@ -367,7 +367,7 @@ impl PaneAxis {
         active_call: Option<&ModelHandle<ActiveCall>>,
         active_pane: &ViewHandle<Pane>,
         cx: &mut ViewContext<Workspace>,
-    ) -> ElementBox<Workspace> {
+    ) -> Element<Workspace> {
         let last_member_ix = self.members.len() - 1;
         Flex::new(self.axis)
             .with_children(self.members.iter().enumerate().map(|(ix, member)| {

crates/workspace/src/shared_screen.rs 🔗

@@ -64,7 +64,7 @@ impl View for SharedScreen {
         "SharedScreen"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         enum Focus {}
 
         let frame = self.frame.clone();
@@ -103,7 +103,7 @@ impl Item for SharedScreen {
         _: Option<usize>,
         style: &theme::Tab,
         _: &AppContext,
-    ) -> gpui::ElementBox<Pane> {
+    ) -> gpui::Element<Pane> {
         Flex::row()
             .with_child(
                 Svg::new("icons/disable_screen_sharing_12.svg")

crates/workspace/src/sidebar.rs 🔗

@@ -188,7 +188,7 @@ impl View for Sidebar {
         "Sidebar"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         if let Some(active_item) = self.active_item() {
             enum ResizeHandleTag {}
             let style = &cx.global::<Settings>().theme.workspace.sidebar;
@@ -225,7 +225,7 @@ impl View for SidebarButtons {
         "SidebarToggleButton"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let theme = &cx.global::<Settings>().theme;
         let tooltip_style = theme.tooltip.clone();
         let theme = &theme.workspace.status_bar.sidebar_buttons;

crates/workspace/src/status_bar.rs 🔗

@@ -8,7 +8,7 @@ use gpui::{
         vector::{vec2f, Vector2F},
     },
     json::{json, ToJson},
-    AnyViewHandle, AppContext, ElementBox, Entity, SceneBuilder, SizeConstraint, Subscription,
+    AnyViewHandle, AppContext, Element, Entity, SceneBuilder, SizeConstraint, Subscription,
     View, ViewContext, ViewHandle,
 };
 use settings::Settings;
@@ -42,7 +42,7 @@ impl View for StatusBar {
         "StatusBar"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let theme = &cx.global::<Settings>().theme.workspace.status_bar;
 
         StatusBarElement {
@@ -139,11 +139,11 @@ impl From<&dyn StatusItemViewHandle> for AnyViewHandle {
 }
 
 struct StatusBarElement {
-    left: ElementBox<StatusBar>,
-    right: ElementBox<StatusBar>,
+    left: Element<StatusBar>,
+    right: Element<StatusBar>,
 }
 
-impl Element<StatusBar> for StatusBarElement {
+impl Drawable<StatusBar> for StatusBarElement {
     type LayoutState = ();
     type PaintState = ();
 

crates/workspace/src/toolbar.rs 🔗

@@ -1,7 +1,7 @@
 use crate::{ItemHandle, Pane};
 use gpui::{
     elements::*, platform::CursorStyle, platform::MouseButton, Action, AnyViewHandle, AppContext,
-    ElementBox, Entity, View, ViewContext, ViewHandle, WeakViewHandle,
+    Element, Entity, View, ViewContext, ViewHandle, WeakViewHandle,
 };
 use settings::Settings;
 
@@ -59,7 +59,7 @@ impl View for Toolbar {
         "Toolbar"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let theme = &cx.global::<Settings>().theme.workspace.toolbar;
 
         let mut primary_left_items = Vec::new();
@@ -169,7 +169,7 @@ fn nav_button<A: Action + Clone>(
     tooltip_action: A,
     action_name: &str,
     cx: &mut ViewContext<Toolbar>,
-) -> ElementBox<Toolbar> {
+) -> Element<Toolbar> {
     MouseEventHandler::<A, _>::new(0, cx, |state, _| {
         let style = if enabled {
             style.style_for(state, false)

crates/workspace/src/workspace.rs 🔗

@@ -2054,7 +2054,7 @@ impl Workspace {
         self.leader_state.followers.contains(&peer_id)
     }
 
-    fn render_titlebar(&self, theme: &Theme, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render_titlebar(&self, theme: &Theme, cx: &mut ViewContext<Self>) -> Element<Self> {
         // TODO: There should be a better system in place for this
         // (https://github.com/zed-industries/zed/issues/1290)
         let is_fullscreen = cx.window_is_fullscreen();
@@ -2157,7 +2157,7 @@ impl Workspace {
     fn render_disconnected_overlay(
         &self,
         cx: &mut ViewContext<Workspace>,
-    ) -> Option<ElementBox<Workspace>> {
+    ) -> Option<Element<Workspace>> {
         if self.project.read(cx).is_read_only() {
             enum DisconnectedOverlay {}
             Some(
@@ -2185,7 +2185,7 @@ impl Workspace {
         &self,
         theme: &theme::Workspace,
         cx: &AppContext,
-    ) -> Option<ElementBox<Workspace>> {
+    ) -> Option<Element<Workspace>> {
         if self.notifications.is_empty() {
             None
         } else {
@@ -2813,7 +2813,7 @@ impl View for Workspace {
         "Workspace"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
         let theme = cx.global::<Settings>().theme.clone();
         Stack::new()
             .with_child(