Merge branch 'main' into fix-nondeterministic-terminal-test

Mikayla Maki created

Change summary

crates/activity_indicator/src/activity_indicator.rs          |  10 
crates/auto_update/src/update_notification.rs                |  18 
crates/breadcrumbs/src/breadcrumbs.rs                        |  25 
crates/collab_ui/src/collab_titlebar_item.rs                 | 128 -
crates/collab_ui/src/collaborator_list_popover.rs            |  20 
crates/collab_ui/src/contact_finder.rs                       |   9 
crates/collab_ui/src/contact_list.rs                         | 244 +-
crates/collab_ui/src/contact_notification.rs                 |   2 
crates/collab_ui/src/contacts_popover.rs                     |   7 
crates/collab_ui/src/face_pile.rs                            |  10 
crates/collab_ui/src/incoming_call_notification.rs           |  35 
crates/collab_ui/src/notifications.rs                        |  22 
crates/collab_ui/src/project_shared_notification.rs          |  33 
crates/collab_ui/src/sharing_status_indicator.rs             |   7 
crates/command_palette/src/command_palette.rs                |  32 
crates/context_menu/src/context_menu.rs                      | 114 
crates/copilot/src/sign_in.rs                                | 239 +-
crates/copilot_button/src/copilot_button.rs                  |  39 
crates/diagnostics/src/diagnostics.rs                        |  45 
crates/diagnostics/src/items.rs                              |  40 
crates/drag_and_drop/src/drag_and_drop.rs                    |  25 
crates/editor/src/display_map.rs                             |   2 
crates/editor/src/display_map/block_map.rs                   |  32 
crates/editor/src/editor.rs                                  |  45 
crates/editor/src/editor_tests.rs                            |   2 
crates/editor/src/element.rs                                 |  28 
crates/editor/src/hover_popover.rs                           |  21 
crates/editor/src/items.rs                                   |  19 
crates/feedback/src/deploy_feedback_button.rs                |   8 
crates/feedback/src/feedback_editor.rs                       |  16 
crates/feedback/src/feedback_info_text.rs                    |  16 
crates/feedback/src/submit_feedback_button.rs                |   7 
crates/file_finder/src/file_finder.rs                        |  12 
crates/go_to_line/src/go_to_line.rs                          |  34 
crates/gpui/examples/text.rs                                 |   8 
crates/gpui/src/app.rs                                       | 139 -
crates/gpui/src/app/window.rs                                |  35 
crates/gpui/src/elements.rs                                  | 216 +-
crates/gpui/src/elements/align.rs                            |   8 
crates/gpui/src/elements/canvas.rs                           |   6 
crates/gpui/src/elements/clipped.rs                          |   8 
crates/gpui/src/elements/constrained_box.rs                  |  10 
crates/gpui/src/elements/container.rs                        |   8 
crates/gpui/src/elements/empty.rs                            |   4 
crates/gpui/src/elements/expanded.rs                         |  10 
crates/gpui/src/elements/flex.rs                             |  18 
crates/gpui/src/elements/hook.rs                             |  10 
crates/gpui/src/elements/image.rs                            |   4 
crates/gpui/src/elements/keystroke_label.rs                  |  17 
crates/gpui/src/elements/label.rs                            |   4 
crates/gpui/src/elements/list.rs                             |  32 
crates/gpui/src/elements/mouse_event_handler.rs              |  20 
crates/gpui/src/elements/overlay.rs                          |  10 
crates/gpui/src/elements/resizable.rs                        |  11 
crates/gpui/src/elements/stack.rs                            |  10 
crates/gpui/src/elements/svg.rs                              |   4 
crates/gpui/src/elements/text.rs                             |  10 
crates/gpui/src/elements/tooltip.rs                          |  32 
crates/gpui/src/elements/uniform_list.rs                     |  12 
crates/gpui/src/gpui.rs                                      |   2 
crates/gpui/src/test.rs                                      |   6 
crates/gpui/src/views/select.rs                              |  97 
crates/language_selector/src/active_buffer_language.rs       |   7 
crates/language_selector/src/language_selector.rs            |   4 
crates/outline/src/outline.rs                                |   4 
crates/picker/src/picker.rs                                  |  17 
crates/project_panel/src/project_panel.rs                    |  52 
crates/project_symbols/src/project_symbols.rs                |   9 
crates/recent_projects/src/highlighted_workspace_location.rs |   6 
crates/recent_projects/src/recent_projects.rs                |   6 
crates/search/src/buffer_search.rs                           |  37 
crates/search/src/project_search.rs                          |  49 
crates/settings/src/settings_file.rs                         |   4 
crates/terminal_view/src/terminal_button.rs                  |  23 
crates/terminal_view/src/terminal_element.rs                 |  11 
crates/terminal_view/src/terminal_view.rs                    |  20 
crates/theme/src/ui.rs                                       |  99 
crates/theme_selector/src/theme_selector.rs                  |   6 
crates/theme_testbench/src/theme_testbench.rs                |  69 
crates/welcome/src/base_keymap_picker.rs                     |   6 
crates/welcome/src/welcome.rs                                | 115 
crates/workspace/src/dock.rs                                 |  51 
crates/workspace/src/dock/toggle_dock_button.rs              |   9 
crates/workspace/src/item.rs                                 |  22 
crates/workspace/src/notifications.rs                        |  30 
crates/workspace/src/pane.rs                                 | 428 ++---
crates/workspace/src/pane/dragged_item_receiver.rs           |  10 
crates/workspace/src/pane_group.rs                           |  32 
crates/workspace/src/shared_screen.rs                        |  15 
crates/workspace/src/sidebar.rs                              |  17 
crates/workspace/src/status_bar.rs                           |  20 
crates/workspace/src/toolbar.rs                              |  26 
crates/workspace/src/workspace.rs                            | 114 
93 files changed, 1,561 insertions(+), 1,854 deletions(-)

Detailed changes

crates/activity_indicator/src/activity_indicator.rs 🔗

@@ -315,7 +315,7 @@ impl View for ActivityIndicator {
         "ActivityIndicator"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let Content {
             icon,
             message,
@@ -343,20 +343,18 @@ impl View for ActivityIndicator {
                         .contained()
                         .with_margin_right(style.icon_spacing)
                         .aligned()
-                        .named("activity-icon")
+                        .into_any_named("activity-icon")
                 }))
                 .with_child(
                     Text::new(message, style.message.clone())
                         .with_soft_wrap(false)
-                        .aligned()
-                        .boxed(),
+                        .aligned(),
                 )
                 .constrained()
                 .with_height(style.height)
                 .contained()
                 .with_style(style.container)
                 .aligned()
-                .boxed()
         });
 
         if let Some(action) = action {
@@ -367,7 +365,7 @@ impl View for ActivityIndicator {
                 });
         }
 
-        element.boxed()
+        element.into_any()
     }
 }
 

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},
-    Drawable, Entity, View, ViewContext,
+    Element, 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::Element<Self> {
+    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::AnyElement<Self> {
         let theme = cx.global::<Settings>().theme.clone();
         let theme = &theme.update_notification;
 
@@ -46,8 +46,7 @@ impl View for UpdateNotification {
                             .aligned()
                             .top()
                             .left()
-                            .flex(1., true)
-                            .boxed(),
+                            .flex(1., true),
                         )
                         .with_child(
                             MouseEventHandler::<Cancel, _>::new(0, cx, |state, _| {
@@ -62,7 +61,6 @@ impl View for UpdateNotification {
                                     .constrained()
                                     .with_width(style.button_width)
                                     .with_height(style.button_width)
-                                    .boxed()
                             })
                             .with_padding(Padding::uniform(5.))
                             .on_click(MouseButton::Left, move |_, _, cx| {
@@ -73,26 +71,22 @@ impl View for UpdateNotification {
                             .with_height(cx.font_cache().line_height(theme.message.text.font_size))
                             .aligned()
                             .top()
-                            .flex_float()
-                            .boxed(),
-                        )
-                        .boxed(),
+                            .flex_float(),
+                        ),
                 )
                 .with_child({
                     let style = theme.action_message.style_for(state, false);
                     Text::new("View the release notes", style.text.clone())
                         .contained()
                         .with_style(style.container)
-                        .boxed()
                 })
                 .contained()
-                .boxed()
         })
         .with_cursor_style(CursorStyle::PointingHand)
         .on_click(MouseButton::Left, |_, _, cx| {
             cx.dispatch_action(ViewReleaseNotes)
         })
-        .boxed()
+        .into_any_named("update notification")
     }
 }
 

crates/breadcrumbs/src/breadcrumbs.rs 🔗

@@ -41,10 +41,10 @@ impl View for Breadcrumbs {
         "Breadcrumbs"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let active_item = match &self.active_item {
             Some(active_item) => active_item,
-            None => return Empty::new().boxed(),
+            None => return Empty::new().into_any(),
         };
         let not_editor = active_item.downcast::<editor::Editor>().is_none();
 
@@ -53,24 +53,21 @@ impl View for Breadcrumbs {
 
         let breadcrumbs = match active_item.breadcrumbs(&theme, cx) {
             Some(breadcrumbs) => breadcrumbs,
-            None => return Empty::new().boxed(),
+            None => return Empty::new().into_any(),
         }
         .into_iter()
         .map(|breadcrumb| {
-            let text = Text::new(
+            Text::new(
                 breadcrumb.text,
                 theme.workspace.breadcrumbs.default.text.clone(),
-            );
-            if let Some(highlights) = breadcrumb.highlights {
-                text.with_highlights(highlights).boxed()
-            } else {
-                text.boxed()
-            }
+            )
+            .with_highlights(breadcrumb.highlights.unwrap_or_default())
+            .into_any()
         });
 
         let crumbs = Flex::row()
             .with_children(Itertools::intersperse_with(breadcrumbs, || {
-                Label::new(" 〉 ", style.default.text.clone()).boxed()
+                Label::new(" 〉 ", style.default.text.clone()).into_any()
             }))
             .constrained()
             .with_height(theme.workspace.breadcrumb_height)
@@ -81,12 +78,12 @@ impl View for Breadcrumbs {
                 .with_style(style.default.container)
                 .aligned()
                 .left()
-                .boxed();
+                .into_any();
         }
 
         MouseEventHandler::<Breadcrumbs, Breadcrumbs>::new(0, cx, |state, _| {
             let style = style.style_for(state, false);
-            crumbs.with_style(style.container).boxed()
+            crumbs.with_style(style.container)
         })
         .on_click(MouseButton::Left, |_, _, cx| {
             cx.dispatch_action(outline::Toggle);
@@ -100,7 +97,7 @@ impl View for Breadcrumbs {
         )
         .aligned()
         .left()
-        .boxed()
+        .into_any()
     }
 }
 

crates/collab_ui/src/collab_titlebar_item.rs 🔗

@@ -68,11 +68,11 @@ impl View for CollabTitlebarItem {
         "CollabTitlebarItem"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let workspace = if let Some(workspace) = self.workspace.upgrade(cx) {
             workspace
         } else {
-            return Empty::new().boxed();
+            return Empty::new().into_any();
         };
 
         let project = workspace.read(cx).project().read(cx);
@@ -97,8 +97,7 @@ impl View for CollabTitlebarItem {
                 .contained()
                 .with_margin_right(theme.workspace.titlebar.item_spacing)
                 .aligned()
-                .left()
-                .boxed(),
+                .left(),
         );
 
         let user = workspace.read(cx).user_store().read(cx).current_user();
@@ -128,9 +127,9 @@ impl View for CollabTitlebarItem {
         }
 
         Stack::new()
-            .with_child(left_container.boxed())
-            .with_child(right_container.aligned().right().boxed())
-            .boxed()
+            .with_child(left_container)
+            .with_child(right_container.aligned().right())
+            .into_any()
     }
 }
 
@@ -294,13 +293,13 @@ impl CollabTitlebarItem {
                                     Color::transparent_black(),
                                 )
                             }))
-                            .with_child(
-                                Label::new(user.github_login.clone(), item_style.label.clone())
-                                    .boxed(),
-                            )
+                            .with_child(Label::new(
+                                user.github_login.clone(),
+                                item_style.label.clone(),
+                            ))
                             .contained()
                             .with_style(item_style.container)
-                            .boxed()
+                            .into_any()
                     })),
                     ContextMenuItem::item("Sign out", SignOut),
                     ContextMenuItem::item("Send Feedback", feedback::feedback_editor::GiveFeedback),
@@ -326,7 +325,7 @@ impl CollabTitlebarItem {
         &self,
         theme: &Theme,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         let titlebar = &theme.workspace.titlebar;
 
         let badge = if self
@@ -345,8 +344,7 @@ impl CollabTitlebarItem {
                     .contained()
                     .with_margin_left(titlebar.toggle_contacts_button.default.icon_width)
                     .with_margin_top(titlebar.toggle_contacts_button.default.icon_width)
-                    .aligned()
-                    .boxed(),
+                    .aligned(),
             )
         };
 
@@ -366,7 +364,6 @@ impl CollabTitlebarItem {
                         .with_height(style.button_width)
                         .contained()
                         .with_style(style.container)
-                        .boxed()
                 })
                 .with_cursor_style(CursorStyle::PointingHand)
                 .on_click(MouseButton::Left, move |_, _, cx| {
@@ -378,12 +375,11 @@ impl CollabTitlebarItem {
                     Some(Box::new(ToggleContactsMenu)),
                     theme.tooltip.clone(),
                     cx,
-                )
-                .boxed(),
+                ),
             )
             .with_children(badge)
             .with_children(self.render_contacts_popover_host(titlebar, cx))
-            .boxed()
+            .into_any()
     }
 
     fn render_toggle_screen_sharing_button(
@@ -391,7 +387,7 @@ impl CollabTitlebarItem {
         theme: &Theme,
         room: &ModelHandle<Room>,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         let icon;
         let tooltip;
         if room.read(cx).is_screen_sharing() {
@@ -415,7 +411,6 @@ impl CollabTitlebarItem {
                 .with_height(style.button_width)
                 .contained()
                 .with_style(style.container)
-                .boxed()
         })
         .with_cursor_style(CursorStyle::PointingHand)
         .on_click(MouseButton::Left, move |_, _, cx| {
@@ -429,7 +424,7 @@ impl CollabTitlebarItem {
             cx,
         )
         .aligned()
-        .boxed()
+        .into_any()
     }
 
     fn render_in_call_share_unshare_button(
@@ -437,7 +432,7 @@ impl CollabTitlebarItem {
         workspace: &ViewHandle<Workspace>,
         theme: &Theme,
         cx: &mut ViewContext<Self>,
-    ) -> Option<Element<Self>> {
+    ) -> Option<AnyElement<Self>> {
         let project = workspace.read(cx).project();
         if project.read(cx).is_remote() {
             return None;
@@ -463,7 +458,6 @@ impl CollabTitlebarItem {
                         Label::new(label, style.text.clone())
                             .contained()
                             .with_style(style.container)
-                            .boxed()
                     })
                     .with_cursor_style(CursorStyle::PointingHand)
                     .on_click(MouseButton::Left, move |_, _, cx| {
@@ -479,17 +473,20 @@ impl CollabTitlebarItem {
                         None,
                         theme.tooltip.clone(),
                         cx,
-                    )
-                    .boxed(),
+                    ),
                 )
                 .aligned()
                 .contained()
                 .with_margin_left(theme.workspace.titlebar.item_spacing)
-                .boxed(),
+                .into_any(),
         )
     }
 
-    fn render_user_menu_button(&self, theme: &Theme, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render_user_menu_button(
+        &self,
+        theme: &Theme,
+        cx: &mut ViewContext<Self>,
+    ) -> AnyElement<Self> {
         let titlebar = &theme.workspace.titlebar;
 
         Stack::new()
@@ -506,7 +503,6 @@ impl CollabTitlebarItem {
                         .with_height(style.button_width)
                         .contained()
                         .with_style(style.container)
-                        .boxed()
                 })
                 .with_cursor_style(CursorStyle::PointingHand)
                 .on_click(MouseButton::Left, move |_, _, cx| {
@@ -520,49 +516,46 @@ impl CollabTitlebarItem {
                     cx,
                 )
                 .contained()
-                .with_margin_left(theme.workspace.titlebar.item_spacing)
-                .boxed(),
+                .with_margin_left(theme.workspace.titlebar.item_spacing),
             )
             .with_child(
                 ChildView::new(&self.user_menu, cx)
                     .aligned()
                     .bottom()
-                    .right()
-                    .boxed(),
+                    .right(),
             )
-            .boxed()
+            .into_any()
     }
 
-    fn render_sign_in_button(&self, theme: &Theme, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render_sign_in_button(&self, theme: &Theme, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let titlebar = &theme.workspace.titlebar;
         MouseEventHandler::<SignIn, Self>::new(0, cx, |state, _| {
             let style = titlebar.sign_in_prompt.style_for(state, false);
             Label::new("Sign In", style.text.clone())
                 .contained()
                 .with_style(style.container)
-                .boxed()
         })
         .with_cursor_style(CursorStyle::PointingHand)
         .on_click(MouseButton::Left, move |_, _, cx| {
             cx.dispatch_action(SignIn);
         })
-        .boxed()
+        .into_any()
     }
 
     fn render_contacts_popover_host<'a>(
         &'a self,
         _theme: &'a theme::Titlebar,
         cx: &'a ViewContext<Self>,
-    ) -> Option<Element<Self>> {
+    ) -> Option<AnyElement<Self>> {
         self.contacts_popover.as_ref().map(|popover| {
-            Overlay::new(ChildView::new(popover, cx).boxed())
+            Overlay::new(ChildView::new(popover, cx))
                 .with_fit_mode(OverlayFitMode::SwitchAnchor)
                 .with_anchor_corner(AnchorCorner::TopRight)
                 .with_z_index(999)
                 .aligned()
                 .bottom()
                 .right()
-                .boxed()
+                .into_any()
         })
     }
 
@@ -572,7 +565,7 @@ impl CollabTitlebarItem {
         theme: &Theme,
         room: &ModelHandle<Room>,
         cx: &mut ViewContext<Self>,
-    ) -> Vec<Element<Self>> {
+    ) -> Vec<Container<Self>> {
         let mut participants = room
             .read(cx)
             .remote_participants()
@@ -600,8 +593,7 @@ impl CollabTitlebarItem {
                         theme,
                         cx,
                     ))
-                    .with_margin_right(theme.workspace.titlebar.face_pile_spacing)
-                    .boxed(),
+                    .with_margin_right(theme.workspace.titlebar.face_pile_spacing),
                 )
             })
             .collect()
@@ -614,7 +606,7 @@ impl CollabTitlebarItem {
         user: &Arc<User>,
         peer_id: PeerId,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         let replica_id = workspace.read(cx).project().read(cx).replica_id();
         Container::new(self.render_face_pile(
             user,
@@ -626,7 +618,7 @@ impl CollabTitlebarItem {
             cx,
         ))
         .with_margin_right(theme.workspace.titlebar.item_spacing)
-        .boxed()
+        .into_any()
     }
 
     fn render_face_pile(
@@ -638,7 +630,7 @@ impl CollabTitlebarItem {
         workspace: &ViewHandle<Workspace>,
         theme: &Theme,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<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);
@@ -730,7 +722,7 @@ impl CollabTitlebarItem {
                     }
                 }
 
-                container.boxed()
+                container
             }))
             .with_children((|| {
                 let replica_id = replica_id?;
@@ -741,11 +733,10 @@ impl CollabTitlebarItem {
                         .with_width(theme.workspace.titlebar.avatar_ribbon.width)
                         .with_height(theme.workspace.titlebar.avatar_ribbon.height)
                         .aligned()
-                        .bottom()
-                        .boxed(),
+                        .bottom(),
                 )
             })())
-            .boxed();
+            .into_any();
 
         if let Some(location) = location {
             if let Some(replica_id) = replica_id {
@@ -769,7 +760,7 @@ impl CollabTitlebarItem {
                     theme.tooltip.clone(),
                     cx,
                 )
-                .boxed();
+                .into_any();
             } else if let ParticipantLocation::SharedProject { project_id } = location {
                 let user_id = user.id;
                 content = MouseEventHandler::<JoinProject, Self>::new(
@@ -791,7 +782,7 @@ impl CollabTitlebarItem {
                     theme.tooltip.clone(),
                     cx,
                 )
-                .boxed();
+                .into_any();
             }
         }
         content
@@ -820,7 +811,7 @@ impl CollabTitlebarItem {
         avatar: Arc<ImageData>,
         avatar_style: AvatarStyle,
         background_color: Color,
-    ) -> Element<V> {
+    ) -> AnyElement<V> {
         Image::from_data(avatar)
             .with_style(avatar_style.image)
             .aligned()
@@ -831,14 +822,14 @@ impl CollabTitlebarItem {
             .with_width(avatar_style.outer_width)
             .with_height(avatar_style.outer_width)
             .aligned()
-            .boxed()
+            .into_any()
     }
 
     fn render_connection_status(
         &self,
         status: &client::Status,
         cx: &mut ViewContext<Self>,
-    ) -> Option<Element<Self>> {
+    ) -> Option<AnyElement<Self>> {
         enum ConnectionStatusButton {}
 
         let theme = &cx.global::<Settings>().theme.clone();
@@ -848,20 +839,14 @@ impl CollabTitlebarItem {
             | client::Status::Reauthenticating { .. }
             | client::Status::Reconnecting { .. }
             | client::Status::ReconnectionError { .. } => Some(
-                Container::new(
-                    Align::new(
-                        ConstrainedBox::new(
-                            Svg::new("icons/cloud_slash_12.svg")
-                                .with_color(theme.workspace.titlebar.offline_icon.color)
-                                .boxed(),
-                        )
-                        .with_width(theme.workspace.titlebar.offline_icon.width)
-                        .boxed(),
-                    )
-                    .boxed(),
-                )
-                .with_style(theme.workspace.titlebar.offline_icon.container)
-                .boxed(),
+                Svg::new("icons/cloud_slash_12.svg")
+                    .with_color(theme.workspace.titlebar.offline_icon.color)
+                    .constrained()
+                    .with_width(theme.workspace.titlebar.offline_icon.width)
+                    .aligned()
+                    .contained()
+                    .with_style(theme.workspace.titlebar.offline_icon.container)
+                    .into_any(),
             ),
             client::Status::UpgradeRequired => Some(
                 MouseEventHandler::<ConnectionStatusButton, Self>::new(0, cx, |_, _| {
@@ -872,13 +857,12 @@ impl CollabTitlebarItem {
                     .contained()
                     .with_style(theme.workspace.titlebar.outdated_warning.container)
                     .aligned()
-                    .boxed()
                 })
                 .with_cursor_style(CursorStyle::PointingHand)
                 .on_click(MouseButton::Left, |_, _, cx| {
                     cx.dispatch_action(auto_update::Check);
                 })
-                .boxed(),
+                .into_any(),
             ),
             _ => None,
         }
@@ -895,7 +879,7 @@ impl AvatarRibbon {
     }
 }
 
-impl Drawable<CollabTitlebarItem> for AvatarRibbon {
+impl Element<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>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let theme = cx.global::<Settings>().theme.clone();
 
         MouseEventHandler::<Self, Self>::new(0, cx, |_, _| {
@@ -40,12 +40,11 @@ impl View for CollaboratorListPopover {
                 .constrained()
                 .with_width(theme.contacts_popover.width)
                 .with_height(theme.contacts_popover.height)
-                .boxed()
         })
         .on_down_out(MouseButton::Left, move |_, _, cx| {
             cx.dispatch_action(ToggleCollaboratorList);
         })
-        .boxed()
+        .into_any()
     }
 
     fn focus_out(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
@@ -117,7 +116,7 @@ fn render_collaborator_list_entry<UA: Action + Clone, IA: Action + Clone>(
     icon_action: IA,
     icon_tooltip: String,
     cx: &mut ViewContext<CollaboratorListPopover>,
-) -> Element<CollaboratorListPopover> {
+) -> AnyElement<CollaboratorListPopover> {
     enum Username {}
     enum UsernameTooltip {}
     enum Icon {}
@@ -129,7 +128,7 @@ fn render_collaborator_list_entry<UA: Action + Clone, IA: Action + Clone>(
 
     let username =
         MouseEventHandler::<Username, CollaboratorListPopover>::new(index, cx, |_, _| {
-            Label::new(username.to_owned(), username_theme.clone()).boxed()
+            Label::new(username.to_owned(), username_theme.clone())
         })
         .on_click(MouseButton::Left, move |_, _, cx| {
             if let Some(username_action) = username_action.clone() {
@@ -147,17 +146,16 @@ fn render_collaborator_list_entry<UA: Action + Clone, IA: Action + Clone>(
                     tooltip_theme.clone(),
                     cx,
                 )
-                .boxed()
+                .into_any()
         } else {
-            username.boxed()
+            username.into_any()
         })
         .with_child(
-            MouseEventHandler::<Icon, CollaboratorListPopover>::new(index, cx, |_, _| icon.boxed())
+            MouseEventHandler::<Icon, CollaboratorListPopover>::new(index, cx, |_, _| icon)
                 .on_click(MouseButton::Left, move |_, _, cx| {
                     cx.dispatch_action(icon_action.clone())
                 })
-                .with_tooltip::<IconTooltip>(index, icon_tooltip, None, tooltip_theme, cx)
-                .boxed(),
+                .with_tooltip::<IconTooltip>(index, icon_tooltip, None, tooltip_theme, cx),
         )
-        .boxed()
+        .into_any()
 }

crates/collab_ui/src/contact_finder.rs 🔗

@@ -96,7 +96,7 @@ impl PickerDelegate for ContactFinderDelegate {
         mouse_state: &mut MouseState,
         selected: bool,
         cx: &gpui::AppContext,
-    ) -> Element<Picker<Self>> {
+    ) -> AnyElement<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);
@@ -124,15 +124,13 @@ impl PickerDelegate for ContactFinderDelegate {
                     .with_style(theme.contact_finder.contact_avatar)
                     .aligned()
                     .left()
-                    .boxed()
             }))
             .with_child(
                 Label::new(user.github_login.clone(), style.label.clone())
                     .contained()
                     .with_style(theme.contact_finder.contact_username)
                     .aligned()
-                    .left()
-                    .boxed(),
+                    .left(),
             )
             .with_children(icon_path.map(|icon_path| {
                 Svg::new(icon_path)
@@ -147,12 +145,11 @@ impl PickerDelegate for ContactFinderDelegate {
                     .with_height(button_style.button_width)
                     .aligned()
                     .flex_float()
-                    .boxed()
             }))
             .contained()
             .with_style(style.container)
             .constrained()
             .with_height(theme.contact_finder.row_height)
-            .boxed()
+            .into_any()
     }
 }

crates/collab_ui/src/contact_list.rs 🔗

@@ -748,14 +748,13 @@ impl ContactList {
         is_pending: bool,
         is_selected: bool,
         theme: &theme::ContactList,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         Flex::row()
             .with_children(user.avatar.clone().map(|avatar| {
                 Image::from_data(avatar)
                     .with_style(theme.contact_avatar)
                     .aligned()
                     .left()
-                    .boxed()
             }))
             .with_child(
                 Label::new(
@@ -766,16 +765,14 @@ impl ContactList {
                 .with_style(theme.contact_username.container)
                 .aligned()
                 .left()
-                .flex(1., true)
-                .boxed(),
+                .flex(1., true),
             )
             .with_children(if is_pending {
                 Some(
                     Label::new("Calling", theme.calling_indicator.text.clone())
                         .contained()
                         .with_style(theme.calling_indicator.container)
-                        .aligned()
-                        .boxed(),
+                        .aligned(),
                 )
             } else {
                 None
@@ -788,7 +785,7 @@ impl ContactList {
                     .contact_row
                     .style_for(&mut Default::default(), is_selected),
             )
-            .boxed()
+            .into_any()
     }
 
     fn render_participant_project(
@@ -800,7 +797,7 @@ impl ContactList {
         is_selected: bool,
         theme: &theme::ContactList,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         let font_cache = cx.font_cache();
         let host_avatar_height = theme
             .contact_avatar
@@ -826,41 +823,37 @@ impl ContactList {
             Flex::row()
                 .with_child(
                     Stack::new()
-                        .with_child(
-                            Canvas::new(move |scene, bounds, _, _, _| {
-                                let start_x = bounds.min_x() + (bounds.width() / 2.)
-                                    - (tree_branch.width / 2.);
-                                let end_x = bounds.max_x();
-                                let start_y = bounds.min_y();
-                                let end_y = bounds.min_y() + baseline_offset - (cap_height / 2.);
-
-                                scene.push_quad(gpui::Quad {
-                                    bounds: RectF::from_points(
-                                        vec2f(start_x, start_y),
-                                        vec2f(
-                                            start_x + tree_branch.width,
-                                            if is_last { end_y } else { bounds.max_y() },
-                                        ),
-                                    ),
-                                    background: Some(tree_branch.color),
-                                    border: gpui::Border::default(),
-                                    corner_radius: 0.,
-                                });
-                                scene.push_quad(gpui::Quad {
-                                    bounds: RectF::from_points(
-                                        vec2f(start_x, end_y),
-                                        vec2f(end_x, end_y + tree_branch.width),
+                        .with_child(Canvas::new(move |scene, bounds, _, _, _| {
+                            let start_x =
+                                bounds.min_x() + (bounds.width() / 2.) - (tree_branch.width / 2.);
+                            let end_x = bounds.max_x();
+                            let start_y = bounds.min_y();
+                            let end_y = bounds.min_y() + baseline_offset - (cap_height / 2.);
+
+                            scene.push_quad(gpui::Quad {
+                                bounds: RectF::from_points(
+                                    vec2f(start_x, start_y),
+                                    vec2f(
+                                        start_x + tree_branch.width,
+                                        if is_last { end_y } else { bounds.max_y() },
                                     ),
-                                    background: Some(tree_branch.color),
-                                    border: gpui::Border::default(),
-                                    corner_radius: 0.,
-                                });
-                            })
-                            .boxed(),
-                        )
+                                ),
+                                background: Some(tree_branch.color),
+                                border: gpui::Border::default(),
+                                corner_radius: 0.,
+                            });
+                            scene.push_quad(gpui::Quad {
+                                bounds: RectF::from_points(
+                                    vec2f(start_x, end_y),
+                                    vec2f(end_x, end_y + tree_branch.width),
+                                ),
+                                background: Some(tree_branch.color),
+                                border: gpui::Border::default(),
+                                corner_radius: 0.,
+                            });
+                        }))
                         .constrained()
-                        .with_width(host_avatar_height)
-                        .boxed(),
+                        .with_width(host_avatar_height),
                 )
                 .with_child(
                     Label::new(project_name, row.name.text.clone())
@@ -868,14 +861,12 @@ impl ContactList {
                         .left()
                         .contained()
                         .with_style(row.name.container)
-                        .flex(1., false)
-                        .boxed(),
+                        .flex(1., false),
                 )
                 .constrained()
                 .with_height(theme.row_height)
                 .contained()
                 .with_style(row.container)
-                .boxed()
         })
         .with_cursor_style(if !is_current {
             CursorStyle::PointingHand
@@ -890,7 +881,7 @@ impl ContactList {
                 });
             }
         })
-        .boxed()
+        .into_any()
     }
 
     fn render_participant_screen(
@@ -899,7 +890,7 @@ impl ContactList {
         is_selected: bool,
         theme: &theme::ContactList,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         let font_cache = cx.font_cache();
         let host_avatar_height = theme
             .contact_avatar
@@ -923,42 +914,37 @@ impl ContactList {
                 Flex::row()
                     .with_child(
                         Stack::new()
-                            .with_child(
-                                Canvas::new(move |scene, bounds, _, _, _| {
-                                    let start_x = bounds.min_x() + (bounds.width() / 2.)
-                                        - (tree_branch.width / 2.);
-                                    let end_x = bounds.max_x();
-                                    let start_y = bounds.min_y();
-                                    let end_y =
-                                        bounds.min_y() + baseline_offset - (cap_height / 2.);
-
-                                    scene.push_quad(gpui::Quad {
-                                        bounds: RectF::from_points(
-                                            vec2f(start_x, start_y),
-                                            vec2f(
-                                                start_x + tree_branch.width,
-                                                if is_last { end_y } else { bounds.max_y() },
-                                            ),
-                                        ),
-                                        background: Some(tree_branch.color),
-                                        border: gpui::Border::default(),
-                                        corner_radius: 0.,
-                                    });
-                                    scene.push_quad(gpui::Quad {
-                                        bounds: RectF::from_points(
-                                            vec2f(start_x, end_y),
-                                            vec2f(end_x, end_y + tree_branch.width),
+                            .with_child(Canvas::new(move |scene, bounds, _, _, _| {
+                                let start_x = bounds.min_x() + (bounds.width() / 2.)
+                                    - (tree_branch.width / 2.);
+                                let end_x = bounds.max_x();
+                                let start_y = bounds.min_y();
+                                let end_y = bounds.min_y() + baseline_offset - (cap_height / 2.);
+
+                                scene.push_quad(gpui::Quad {
+                                    bounds: RectF::from_points(
+                                        vec2f(start_x, start_y),
+                                        vec2f(
+                                            start_x + tree_branch.width,
+                                            if is_last { end_y } else { bounds.max_y() },
                                         ),
-                                        background: Some(tree_branch.color),
-                                        border: gpui::Border::default(),
-                                        corner_radius: 0.,
-                                    });
-                                })
-                                .boxed(),
-                            )
+                                    ),
+                                    background: Some(tree_branch.color),
+                                    border: gpui::Border::default(),
+                                    corner_radius: 0.,
+                                });
+                                scene.push_quad(gpui::Quad {
+                                    bounds: RectF::from_points(
+                                        vec2f(start_x, end_y),
+                                        vec2f(end_x, end_y + tree_branch.width),
+                                    ),
+                                    background: Some(tree_branch.color),
+                                    border: gpui::Border::default(),
+                                    corner_radius: 0.,
+                                });
+                            }))
                             .constrained()
-                            .with_width(host_avatar_height)
-                            .boxed(),
+                            .with_width(host_avatar_height),
                     )
                     .with_child(
                         Svg::new("icons/disable_screen_sharing_12.svg")
@@ -968,8 +954,7 @@ impl ContactList {
                             .aligned()
                             .left()
                             .contained()
-                            .with_style(row.icon.container)
-                            .boxed(),
+                            .with_style(row.icon.container),
                     )
                     .with_child(
                         Label::new("Screen", row.name.text.clone())
@@ -977,21 +962,19 @@ impl ContactList {
                             .left()
                             .contained()
                             .with_style(row.name.container)
-                            .flex(1., false)
-                            .boxed(),
+                            .flex(1., false),
                     )
                     .constrained()
                     .with_height(theme.row_height)
                     .contained()
                     .with_style(row.container)
-                    .boxed()
             },
         )
         .with_cursor_style(CursorStyle::PointingHand)
         .on_click(MouseButton::Left, move |_, _, cx| {
             cx.dispatch_action(OpenSharedScreen { peer_id });
         })
-        .boxed()
+        .into_any()
     }
 
     fn render_header(
@@ -1000,7 +983,7 @@ impl ContactList {
         is_selected: bool,
         is_collapsed: bool,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         enum Header {}
         enum LeaveCallContactList {}
 
@@ -1020,11 +1003,9 @@ impl ContactList {
                     Label::new("Leave Call", style.text.clone())
                         .contained()
                         .with_style(style.container)
-                        .boxed()
                 })
                 .on_click(MouseButton::Left, |_, _, cx| cx.dispatch_action(LeaveCall))
-                .aligned()
-                .boxed(),
+                .aligned(),
             )
         } else {
             None
@@ -1045,8 +1026,7 @@ impl ContactList {
                     .with_max_height(icon_size)
                     .aligned()
                     .constrained()
-                    .with_width(icon_size)
-                    .boxed(),
+                    .with_width(icon_size),
                 )
                 .with_child(
                     Label::new(text, header_style.text.clone())
@@ -1054,21 +1034,19 @@ impl ContactList {
                         .left()
                         .contained()
                         .with_margin_left(theme.contact_username.container.margin.left)
-                        .flex(1., true)
-                        .boxed(),
+                        .flex(1., true),
                 )
                 .with_children(leave_call)
                 .constrained()
                 .with_height(theme.row_height)
                 .contained()
                 .with_style(header_style.container)
-                .boxed()
         })
         .with_cursor_style(CursorStyle::PointingHand)
         .on_click(MouseButton::Left, move |_, _, cx| {
             cx.dispatch_action(ToggleExpanded(section))
         })
-        .boxed()
+        .into_any()
     }
 
     fn render_contact(
@@ -1078,13 +1056,13 @@ impl ContactList {
         theme: &theme::ContactList,
         is_selected: bool,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         let online = contact.online;
         let busy = contact.busy || calling;
         let user_id = contact.user.id;
         let github_login = contact.user.github_login.clone();
         let initial_project = project.clone();
-        let mut element =
+        let mut event_handler =
             MouseEventHandler::<Contact, Self>::new(contact.user.id as usize, cx, |_, cx| {
                 Flex::row()
                     .with_children(contact.user.avatar.clone().map(|avatar| {
@@ -1098,8 +1076,7 @@ impl ContactList {
                                     } else {
                                         theme.contact_status_free
                                     })
-                                    .aligned()
-                                    .boxed(),
+                                    .aligned(),
                             )
                         } else {
                             None
@@ -1109,11 +1086,9 @@ impl ContactList {
                                 Image::from_data(avatar)
                                     .with_style(theme.contact_avatar)
                                     .aligned()
-                                    .left()
-                                    .boxed(),
+                                    .left(),
                             )
                             .with_children(status_badge)
-                            .boxed()
                     }))
                     .with_child(
                         Label::new(
@@ -1124,8 +1099,7 @@ impl ContactList {
                         .with_style(theme.contact_username.container)
                         .aligned()
                         .left()
-                        .flex(1., true)
-                        .boxed(),
+                        .flex(1., true),
                     )
                     .with_child(
                         MouseEventHandler::<Cancel, Self>::new(
@@ -1137,7 +1111,6 @@ impl ContactList {
                                 render_icon_button(button_style, "icons/x_mark_8.svg")
                                     .aligned()
                                     .flex_float()
-                                    .boxed()
                             },
                         )
                         .with_padding(Padding::uniform(2.))
@@ -1148,16 +1121,14 @@ impl ContactList {
                                 github_login: github_login.clone(),
                             })
                         })
-                        .flex_float()
-                        .boxed(),
+                        .flex_float(),
                     )
                     .with_children(if calling {
                         Some(
                             Label::new("Calling", theme.calling_indicator.text.clone())
                                 .contained()
                                 .with_style(theme.calling_indicator.container)
-                                .aligned()
-                                .boxed(),
+                                .aligned(),
                         )
                     } else {
                         None
@@ -1170,7 +1141,6 @@ impl ContactList {
                             .contact_row
                             .style_for(&mut Default::default(), is_selected),
                     )
-                    .boxed()
             })
             .on_click(MouseButton::Left, move |_, _, cx| {
                 if online && !busy {
@@ -1182,10 +1152,10 @@ impl ContactList {
             });
 
         if online {
-            element = element.with_cursor_style(CursorStyle::PointingHand);
+            event_handler = event_handler.with_cursor_style(CursorStyle::PointingHand);
         }
 
-        element.boxed()
+        event_handler.into_any()
     }
 
     fn render_contact_request(
@@ -1195,7 +1165,7 @@ impl ContactList {
         is_incoming: bool,
         is_selected: bool,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         enum Decline {}
         enum Accept {}
         enum Cancel {}
@@ -1206,7 +1176,6 @@ impl ContactList {
                     .with_style(theme.contact_avatar)
                     .aligned()
                     .left()
-                    .boxed()
             }))
             .with_child(
                 Label::new(
@@ -1217,8 +1186,7 @@ impl ContactList {
                 .with_style(theme.contact_username.container)
                 .aligned()
                 .left()
-                .flex(1., true)
-                .boxed(),
+                .flex(1., true),
             );
 
         let user_id = user.id;
@@ -1227,16 +1195,14 @@ impl ContactList {
         let button_spacing = theme.contact_button_spacing;
 
         if is_incoming {
-            row.add_children([
+            row.add_child(
                 MouseEventHandler::<Decline, Self>::new(user.id as usize, cx, |mouse_state, _| {
                     let button_style = if is_contact_request_pending {
                         &theme.disabled_button
                     } else {
                         theme.contact_button.style_for(mouse_state, false)
                     };
-                    render_icon_button(button_style, "icons/x_mark_8.svg")
-                        .aligned()
-                        .boxed()
+                    render_icon_button(button_style, "icons/x_mark_8.svg").aligned()
                 })
                 .with_cursor_style(CursorStyle::PointingHand)
                 .on_click(MouseButton::Left, move |_, _, cx| {
@@ -1246,8 +1212,10 @@ impl ContactList {
                     })
                 })
                 .contained()
-                .with_margin_right(button_spacing)
-                .boxed(),
+                .with_margin_right(button_spacing),
+            );
+
+            row.add_child(
                 MouseEventHandler::<Accept, Self>::new(user.id as usize, cx, |mouse_state, _| {
                     let button_style = if is_contact_request_pending {
                         &theme.disabled_button
@@ -1257,7 +1225,6 @@ impl ContactList {
                     render_icon_button(button_style, "icons/check_8.svg")
                         .aligned()
                         .flex_float()
-                        .boxed()
                 })
                 .with_cursor_style(CursorStyle::PointingHand)
                 .on_click(MouseButton::Left, move |_, _, cx| {
@@ -1265,9 +1232,8 @@ impl ContactList {
                         user_id,
                         accept: true,
                     })
-                })
-                .boxed(),
-            ]);
+                }),
+            );
         } else {
             row.add_child(
                 MouseEventHandler::<Cancel, Self>::new(user.id as usize, cx, |mouse_state, _| {
@@ -1279,7 +1245,6 @@ impl ContactList {
                     render_icon_button(button_style, "icons/x_mark_8.svg")
                         .aligned()
                         .flex_float()
-                        .boxed()
                 })
                 .with_padding(Padding::uniform(2.))
                 .with_cursor_style(CursorStyle::PointingHand)
@@ -1289,8 +1254,7 @@ impl ContactList {
                         github_login: github_login.clone(),
                     })
                 })
-                .flex_float()
-                .boxed(),
+                .flex_float(),
             );
         }
 
@@ -1302,7 +1266,7 @@ impl ContactList {
                     .contact_row
                     .style_for(&mut Default::default(), is_selected),
             )
-            .boxed()
+            .into_any()
     }
 
     fn call(&mut self, action: &Call, cx: &mut ViewContext<Self>) {
@@ -1331,7 +1295,7 @@ impl View for ContactList {
         cx
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         enum AddContact {}
         let theme = cx.global::<Settings>().theme.clone();
 
@@ -1342,8 +1306,7 @@ impl View for ContactList {
                         ChildView::new(&self.filter_editor, cx)
                             .contained()
                             .with_style(theme.contact_list.user_query_editor.container)
-                            .flex(1., true)
-                            .boxed(),
+                            .flex(1., true),
                     )
                     .with_child(
                         MouseEventHandler::<AddContact, Self>::new(0, cx, |_, _| {
@@ -1351,7 +1314,6 @@ impl View for ContactList {
                                 &theme.contact_list.add_contact_button,
                                 "icons/user_plus_16.svg",
                             )
-                            .boxed()
                         })
                         .with_cursor_style(CursorStyle::PointingHand)
                         .on_click(MouseButton::Left, |_, _, cx| {
@@ -1363,15 +1325,13 @@ impl View for ContactList {
                             None,
                             theme.tooltip.clone(),
                             cx,
-                        )
-                        .boxed(),
+                        ),
                     )
                     .constrained()
-                    .with_height(theme.contact_list.user_query_editor_height)
-                    .boxed(),
+                    .with_height(theme.contact_list.user_query_editor_height),
             )
-            .with_child(List::new(self.list_state.clone()).flex(1., false).boxed())
-            .boxed()
+            .with_child(List::new(self.list_state.clone()).flex(1., false))
+            .into_any()
     }
 
     fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
@@ -1387,7 +1347,7 @@ impl View for ContactList {
     }
 }
 
-fn render_icon_button(style: &IconButton, svg_path: &'static str) -> impl Drawable<ContactList> {
+fn render_icon_button(style: &IconButton, svg_path: &'static str) -> impl Element<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>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         match self.kind {
             ContactEventKind::Requested => render_user_notification(
                 self.user.clone(),

crates/collab_ui/src/contacts_popover.rs 🔗

@@ -96,7 +96,7 @@ impl View for ContactsPopover {
         "ContactsPopover"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let theme = cx.global::<Settings>().theme.clone();
         let child = match &self.child {
             Child::ContactList(child) => ChildView::new(child, cx),
@@ -105,18 +105,17 @@ impl View for ContactsPopover {
 
         MouseEventHandler::<ContactsPopover, Self>::new(0, cx, |_, _| {
             Flex::column()
-                .with_child(child.flex(1., true).boxed())
+                .with_child(child.flex(1., true))
                 .contained()
                 .with_style(theme.contacts_popover.container)
                 .constrained()
                 .with_width(theme.contacts_popover.width)
                 .with_height(theme.contacts_popover.height)
-                .boxed()
         })
         .on_down_out(MouseButton::Left, move |_, _, cx| {
             cx.dispatch_action(ToggleContactsMenu);
         })
-        .boxed()
+        .into_any()
     }
 
     fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {

crates/collab_ui/src/face_pile.rs 🔗

@@ -7,14 +7,14 @@ use gpui::{
     },
     json::ToJson,
     serde_json::{self, json},
-    Axis, Drawable, Element, SceneBuilder, ViewContext,
+    AnyElement, Axis, Element, SceneBuilder, ViewContext,
 };
 
 use crate::CollabTitlebarItem;
 
 pub(crate) struct FacePile {
     overlap: f32,
-    faces: Vec<Element<CollabTitlebarItem>>,
+    faces: Vec<AnyElement<CollabTitlebarItem>>,
 }
 
 impl FacePile {
@@ -26,7 +26,7 @@ impl FacePile {
     }
 }
 
-impl Drawable<CollabTitlebarItem> for FacePile {
+impl Element<CollabTitlebarItem> for FacePile {
     type LayoutState = ();
     type PaintState = ();
 
@@ -101,8 +101,8 @@ impl Drawable<CollabTitlebarItem> for FacePile {
     }
 }
 
-impl Extend<Element<CollabTitlebarItem>> for FacePile {
-    fn extend<T: IntoIterator<Item = Element<CollabTitlebarItem>>>(&mut self, children: T) {
+impl Extend<AnyElement<CollabTitlebarItem>> for FacePile {
+    fn extend<T: IntoIterator<Item = AnyElement<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, Element, Entity, View, ViewContext,
+    AnyElement, AppContext, Entity, View, ViewContext,
 };
 use settings::Settings;
 use util::ResultExt;
@@ -99,7 +99,7 @@ impl IncomingCallNotification {
         }
     }
 
-    fn render_caller(&self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render_caller(&self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let theme = &cx.global::<Settings>().theme.incoming_call_notification;
         let default_project = proto::ParticipantProject::default();
         let initial_project = self
@@ -112,7 +112,6 @@ impl IncomingCallNotification {
                 Image::from_data(avatar)
                     .with_style(theme.caller_avatar)
                     .aligned()
-                    .boxed()
             }))
             .with_child(
                 Flex::column()
@@ -122,8 +121,7 @@ impl IncomingCallNotification {
                             theme.caller_username.text.clone(),
                         )
                         .contained()
-                        .with_style(theme.caller_username.container)
-                        .boxed(),
+                        .with_style(theme.caller_username.container),
                     )
                     .with_child(
                         Label::new(
@@ -138,8 +136,7 @@ impl IncomingCallNotification {
                             theme.caller_message.text.clone(),
                         )
                         .contained()
-                        .with_style(theme.caller_message.container)
-                        .boxed(),
+                        .with_style(theme.caller_message.container),
                     )
                     .with_children(if initial_project.worktree_root_names.is_empty() {
                         None
@@ -150,22 +147,20 @@ impl IncomingCallNotification {
                                 theme.worktree_roots.text.clone(),
                             )
                             .contained()
-                            .with_style(theme.worktree_roots.container)
-                            .boxed(),
+                            .with_style(theme.worktree_roots.container),
                         )
                     })
                     .contained()
                     .with_style(theme.caller_metadata)
-                    .aligned()
-                    .boxed(),
+                    .aligned(),
             )
             .contained()
             .with_style(theme.caller_container)
             .flex(1., true)
-            .boxed()
+            .into_any()
     }
 
-    fn render_buttons(&self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render_buttons(&self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         enum Accept {}
         enum Decline {}
 
@@ -177,14 +172,12 @@ impl IncomingCallNotification {
                         .aligned()
                         .contained()
                         .with_style(theme.accept_button.container)
-                        .boxed()
                 })
                 .with_cursor_style(CursorStyle::PointingHand)
                 .on_click(MouseButton::Left, |_, _, cx| {
                     cx.dispatch_action(RespondToCall { accept: true });
                 })
-                .flex(1., true)
-                .boxed(),
+                .flex(1., true),
             )
             .with_child(
                 MouseEventHandler::<Decline, Self>::new(0, cx, |_, cx| {
@@ -193,14 +186,12 @@ impl IncomingCallNotification {
                         .aligned()
                         .contained()
                         .with_style(theme.decline_button.container)
-                        .boxed()
                 })
                 .with_cursor_style(CursorStyle::PointingHand)
                 .on_click(MouseButton::Left, |_, _, cx| {
                     cx.dispatch_action(RespondToCall { accept: false });
                 })
-                .flex(1., true)
-                .boxed(),
+                .flex(1., true),
             )
             .constrained()
             .with_width(
@@ -209,7 +200,7 @@ impl IncomingCallNotification {
                     .incoming_call_notification
                     .button_width,
             )
-            .boxed()
+            .into_any()
     }
 }
 
@@ -222,7 +213,7 @@ impl View for IncomingCallNotification {
         "IncomingCallNotification"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let background = cx
             .global::<Settings>()
             .theme
@@ -235,6 +226,6 @@ impl View for IncomingCallNotification {
             .contained()
             .with_background_color(background)
             .expanded()
-            .boxed()
+            .into_any()
     }
 }

crates/collab_ui/src/notifications.rs 🔗

@@ -2,7 +2,7 @@ use client::User;
 use gpui::{
     elements::*,
     platform::{CursorStyle, MouseButton},
-    Action, Drawable, Element, View, ViewContext,
+    Action, AnyElement, 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>,
-) -> Element<V> {
+) -> AnyElement<V> {
     let theme = cx.global::<Settings>().theme.clone();
     let theme = &theme.contact_notification;
 
@@ -35,7 +35,6 @@ pub fn render_user_notification<V: View, A: Action + Clone>(
                         )
                         .aligned()
                         .top()
-                        .boxed()
                 }))
                 .with_child(
                     Text::new(
@@ -47,8 +46,7 @@ pub fn render_user_notification<V: View, A: Action + Clone>(
                     .aligned()
                     .top()
                     .left()
-                    .flex(1., true)
-                    .boxed(),
+                    .flex(1., true),
                 )
                 .with_child(
                     MouseEventHandler::<Dismiss, V>::new(user.id as usize, cx, |state, _| {
@@ -63,7 +61,6 @@ pub fn render_user_notification<V: View, A: Action + Clone>(
                             .constrained()
                             .with_width(style.button_width)
                             .with_height(style.button_width)
-                            .boxed()
                     })
                     .with_cursor_style(CursorStyle::PointingHand)
                     .with_padding(Padding::uniform(5.))
@@ -78,16 +75,14 @@ pub fn render_user_notification<V: View, A: Action + Clone>(
                     )
                     .aligned()
                     .top()
-                    .flex_float()
-                    .boxed(),
+                    .flex_float(),
                 )
-                .named("contact notification header"),
+                .into_any_named("contact notification header"),
         )
         .with_children(body.map(|body| {
             Label::new(body, theme.body_message.text.clone())
                 .contained()
                 .with_style(theme.body_message.container)
-                .boxed()
         }))
         .with_children(if buttons.is_empty() {
             None
@@ -101,20 +96,17 @@ pub fn render_user_notification<V: View, A: Action + Clone>(
                                 Label::new(message, button.text.clone())
                                     .contained()
                                     .with_style(button.container)
-                                    .boxed()
                             })
                             .with_cursor_style(CursorStyle::PointingHand)
                             .on_click(MouseButton::Left, move |_, _, cx| {
                                 cx.dispatch_any_action(action.boxed_clone())
                             })
-                            .boxed()
                         },
                     ))
                     .aligned()
-                    .right()
-                    .boxed(),
+                    .right(),
             )
         })
         .contained()
-        .boxed()
+        .into_any()
 }

crates/collab_ui/src/project_shared_notification.rs 🔗

@@ -102,14 +102,13 @@ impl ProjectSharedNotification {
         cx.remove_window();
     }
 
-    fn render_owner(&self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render_owner(&self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let theme = &cx.global::<Settings>().theme.project_shared_notification;
         Flex::row()
             .with_children(self.owner.avatar.clone().map(|avatar| {
                 Image::from_data(avatar)
                     .with_style(theme.owner_avatar)
                     .aligned()
-                    .boxed()
             }))
             .with_child(
                 Flex::column()
@@ -119,8 +118,7 @@ impl ProjectSharedNotification {
                             theme.owner_username.text.clone(),
                         )
                         .contained()
-                        .with_style(theme.owner_username.container)
-                        .boxed(),
+                        .with_style(theme.owner_username.container),
                     )
                     .with_child(
                         Label::new(
@@ -135,8 +133,7 @@ impl ProjectSharedNotification {
                             theme.message.text.clone(),
                         )
                         .contained()
-                        .with_style(theme.message.container)
-                        .boxed(),
+                        .with_style(theme.message.container),
                     )
                     .with_children(if self.worktree_root_names.is_empty() {
                         None
@@ -147,22 +144,20 @@ impl ProjectSharedNotification {
                                 theme.worktree_roots.text.clone(),
                             )
                             .contained()
-                            .with_style(theme.worktree_roots.container)
-                            .boxed(),
+                            .with_style(theme.worktree_roots.container),
                         )
                     })
                     .contained()
                     .with_style(theme.owner_metadata)
-                    .aligned()
-                    .boxed(),
+                    .aligned(),
             )
             .contained()
             .with_style(theme.owner_container)
             .flex(1., true)
-            .boxed()
+            .into_any()
     }
 
-    fn render_buttons(&self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render_buttons(&self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         enum Open {}
         enum Dismiss {}
 
@@ -177,7 +172,6 @@ impl ProjectSharedNotification {
                         .aligned()
                         .contained()
                         .with_style(theme.open_button.container)
-                        .boxed()
                 })
                 .with_cursor_style(CursorStyle::PointingHand)
                 .on_click(MouseButton::Left, move |_, _, cx| {
@@ -186,8 +180,7 @@ impl ProjectSharedNotification {
                         follow_user_id: owner_user_id,
                     });
                 })
-                .flex(1., true)
-                .boxed(),
+                .flex(1., true),
             )
             .with_child(
                 MouseEventHandler::<Dismiss, Self>::new(0, cx, |_, cx| {
@@ -196,14 +189,12 @@ impl ProjectSharedNotification {
                         .aligned()
                         .contained()
                         .with_style(theme.dismiss_button.container)
-                        .boxed()
                 })
                 .with_cursor_style(CursorStyle::PointingHand)
                 .on_click(MouseButton::Left, |_, _, cx| {
                     cx.dispatch_action(DismissProject);
                 })
-                .flex(1., true)
-                .boxed(),
+                .flex(1., true),
             )
             .constrained()
             .with_width(
@@ -212,7 +203,7 @@ impl ProjectSharedNotification {
                     .project_shared_notification
                     .button_width,
             )
-            .boxed()
+            .into_any()
     }
 }
 
@@ -225,7 +216,7 @@ impl View for ProjectSharedNotification {
         "ProjectSharedNotification"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> gpui::Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> gpui::AnyElement<Self> {
         let background = cx
             .global::<Settings>()
             .theme
@@ -237,6 +228,6 @@ impl View for ProjectSharedNotification {
             .contained()
             .with_background_color(background)
             .expanded()
-            .boxed()
+            .into_any()
     }
 }

crates/collab_ui/src/sharing_status_indicator.rs 🔗

@@ -3,7 +3,7 @@ use gpui::{
     color::Color,
     elements::{MouseEventHandler, Svg},
     platform::{Appearance, MouseButton},
-    AppContext, Drawable, Element, Entity, View, ViewContext,
+    AnyElement, AppContext, Element, Entity, View, ViewContext,
 };
 use settings::Settings;
 
@@ -40,7 +40,7 @@ impl View for SharingStatusIndicator {
         "SharingStatusIndicator"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let color = match cx.window_appearance() {
             Appearance::Light | Appearance::VibrantLight => Color::black(),
             Appearance::Dark | Appearance::VibrantDark => Color::white(),
@@ -52,11 +52,10 @@ impl View for SharingStatusIndicator {
                 .constrained()
                 .with_width(18.)
                 .aligned()
-                .boxed()
         })
         .on_click(MouseButton::Left, |_, _, cx| {
             cx.dispatch_action(ToggleScreenSharing);
         })
-        .boxed()
+        .into_any()
     }
 }

crates/command_palette/src/command_palette.rs 🔗

@@ -1,8 +1,8 @@
 use collections::CommandPaletteFilter;
 use fuzzy::{StringMatch, StringMatchCandidate};
 use gpui::{
-    actions, elements::*, keymap_matcher::Keystroke, Action, AppContext, Drawable, MouseState,
-    ViewContext,
+    actions, elements::*, keymap_matcher::Keystroke, Action, AppContext, Element, MouseState,
+    ViewContext, WindowContext,
 };
 use picker::{Picker, PickerDelegate, PickerEvent};
 use settings::Settings;
@@ -45,15 +45,19 @@ fn toggle_command_palette(_: &mut Workspace, _: &Toggle, cx: &mut ViewContext<Wo
     let workspace = cx.handle();
     let focused_view_id = cx.focused_view_id().unwrap_or_else(|| workspace.id());
 
-    cx.defer(move |workspace, cx| {
-        workspace.toggle_modal(cx, |_, cx| {
-            cx.add_view(|cx| Picker::new(CommandPaletteDelegate::new(focused_view_id, cx), cx))
-        });
+    cx.window_context().defer(move |cx| {
+        // Build the delegate before the workspace is put on the stack so we can find it when
+        // computing the actions. We should really not allow available_actions to be called
+        // if it's not reliable however.
+        let delegate = CommandPaletteDelegate::new(focused_view_id, cx);
+        workspace.update(cx, |workspace, cx| {
+            workspace.toggle_modal(cx, |_, cx| cx.add_view(|cx| Picker::new(delegate, cx)));
+        })
     });
 }
 
 impl CommandPaletteDelegate {
-    pub fn new(focused_view_id: usize, cx: &mut ViewContext<Picker<Self>>) -> Self {
+    pub fn new(focused_view_id: usize, cx: &mut WindowContext) -> Self {
         let actions = cx
             .available_actions(focused_view_id)
             .filter_map(|(name, action, bindings)| {
@@ -176,7 +180,7 @@ impl PickerDelegate for CommandPaletteDelegate {
         mouse_state: &mut MouseState,
         selected: bool,
         cx: &gpui::AppContext,
-    ) -> Element<Picker<Self>> {
+    ) -> AnyElement<Picker<Self>> {
         let mat = &self.matches[ix];
         let command = &self.actions[mat.candidate_id];
         let settings = cx.global::<Settings>();
@@ -188,8 +192,7 @@ impl PickerDelegate for CommandPaletteDelegate {
         Flex::row()
             .with_child(
                 Label::new(mat.string.clone(), style.label.clone())
-                    .with_highlights(mat.positions.clone())
-                    .boxed(),
+                    .with_highlights(mat.positions.clone()),
             )
             .with_children(command.keystrokes.iter().map(|keystroke| {
                 Flex::row()
@@ -206,8 +209,7 @@ impl PickerDelegate for CommandPaletteDelegate {
                                 Some(
                                     Label::new(label, key_style.label.clone())
                                         .contained()
-                                        .with_style(key_style.container)
-                                        .boxed(),
+                                        .with_style(key_style.container),
                                 )
                             } else {
                                 None
@@ -217,17 +219,15 @@ impl PickerDelegate for CommandPaletteDelegate {
                     .with_child(
                         Label::new(keystroke.key.clone(), key_style.label.clone())
                             .contained()
-                            .with_style(key_style.container)
-                            .boxed(),
+                            .with_style(key_style.container),
                     )
                     .contained()
                     .with_margin_left(keystroke_spacing)
                     .flex_float()
-                    .boxed()
             }))
             .contained()
             .with_style(style.container)
-            .boxed()
+            .into_any()
     }
 }
 

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) -> Element<ContextMenu>>;
+pub type StaticItem = Box<dyn Fn(&mut AppContext) -> AnyElement<ContextMenu>>;
 
 type ContextMenuItemBuilder =
-    Box<dyn Fn(&mut MouseState, &theme::ContextMenuItem) -> Element<ContextMenu>>;
+    Box<dyn Fn(&mut MouseState, &theme::ContextMenuItem) -> AnyElement<ContextMenu>>;
 
 pub enum ContextMenuItemLabel {
     String(Cow<'static, str>),
@@ -142,23 +142,22 @@ impl View for ContextMenu {
         cx
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         if !self.visible {
-            return Empty::new().boxed();
+            return Empty::new().into_any();
         }
 
         // Render the menu once at minimum width.
-        let mut collapsed_menu = self.render_menu_for_measurement(cx).boxed();
-        let expanded_menu = self
-            .render_menu(cx)
-            .constrained()
-            .dynamically(move |constraint, view, cx| {
-                SizeConstraint::strict_along(
-                    Axis::Horizontal,
-                    collapsed_menu.layout(constraint, view, cx).x(),
-                )
-            })
-            .boxed();
+        let mut collapsed_menu = self.render_menu_for_measurement(cx);
+        let expanded_menu =
+            self.render_menu(cx)
+                .constrained()
+                .dynamically(move |constraint, view, cx| {
+                    SizeConstraint::strict_along(
+                        Axis::Horizontal,
+                        collapsed_menu.layout(constraint, view, cx).0.x(),
+                    )
+                });
 
         Overlay::new(expanded_menu)
             .with_hoverable(true)
@@ -166,7 +165,7 @@ impl View for ContextMenu {
             .with_anchor_position(self.anchor_position)
             .with_anchor_corner(self.anchor_corner)
             .with_position_mode(self.position_mode)
-            .boxed()
+            .into_any()
     }
 
     fn focus_out(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
@@ -328,47 +327,42 @@ impl ContextMenu {
         self.position_mode = mode;
     }
 
-    fn render_menu_for_measurement(
-        &self,
-        cx: &mut ViewContext<Self>,
-    ) -> impl Drawable<ContextMenu> {
+    fn render_menu_for_measurement(&self, cx: &mut ViewContext<Self>) -> impl Element<ContextMenu> {
         let style = cx.global::<Settings>().theme.context_menu.clone();
         Flex::row()
             .with_child(
-                Flex::column()
-                    .with_children(self.items.iter().enumerate().map(|(ix, item)| {
-                        match item {
-                            ContextMenuItem::Item { label, .. } => {
-                                let style = style.item.style_for(
-                                    &mut Default::default(),
-                                    Some(ix) == self.selected_index,
-                                );
-
-                                match label {
-                                    ContextMenuItemLabel::String(label) => {
-                                        Label::new(label.to_string(), style.label.clone())
-                                            .contained()
-                                            .with_style(style.container)
-                                            .boxed()
-                                    }
-                                    ContextMenuItemLabel::Element(element) => {
-                                        element(&mut Default::default(), style)
-                                    }
+                Flex::column().with_children(self.items.iter().enumerate().map(|(ix, item)| {
+                    match item {
+                        ContextMenuItem::Item { label, .. } => {
+                            let style = style.item.style_for(
+                                &mut Default::default(),
+                                Some(ix) == self.selected_index,
+                            );
+
+                            match label {
+                                ContextMenuItemLabel::String(label) => {
+                                    Label::new(label.to_string(), style.label.clone())
+                                        .contained()
+                                        .with_style(style.container)
+                                        .into_any()
+                                }
+                                ContextMenuItemLabel::Element(element) => {
+                                    element(&mut Default::default(), style)
                                 }
                             }
+                        }
 
-                            ContextMenuItem::Static(f) => f(cx),
+                        ContextMenuItem::Static(f) => f(cx),
 
-                            ContextMenuItem::Separator => Empty::new()
-                                .collapsed()
-                                .contained()
-                                .with_style(style.separator)
-                                .constrained()
-                                .with_height(1.)
-                                .boxed(),
-                        }
-                    }))
-                    .boxed(),
+                        ContextMenuItem::Separator => Empty::new()
+                            .collapsed()
+                            .contained()
+                            .with_style(style.separator)
+                            .constrained()
+                            .with_height(1.)
+                            .into_any(),
+                    }
+                })),
             )
             .with_child(
                 Flex::column()
@@ -394,10 +388,10 @@ impl ContextMenu {
                                     style.keystroke.container,
                                     style.keystroke.text.clone(),
                                 )
-                                .boxed()
+                                .into_any()
                             }
 
-                            ContextMenuItem::Static(_) => Empty::new().boxed(),
+                            ContextMenuItem::Static(_) => Empty::new().into_any(),
 
                             ContextMenuItem::Separator => Empty::new()
                                 .collapsed()
@@ -405,18 +399,17 @@ impl ContextMenu {
                                 .with_height(1.)
                                 .contained()
                                 .with_style(style.separator)
-                                .boxed(),
+                                .into_any(),
                         }
                     }))
                     .contained()
-                    .with_margin_left(style.keystroke_margin)
-                    .boxed(),
+                    .with_margin_left(style.keystroke_margin),
             )
             .contained()
             .with_style(style.container)
     }
 
-    fn render_menu(&self, cx: &mut ViewContext<Self>) -> impl Drawable<ContextMenu> {
+    fn render_menu(&self, cx: &mut ViewContext<Self>) -> impl Element<ContextMenu> {
         enum Menu {}
         enum MenuItem {}
 
@@ -445,7 +438,7 @@ impl ContextMenu {
                                         ContextMenuItemLabel::String(label) => {
                                             Label::new(label.clone(), style.label.clone())
                                                 .contained()
-                                                .boxed()
+                                                .into_any()
                                         }
                                         ContextMenuItemLabel::Element(element) => {
                                             element(state, style)
@@ -459,11 +452,9 @@ impl ContextMenu {
                                             style.keystroke.text.clone(),
                                         )
                                         .flex_float()
-                                        .boxed()
                                     })
                                     .contained()
                                     .with_style(style.container)
-                                    .boxed()
                             })
                             .with_cursor_style(CursorStyle::PointingHand)
                             .on_up(MouseButton::Left, |_, _, _| {}) // Capture these events
@@ -474,7 +465,7 @@ impl ContextMenu {
                                 cx.dispatch_any_action_at(window_id, view_id, action.boxed_clone());
                             })
                             .on_drag(MouseButton::Left, |_, _, _| {})
-                            .boxed()
+                            .into_any()
                         }
 
                         ContextMenuItem::Static(f) => f(cx),
@@ -484,12 +475,11 @@ impl ContextMenu {
                             .with_height(1.)
                             .contained()
                             .with_style(style.separator)
-                            .boxed(),
+                            .into_any(),
                     }
                 }))
                 .contained()
                 .with_style(style.container)
-                .boxed()
         })
         .on_down_out(MouseButton::Left, |_, _, cx| cx.dispatch_action(Cancel))
         .on_down_out(MouseButton::Right, |_, _, cx| cx.dispatch_action(Cancel))

crates/copilot/src/sign_in.rs 🔗

@@ -4,7 +4,7 @@ use gpui::{
     geometry::rect::RectF,
     impl_internal_actions,
     platform::{WindowBounds, WindowKind, WindowOptions},
-    AnyViewHandle, AppContext, ClipboardItem, Drawable, Element, Entity, View, ViewContext,
+    AnyElement, AnyViewHandle, AppContext, ClipboardItem, Element, Entity, View, ViewContext,
     ViewHandle,
 };
 use settings::Settings;
@@ -119,7 +119,7 @@ impl CopilotCodeVerification {
         data: &PromptUserDeviceFlow,
         style: &theme::Copilot,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> impl Element<Self> {
         let copied = cx
             .read_from_clipboard()
             .map(|item| item.text() == &data.user_code)
@@ -129,14 +129,15 @@ impl CopilotCodeVerification {
 
         MouseEventHandler::<Self, _>::new(0, cx, |state, _cx| {
             Flex::row()
-                .with_children([
+                .with_child(
                     Label::new(data.user_code.clone(), device_code_style.text.clone())
                         .aligned()
                         .contained()
                         .with_style(device_code_style.left_container)
                         .constrained()
-                        .with_width(device_code_style.left)
-                        .boxed(),
+                        .with_width(device_code_style.left),
+                )
+                .with_child(
                     Label::new(
                         if copied { "Copied!" } else { "Copy" },
                         device_code_style.cta.style_for(state, false).text.clone(),
@@ -145,12 +146,10 @@ impl CopilotCodeVerification {
                     .contained()
                     .with_style(*device_code_style.right_container.style_for(state, false))
                     .constrained()
-                    .with_width(device_code_style.right)
-                    .boxed(),
-                ])
+                    .with_width(device_code_style.right),
+                )
                 .contained()
                 .with_style(device_code_style.cta.style_for(state, false).container)
-                .boxed()
         })
         .on_click(gpui::platform::MouseButton::Left, {
             let user_code = data.user_code.clone();
@@ -161,7 +160,6 @@ impl CopilotCodeVerification {
             }
         })
         .with_cursor_style(gpui::platform::CursorStyle::PointingHand)
-        .boxed()
     }
 
     fn render_prompting_modal(
@@ -169,177 +167,167 @@ impl CopilotCodeVerification {
         data: &PromptUserDeviceFlow,
         style: &theme::Copilot,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         enum ConnectButton {}
 
         Flex::column()
-            .with_children([
+            .with_child(
                 Flex::column()
                     .with_children([
                         Label::new(
                             "Enable Copilot by connecting",
                             style.auth.prompting.subheading.text.clone(),
                         )
-                        .aligned()
-                        .boxed(),
+                        .aligned(),
                         Label::new(
                             "your existing license.",
                             style.auth.prompting.subheading.text.clone(),
                         )
-                        .aligned()
-                        .boxed(),
+                        .aligned(),
                     ])
                     .align_children_center()
                     .contained()
-                    .with_style(style.auth.prompting.subheading.container)
-                    .boxed(),
-                Self::render_device_code(data, &style, cx),
+                    .with_style(style.auth.prompting.subheading.container),
+            )
+            .with_child(Self::render_device_code(data, &style, cx))
+            .with_child(
                 Flex::column()
                     .with_children([
                         Label::new(
                             "Paste this code into GitHub after",
                             style.auth.prompting.hint.text.clone(),
                         )
-                        .aligned()
-                        .boxed(),
+                        .aligned(),
                         Label::new(
                             "clicking the button below.",
                             style.auth.prompting.hint.text.clone(),
                         )
-                        .aligned()
-                        .boxed(),
+                        .aligned(),
                     ])
                     .align_children_center()
                     .contained()
-                    .with_style(style.auth.prompting.hint.container.clone())
-                    .boxed(),
-                theme::ui::cta_button_with_click::<ConnectButton, _, _, _>(
-                    if connect_clicked {
-                        "Waiting for connection..."
-                    } else {
-                        "Connect to GitHub"
-                    },
-                    style.auth.content_width,
-                    &style.auth.cta_button,
-                    cx,
-                    {
-                        let verification_uri = data.verification_uri.clone();
-                        move |_, _, cx| {
-                            cx.platform().open_url(&verification_uri);
-                            cx.dispatch_action(ClickedConnect)
-                        }
-                    },
-                )
-                .boxed(),
-            ])
+                    .with_style(style.auth.prompting.hint.container.clone()),
+            )
+            .with_child(theme::ui::cta_button_with_click::<ConnectButton, _, _, _>(
+                if connect_clicked {
+                    "Waiting for connection..."
+                } else {
+                    "Connect to GitHub"
+                },
+                style.auth.content_width,
+                &style.auth.cta_button,
+                cx,
+                {
+                    let verification_uri = data.verification_uri.clone();
+                    move |_, _, cx| {
+                        cx.platform().open_url(&verification_uri);
+                        cx.dispatch_action(ClickedConnect)
+                    }
+                },
+            ))
             .align_children_center()
-            .boxed()
+            .into_any()
     }
-    fn render_enabled_modal(style: &theme::Copilot, cx: &mut ViewContext<Self>) -> Element<Self> {
+
+    fn render_enabled_modal(
+        style: &theme::Copilot,
+        cx: &mut ViewContext<Self>,
+    ) -> AnyElement<Self> {
         enum DoneButton {}
 
         let enabled_style = &style.auth.authorized;
         Flex::column()
-            .with_children([
+            .with_child(
                 Label::new("Copilot Enabled!", enabled_style.subheading.text.clone())
                     .contained()
                     .with_style(enabled_style.subheading.container)
-                    .aligned()
-                    .boxed(),
+                    .aligned(),
+            )
+            .with_child(
                 Flex::column()
                     .with_children([
                         Label::new(
                             "You can update your settings or",
                             enabled_style.hint.text.clone(),
                         )
-                        .aligned()
-                        .boxed(),
+                        .aligned(),
                         Label::new(
                             "sign out from the Copilot menu in",
                             enabled_style.hint.text.clone(),
                         )
-                        .aligned()
-                        .boxed(),
-                        Label::new("the status bar.", enabled_style.hint.text.clone())
-                            .aligned()
-                            .boxed(),
+                        .aligned(),
+                        Label::new("the status bar.", enabled_style.hint.text.clone()).aligned(),
                     ])
                     .align_children_center()
                     .contained()
-                    .with_style(enabled_style.hint.container)
-                    .boxed(),
-                theme::ui::cta_button_with_click::<DoneButton, _, _, _>(
-                    "Done",
-                    style.auth.content_width,
-                    &style.auth.cta_button,
-                    cx,
-                    |_, _, cx| cx.remove_window(),
-                )
-                .boxed(),
-            ])
+                    .with_style(enabled_style.hint.container),
+            )
+            .with_child(theme::ui::cta_button_with_click::<DoneButton, _, _, _>(
+                "Done",
+                style.auth.content_width,
+                &style.auth.cta_button,
+                cx,
+                |_, _, cx| cx.remove_window(),
+            ))
             .align_children_center()
-            .boxed()
+            .into_any()
     }
+
     fn render_unauthorized_modal(
         style: &theme::Copilot,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         let unauthorized_style = &style.auth.not_authorized;
 
         Flex::column()
-            .with_children([
+            .with_child(
                 Flex::column()
                     .with_children([
                         Label::new(
                             "Enable Copilot by connecting",
                             unauthorized_style.subheading.text.clone(),
                         )
-                        .aligned()
-                        .boxed(),
+                        .aligned(),
                         Label::new(
                             "your existing license.",
                             unauthorized_style.subheading.text.clone(),
                         )
-                        .aligned()
-                        .boxed(),
+                        .aligned(),
                     ])
                     .align_children_center()
                     .contained()
-                    .with_style(unauthorized_style.subheading.container)
-                    .boxed(),
+                    .with_style(unauthorized_style.subheading.container),
+            )
+            .with_child(
                 Flex::column()
                     .with_children([
                         Label::new(
                             "You must have an active copilot",
                             unauthorized_style.warning.text.clone(),
                         )
-                        .aligned()
-                        .boxed(),
+                        .aligned(),
                         Label::new(
                             "license to use it in Zed.",
                             unauthorized_style.warning.text.clone(),
                         )
-                        .aligned()
-                        .boxed(),
+                        .aligned(),
                     ])
                     .align_children_center()
                     .contained()
-                    .with_style(unauthorized_style.warning.container)
-                    .boxed(),
-                theme::ui::cta_button_with_click::<CopilotCodeVerification, _, _, _>(
-                    "Subscribe on GitHub",
-                    style.auth.content_width,
-                    &style.auth.cta_button,
-                    cx,
-                    |_, _, cx| {
-                        cx.remove_window();
-                        cx.platform().open_url(COPILOT_SIGN_UP_URL)
-                    },
-                )
-                .boxed(),
-            ])
+                    .with_style(unauthorized_style.warning.container),
+            )
+            .with_child(theme::ui::cta_button_with_click::<Self, _, _, _>(
+                "Subscribe on GitHub",
+                style.auth.content_width,
+                &style.auth.cta_button,
+                cx,
+                |_, _, cx| {
+                    cx.remove_window();
+                    cx.platform().open_url(COPILOT_SIGN_UP_URL)
+                },
+            ))
             .align_children_center()
-            .boxed()
+            .into_any()
     }
 }
 
@@ -360,37 +348,42 @@ impl View for CopilotCodeVerification {
         cx.notify()
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         enum ConnectModal {}
 
         let style = cx.global::<Settings>().theme.clone();
 
-        modal::<ConnectModal, _, _, _>("Connect Copilot to Zed", &style.copilot.modal, cx, |cx| {
-            Flex::column()
-                .with_children([
-                    theme::ui::icon(&style.copilot.auth.header).boxed(),
-                    match &self.status {
-                        Status::SigningIn {
-                            prompt: Some(prompt),
-                        } => Self::render_prompting_modal(
-                            self.connect_clicked,
-                            &prompt,
-                            &style.copilot,
-                            cx,
-                        ),
-                        Status::Unauthorized => {
-                            self.connect_clicked = false;
-                            Self::render_unauthorized_modal(&style.copilot, cx)
-                        }
-                        Status::Authorized => {
-                            self.connect_clicked = false;
-                            Self::render_enabled_modal(&style.copilot, cx)
-                        }
-                        _ => Empty::new().boxed(),
-                    },
-                ])
-                .align_children_center()
-                .boxed()
-        })
+        modal::<ConnectModal, _, _, _, _>(
+            "Connect Copilot to Zed",
+            &style.copilot.modal,
+            cx,
+            |cx| {
+                Flex::column()
+                    .with_children([
+                        theme::ui::icon(&style.copilot.auth.header).into_any(),
+                        match &self.status {
+                            Status::SigningIn {
+                                prompt: Some(prompt),
+                            } => Self::render_prompting_modal(
+                                self.connect_clicked,
+                                &prompt,
+                                &style.copilot,
+                                cx,
+                            ),
+                            Status::Unauthorized => {
+                                self.connect_clicked = false;
+                                Self::render_unauthorized_modal(&style.copilot, cx)
+                            }
+                            Status::Authorized => {
+                                self.connect_clicked = false;
+                                Self::render_enabled_modal(&style.copilot, cx)
+                            }
+                            _ => Empty::new().into_any(),
+                        },
+                    ])
+                    .align_children_center()
+            },
+        )
+        .into_any()
     }
 }

crates/copilot_button/src/copilot_button.rs 🔗

@@ -6,7 +6,8 @@ use gpui::{
     elements::*,
     impl_internal_actions,
     platform::{CursorStyle, MouseButton},
-    AppContext, Drawable, Element, Entity, MouseState, Subscription, View, ViewContext, ViewHandle,
+    AnyElement, AppContext, Element, Entity, MouseState, Subscription, View, ViewContext,
+    ViewHandle,
 };
 use settings::{settings_file::SettingsFile, Settings};
 use workspace::{
@@ -155,17 +156,17 @@ impl View for CopilotButton {
         "CopilotButton"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let settings = cx.global::<Settings>();
 
         if !settings.features.copilot {
-            return Empty::new().boxed();
+            return Empty::new().into_any();
         }
 
         let theme = settings.theme.clone();
         let active = self.popup_menu.read(cx).visible();
         let Some(copilot) = Copilot::global(cx) else {
-            return Empty::new().boxed();
+            return Empty::new().into_any();
         };
         let status = copilot.read(cx).status();
 
@@ -205,13 +206,12 @@ impl View for CopilotButton {
                                 .constrained()
                                 .with_width(style.icon_size)
                                 .aligned()
-                                .named("copilot-icon"),
+                                .into_any_named("copilot-icon"),
                             )
                             .constrained()
                             .with_height(style.icon_size)
                             .contained()
                             .with_style(style.container)
-                            .boxed()
                     }
                 })
                 .with_cursor_style(CursorStyle::PointingHand)
@@ -228,17 +228,16 @@ impl View for CopilotButton {
                         _ => cx.dispatch_action(DeployCopilotStartMenu),
                     }
                 })
-                .with_tooltip::<Self>(0, "GitHub Copilot".into(), None, theme.tooltip.clone(), cx)
-                .boxed(),
-            )
-            .with_child(
-                ChildView::new(&self.popup_menu, cx)
-                    .aligned()
-                    .top()
-                    .right()
-                    .boxed(),
+                .with_tooltip::<Self>(
+                    0,
+                    "GitHub Copilot".into(),
+                    None,
+                    theme.tooltip.clone(),
+                    cx,
+                ),
             )
-            .boxed()
+            .with_child(ChildView::new(&self.popup_menu, cx).aligned().top().right())
+            .into_any()
     }
 }
 
@@ -322,12 +321,10 @@ impl CopilotButton {
             Box::new(
                 move |state: &mut MouseState, style: &theme::ContextMenuItem| {
                     Flex::row()
-                        .with_children([
-                            Label::new("Copilot Settings", style.label.clone()).boxed(),
-                            theme::ui::icon(icon_style.style_for(state, false)).boxed(),
-                        ])
+                        .with_child(Label::new("Copilot Settings", style.label.clone()))
+                        .with_child(theme::ui::icon(icon_style.style_for(state, false)))
                         .align_children_center()
-                        .boxed()
+                        .into_any()
                 },
             ),
             OsOpen::new(COPILOT_SETTINGS_URL),

crates/diagnostics/src/diagnostics.rs 🔗

@@ -89,16 +89,16 @@ impl View for ProjectDiagnosticsEditor {
         "ProjectDiagnosticsEditor"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<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())
                 .aligned()
                 .contained()
                 .with_style(theme.container)
-                .boxed()
+                .into_any()
         } else {
-            ChildView::new(&self.editor, cx).boxed()
+            ChildView::new(&self.editor, cx).into_any()
         }
     }
 
@@ -535,7 +535,7 @@ impl Item for ProjectDiagnosticsEditor {
         _detail: Option<usize>,
         style: &theme::Tab,
         cx: &AppContext,
-    ) -> Element<T> {
+    ) -> AnyElement<T> {
         render_summary(
             &self.summary,
             &style.label.text,
@@ -694,8 +694,7 @@ fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock {
                 icon.constrained()
                     .with_width(icon_width)
                     .aligned()
-                    .contained()
-                    .boxed(),
+                    .contained(),
             )
             .with_child(
                 Label::new(
@@ -706,22 +705,20 @@ fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock {
                 .contained()
                 .with_style(style.message.container)
                 .with_margin_left(cx.gutter_padding)
-                .aligned()
-                .boxed(),
+                .aligned(),
             )
             .with_children(diagnostic.code.clone().map(|code| {
                 Label::new(code, style.code.text.clone().with_font_size(font_size))
                     .contained()
                     .with_style(style.code.container)
                     .aligned()
-                    .boxed()
             }))
             .contained()
             .with_style(style.container)
             .with_padding_left(cx.gutter_padding)
             .with_padding_right(cx.gutter_padding)
             .expanded()
-            .named("diagnostic header")
+            .into_any_named("diagnostic header")
     })
 }
 
@@ -729,23 +726,24 @@ pub(crate) fn render_summary<T: View>(
     summary: &DiagnosticSummary,
     text_style: &TextStyle,
     theme: &theme::ProjectDiagnostics,
-) -> Element<T> {
+) -> AnyElement<T> {
     if summary.error_count == 0 && summary.warning_count == 0 {
-        Label::new("No problems", text_style.clone()).boxed()
+        Label::new("No problems", text_style.clone()).into_any()
     } else {
         let icon_width = theme.tab_icon_width;
         let icon_spacing = theme.tab_icon_spacing;
         let summary_spacing = theme.tab_summary_spacing;
         Flex::row()
-            .with_children([
+            .with_child(
                 Svg::new("icons/circle_x_mark_12.svg")
                     .with_color(text_style.color)
                     .constrained()
                     .with_width(icon_width)
                     .aligned()
                     .contained()
-                    .with_margin_right(icon_spacing)
-                    .named("no-icon"),
+                    .with_margin_right(icon_spacing),
+            )
+            .with_child(
                 Label::new(
                     summary.error_count.to_string(),
                     LabelStyle {
@@ -753,8 +751,9 @@ pub(crate) fn render_summary<T: View>(
                         highlight_text: None,
                     },
                 )
-                .aligned()
-                .boxed(),
+                .aligned(),
+            )
+            .with_child(
                 Svg::new("icons/triangle_exclamation_12.svg")
                     .with_color(text_style.color)
                     .constrained()
@@ -762,8 +761,9 @@ pub(crate) fn render_summary<T: View>(
                     .aligned()
                     .contained()
                     .with_margin_left(summary_spacing)
-                    .with_margin_right(icon_spacing)
-                    .named("warn-icon"),
+                    .with_margin_right(icon_spacing),
+            )
+            .with_child(
                 Label::new(
                     summary.warning_count.to_string(),
                     LabelStyle {
@@ -771,10 +771,9 @@ pub(crate) fn render_summary<T: View>(
                         highlight_text: None,
                     },
                 )
-                .aligned()
-                .boxed(),
-            ])
-            .boxed()
+                .aligned(),
+            )
+            .into_any()
     }
 }
 

crates/diagnostics/src/items.rs 🔗

@@ -85,7 +85,7 @@ impl View for DiagnosticIndicator {
         "DiagnosticIndicator"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         enum Summary {}
         enum Message {}
 
@@ -103,23 +103,23 @@ impl View for DiagnosticIndicator {
 
                 let mut summary_row = Flex::row();
                 if self.summary.error_count > 0 {
-                    summary_row.add_children([
+                    summary_row.add_child(
                         Svg::new("icons/circle_x_mark_16.svg")
                             .with_color(style.icon_color_error)
                             .constrained()
                             .with_width(style.icon_width)
                             .aligned()
                             .contained()
-                            .with_margin_right(style.icon_spacing)
-                            .named("error-icon"),
+                            .with_margin_right(style.icon_spacing),
+                    );
+                    summary_row.add_child(
                         Label::new(self.summary.error_count.to_string(), style.text.clone())
-                            .aligned()
-                            .boxed(),
-                    ]);
+                            .aligned(),
+                    );
                 }
 
                 if self.summary.warning_count > 0 {
-                    summary_row.add_children([
+                    summary_row.add_child(
                         Svg::new("icons/triangle_exclamation_16.svg")
                             .with_color(style.icon_color_warning)
                             .constrained()
@@ -131,12 +131,12 @@ impl View for DiagnosticIndicator {
                                 style.summary_spacing
                             } else {
                                 0.
-                            })
-                            .named("warning-icon"),
+                            }),
+                    );
+                    summary_row.add_child(
                         Label::new(self.summary.warning_count.to_string(), style.text.clone())
-                            .aligned()
-                            .boxed(),
-                    ]);
+                            .aligned(),
+                    );
                 }
 
                 if self.summary.error_count == 0 && self.summary.warning_count == 0 {
@@ -146,7 +146,7 @@ impl View for DiagnosticIndicator {
                             .constrained()
                             .with_width(style.icon_width)
                             .aligned()
-                            .named("ok-icon"),
+                            .into_any_named("ok-icon"),
                     );
                 }
 
@@ -161,7 +161,6 @@ impl View for DiagnosticIndicator {
                     } else {
                         style.container_ok
                     })
-                    .boxed()
             })
             .with_cursor_style(CursorStyle::PointingHand)
             .on_click(MouseButton::Left, |_, _, cx| {
@@ -175,7 +174,7 @@ impl View for DiagnosticIndicator {
                 cx,
             )
             .aligned()
-            .boxed(),
+            .into_any(),
         );
 
         let style = &cx.global::<Settings>().theme.workspace.status_bar;
@@ -186,8 +185,7 @@ impl View for DiagnosticIndicator {
                 Label::new("Checking…", style.diagnostic_message.default.text.clone())
                     .aligned()
                     .contained()
-                    .with_margin_left(item_spacing)
-                    .boxed(),
+                    .with_margin_left(item_spacing),
             );
         } else if let Some(diagnostic) = &self.current_diagnostic {
             let message_style = style.diagnostic_message.clone();
@@ -200,17 +198,15 @@ impl View for DiagnosticIndicator {
                     .aligned()
                     .contained()
                     .with_margin_left(item_spacing)
-                    .boxed()
                 })
                 .with_cursor_style(CursorStyle::PointingHand)
                 .on_click(MouseButton::Left, |_, _, cx| {
                     cx.dispatch_action(GoToDiagnostic)
-                })
-                .boxed(),
+                }),
             );
         }
 
-        element.named("diagnostic indicator")
+        element.into_any_named("diagnostic indicator")
     }
 
     fn debug_json(&self, _: &gpui::AppContext) -> serde_json::Value {

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},
-    Drawable, Element, View, ViewContext, WeakViewHandle, WindowContext,
+    AnyElement, Element, View, ViewContext, WeakViewHandle, WindowContext,
 };
 
 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>) -> Element<V>>,
+        render: Rc<dyn Fn(Rc<dyn Any>, &mut ViewContext<V>) -> AnyElement<V>>,
     },
     Canceled,
 }
@@ -124,7 +124,7 @@ impl<V: View> DragAndDrop<V> {
         event: MouseDrag,
         payload: Rc<T>,
         cx: &mut WindowContext,
-        render: Rc<impl 'static + Fn(&T, &mut ViewContext<V>) -> Element<V>>,
+        render: Rc<impl 'static + Fn(&T, &mut ViewContext<V>) -> AnyElement<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<Element<V>> {
+    pub fn render(cx: &mut ViewContext<V>) -> Option<AnyElement<V>> {
         enum DraggedElementHandler {}
         cx.global::<Self>()
             .currently_dragged
@@ -227,21 +227,16 @@ impl<V: View> DragAndDrop<V> {
                                 .with_hoverable(false)
                                 .constrained()
                                 .with_width(region.width())
-                                .with_height(region.height())
-                                .boxed(),
+                                .with_height(region.height()),
                             )
                             .with_anchor_position(position)
-                            .boxed(),
+                            .into_any(),
                         )
                     }
 
                     State::Canceled => Some(
                         MouseEventHandler::<DraggedElementHandler, V>::new(0, cx, |_, _| {
-                            Empty::new()
-                                .constrained()
-                                .with_width(0.)
-                                .with_height(0.)
-                                .boxed()
+                            Empty::new().constrained().with_width(0.).with_height(0.)
                         })
                         .on_up(MouseButton::Left, |_, _, cx| {
                             cx.window_context().defer(|cx| {
@@ -257,7 +252,7 @@ impl<V: View> DragAndDrop<V> {
                                 });
                             });
                         })
-                        .boxed(),
+                        .into_any(),
                     ),
                 }
             })
@@ -300,7 +295,7 @@ pub trait Draggable<V: View> {
     fn as_draggable<D: View, P: Any>(
         self,
         payload: P,
-        render: impl 'static + Fn(&P, &mut ViewContext<D>) -> Element<D>,
+        render: impl 'static + Fn(&P, &mut ViewContext<D>) -> AnyElement<D>,
     ) -> Self
     where
         Self: Sized;
@@ -310,7 +305,7 @@ impl<Tag, V: View> Draggable<V> for MouseEventHandler<Tag, V> {
     fn as_draggable<D: View, P: Any>(
         self,
         payload: P,
-        render: impl 'static + Fn(&P, &mut ViewContext<D>) -> Element<D>,
+        render: impl 'static + Fn(&P, &mut ViewContext<D>) -> AnyElement<D>,
     ) -> Self
     where
         Self: Sized,

crates/editor/src/display_map.rs 🔗

@@ -973,7 +973,7 @@ pub mod tests {
                                         position,
                                         height,
                                         disposition,
-                                        render: Arc::new(|_| Empty::new().boxed()),
+                                        render: Arc::new(|_| Empty::new().into_any()),
                                     }
                                 })
                                 .collect::<Vec<_>>();

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, Element, ViewContext};
+use gpui::{fonts::HighlightStyle, AnyElement, 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) -> Element<Editor>>;
+pub type RenderBlock = Arc<dyn Fn(&mut BlockContext) -> AnyElement<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) -> Element<Editor>>,
+    pub render: Arc<dyn Fn(&mut BlockContext) -> AnyElement<Editor>>,
     pub disposition: BlockDisposition,
 }
 
@@ -80,8 +80,8 @@ pub enum BlockStyle {
     Sticky,
 }
 
-pub struct BlockContext<'a, 'b, 'c, 'd> {
-    pub view_context: &'d mut ViewContext<'a, 'b, 'c, Editor>,
+pub struct BlockContext<'a, 'b, 'c> {
+    pub view_context: &'c mut ViewContext<'a, 'b, Editor>,
     pub anchor_x: f32,
     pub scroll_x: f32,
     pub gutter_width: f32,
@@ -932,22 +932,22 @@ impl BlockDisposition {
     }
 }
 
-impl<'a, 'b, 'c, 'd> Deref for BlockContext<'a, 'b, 'c, 'd> {
-    type Target = ViewContext<'a, 'b, 'c, Editor>;
+impl<'a, 'b, 'c> Deref for BlockContext<'a, 'b, 'c> {
+    type Target = ViewContext<'a, 'b, Editor>;
 
     fn deref(&self) -> &Self::Target {
         self.view_context
     }
 }
 
-impl DerefMut for BlockContext<'_, '_, '_, '_> {
+impl DerefMut for BlockContext<'_, '_, '_> {
     fn deref_mut(&mut self) -> &mut Self::Target {
         self.view_context
     }
 }
 
 impl Block {
-    pub fn render(&self, cx: &mut BlockContext) -> Element<Editor> {
+    pub fn render(&self, cx: &mut BlockContext) -> AnyElement<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, Drawable};
+    use gpui::{elements::Empty, Element};
     use rand::prelude::*;
     use settings::Settings;
     use std::env;
@@ -1045,21 +1045,21 @@ mod tests {
                 position: buffer_snapshot.anchor_after(Point::new(1, 0)),
                 height: 1,
                 disposition: BlockDisposition::Above,
-                render: Arc::new(|_| Empty::new().named("block 1")),
+                render: Arc::new(|_| Empty::new().into_any_named("block 1")),
             },
             BlockProperties {
                 style: BlockStyle::Fixed,
                 position: buffer_snapshot.anchor_after(Point::new(1, 2)),
                 height: 2,
                 disposition: BlockDisposition::Above,
-                render: Arc::new(|_| Empty::new().named("block 2")),
+                render: Arc::new(|_| Empty::new().into_any_named("block 2")),
             },
             BlockProperties {
                 style: BlockStyle::Fixed,
                 position: buffer_snapshot.anchor_after(Point::new(3, 3)),
                 height: 3,
                 disposition: BlockDisposition::Below,
-                render: Arc::new(|_| Empty::new().named("block 3")),
+                render: Arc::new(|_| Empty::new().into_any_named("block 3")),
             },
         ]);
 
@@ -1219,14 +1219,14 @@ mod tests {
                 style: BlockStyle::Fixed,
                 position: buffer_snapshot.anchor_after(Point::new(1, 12)),
                 disposition: BlockDisposition::Above,
-                render: Arc::new(|_| Empty::new().named("block 1")),
+                render: Arc::new(|_| Empty::new().into_any_named("block 1")),
                 height: 1,
             },
             BlockProperties {
                 style: BlockStyle::Fixed,
                 position: buffer_snapshot.anchor_after(Point::new(1, 1)),
                 disposition: BlockDisposition::Below,
-                render: Arc::new(|_| Empty::new().named("block 2")),
+                render: Arc::new(|_| Empty::new().into_any_named("block 2")),
                 height: 1,
             },
         ]);
@@ -1329,7 +1329,7 @@ mod tests {
                                 position,
                                 height,
                                 disposition,
-                                render: Arc::new(|_| Empty::new().boxed()),
+                                render: Arc::new(|_| Empty::new().into_any()),
                             }
                         })
                         .collect::<Vec<_>>();

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, Drawable, Element, Entity,
+    AnyElement, AnyViewHandle, AppContext, AsyncAppContext, ClipboardItem, Element, Entity,
     ModelHandle, Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle, WindowContext,
 };
 use highlight_matching_bracket::refresh_matching_bracket_highlights;
@@ -725,7 +725,7 @@ impl ContextMenu {
         cursor_position: DisplayPoint,
         style: EditorStyle,
         cx: &mut ViewContext<Editor>,
-    ) -> (DisplayPoint, Element<Editor>) {
+    ) -> (DisplayPoint, AnyElement<Editor>) {
         match self {
             ContextMenu::Completions(menu) => (cursor_position, menu.render(style, cx)),
             ContextMenu::CodeActions(menu) => menu.render(cursor_position, style, cx),
@@ -777,7 +777,7 @@ impl CompletionsMenu {
         !self.matches.is_empty()
     }
 
-    fn render(&self, style: EditorStyle, cx: &mut ViewContext<Editor>) -> Element<Editor> {
+    fn render(&self, style: EditorStyle, cx: &mut ViewContext<Editor>) -> AnyElement<Editor> {
         enum CompletionTag {}
 
         let completions = self.completions.clone();
@@ -819,7 +819,6 @@ impl CompletionsMenu {
                                     ))
                                     .contained()
                                     .with_style(item_style)
-                                    .boxed()
                             },
                         )
                         .with_cursor_style(CursorStyle::PointingHand)
@@ -828,7 +827,7 @@ impl CompletionsMenu {
                                 item_ix: Some(item_ix),
                             });
                         })
-                        .boxed(),
+                        .into_any(),
                     );
                 }
             },
@@ -848,7 +847,7 @@ impl CompletionsMenu {
         )
         .contained()
         .with_style(container_style)
-        .boxed()
+        .into_any()
     }
 
     pub async fn filter(&mut self, query: Option<&str>, executor: Arc<executor::Background>) {
@@ -954,7 +953,7 @@ impl CodeActionsMenu {
         mut cursor_position: DisplayPoint,
         style: EditorStyle,
         cx: &mut ViewContext<Editor>,
-    ) -> (DisplayPoint, Element<Editor>) {
+    ) -> (DisplayPoint, AnyElement<Editor>) {
         enum ActionTag {}
 
         let container_style = style.autocomplete.container;
@@ -982,7 +981,6 @@ impl CodeActionsMenu {
                                 .with_soft_wrap(false)
                                 .contained()
                                 .with_style(item_style)
-                                .boxed()
                         })
                         .with_cursor_style(CursorStyle::PointingHand)
                         .on_down(MouseButton::Left, move |_, _, cx| {
@@ -990,7 +988,7 @@ impl CodeActionsMenu {
                                 item_ix: Some(item_ix),
                             });
                         })
-                        .boxed(),
+                        .into_any(),
                     );
                 }
             },
@@ -1004,7 +1002,7 @@ impl CodeActionsMenu {
         )
         .contained()
         .with_style(container_style)
-        .boxed();
+        .into_any();
 
         if self.deployed_from_indicator {
             *cursor_position.column_mut() = 0;
@@ -3131,14 +3129,13 @@ impl Editor {
         style: &EditorStyle,
         active: bool,
         cx: &mut ViewContext<Self>,
-    ) -> Option<Element<Self>> {
+    ) -> Option<AnyElement<Self>> {
         if self.available_code_actions.is_some() {
             enum CodeActions {}
             Some(
                 MouseEventHandler::<CodeActions, _>::new(0, cx, |state, _| {
                     Svg::new("icons/bolt_8.svg")
                         .with_color(style.code_actions.indicator.style_for(state, active).color)
-                        .boxed()
                 })
                 .with_cursor_style(CursorStyle::PointingHand)
                 .with_padding(Padding::uniform(3.))
@@ -3147,7 +3144,7 @@ impl Editor {
                         deployed_from_indicator: true,
                     });
                 })
-                .boxed(),
+                .into_any(),
             )
         } else {
             None
@@ -3162,7 +3159,7 @@ impl Editor {
         line_height: f32,
         gutter_margin: f32,
         cx: &mut ViewContext<Self>,
-    ) -> Vec<Option<Element<Self>>> {
+    ) -> Vec<Option<AnyElement<Self>>> {
         enum FoldIndicators {}
 
         let style = style.folds.clone();
@@ -3177,7 +3174,7 @@ impl Editor {
                             MouseEventHandler::<FoldIndicators, _>::new(
                                 ix as usize,
                                 cx,
-                                |mouse_state, _| -> Element<Editor> {
+                                |mouse_state, _| {
                                     Svg::new(match fold_status {
                                         FoldStatus::Folded => style.folded_icon.clone(),
                                         FoldStatus::Foldable => style.foldable_icon.clone(),
@@ -3198,7 +3195,6 @@ impl Editor {
                                     .with_height(line_height)
                                     .with_width(gutter_margin)
                                     .aligned()
-                                    .boxed()
                                 },
                             )
                             .with_cursor_style(CursorStyle::PointingHand)
@@ -3211,7 +3207,7 @@ impl Editor {
                                     });
                                 }
                             })
-                            .boxed()
+                            .into_any()
                         })
                     })
                     .flatten()
@@ -3230,7 +3226,7 @@ impl Editor {
         cursor_position: DisplayPoint,
         style: EditorStyle,
         cx: &mut ViewContext<Editor>,
-    ) -> Option<(DisplayPoint, Element<Editor>)> {
+    ) -> Option<(DisplayPoint, AnyElement<Editor>)> {
         self.context_menu
             .as_ref()
             .map(|menu| menu.render(cursor_position, style, cx))
@@ -5893,7 +5889,7 @@ impl Editor {
                                     ChildView::new(&editor, cx)
                                         .contained()
                                         .with_padding_left(cx.anchor_x)
-                                        .boxed()
+                                        .into_any()
                                 }
                             }),
                             disposition: BlockDisposition::Below,
@@ -7007,7 +7003,7 @@ impl Entity for Editor {
 }
 
 impl View for Editor {
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<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);
@@ -7022,9 +7018,9 @@ impl View for Editor {
         }
 
         Stack::new()
-            .with_child(EditorElement::new(style.clone()).boxed())
-            .with_child(ChildView::new(&self.mouse_context_menu, cx).boxed())
-            .boxed()
+            .with_child(EditorElement::new(style.clone()))
+            .with_child(ChildView::new(&self.mouse_context_menu, cx))
+            .into_any()
     }
 
     fn ui_name() -> &'static str {
@@ -7497,11 +7493,10 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> Rend
                 .with_highlights(highlights.clone())
                 .contained()
                 .with_margin_left(cx.anchor_x)
-                .boxed()
             }))
             .aligned()
             .left()
-            .boxed()
+            .into_any()
     })
 }
 

crates/editor/src/editor_tests.rs 🔗

@@ -2299,7 +2299,7 @@ fn test_move_line_up_down_with_blocks(cx: &mut TestAppContext) {
                 position: snapshot.anchor_after(Point::new(2, 0)),
                 disposition: BlockDisposition::Below,
                 height: 1,
-                render: Arc::new(|_| Empty::new().boxed()),
+                render: Arc::new(|_| Empty::new().into_any()),
             }],
             cx,
         );

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},
-    Axis, Border, CursorRegion, Drawable, Element, EventContext, MouseRegion, Quad, SceneBuilder,
+    AnyElement, Axis, Border, CursorRegion, Element, EventContext, MouseRegion, Quad, SceneBuilder,
     SizeConstraint, ViewContext, WindowContext,
 };
 use itertools::Itertools;
@@ -1447,7 +1447,6 @@ impl EditorElement {
                                 .constrained()
                                 .with_width(style.button_width)
                                 .with_height(style.button_width)
-                                .boxed()
                         })
                         .with_cursor_style(CursorStyle::PointingHand)
                         .on_click(MouseButton::Left, move |_, _, cx| {
@@ -1462,7 +1461,6 @@ impl EditorElement {
                         )
                         .aligned()
                         .flex_float()
-                        .boxed()
                     });
 
                     if *starts_new_buffer {
@@ -1488,15 +1486,13 @@ impl EditorElement {
                                 )
                                 .contained()
                                 .with_style(style.filename.container)
-                                .aligned()
-                                .boxed(),
+                                .aligned(),
                             )
                             .with_children(parent_path.map(|path| {
                                 Label::new(path, style.path.text.clone().with_font_size(font_size))
                                     .contained()
                                     .with_style(style.path.container)
                                     .aligned()
-                                    .boxed()
                             }))
                             .with_children(jump_icon)
                             .contained()
@@ -1504,17 +1500,17 @@ impl EditorElement {
                             .with_padding_left(gutter_padding)
                             .with_padding_right(gutter_padding)
                             .expanded()
-                            .named("path header block")
+                            .into_any_named("path header block")
                     } else {
                         let text_style = self.style.text.clone();
                         Flex::row()
-                            .with_child(Label::new("⋯", text_style).boxed())
+                            .with_child(Label::new("⋯", text_style))
                             .with_children(jump_icon)
                             .contained()
                             .with_padding_left(gutter_padding)
                             .with_padding_right(gutter_padding)
                             .expanded()
-                            .named("collapsed context")
+                            .into_any_named("collapsed context")
                     }
                 }
             };
@@ -1567,7 +1563,7 @@ impl EditorElement {
     }
 }
 
-impl Drawable<Editor> for EditorElement {
+impl Element<Editor> for EditorElement {
     type LayoutState = LayoutState;
     type PaintState = ();
 
@@ -2110,10 +2106,10 @@ pub struct LayoutState {
     scrollbar_row_range: Range<f32>,
     show_scrollbars: bool,
     max_row: u32,
-    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>>>,
+    context_menu: Option<(DisplayPoint, AnyElement<Editor>)>,
+    code_actions_indicator: Option<(u32, AnyElement<Editor>)>,
+    hover_popovers: Option<(DisplayPoint, Vec<AnyElement<Editor>>)>,
+    fold_indicators: Vec<Option<AnyElement<Editor>>>,
 }
 
 pub struct PositionMap {
@@ -2164,7 +2160,7 @@ impl PositionMap {
 
 struct BlockLayout {
     row: u32,
-    element: Element<Editor>,
+    element: AnyElement<Editor>,
     style: BlockStyle,
 }
 
@@ -2535,7 +2531,7 @@ mod tests {
                     disposition: BlockDisposition::Above,
                     height: 3,
                     position: Anchor::min(),
-                    render: Arc::new(|_| Empty::new().boxed()),
+                    render: Arc::new(|_| Empty::new().into_any()),
                 }],
                 cx,
             );

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, Drawable, Element, ModelHandle, Task, ViewContext,
+    AnyElement, AppContext, Axis, 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<Element<Editor>>)> {
+    ) -> Option<(DisplayPoint, Vec<AnyElement<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>) -> Element<Editor> {
+    pub fn render(&self, style: &EditorStyle, cx: &mut ViewContext<Editor>) -> AnyElement<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| {
@@ -344,7 +344,7 @@ impl InfoPopover {
                                 })
                                 .collect(),
                         )
-                        .boxed()
+                        .into_any()
                 } else {
                     let mut text_style = style.hover_popover.prose.clone();
                     text_style.font_size = style.text.font_size;
@@ -353,12 +353,10 @@ impl InfoPopover {
                         .with_soft_wrap(true)
                         .contained()
                         .with_style(style.hover_popover.block_style)
-                        .boxed()
+                        .into_any()
                 }
             }));
-            flex.contained()
-                .with_style(style.hover_popover.container)
-                .boxed()
+            flex.contained().with_style(style.hover_popover.container)
         })
         .on_move(|_, _, _| {}) // Consume move events so they don't reach regions underneath.
         .with_cursor_style(CursorStyle::Arrow)
@@ -367,7 +365,7 @@ impl InfoPopover {
             top: HOVER_POPOVER_GAP,
             ..Default::default()
         })
-        .boxed()
+        .into_any()
     }
 }
 
@@ -378,7 +376,7 @@ pub struct DiagnosticPopover {
 }
 
 impl DiagnosticPopover {
-    pub fn render(&self, style: &EditorStyle, cx: &mut ViewContext<Editor>) -> Element<Editor> {
+    pub fn render(&self, style: &EditorStyle, cx: &mut ViewContext<Editor>) -> AnyElement<Editor> {
         enum PrimaryDiagnostic {}
 
         let mut text_style = style.hover_popover.prose.clone();
@@ -399,7 +397,6 @@ impl DiagnosticPopover {
                 .with_soft_wrap(true)
                 .contained()
                 .with_style(container_style)
-                .boxed()
         })
         .with_padding(Padding {
             top: HOVER_POPOVER_GAP,
@@ -418,7 +415,7 @@ impl DiagnosticPopover {
             tooltip_style,
             cx,
         )
-        .boxed()
+        .into_any()
     }
 
     pub fn activation_info(&self) -> (usize, Anchor) {

crates/editor/src/items.rs 🔗

@@ -563,13 +563,9 @@ impl Item for Editor {
         detail: Option<usize>,
         style: &theme::Tab,
         cx: &AppContext,
-    ) -> Element<T> {
+    ) -> AnyElement<T> {
         Flex::row()
-            .with_child(
-                Label::new(self.title(cx).to_string(), style.label.clone())
-                    .aligned()
-                    .boxed(),
-            )
+            .with_child(Label::new(self.title(cx).to_string(), style.label.clone()).aligned())
             .with_children(detail.and_then(|detail| {
                 let path = path_for_buffer(&self.buffer, detail, false, cx)?;
                 let description = path.to_string_lossy();
@@ -580,11 +576,10 @@ impl Item for Editor {
                     )
                     .contained()
                     .with_style(style.description.container)
-                    .aligned()
-                    .boxed(),
+                    .aligned(),
                 )
             }))
-            .boxed()
+            .into_any()
     }
 
     fn for_each_project_item(&self, cx: &AppContext, f: &mut dyn FnMut(usize, &dyn project::Item)) {
@@ -1113,16 +1108,16 @@ impl View for CursorPosition {
         "CursorPosition"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<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);
             if self.selected_count > 0 {
                 write!(text, " ({} selected)", self.selected_count).unwrap();
             }
-            Label::new(text, theme.cursor_position.clone()).boxed()
+            Label::new(text, theme.cursor_position.clone()).into_any()
         } else {
-            Empty::new().boxed()
+            Empty::new().into_any()
         }
     }
 }

crates/feedback/src/deploy_feedback_button.rs 🔗

@@ -27,7 +27,7 @@ impl View for DeployFeedbackButton {
         "DeployFeedbackButton"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let active = self.active;
         let theme = cx.global::<Settings>().theme.clone();
         Stack::new()
@@ -50,7 +50,6 @@ impl View for DeployFeedbackButton {
                         .with_height(style.icon_size)
                         .contained()
                         .with_style(style.container)
-                        .boxed()
                 })
                 .with_cursor_style(CursorStyle::PointingHand)
                 .on_click(MouseButton::Left, move |_, _, cx| {
@@ -64,10 +63,9 @@ impl View for DeployFeedbackButton {
                     Some(Box::new(GiveFeedback)),
                     theme.tooltip.clone(),
                     cx,
-                )
-                .boxed(),
+                ),
             )
-            .boxed()
+            .into_any()
     }
 }
 

crates/feedback/src/feedback_editor.rs 🔗

@@ -13,7 +13,7 @@ use gpui::{
     actions,
     elements::{ChildView, Flex, Label, ParentElement, Svg},
     platform::PromptLevel,
-    serde_json, AnyViewHandle, AppContext, Drawable, Element, Entity, ModelHandle, Task, View,
+    serde_json, AnyElement, AnyViewHandle, AppContext, Element, Entity, ModelHandle, Task, View,
     ViewContext, ViewHandle,
 };
 use isahc::Request;
@@ -230,8 +230,8 @@ impl View for FeedbackEditor {
         "FeedbackEditor"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
-        ChildView::new(&self.editor, cx).boxed()
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
+        ChildView::new(&self.editor, cx).into_any()
     }
 
     fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
@@ -255,7 +255,7 @@ impl Item for FeedbackEditor {
         _: Option<usize>,
         style: &theme::Tab,
         _: &AppContext,
-    ) -> Element<T> {
+    ) -> AnyElement<T> {
         Flex::row()
             .with_child(
                 Svg::new("icons/feedback_16.svg")
@@ -264,16 +264,14 @@ impl Item for FeedbackEditor {
                     .with_width(style.type_icon_width)
                     .aligned()
                     .contained()
-                    .with_margin_right(style.spacing)
-                    .boxed(),
+                    .with_margin_right(style.spacing),
             )
             .with_child(
                 Label::new("Send Feedback", style.label.clone())
                     .aligned()
-                    .contained()
-                    .boxed(),
+                    .contained(),
             )
-            .boxed()
+            .into_any()
     }
 
     fn for_each_project_item(&self, cx: &AppContext, f: &mut dyn FnMut(usize, &dyn project::Item)) {

crates/feedback/src/feedback_info_text.rs 🔗

@@ -1,7 +1,7 @@
 use gpui::{
     elements::{Flex, Label, MouseEventHandler, ParentElement, Text},
     platform::{CursorStyle, MouseButton},
-    Drawable, Element, Entity, View, ViewContext, ViewHandle,
+    AnyElement, 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>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let theme = cx.global::<Settings>().theme.clone();
 
         Flex::row()
@@ -39,8 +39,7 @@ impl View for FeedbackInfoText {
                     theme.feedback.info_text_default.text.clone(),
                 )
                 .with_soft_wrap(false)
-                .aligned()
-                .boxed(),
+                .aligned(),
             )
             .with_child(
                 MouseEventHandler::<OpenZedCommunityRepo, Self>::new(0, cx, |state, _| {
@@ -55,24 +54,21 @@ impl View for FeedbackInfoText {
                         .aligned()
                         .left()
                         .clipped()
-                        .boxed()
                 })
                 .with_cursor_style(CursorStyle::PointingHand)
                 .on_click(MouseButton::Left, |_, _, cx| {
                     cx.dispatch_action(OpenZedCommunityRepo)
-                })
-                .boxed(),
+                }),
             )
             .with_child(
                 Text::new(" on GitHub.", theme.feedback.info_text_default.text.clone())
                     .with_soft_wrap(false)
-                    .aligned()
-                    .boxed(),
+                    .aligned(),
             )
             .aligned()
             .left()
             .clipped()
-            .boxed()
+            .into_any()
     }
 }
 

crates/feedback/src/submit_feedback_button.rs 🔗

@@ -1,7 +1,7 @@
 use gpui::{
     elements::{Label, MouseEventHandler},
     platform::{CursorStyle, MouseButton},
-    Drawable, Element, Entity, View, ViewContext, ViewHandle,
+    AnyElement, 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>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let theme = cx.global::<Settings>().theme.clone();
         enum SubmitFeedbackButton {}
         MouseEventHandler::<SubmitFeedbackButton, Self>::new(0, cx, |state, _| {
@@ -37,7 +37,6 @@ impl View for SubmitFeedbackButton {
             Label::new("Submit as Markdown", style.text.clone())
                 .contained()
                 .with_style(style.container)
-                .boxed()
         })
         .with_cursor_style(CursorStyle::PointingHand)
         .on_click(MouseButton::Left, |_, _, cx| {
@@ -53,7 +52,7 @@ impl View for SubmitFeedbackButton {
             theme.tooltip.clone(),
             cx,
         )
-        .boxed()
+        .into_any()
     }
 }
 

crates/file_finder/src/file_finder.rs 🔗

@@ -246,7 +246,7 @@ impl PickerDelegate for FileFinderDelegate {
         mouse_state: &mut MouseState,
         selected: bool,
         cx: &AppContext,
-    ) -> Element<Picker<Self>> {
+    ) -> AnyElement<Picker<Self>> {
         let path_match = &self.matches[ix];
         let settings = cx.global::<Settings>();
         let style = settings.theme.picker.item.style_for(mouse_state, selected);
@@ -254,19 +254,15 @@ impl PickerDelegate for FileFinderDelegate {
             self.labels_for_match(path_match);
         Flex::column()
             .with_child(
-                Label::new(file_name, style.label.clone())
-                    .with_highlights(file_name_positions)
-                    .boxed(),
+                Label::new(file_name, style.label.clone()).with_highlights(file_name_positions),
             )
             .with_child(
-                Label::new(full_path, style.label.clone())
-                    .with_highlights(full_path_positions)
-                    .boxed(),
+                Label::new(full_path, style.label.clone()).with_highlights(full_path_positions),
             )
             .flex(1., false)
             .contained()
             .with_style(style.container)
-            .named("match")
+            .into_any_named("match")
     }
 }
 

crates/go_to_line/src/go_to_line.rs 🔗

@@ -143,7 +143,7 @@ impl View for GoToLine {
         "GoToLine"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let theme = &cx.global::<Settings>().theme.picker;
 
         let label = format!(
@@ -153,26 +153,22 @@ impl View for GoToLine {
             self.max_point.row + 1
         );
 
-        ConstrainedBox::new(
-            Container::new(
-                Flex::new(Axis::Vertical)
-                    .with_child(
-                        Container::new(ChildView::new(&self.line_editor, cx).boxed())
-                            .with_style(theme.input_editor.container)
-                            .boxed(),
-                    )
-                    .with_child(
-                        Container::new(Label::new(label, theme.no_matches.label.clone()).boxed())
-                            .with_style(theme.no_matches.container)
-                            .boxed(),
-                    )
-                    .boxed(),
+        Flex::new(Axis::Vertical)
+            .with_child(
+                ChildView::new(&self.line_editor, cx)
+                    .contained()
+                    .with_style(theme.input_editor.container),
+            )
+            .with_child(
+                Label::new(label, theme.no_matches.label.clone())
+                    .contained()
+                    .with_style(theme.no_matches.container),
             )
+            .contained()
             .with_style(theme.container)
-            .boxed(),
-        )
-        .with_max_width(500.0)
-        .named("go to line")
+            .constrained()
+            .with_max_width(500.0)
+            .into_any_named("go to line")
     }
 
     fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {

crates/gpui/examples/text.rs 🔗

@@ -2,7 +2,7 @@ use gpui::{
     color::Color,
     fonts::{Properties, Weight},
     text_layout::RunStyle,
-    Drawable, Element, Quad, SceneBuilder, View, ViewContext,
+    AnyElement, 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>) -> Element<TextView> {
-        TextElement.boxed()
+    fn render(&mut self, _: &mut gpui::ViewContext<Self>) -> AnyElement<TextView> {
+        TextElement.into_any()
     }
 }
 
-impl<V: View> Drawable<V> for TextElement {
+impl<V: View> Element<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::{AnyRootElement, Element, RootElement},
+    elements::{AnyElement, AnyRootElement, RootElement},
     executor::{self, Task},
     keymap_matcher::{self, Binding, KeymapContext, KeymapMatcher, Keystroke, MatchResult},
     platform::{
@@ -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>) -> Element<Self>;
+    fn render(&mut self, cx: &mut ViewContext<'_, '_, Self>) -> AnyElement<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 {
@@ -2518,12 +2518,7 @@ pub trait AnyView {
     ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
     fn ui_name(&self) -> &'static str;
     fn render(&mut self, cx: &mut WindowContext, view_id: usize) -> Box<dyn AnyRootElement>;
-    fn focus_in<'a, 'b>(
-        &mut self,
-        focused_id: usize,
-        cx: &mut WindowContext<'a, 'b>,
-        view_id: usize,
-    );
+    fn focus_in<'a, 'b>(&mut self, focused_id: usize, cx: &mut WindowContext<'a>, view_id: usize);
     fn focus_out(&mut self, focused_id: usize, cx: &mut WindowContext, view_id: usize);
     fn key_down(&mut self, event: &KeyDownEvent, cx: &mut WindowContext, view_id: usize) -> bool;
     fn key_up(&mut self, event: &KeyUpEvent, cx: &mut WindowContext, view_id: usize) -> bool;
@@ -2919,28 +2914,28 @@ impl<M> DerefMut for ModelContext<'_, M> {
     }
 }
 
-pub struct ViewContext<'a, 'b, 'c, T: ?Sized> {
-    window_context: Reference<'c, WindowContext<'a, 'b>>,
+pub struct ViewContext<'a, 'b, T: ?Sized> {
+    window_context: Reference<'b, WindowContext<'a>>,
     view_id: usize,
     view_type: PhantomData<T>,
 }
 
-impl<'a, 'b, 'c, T: View> Deref for ViewContext<'a, 'b, 'c, T> {
-    type Target = WindowContext<'a, 'b>;
+impl<'a, 'b, T: View> Deref for ViewContext<'a, 'b, T> {
+    type Target = WindowContext<'a>;
 
     fn deref(&self) -> &Self::Target {
         &self.window_context
     }
 }
 
-impl<T: View> DerefMut for ViewContext<'_, '_, '_, T> {
+impl<T: View> DerefMut for ViewContext<'_, '_, T> {
     fn deref_mut(&mut self) -> &mut Self::Target {
         &mut self.window_context
     }
 }
 
-impl<'a, 'b, 'c, V: View> ViewContext<'a, 'b, 'c, V> {
-    pub(crate) fn mutable(window_context: &'c mut WindowContext<'a, 'b>, view_id: usize) -> Self {
+impl<'a, 'b, V: View> ViewContext<'a, 'b, V> {
+    pub(crate) fn mutable(window_context: &'b mut WindowContext<'a>, view_id: usize) -> Self {
         Self {
             window_context: Reference::Mutable(window_context),
             view_id,
@@ -2948,7 +2943,7 @@ impl<'a, 'b, 'c, V: View> ViewContext<'a, 'b, 'c, V> {
         }
     }
 
-    pub(crate) fn immutable(window_context: &'c WindowContext<'a, 'b>, view_id: usize) -> Self {
+    pub(crate) fn immutable(window_context: &'b WindowContext<'a>, view_id: usize) -> Self {
         Self {
             window_context: Reference::Immutable(window_context),
             view_id,
@@ -2956,7 +2951,7 @@ impl<'a, 'b, 'c, V: View> ViewContext<'a, 'b, 'c, V> {
         }
     }
 
-    pub fn window_context(&mut self) -> &mut WindowContext<'a, 'b> {
+    pub fn window_context(&mut self) -> &mut WindowContext<'a> {
         &mut self.window_context
     }
 
@@ -3450,7 +3445,7 @@ impl<'a, 'b, 'c, V: View> ViewContext<'a, 'b, 'c, V> {
     }
 }
 
-impl<V> UpgradeModelHandle for ViewContext<'_, '_, '_, V> {
+impl<V> UpgradeModelHandle for ViewContext<'_, '_, V> {
     fn upgrade_model_handle<T: Entity>(
         &self,
         handle: &WeakModelHandle<T>,
@@ -3467,7 +3462,7 @@ impl<V> UpgradeModelHandle for ViewContext<'_, '_, '_, V> {
     }
 }
 
-impl<V> UpgradeViewHandle for ViewContext<'_, '_, '_, V> {
+impl<V> UpgradeViewHandle for ViewContext<'_, '_, V> {
     fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
         self.window_context.upgrade_view_handle(handle)
     }
@@ -3477,13 +3472,13 @@ impl<V> UpgradeViewHandle for ViewContext<'_, '_, '_, V> {
     }
 }
 
-impl<V: View> ReadModel for ViewContext<'_, '_, '_, V> {
+impl<V: View> ReadModel for ViewContext<'_, '_, V> {
     fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
         self.window_context.read_model(handle)
     }
 }
 
-impl<V: View> UpdateModel for ViewContext<'_, '_, '_, V> {
+impl<V: View> UpdateModel for ViewContext<'_, '_, V> {
     fn update_model<T: Entity, O>(
         &mut self,
         handle: &ModelHandle<T>,
@@ -3493,13 +3488,13 @@ impl<V: View> UpdateModel for ViewContext<'_, '_, '_, V> {
     }
 }
 
-impl<V: View> ReadView for ViewContext<'_, '_, '_, V> {
+impl<V: View> ReadView for ViewContext<'_, '_, V> {
     fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
         self.window_context.read_view(handle)
     }
 }
 
-impl<V: View> UpdateView for ViewContext<'_, '_, '_, V> {
+impl<V: View> UpdateView for ViewContext<'_, '_, V> {
     type Output<S> = S;
 
     fn update_view<T, S>(
@@ -3514,13 +3509,13 @@ impl<V: View> UpdateView for ViewContext<'_, '_, '_, V> {
     }
 }
 
-pub struct EventContext<'a, 'b, 'c, 'd, V: View> {
-    view_context: &'d mut ViewContext<'a, 'b, 'c, V>,
+pub struct EventContext<'a, 'b, 'c, V: View> {
+    view_context: &'c mut ViewContext<'a, 'b, V>,
     pub(crate) handled: bool,
 }
 
-impl<'a, 'b, 'c, 'd, V: View> EventContext<'a, 'b, 'c, 'd, V> {
-    pub(crate) fn new(view_context: &'d mut ViewContext<'a, 'b, 'c, V>) -> Self {
+impl<'a, 'b, 'c, V: View> EventContext<'a, 'b, 'c, V> {
+    pub(crate) fn new(view_context: &'c mut ViewContext<'a, 'b, V>) -> Self {
         EventContext {
             view_context,
             handled: true,
@@ -3532,21 +3527,21 @@ impl<'a, 'b, 'c, 'd, V: View> EventContext<'a, 'b, 'c, 'd, V> {
     }
 }
 
-impl<'a, 'b, 'c, 'd, V: View> Deref for EventContext<'a, 'b, 'c, 'd, V> {
-    type Target = ViewContext<'a, 'b, 'c, V>;
+impl<'a, 'b, 'c, V: View> Deref for EventContext<'a, 'b, 'c, V> {
+    type Target = ViewContext<'a, 'b, V>;
 
     fn deref(&self) -> &Self::Target {
         &self.view_context
     }
 }
 
-impl<V: View> DerefMut for EventContext<'_, '_, '_, '_, V> {
+impl<V: View> DerefMut for EventContext<'_, '_, '_, V> {
     fn deref_mut(&mut self) -> &mut Self::Target {
         &mut self.view_context
     }
 }
 
-impl<V: View> UpdateModel for EventContext<'_, '_, '_, '_, V> {
+impl<V: View> UpdateModel for EventContext<'_, '_, '_, V> {
     fn update_model<T: Entity, O>(
         &mut self,
         handle: &ModelHandle<T>,
@@ -3556,13 +3551,13 @@ impl<V: View> UpdateModel for EventContext<'_, '_, '_, '_, V> {
     }
 }
 
-impl<V: View> ReadView for EventContext<'_, '_, '_, '_, V> {
+impl<V: View> ReadView for EventContext<'_, '_, '_, V> {
     fn read_view<W: View>(&self, handle: &crate::ViewHandle<W>) -> &W {
         self.view_context.read_view(handle)
     }
 }
 
-impl<V: View> UpdateView for EventContext<'_, '_, '_, '_, V> {
+impl<V: View> UpdateView for EventContext<'_, '_, '_, V> {
     type Output<S> = S;
 
     fn update_view<T, S>(
@@ -3577,7 +3572,7 @@ impl<V: View> UpdateView for EventContext<'_, '_, '_, '_, V> {
     }
 }
 
-impl<V: View> UpgradeModelHandle for EventContext<'_, '_, '_, '_, V> {
+impl<V: View> UpgradeModelHandle for EventContext<'_, '_, '_, V> {
     fn upgrade_model_handle<T: Entity>(
         &self,
         handle: &WeakModelHandle<T>,
@@ -3594,7 +3589,7 @@ impl<V: View> UpgradeModelHandle for EventContext<'_, '_, '_, '_, V> {
     }
 }
 
-impl<V: View> UpgradeViewHandle for EventContext<'_, '_, '_, '_, V> {
+impl<V: View> UpgradeViewHandle for EventContext<'_, '_, '_, V> {
     fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
         self.view_context.upgrade_view_handle(handle)
     }
@@ -4106,7 +4101,7 @@ impl AnyViewHandle {
         self.view_type
     }
 
-    pub fn debug_json<'a, 'b>(&self, cx: &'b WindowContext<'a, 'b>) -> serde_json::Value {
+    pub fn debug_json<'a, 'b>(&self, cx: &'b WindowContext<'a>) -> serde_json::Value {
         cx.views
             .get(&(self.window_id, self.view_id))
             .map_or_else(|| serde_json::Value::Null, |view| view.debug_json(cx))
@@ -4683,9 +4678,9 @@ mod tests {
         }
 
         impl super::View for View {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
+            fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
                 post_inc(&mut self.render_count);
-                Empty::new().boxed()
+                Empty::new().into_any()
             }
 
             fn ui_name() -> &'static str {
@@ -4736,8 +4731,8 @@ mod tests {
         }
 
         impl super::View for View {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-                Empty::new().boxed()
+            fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+                Empty::new().into_any()
             }
 
             fn ui_name() -> &'static str {
@@ -4806,14 +4801,14 @@ mod tests {
         }
 
         impl super::View for View {
-            fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+            fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
                 enum Handler {}
                 let mouse_down_count = self.mouse_down_count.clone();
-                MouseEventHandler::<Handler, _>::new(0, cx, |_, _| Empty::new().boxed())
+                MouseEventHandler::<Handler, _>::new(0, cx, |_, _| Empty::new())
                     .on_down(MouseButton::Left, move |_, _, _| {
                         mouse_down_count.fetch_add(1, SeqCst);
                     })
-                    .boxed()
+                    .into_any()
             }
 
             fn ui_name() -> &'static str {
@@ -4872,8 +4867,8 @@ mod tests {
                 "View"
             }
 
-            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-                Empty::new().boxed()
+            fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+                Empty::new().into_any()
             }
         }
 
@@ -5390,8 +5385,8 @@ mod tests {
         }
 
         impl super::View for View {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-                Empty::new().boxed()
+            fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+                Empty::new().into_any()
             }
 
             fn ui_name() -> &'static str {
@@ -5457,8 +5452,8 @@ mod tests {
         }
 
         impl super::View for View {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-                Empty::new().boxed()
+            fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+                Empty::new().into_any()
             }
 
             fn ui_name() -> &'static str {
@@ -5638,8 +5633,8 @@ mod tests {
         }
 
         impl View for ViewA {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-                Empty::new().boxed()
+            fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+                Empty::new().into_any()
             }
 
             fn ui_name() -> &'static str {
@@ -5656,8 +5651,8 @@ mod tests {
         }
 
         impl View for ViewB {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-                Empty::new().boxed()
+            fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+                Empty::new().into_any()
             }
 
             fn ui_name() -> &'static str {
@@ -5804,8 +5799,8 @@ mod tests {
         }
 
         impl super::View for View {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-                Empty::new().boxed()
+            fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+                Empty::new().into_any()
             }
 
             fn ui_name() -> &'static str {
@@ -5931,16 +5926,16 @@ mod tests {
         }
 
         impl super::View for View1 {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-                Empty::new().boxed()
+            fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+                Empty::new().into_any()
             }
             fn ui_name() -> &'static str {
                 "View1"
             }
         }
         impl super::View for View2 {
-            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-                Empty::new().boxed()
+            fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+                Empty::new().into_any()
             }
             fn ui_name() -> &'static str {
                 "View2"
@@ -6109,8 +6104,8 @@ mod tests {
                 "test view"
             }
 
-            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-                Empty::new().boxed()
+            fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+                Empty::new().into_any()
             }
         }
 
@@ -6171,8 +6166,8 @@ mod tests {
                 "test view"
             }
 
-            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-                Empty::new().named(format!("render count: {}", post_inc(&mut self.0)))
+            fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+                Empty::new().into_any_named(format!("render count: {}", post_inc(&mut self.0)))
             }
         }
 
@@ -6260,8 +6255,8 @@ mod tests {
                 "test view"
             }
 
-            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-                Empty::new().boxed()
+            fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+                Empty::new().into_any()
             }
         }
 
@@ -6340,9 +6335,9 @@ mod tests {
                 "child view"
             }
 
-            fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
+            fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
                 self.rendered.set(true);
-                Empty::new().boxed()
+                Empty::new().into_any()
             }
         }
 
@@ -6365,11 +6360,11 @@ mod tests {
                 "parent view"
             }
 
-            fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+            fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
                 if let Some(child) = self.child.as_ref() {
-                    ChildView::new(child, cx).boxed()
+                    ChildView::new(child, cx).into_any()
                 } else {
-                    Empty::new().boxed()
+                    Empty::new().into_any()
                 }
             }
         }
@@ -6407,8 +6402,8 @@ mod tests {
             "TestView"
         }
 
-        fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-            Empty::new().boxed()
+        fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+            Empty::new().into_any()
         }
     }
 }

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

@@ -14,7 +14,7 @@ use crate::{
     text_layout::TextLayoutCache,
     util::post_inc,
     Action, AnyModelHandle, AnyView, AnyViewHandle, AnyWeakModelHandle, AnyWeakViewHandle,
-    AppContext, Drawable, Effect, Entity, Handle, ModelContext, ModelHandle, MouseRegion,
+    AppContext, Effect, Element, Entity, Handle, ModelContext, ModelHandle, MouseRegion,
     MouseRegionId, ParentId, ReadModel, ReadView, SceneBuilder, Subscription, UpdateModel,
     UpdateView, UpgradeModelHandle, UpgradeViewHandle, View, ViewContext, ViewHandle,
     WeakModelHandle, WeakViewHandle, WindowInvalidation,
@@ -111,15 +111,15 @@ impl Window {
     }
 }
 
-pub struct WindowContext<'a: 'b, 'b> {
+pub struct WindowContext<'a> {
     pub(crate) app_context: Reference<'a, AppContext>,
-    pub(crate) window: Reference<'b, Window>,
+    pub(crate) window: Reference<'a, Window>,
     pub(crate) window_id: usize,
     pub(crate) refreshing: bool,
     pub(crate) removed: bool,
 }
 
-impl Deref for WindowContext<'_, '_> {
+impl Deref for WindowContext<'_> {
     type Target = AppContext;
 
     fn deref(&self) -> &Self::Target {
@@ -127,19 +127,19 @@ impl Deref for WindowContext<'_, '_> {
     }
 }
 
-impl DerefMut for WindowContext<'_, '_> {
+impl DerefMut for WindowContext<'_> {
     fn deref_mut(&mut self) -> &mut Self::Target {
         &mut self.app_context
     }
 }
 
-impl ReadModel for WindowContext<'_, '_> {
+impl ReadModel for WindowContext<'_> {
     fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
         self.app_context.read_model(handle)
     }
 }
 
-impl UpdateModel for WindowContext<'_, '_> {
+impl UpdateModel for WindowContext<'_> {
     fn update_model<T: Entity, R>(
         &mut self,
         handle: &ModelHandle<T>,
@@ -149,13 +149,13 @@ impl UpdateModel for WindowContext<'_, '_> {
     }
 }
 
-impl ReadView for WindowContext<'_, '_> {
+impl ReadView for WindowContext<'_> {
     fn read_view<W: View>(&self, handle: &crate::ViewHandle<W>) -> &W {
         self.app_context.read_view(handle)
     }
 }
 
-impl UpdateView for WindowContext<'_, '_> {
+impl UpdateView for WindowContext<'_> {
     type Output<S> = S;
 
     fn update_view<T, S>(
@@ -179,7 +179,7 @@ impl UpdateView for WindowContext<'_, '_> {
     }
 }
 
-impl UpgradeModelHandle for WindowContext<'_, '_> {
+impl UpgradeModelHandle for WindowContext<'_> {
     fn upgrade_model_handle<T: Entity>(
         &self,
         handle: &WeakModelHandle<T>,
@@ -196,7 +196,7 @@ impl UpgradeModelHandle for WindowContext<'_, '_> {
     }
 }
 
-impl UpgradeViewHandle for WindowContext<'_, '_> {
+impl UpgradeViewHandle for WindowContext<'_> {
     fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
         self.app_context.upgrade_view_handle(handle)
     }
@@ -206,10 +206,10 @@ impl UpgradeViewHandle for WindowContext<'_, '_> {
     }
 }
 
-impl<'a: 'b, 'b> WindowContext<'a, 'b> {
+impl<'a> WindowContext<'a> {
     pub fn mutable(
         app_context: &'a mut AppContext,
-        window: &'b mut Window,
+        window: &'a mut Window,
         window_id: usize,
     ) -> Self {
         Self {
@@ -221,7 +221,7 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
         }
     }
 
-    pub fn immutable(app_context: &'a AppContext, window: &'b Window, window_id: usize) -> Self {
+    pub fn immutable(app_context: &'a AppContext, window: &'a Window, window_id: usize) -> Self {
         Self {
             app_context: Reference::Immutable(app_context),
             window: Reference::Immutable(window),
@@ -444,6 +444,11 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
                             .map(|action_type| (action_type, depth)),
                     );
                 }
+            } else {
+                log::error!(
+                    "view {} not found when computing available actions",
+                    view_id
+                );
             }
         }
 
@@ -1391,7 +1396,7 @@ impl ChildView {
     }
 }
 
-impl<V: View> Drawable<V> for ChildView {
+impl<V: View> Element<V> for ChildView {
     type LayoutState = ();
     type PaintState = ();
 

crates/gpui/src/elements.rs 🔗

@@ -47,7 +47,7 @@ use std::{
 };
 use util::ResultExt;
 
-pub trait Drawable<V: View> {
+pub trait Element<V: View>: 'static {
     type LayoutState;
     type PaintState;
 
@@ -92,35 +92,33 @@ pub trait Drawable<V: View> {
         cx: &ViewContext<V>,
     ) -> serde_json::Value;
 
-    fn boxed(self) -> Element<V>
+    fn into_any(self) -> AnyElement<V>
     where
         Self: 'static + Sized,
     {
-        Element {
-            drawable: Box::new(Lifecycle::Init { element: self }),
-            view_type: PhantomData,
+        AnyElement {
+            state: Box::new(ElementState::Init { element: self }),
             name: None,
         }
     }
 
-    fn into_root(self, cx: &ViewContext<V>) -> RootElement<V>
+    fn into_any_named(self, name: impl Into<Cow<'static, str>>) -> AnyElement<V>
     where
         Self: 'static + Sized,
     {
-        RootElement {
-            element: self.boxed(),
-            view: cx.handle().downgrade(),
+        AnyElement {
+            state: Box::new(ElementState::Init { element: self }),
+            name: Some(name.into()),
         }
     }
 
-    fn named(self, name: impl Into<Cow<'static, str>>) -> Element<V>
+    fn into_root_element(self, cx: &ViewContext<V>) -> RootElement<V>
     where
         Self: 'static + Sized,
     {
-        Element {
-            drawable: Box::new(Lifecycle::Init { element: self }),
-            view_type: PhantomData,
-            name: Some(name.into()),
+        RootElement {
+            element: self.into_any(),
+            view: cx.handle().downgrade(),
         }
     }
 
@@ -128,49 +126,49 @@ pub trait Drawable<V: View> {
     where
         Self: 'static + Sized,
     {
-        ConstrainedBox::new(self.boxed())
+        ConstrainedBox::new(self.into_any())
     }
 
     fn aligned(self) -> Align<V>
     where
         Self: 'static + Sized,
     {
-        Align::new(self.boxed())
+        Align::new(self.into_any())
     }
 
     fn clipped(self) -> Clipped<V>
     where
         Self: 'static + Sized,
     {
-        Clipped::new(self.boxed())
+        Clipped::new(self.into_any())
     }
 
     fn contained(self) -> Container<V>
     where
         Self: 'static + Sized,
     {
-        Container::new(self.boxed())
+        Container::new(self.into_any())
     }
 
     fn expanded(self) -> Expanded<V>
     where
         Self: 'static + Sized,
     {
-        Expanded::new(self.boxed())
+        Expanded::new(self.into_any())
     }
 
     fn flex(self, flex: f32, expanded: bool) -> FlexItem<V>
     where
         Self: 'static + Sized,
     {
-        FlexItem::new(self.boxed()).flex(flex, expanded)
+        FlexItem::new(self.into_any()).flex(flex, expanded)
     }
 
     fn flex_float(self) -> FlexItem<V>
     where
         Self: 'static + Sized,
     {
-        FlexItem::new(self.boxed()).float()
+        FlexItem::new(self.into_any()).float()
     }
 
     fn with_tooltip<Tag: 'static>(
@@ -184,7 +182,7 @@ pub trait Drawable<V: View> {
     where
         Self: 'static + Sized,
     {
-        Tooltip::new::<Tag, V>(id, text, action, style, self.boxed(), cx)
+        Tooltip::new::<Tag, V>(id, text, action, style, self.into_any(), cx)
     }
 
     fn with_resize_handle<Tag: 'static>(
@@ -199,7 +197,7 @@ pub trait Drawable<V: View> {
         Self: 'static + Sized,
     {
         Resizable::new::<Tag, V>(
-            self.boxed(),
+            self.into_any(),
             element_id,
             side,
             handle_size,
@@ -209,7 +207,7 @@ pub trait Drawable<V: View> {
     }
 }
 
-trait AnyDrawable<V: View> {
+trait AnyElementState<V: View> {
     fn layout(
         &mut self,
         constraint: SizeConstraint,
@@ -240,7 +238,7 @@ trait AnyDrawable<V: View> {
     fn metadata(&self) -> Option<&dyn Any>;
 }
 
-enum Lifecycle<V: View, E: Drawable<V>> {
+enum ElementState<V: View, E: Element<V>> {
     Empty,
     Init {
         element: E,
@@ -261,7 +259,7 @@ enum Lifecycle<V: View, E: Drawable<V>> {
     },
 }
 
-impl<V: View, E: Drawable<V>> AnyDrawable<V> for Lifecycle<V, E> {
+impl<V: View, E: Element<V>> AnyElementState<V> for ElementState<V, E> {
     fn layout(
         &mut self,
         constraint: SizeConstraint,
@@ -270,16 +268,16 @@ impl<V: View, E: Drawable<V>> AnyDrawable<V> for Lifecycle<V, E> {
     ) -> Vector2F {
         let result;
         *self = match mem::take(self) {
-            Lifecycle::Empty => unreachable!(),
-            Lifecycle::Init { mut element }
-            | Lifecycle::PostLayout { mut element, .. }
-            | Lifecycle::PostPaint { mut element, .. } => {
+            ElementState::Empty => unreachable!(),
+            ElementState::Init { mut element }
+            | ElementState::PostLayout { mut element, .. }
+            | ElementState::PostPaint { mut element, .. } => {
                 let (size, layout) = element.layout(constraint, view, cx);
                 debug_assert!(size.x().is_finite());
                 debug_assert!(size.y().is_finite());
 
                 result = size;
-                Lifecycle::PostLayout {
+                ElementState::PostLayout {
                     element,
                     constraint,
                     size,
@@ -299,7 +297,7 @@ impl<V: View, E: Drawable<V>> AnyDrawable<V> for Lifecycle<V, E> {
         cx: &mut ViewContext<V>,
     ) {
         *self = match mem::take(self) {
-            Lifecycle::PostLayout {
+            ElementState::PostLayout {
                 mut element,
                 constraint,
                 size,
@@ -307,7 +305,7 @@ impl<V: View, E: Drawable<V>> AnyDrawable<V> for Lifecycle<V, E> {
             } => {
                 let bounds = RectF::new(origin, size);
                 let paint = element.paint(scene, bounds, visible_bounds, &mut layout, view, cx);
-                Lifecycle::PostPaint {
+                ElementState::PostPaint {
                     element,
                     constraint,
                     bounds,
@@ -316,7 +314,7 @@ impl<V: View, E: Drawable<V>> AnyDrawable<V> for Lifecycle<V, E> {
                     paint,
                 }
             }
-            Lifecycle::PostPaint {
+            ElementState::PostPaint {
                 mut element,
                 constraint,
                 bounds,
@@ -325,7 +323,7 @@ impl<V: View, E: Drawable<V>> AnyDrawable<V> for Lifecycle<V, E> {
             } => {
                 let bounds = RectF::new(origin, bounds.size());
                 let paint = element.paint(scene, bounds, visible_bounds, &mut layout, view, cx);
-                Lifecycle::PostPaint {
+                ElementState::PostPaint {
                     element,
                     constraint,
                     bounds,
@@ -334,8 +332,8 @@ impl<V: View, E: Drawable<V>> AnyDrawable<V> for Lifecycle<V, E> {
                     paint,
                 }
             }
-            Lifecycle::Empty => panic!("invalid element lifecycle state"),
-            Lifecycle::Init { .. } => {
+            ElementState::Empty => panic!("invalid element lifecycle state"),
+            ElementState::Init { .. } => {
                 panic!("invalid element lifecycle state, paint called before layout")
             }
         }
@@ -347,7 +345,7 @@ impl<V: View, E: Drawable<V>> AnyDrawable<V> for Lifecycle<V, E> {
         view: &V,
         cx: &ViewContext<V>,
     ) -> Option<RectF> {
-        if let Lifecycle::PostPaint {
+        if let ElementState::PostPaint {
             element,
             bounds,
             visible_bounds,
@@ -372,24 +370,26 @@ impl<V: View, E: Drawable<V>> AnyDrawable<V> for Lifecycle<V, E> {
 
     fn size(&self) -> Vector2F {
         match self {
-            Lifecycle::Empty | Lifecycle::Init { .. } => panic!("invalid element lifecycle state"),
-            Lifecycle::PostLayout { size, .. } => *size,
-            Lifecycle::PostPaint { bounds, .. } => bounds.size(),
+            ElementState::Empty | ElementState::Init { .. } => {
+                panic!("invalid element lifecycle state")
+            }
+            ElementState::PostLayout { size, .. } => *size,
+            ElementState::PostPaint { bounds, .. } => bounds.size(),
         }
     }
 
     fn metadata(&self) -> Option<&dyn Any> {
         match self {
-            Lifecycle::Empty => unreachable!(),
-            Lifecycle::Init { element }
-            | Lifecycle::PostLayout { element, .. }
-            | Lifecycle::PostPaint { element, .. } => element.metadata(),
+            ElementState::Empty => unreachable!(),
+            ElementState::Init { element }
+            | ElementState::PostLayout { element, .. }
+            | ElementState::PostPaint { element, .. } => element.metadata(),
         }
     }
 
     fn debug(&self, view: &V, cx: &ViewContext<V>) -> serde_json::Value {
         match self {
-            Lifecycle::PostPaint {
+            ElementState::PostPaint {
                 element,
                 constraint,
                 bounds,
@@ -419,25 +419,24 @@ impl<V: View, E: Drawable<V>> AnyDrawable<V> for Lifecycle<V, E> {
     }
 }
 
-impl<V: View, E: Drawable<V>> Default for Lifecycle<V, E> {
+impl<V: View, E: Element<V>> Default for ElementState<V, E> {
     fn default() -> Self {
         Self::Empty
     }
 }
 
-pub struct Element<V: View> {
-    drawable: Box<dyn AnyDrawable<V>>,
-    view_type: PhantomData<V>,
+pub struct AnyElement<V: View> {
+    state: Box<dyn AnyElementState<V>>,
     name: Option<Cow<'static, str>>,
 }
 
-impl<V: View> Element<V> {
+impl<V: View> AnyElement<V> {
     pub fn name(&self) -> Option<&str> {
         self.name.as_deref()
     }
 
     pub fn metadata<T: 'static>(&self) -> Option<&T> {
-        self.drawable
+        self.state
             .metadata()
             .and_then(|data| data.downcast_ref::<T>())
     }
@@ -448,7 +447,7 @@ impl<V: View> Element<V> {
         view: &mut V,
         cx: &mut ViewContext<V>,
     ) -> Vector2F {
-        self.drawable.layout(constraint, view, cx)
+        self.state.layout(constraint, view, cx)
     }
 
     pub fn paint(
@@ -459,7 +458,7 @@ impl<V: View> Element<V> {
         view: &mut V,
         cx: &mut ViewContext<V>,
     ) {
-        self.drawable.paint(scene, origin, visible_bounds, view, cx);
+        self.state.paint(scene, origin, visible_bounds, view, cx);
     }
 
     pub fn rect_for_text_range(
@@ -468,15 +467,15 @@ impl<V: View> Element<V> {
         view: &V,
         cx: &ViewContext<V>,
     ) -> Option<RectF> {
-        self.drawable.rect_for_text_range(range_utf16, view, cx)
+        self.state.rect_for_text_range(range_utf16, view, cx)
     }
 
     pub fn size(&self) -> Vector2F {
-        self.drawable.size()
+        self.state.size()
     }
 
     pub fn debug(&self, view: &V, cx: &ViewContext<V>) -> json::Value {
-        let mut value = self.drawable.debug(view, cx);
+        let mut value = self.state.debug(view, cx);
 
         if let Some(name) = &self.name {
             if let json::Value::Object(map) = &mut value {
@@ -495,23 +494,81 @@ impl<V: View> Element<V> {
         T: 'static,
         F: FnOnce(Option<&T>) -> R,
     {
-        f(self.drawable.metadata().and_then(|m| m.downcast_ref()))
+        f(self.state.metadata().and_then(|m| m.downcast_ref()))
+    }
+}
+
+impl<V: View> Element<V> for AnyElement<V> {
+    type LayoutState = ();
+    type PaintState = ();
+
+    fn layout(
+        &mut self,
+        constraint: SizeConstraint,
+        view: &mut V,
+        cx: &mut ViewContext<V>,
+    ) -> (Vector2F, Self::LayoutState) {
+        let size = self.layout(constraint, view, cx);
+        (size, ())
+    }
+
+    fn paint(
+        &mut self,
+        scene: &mut SceneBuilder,
+        bounds: RectF,
+        visible_bounds: RectF,
+        _: &mut Self::LayoutState,
+        view: &mut V,
+        cx: &mut ViewContext<V>,
+    ) -> Self::PaintState {
+        self.paint(scene, bounds.origin(), visible_bounds, view, cx);
+    }
+
+    fn rect_for_text_range(
+        &self,
+        range_utf16: Range<usize>,
+        _: RectF,
+        _: RectF,
+        _: &Self::LayoutState,
+        _: &Self::PaintState,
+        view: &V,
+        cx: &ViewContext<V>,
+    ) -> Option<RectF> {
+        self.rect_for_text_range(range_utf16, view, cx)
+    }
+
+    fn debug(
+        &self,
+        _: RectF,
+        _: &Self::LayoutState,
+        _: &Self::PaintState,
+        view: &V,
+        cx: &ViewContext<V>,
+    ) -> serde_json::Value {
+        self.debug(view, cx)
+    }
+
+    fn into_any(self) -> AnyElement<V>
+    where
+        Self: Sized,
+    {
+        self
     }
 }
 
 pub struct RootElement<V: View> {
-    element: Element<V>,
+    element: AnyElement<V>,
     view: WeakViewHandle<V>,
 }
 
 impl<V: View> RootElement<V> {
-    pub fn new(element: Element<V>, view: WeakViewHandle<V>) -> Self {
+    pub fn new(element: AnyElement<V>, view: WeakViewHandle<V>) -> Self {
         Self { element, view }
     }
 }
 
-pub trait Component<V: View> {
-    fn render(&self, view: &mut V, cx: &mut ViewContext<V>) -> Element<V>;
+pub trait Component<V: View>: 'static {
+    fn render(&self, view: &mut V, cx: &mut ViewContext<V>) -> AnyElement<V>;
 }
 
 pub struct ComponentHost<V: View, C: Component<V>> {
@@ -533,8 +590,8 @@ impl<V: View, C: Component<V>> DerefMut for ComponentHost<V, C> {
     }
 }
 
-impl<V: View, C: Component<V>> Drawable<V> for ComponentHost<V, C> {
-    type LayoutState = Element<V>;
+impl<V: View, C: Component<V>> Element<V> for ComponentHost<V, C> {
+    type LayoutState = AnyElement<V>;
     type PaintState = ();
 
     fn layout(
@@ -542,7 +599,7 @@ impl<V: View, C: Component<V>> Drawable<V> for ComponentHost<V, C> {
         constraint: SizeConstraint,
         view: &mut V,
         cx: &mut ViewContext<V>,
-    ) -> (Vector2F, Element<V>) {
+    ) -> (Vector2F, AnyElement<V>) {
         let mut element = self.component.render(view, cx);
         let size = element.layout(constraint, view, cx);
         (size, element)
@@ -553,7 +610,7 @@ impl<V: View, C: Component<V>> Drawable<V> for ComponentHost<V, C> {
         scene: &mut SceneBuilder,
         bounds: RectF,
         visible_bounds: RectF,
-        element: &mut Element<V>,
+        element: &mut AnyElement<V>,
         view: &mut V,
         cx: &mut ViewContext<V>,
     ) {
@@ -565,7 +622,7 @@ impl<V: View, C: Component<V>> Drawable<V> for ComponentHost<V, C> {
         range_utf16: Range<usize>,
         _: RectF,
         _: RectF,
-        element: &Element<V>,
+        element: &AnyElement<V>,
         _: &(),
         view: &V,
         cx: &ViewContext<V>,
@@ -576,7 +633,7 @@ impl<V: View, C: Component<V>> Drawable<V> for ComponentHost<V, C> {
     fn debug(
         &self,
         _: RectF,
-        element: &Element<V>,
+        element: &AnyElement<V>,
         _: &(),
         view: &V,
         cx: &ViewContext<V>,
@@ -660,7 +717,7 @@ impl<V: View> AnyRootElement for RootElement<V> {
     }
 }
 
-impl<V: View, R: View> Drawable<V> for RootElement<R> {
+impl<V: View, R: View> Element<V> for RootElement<R> {
     type LayoutState = ();
     type PaintState = ();
 
@@ -717,26 +774,27 @@ impl<V: View, R: View> Drawable<V> for RootElement<R> {
     }
 }
 
-pub trait ParentElement<'a, V: View>: Extend<Element<V>> + Sized {
-    fn add_children(&mut self, children: impl IntoIterator<Item = Element<V>>) {
-        self.extend(children);
+pub trait ParentElement<'a, V: View>: Extend<AnyElement<V>> + Sized {
+    fn add_children<E: Element<V>>(&mut self, children: impl IntoIterator<Item = E>) {
+        self.extend(children.into_iter().map(|child| child.into_any()));
     }
 
-    fn add_child(&mut self, child: Element<V>) {
-        self.add_children(Some(child));
+    fn add_child<D: Element<V>>(&mut self, child: D) {
+        self.extend(Some(child.into_any()));
     }
 
-    fn with_children(mut self, children: impl IntoIterator<Item = Element<V>>) -> Self {
-        self.add_children(children);
+    fn with_children<D: Element<V>>(mut self, children: impl IntoIterator<Item = D>) -> Self {
+        self.extend(children.into_iter().map(|child| child.into_any()));
         self
     }
 
-    fn with_child(self, child: Element<V>) -> Self {
-        self.with_children(Some(child))
+    fn with_child<D: Element<V>>(mut self, child: D) -> Self {
+        self.extend(Some(child.into_any()));
+        self
     }
 }
 
-impl<'a, V: View, T> ParentElement<'a, V> for T where T: Extend<Element<V>> {}
+impl<'a, V: View, T> ParentElement<'a, V> for T where T: Extend<AnyElement<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, Drawable, Element, SceneBuilder, SizeConstraint, View, ViewContext,
+    json, AnyElement, Element, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 use json::ToJson;
 
 use serde_json::json;
 
 pub struct Align<V: View> {
-    child: Element<V>,
+    child: AnyElement<V>,
     alignment: Vector2F,
 }
 
 impl<V: View> Align<V> {
-    pub fn new(child: Element<V>) -> Self {
+    pub fn new(child: AnyElement<V>) -> Self {
         Self {
             child,
             alignment: Vector2F::zero(),
@@ -40,7 +40,7 @@ impl<V: View> Align<V> {
     }
 }
 
-impl<V: View> Drawable<V> for Align<V> {
+impl<V: View> Element<V> for Align<V> {
     type LayoutState = ();
     type PaintState = ();
 

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

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

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, Drawable, Element, SceneBuilder, SizeConstraint, View, ViewContext};
+use crate::{json, AnyElement, Element, SceneBuilder, SizeConstraint, View, ViewContext};
 
 pub struct Clipped<V: View> {
-    child: Element<V>,
+    child: AnyElement<V>,
 }
 
 impl<V: View> Clipped<V> {
-    pub fn new(child: Element<V>) -> Self {
+    pub fn new(child: AnyElement<V>) -> Self {
         Self { child }
     }
 }
 
-impl<V: View> Drawable<V> for Clipped<V> {
+impl<V: View> Element<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, Drawable, Element, SceneBuilder, SizeConstraint, View, ViewContext,
+    json, AnyElement, Element, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 
 pub struct ConstrainedBox<V: View> {
-    child: Element<V>,
+    child: AnyElement<V>,
     constraint: Constraint<V>,
 }
 
@@ -28,9 +28,9 @@ impl<V: View> ToJson for Constraint<V> {
 }
 
 impl<V: View> ConstrainedBox<V> {
-    pub fn new(child: Element<V>) -> Self {
+    pub fn new(child: impl Element<V>) -> Self {
         Self {
-            child,
+            child: child.into_any(),
             constraint: Constraint::Static(Default::default()),
         }
     }
@@ -130,7 +130,7 @@ impl<V: View> ConstrainedBox<V> {
     }
 }
 
-impl<V: View> Drawable<V> for ConstrainedBox<V> {
+impl<V: View> Element<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},
-    Drawable, Element, SceneBuilder, SizeConstraint, View, ViewContext,
+    AnyElement, 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: Element<V>,
+    child: AnyElement<V>,
     style: ContainerStyle,
 }
 
 impl<V: View> Container<V> {
-    pub fn new(child: Element<V>) -> Self {
+    pub fn new(child: AnyElement<V>) -> Self {
         Self {
             child,
             style: Default::default(),
@@ -184,7 +184,7 @@ impl<V: View> Container<V> {
     }
 }
 
-impl<V: View> Drawable<V> for Container<V> {
+impl<V: View> Element<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::{Drawable, SizeConstraint};
+use crate::{Element, SizeConstraint};
 
 #[derive(Default)]
 pub struct Empty {
@@ -26,7 +26,7 @@ impl Empty {
     }
 }
 
-impl<V: View> Drawable<V> for Empty {
+impl<V: View> Element<V> for Empty {
     type LayoutState = ();
     type PaintState = ();
 

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

@@ -2,20 +2,20 @@ use std::ops::Range;
 
 use crate::{
     geometry::{rect::RectF, vector::Vector2F},
-    json, Drawable, Element, SceneBuilder, SizeConstraint, View, ViewContext,
+    json, AnyElement, Element, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 use serde_json::json;
 
 pub struct Expanded<V: View> {
-    child: Element<V>,
+    child: AnyElement<V>,
     full_width: bool,
     full_height: bool,
 }
 
 impl<V: View> Expanded<V> {
-    pub fn new(child: Element<V>) -> Self {
+    pub fn new(child: impl Element<V>) -> Self {
         Self {
-            child,
+            child: child.into_any(),
             full_width: true,
             full_height: true,
         }
@@ -34,7 +34,7 @@ impl<V: View> Expanded<V> {
     }
 }
 
-impl<V: View> Drawable<V> for Expanded<V> {
+impl<V: View> Element<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, Drawable, Element, ElementStateHandle, SceneBuilder, SizeConstraint, Vector2FExt, View,
+    AnyElement, Axis, 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<Element<V>>,
+    children: Vec<AnyElement<V>>,
     scroll_state: Option<(ElementStateHandle<Rc<ScrollState>>, usize)>,
     child_alignment: f32,
 }
@@ -111,13 +111,13 @@ impl<V: View> Flex<V> {
     }
 }
 
-impl<V: View> Extend<Element<V>> for Flex<V> {
-    fn extend<T: IntoIterator<Item = Element<V>>>(&mut self, children: T) {
+impl<V: View> Extend<AnyElement<V>> for Flex<V> {
+    fn extend<T: IntoIterator<Item = AnyElement<V>>>(&mut self, children: T) {
         self.children.extend(children);
     }
 }
 
-impl<V: View> Drawable<V> for Flex<V> {
+impl<V: View> Element<V> for Flex<V> {
     type LayoutState = f32;
     type PaintState = ();
 
@@ -399,17 +399,17 @@ struct FlexParentData {
 
 pub struct FlexItem<V: View> {
     metadata: FlexParentData,
-    child: Element<V>,
+    child: AnyElement<V>,
 }
 
 impl<V: View> FlexItem<V> {
-    pub fn new(child: Element<V>) -> Self {
+    pub fn new(child: impl Element<V>) -> Self {
         FlexItem {
             metadata: FlexParentData {
                 flex: None,
                 float: false,
             },
-            child,
+            child: child.into_any(),
         }
     }
 
@@ -424,7 +424,7 @@ impl<V: View> FlexItem<V> {
     }
 }
 
-impl<V: View> Drawable<V> for FlexItem<V> {
+impl<V: View> Element<V> for FlexItem<V> {
     type LayoutState = ();
     type PaintState = ();
 

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

@@ -3,18 +3,18 @@ use std::ops::Range;
 use crate::{
     geometry::{rect::RectF, vector::Vector2F},
     json::json,
-    Drawable, Element, SceneBuilder, SizeConstraint, View, ViewContext,
+    AnyElement, Element, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 
 pub struct Hook<V: View> {
-    child: Element<V>,
+    child: AnyElement<V>,
     after_layout: Option<Box<dyn FnMut(Vector2F, &mut ViewContext<V>)>>,
 }
 
 impl<V: View> Hook<V> {
-    pub fn new(child: Element<V>) -> Self {
+    pub fn new(child: impl Element<V>) -> Self {
         Self {
-            child,
+            child: child.into_any(),
             after_layout: None,
         }
     }
@@ -28,7 +28,7 @@ impl<V: View> Hook<V> {
     }
 }
 
-impl<V: View> Drawable<V> for Hook<V> {
+impl<V: View> Element<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, Drawable, ImageData, SceneBuilder, SizeConstraint, View, ViewContext,
+    scene, Border, Element, ImageData, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 use serde::Deserialize;
 use std::{ops::Range, sync::Arc};
@@ -55,7 +55,7 @@ impl Image {
     }
 }
 
-impl<V: View> Drawable<V> for Image {
+impl<V: View> Element<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, Element, SizeConstraint,
+    Action, AnyElement, SizeConstraint,
 };
 use serde_json::json;
 
@@ -31,8 +31,8 @@ impl KeystrokeLabel {
     }
 }
 
-impl<V: View> Drawable<V> for KeystrokeLabel {
-    type LayoutState = Element<V>;
+impl<V: View> Element<V> for KeystrokeLabel {
+    type LayoutState = AnyElement<V>;
     type PaintState = ();
 
     fn layout(
@@ -40,7 +40,7 @@ impl<V: View> Drawable<V> for KeystrokeLabel {
         constraint: SizeConstraint,
         view: &mut V,
         cx: &mut ViewContext<V>,
-    ) -> (Vector2F, Element<V>) {
+    ) -> (Vector2F, AnyElement<V>) {
         let mut element = if let Some(keystrokes) =
             cx.keystrokes_for_action(self.view_id, self.action.as_ref())
         {
@@ -49,11 +49,10 @@ impl<V: View> Drawable<V> for KeystrokeLabel {
                     Label::new(keystroke.to_string(), self.text_style.clone())
                         .contained()
                         .with_style(self.container_style)
-                        .boxed()
                 }))
-                .boxed()
+                .into_any()
         } else {
-            Empty::new().collapsed().boxed()
+            Empty::new().collapsed().into_any()
         };
 
         let size = element.layout(constraint, view, cx);
@@ -65,7 +64,7 @@ impl<V: View> Drawable<V> for KeystrokeLabel {
         scene: &mut SceneBuilder,
         bounds: RectF,
         visible_bounds: RectF,
-        element: &mut Element<V>,
+        element: &mut AnyElement<V>,
         view: &mut V,
         cx: &mut ViewContext<V>,
     ) {
@@ -88,7 +87,7 @@ impl<V: View> Drawable<V> for KeystrokeLabel {
     fn debug(
         &self,
         _: RectF,
-        element: &Element<V>,
+        element: &AnyElement<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},
-    Drawable, SceneBuilder, SizeConstraint, View, ViewContext,
+    Element, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 use serde::Deserialize;
 use serde_json::json;
@@ -127,7 +127,7 @@ impl Label {
     }
 }
 
-impl<V: View> Drawable<V> for Label {
+impl<V: View> Element<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,
-    Drawable, Element, MouseRegion, SceneBuilder, SizeConstraint, View, ViewContext,
+    AnyElement, 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>) -> Element<V>>,
+    render_item: Box<dyn FnMut(&mut V, usize, &mut ViewContext<V>) -> AnyElement<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<Element<V>>>),
+    Rendered(Rc<RefCell<AnyElement<V>>>),
     Removed(f32),
 }
 
@@ -91,7 +91,7 @@ impl<V: View> List<V> {
     }
 }
 
-impl<V: View> Drawable<V> for List<V> {
+impl<V: View> Element<V> for List<V> {
     type LayoutState = ListOffset;
     type PaintState = ();
 
@@ -347,21 +347,21 @@ impl<V: View> Drawable<V> for List<V> {
 }
 
 impl<V: View> ListState<V> {
-    pub fn new<F>(
+    pub fn new<D, F>(
         element_count: usize,
         orientation: Orientation,
         overdraw: f32,
-        render_item: F,
+        mut render_item: F,
     ) -> Self
     where
-        V: View,
-        F: 'static + FnMut(&mut V, usize, &mut ViewContext<V>) -> Element<V>,
+        D: Element<V>,
+        F: 'static + FnMut(&mut V, usize, &mut ViewContext<V>) -> D,
     {
         let mut items = SumTree::new();
         items.extend((0..element_count).map(|_| ListItem::Unrendered), &());
         Self(Rc::new(RefCell::new(StateInner {
             last_layout_width: None,
-            render_item: Box::new(render_item),
+            render_item: Box::new(move |view, ix, cx| render_item(view, ix, cx).into_any()),
             rendered_range: 0..0,
             items,
             logical_scroll_top: None,
@@ -453,7 +453,7 @@ impl<V: View> StateInner<V> {
         constraint: SizeConstraint,
         view: &mut V,
         cx: &mut ViewContext<V>,
-    ) -> Option<Rc<RefCell<Element<V>>>> {
+    ) -> Option<Rc<RefCell<AnyElement<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<Element<V>>>, Vector2F)> + 'a {
+    ) -> impl Iterator<Item = (Rc<RefCell<AnyElement<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, &());
@@ -660,7 +660,7 @@ mod tests {
                 let elements = elements.clone();
                 move |_, ix, _| {
                     let (id, height) = elements.borrow()[ix];
-                    TestElement::new(id, height).boxed()
+                    TestElement::new(id, height).into_any()
                 }
             });
 
@@ -765,7 +765,7 @@ mod tests {
                 let elements = elements.clone();
                 move |_, ix, _| {
                     let (id, height) = elements.borrow()[ix];
-                    TestElement::new(id, height).boxed()
+                    TestElement::new(id, height).into_any()
                 }
             });
 
@@ -920,8 +920,8 @@ mod tests {
             "TestView"
         }
 
-        fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-            Empty::new().boxed()
+        fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+            Empty::new().into_any()
         }
     }
 
@@ -939,7 +939,7 @@ mod tests {
         }
     }
 
-    impl<V: View> Drawable<V> for TestElement {
+    impl<V: View> Element<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,
     },
-    Drawable, Element, EventContext, MouseRegion, MouseState, SceneBuilder, SizeConstraint, View,
+    AnyElement, 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: Element<V>,
+    child: AnyElement<V>,
     region_id: usize,
     cursor_style: Option<CursorStyle>,
     handlers: HandlerSet,
@@ -32,13 +32,13 @@ pub struct MouseEventHandler<Tag: 'static, V: View> {
 /// Element which provides a render_child callback with a MouseState and paints a mouse
 /// region under (or above) it for easy mouse event handling.
 impl<Tag, V: View> MouseEventHandler<Tag, V> {
-    pub fn new<F>(region_id: usize, cx: &mut ViewContext<V>, render_child: F) -> Self
+    pub fn new<D, F>(region_id: usize, cx: &mut ViewContext<V>, render_child: F) -> Self
     where
-        V: View,
-        F: FnOnce(&mut MouseState, &mut ViewContext<V>) -> Element<V>,
+        D: Element<V>,
+        F: FnOnce(&mut MouseState, &mut ViewContext<V>) -> D,
     {
         let mut mouse_state = cx.mouse_state::<Tag>(region_id);
-        let child = render_child(&mut mouse_state, cx);
+        let child = render_child(&mut mouse_state, cx).into_any();
         let notify_on_hover = mouse_state.accessed_hovered();
         let notify_on_click = mouse_state.accessed_clicked();
         Self {
@@ -58,10 +58,10 @@ impl<Tag, V: View> MouseEventHandler<Tag, V> {
     /// Modifies the MouseEventHandler to render the MouseRegion above the child element. Useful
     /// for drag and drop handling and similar events which should be captured before the child
     /// gets the opportunity
-    pub fn above<F>(region_id: usize, cx: &mut ViewContext<V>, render_child: F) -> Self
+    pub fn above<D, F>(region_id: usize, cx: &mut ViewContext<V>, render_child: F) -> Self
     where
-        V: View,
-        F: FnOnce(&mut MouseState, &mut ViewContext<V>) -> Element<V>,
+        D: Element<V>,
+        F: FnOnce(&mut MouseState, &mut ViewContext<V>) -> D,
     {
         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> Drawable<V> for MouseEventHandler<Tag, V> {
+impl<Tag, V: View> Element<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, Drawable, Element, MouseRegion, SceneBuilder, SizeConstraint, View, ViewContext,
+    AnyElement, Axis, Element, MouseRegion, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 use serde_json::json;
 
 pub struct Overlay<V: View> {
-    child: Element<V>,
+    child: AnyElement<V>,
     anchor_position: Option<Vector2F>,
     anchor_corner: AnchorCorner,
     fit_mode: OverlayFitMode,
@@ -73,9 +73,9 @@ impl AnchorCorner {
 }
 
 impl<V: View> Overlay<V> {
-    pub fn new(child: Element<V>) -> Self {
+    pub fn new(child: impl Element<V>) -> Self {
         Self {
-            child,
+            child: child.into_any(),
             anchor_position: None,
             anchor_corner: AnchorCorner::TopLeft,
             fit_mode: OverlayFitMode::None,
@@ -116,7 +116,7 @@ impl<V: View> Overlay<V> {
     }
 }
 
-impl<V: View> Drawable<V> for Overlay<V> {
+impl<V: View> Element<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, Drawable, Element, ElementStateHandle, MouseRegion, SceneBuilder, View, ViewContext,
+    AnyElement, Axis, 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: Element<V>,
+    child: AnyElement<V>,
     state: Rc<ResizeHandleState>,
     _state_handle: ElementStateHandle<Rc<ResizeHandleState>>,
 }
 
 impl<V: View> Resizable<V> {
     pub fn new<Tag: 'static, T: View>(
-        child: Element<V>,
+        child: AnyElement<V>,
         element_id: usize,
         side: Side,
         handle_size: f32,
@@ -108,7 +108,6 @@ impl<V: View> Resizable<V> {
                 Axis::Horizontal => constrained.with_max_width(state.custom_dimension.get()),
                 Axis::Vertical => constrained.with_max_height(state.custom_dimension.get()),
             }
-            .boxed()
         })
         .on_after_layout({
             let state = state.clone();
@@ -116,7 +115,7 @@ impl<V: View> Resizable<V> {
                 state.actual_dimension.set(side.relevant_component(size));
             }
         })
-        .boxed();
+        .into_any();
 
         Self {
             side,
@@ -132,7 +131,7 @@ impl<V: View> Resizable<V> {
     }
 }
 
-impl<V: View> Drawable<V> for Resizable<V> {
+impl<V: View> Element<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},
-    Drawable, Element, SceneBuilder, SizeConstraint, View, ViewContext,
+    AnyElement, 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<Element<V>>,
+    children: Vec<AnyElement<V>>,
 }
 
 impl<V: View> Default for Stack<V> {
@@ -26,7 +26,7 @@ impl<V: View> Stack<V> {
     }
 }
 
-impl<V: View> Drawable<V> for Stack<V> {
+impl<V: View> Element<V> for Stack<V> {
     type LayoutState = ();
     type PaintState = ();
 
@@ -98,8 +98,8 @@ impl<V: View> Drawable<V> for Stack<V> {
     }
 }
 
-impl<V: View> Extend<Element<V>> for Stack<V> {
-    fn extend<T: IntoIterator<Item = Element<V>>>(&mut self, children: T) {
+impl<V: View> Extend<AnyElement<V>> for Stack<V> {
+    fn extend<T: IntoIterator<Item = AnyElement<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, Drawable, SceneBuilder, SizeConstraint, View, ViewContext,
+    scene, Element, SceneBuilder, SizeConstraint, View, ViewContext,
 };
 
 pub struct Svg {
@@ -30,7 +30,7 @@ impl Svg {
     }
 }
 
-impl<V: View> Drawable<V> for Svg {
+impl<V: View> Element<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},
-    Drawable, FontCache, SceneBuilder, SizeConstraint, TextLayoutCache, View, ViewContext,
+    Element, FontCache, SceneBuilder, SizeConstraint, TextLayoutCache, View, ViewContext,
 };
 use log::warn;
 use serde_json::json;
@@ -52,7 +52,7 @@ impl Text {
     }
 }
 
-impl<V: View> Drawable<V> for Text {
+impl<V: View> Element<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, Element, Entity, View, ViewContext};
+    use crate::{elements::Empty, fonts, AnyElement, AppContext, Entity, View, ViewContext};
 
     #[crate::test(self)]
     fn test_soft_wrapping_with_carriage_returns(cx: &mut AppContext) {
@@ -307,8 +307,8 @@ mod tests {
             "TestView"
         }
 
-        fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-            Empty::new().boxed()
+        fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+            Empty::new().into_any()
         }
     }
 }

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

@@ -1,5 +1,5 @@
 use super::{
-    ContainerStyle, Drawable, Element, Flex, KeystrokeLabel, MouseEventHandler, Overlay,
+    AnyElement, ContainerStyle, Element, Flex, KeystrokeLabel, MouseEventHandler, Overlay,
     OverlayFitMode, ParentElement, Text,
 };
 use crate::{
@@ -20,8 +20,8 @@ use util::ResultExt;
 const DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(500);
 
 pub struct Tooltip<V: View> {
-    child: Element<V>,
-    tooltip: Option<Element<V>>,
+    child: AnyElement<V>,
+    tooltip: Option<AnyElement<V>>,
     _state: ElementStateHandle<Rc<TooltipState>>,
 }
 
@@ -55,7 +55,7 @@ impl<V: View> Tooltip<V> {
         text: String,
         action: Option<Box<dyn Action>>,
         style: TooltipStyle,
-        child: Element<V>,
+        child: AnyElement<V>,
         cx: &mut ViewContext<V>,
     ) -> Self {
         struct ElementState<Tag>(Tag);
@@ -71,8 +71,7 @@ impl<V: View> Tooltip<V> {
                 style.clone(),
                 action.as_ref().map(|a| a.boxed_clone()),
                 true,
-            )
-            .boxed();
+            );
             Some(
                 Overlay::new(
                     Self::render_tooltip(focused_view_id, text, style, action, false)
@@ -80,14 +79,13 @@ impl<V: View> Tooltip<V> {
                         .dynamically(move |constraint, view, cx| {
                             SizeConstraint::strict_along(
                                 Axis::Vertical,
-                                collapsed_tooltip.layout(constraint, view, cx).y(),
+                                collapsed_tooltip.layout(constraint, view, cx).0.y(),
                             )
-                        })
-                        .boxed(),
+                        }),
                 )
                 .with_fit_mode(OverlayFitMode::SwitchAnchor)
                 .with_anchor_position(state.position.get())
-                .boxed(),
+                .into_any(),
             )
         } else {
             None
@@ -119,7 +117,7 @@ impl<V: View> Tooltip<V> {
                     cx.notify();
                 }
             })
-            .boxed();
+            .into_any();
         Self {
             child,
             tooltip,
@@ -133,7 +131,7 @@ impl<V: View> Tooltip<V> {
         style: TooltipStyle,
         action: Option<Box<dyn Action>>,
         measure: bool,
-    ) -> impl Drawable<V> {
+    ) -> impl Element<V> {
         Flex::row()
             .with_child({
                 let text = if let Some(max_text_width) = style.max_text_width {
@@ -145,9 +143,9 @@ impl<V: View> Tooltip<V> {
                 };
 
                 if measure {
-                    text.flex(1., false).boxed()
+                    text.flex(1., false).into_any()
                 } else {
-                    text.flex(1., false).aligned().boxed()
+                    text.flex(1., false).aligned().into_any()
                 }
             })
             .with_children(action.and_then(|action| {
@@ -158,9 +156,9 @@ impl<V: View> Tooltip<V> {
                     style.keystroke.text,
                 );
                 if measure {
-                    Some(keystroke_label.boxed())
+                    Some(keystroke_label.into_any())
                 } else {
-                    Some(keystroke_label.aligned().boxed())
+                    Some(keystroke_label.aligned().into_any())
                 }
             }))
             .contained()
@@ -168,7 +166,7 @@ impl<V: View> Tooltip<V> {
     }
 }
 
-impl<V: View> Drawable<V> for Tooltip<V> {
+impl<V: View> Element<V> for Tooltip<V> {
     type LayoutState = ();
     type PaintState = ();
 

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

@@ -1,4 +1,4 @@
-use super::{Drawable, SizeConstraint};
+use super::{Element, SizeConstraint};
 use crate::{
     geometry::{
         rect::RectF,
@@ -6,7 +6,7 @@ use crate::{
     },
     json::{self, json},
     platform::ScrollWheelEvent,
-    Element, MouseRegion, SceneBuilder, View, ViewContext,
+    AnyElement, 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<Element<V>>,
+    items: Vec<AnyElement<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<Element<V>>, &mut ViewContext<V>)>,
+    append_items: Box<dyn Fn(&mut V, Range<usize>, &mut Vec<AnyElement<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<Element<V>>, &mut ViewContext<V>),
+        F: 'static + Fn(&mut V, Range<usize>, &mut Vec<AnyElement<V>>, &mut ViewContext<V>),
     {
         Self {
             state,
@@ -151,7 +151,7 @@ impl<V: View> UniformList<V> {
     }
 }
 
-impl<V: View> Drawable<V> for UniformList<V> {
+impl<V: View> Element<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::{Drawable, Element};
+pub use elements::{AnyElement, Element};
 pub mod executor;
 pub use executor::Task;
 pub mod color;

crates/gpui/src/test.rs 🔗

@@ -19,7 +19,7 @@ use crate::{
     platform,
     platform::Platform,
     util::CwdBacktrace,
-    AppContext, Drawable, Element, Entity, FontCache, Handle, Subscription, TestAppContext, View,
+    AnyElement, AppContext, Element, Entity, FontCache, Handle, Subscription, TestAppContext, View,
     ViewContext,
 };
 
@@ -242,7 +242,7 @@ impl View for EmptyView {
         "empty view"
     }
 
-    fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-        Drawable::boxed(Empty::new())
+    fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+        Empty::new().into_any()
     }
 }

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) -> Element<Self>>,
+    render_item: Box<dyn Fn(usize, ItemType, bool, &AppContext) -> AnyElement<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) -> Element<Self>>(
+    pub fn new<F: 'static + Fn(usize, ItemType, bool, &AppContext) -> AnyElement<Self>>(
         item_count: usize,
         cx: &mut ViewContext<Self>,
         render_item: F,
@@ -92,9 +92,9 @@ impl View for Select {
         "Select"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         if self.item_count == 0 {
-            return Empty::new().boxed();
+            return Empty::new().into_any();
         }
 
         enum Header {}
@@ -107,71 +107,58 @@ impl View for Select {
         };
         let mut result = Flex::column().with_child(
             MouseEventHandler::<Header, _>::new(self.handle.id(), cx, |mouse_state, cx| {
-                Container::new((self.render_item)(
+                (self.render_item)(
                     self.selected_item_ix,
                     ItemType::Header,
                     mouse_state.hovered(),
                     cx,
-                ))
+                )
+                .contained()
                 .with_style(style.header)
-                .boxed()
             })
             .on_click(
                 MouseButton::Left,
                 move |_, _, cx: &mut EventContext<Self>| cx.dispatch_action(ToggleSelect),
-            )
-            .boxed(),
+            ),
         );
         if self.is_open {
-            result.add_child(
-                Overlay::new(
-                    Container::new(
-                        ConstrainedBox::new(
-                            UniformList::new(
-                                self.list_state.clone(),
-                                self.item_count,
-                                cx,
-                                move |this, mut range, items, cx| {
-                                    let selected_item_ix = this.selected_item_ix;
-                                    range.end = range.end.min(this.item_count);
-                                    items.extend(range.map(|ix| {
-                                        MouseEventHandler::<Item, _>::new(
-                                            ix,
-                                            cx,
-                                            |mouse_state, cx| {
-                                                (this.render_item)(
-                                                    ix,
-                                                    if ix == selected_item_ix {
-                                                        ItemType::Selected
-                                                    } else {
-                                                        ItemType::Unselected
-                                                    },
-                                                    mouse_state.hovered(),
-                                                    cx,
-                                                )
-                                            },
-                                        )
-                                        .on_click(
-                                            MouseButton::Left,
-                                            move |_, _, cx: &mut EventContext<Self>| {
-                                                cx.dispatch_action(SelectItem(ix))
-                                            },
-                                        )
-                                        .boxed()
-                                    }))
+            result.add_child(Overlay::new(
+                UniformList::new(
+                    self.list_state.clone(),
+                    self.item_count,
+                    cx,
+                    move |this, mut range, items, cx| {
+                        let selected_item_ix = this.selected_item_ix;
+                        range.end = range.end.min(this.item_count);
+                        items.extend(range.map(|ix| {
+                            MouseEventHandler::<Item, _>::new(ix, cx, |mouse_state, cx| {
+                                (this.render_item)(
+                                    ix,
+                                    if ix == selected_item_ix {
+                                        ItemType::Selected
+                                    } else {
+                                        ItemType::Unselected
+                                    },
+                                    mouse_state.hovered(),
+                                    cx,
+                                )
+                            })
+                            .on_click(
+                                MouseButton::Left,
+                                move |_, _, cx: &mut EventContext<Self>| {
+                                    cx.dispatch_action(SelectItem(ix))
                                 },
                             )
-                            .boxed(),
-                        )
-                        .with_max_height(200.)
-                        .boxed(),
-                    )
-                    .with_style(style.menu)
-                    .boxed(),
+                            .into_any()
+                        }))
+                    },
                 )
-                .boxed(),
-            )
+                .constrained()
+                .with_max_height(200.)
+                .contained()
+                .with_style(style.menu),
+            ));
         }
-        result.boxed()
+        result.into_any()
     }
 }

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>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<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()
@@ -64,15 +64,14 @@ impl View for ActiveBufferLanguage {
                 Label::new(active_language_text, style.text.clone())
                     .contained()
                     .with_style(style.container)
-                    .boxed()
             })
             .with_cursor_style(CursorStyle::PointingHand)
             .on_click(MouseButton::Left, |_, _, cx| {
                 cx.dispatch_action(crate::Toggle)
             })
-            .boxed()
+            .into_any()
         } else {
-            Empty::new().boxed()
+            Empty::new().into_any()
         }
     }
 }

crates/language_selector/src/language_selector.rs 🔗

@@ -182,7 +182,7 @@ impl PickerDelegate for LanguageSelectorDelegate {
         mouse_state: &mut MouseState,
         selected: bool,
         cx: &AppContext,
-    ) -> Element<Picker<Self>> {
+    ) -> AnyElement<Picker<Self>> {
         let settings = cx.global::<Settings>();
         let theme = &settings.theme;
         let mat = &self.matches[ix];
@@ -197,6 +197,6 @@ impl PickerDelegate for LanguageSelectorDelegate {
             .with_highlights(mat.positions.clone())
             .contained()
             .with_style(style.container)
-            .boxed()
+            .into_any()
     }
 }

crates/outline/src/outline.rs 🔗

@@ -202,7 +202,7 @@ impl PickerDelegate for OutlineViewDelegate {
         mouse_state: &mut MouseState,
         selected: bool,
         cx: &AppContext,
-    ) -> Element<Picker<Self>> {
+    ) -> AnyElement<Picker<Self>> {
         let settings = cx.global::<Settings>();
         let string_match = &self.matches[ix];
         let style = settings.theme.picker.item.style_for(mouse_state, selected);
@@ -220,6 +220,6 @@ impl PickerDelegate for OutlineViewDelegate {
             .with_padding_left(20. * outline_item.depth as f32)
             .contained()
             .with_style(style.container)
-            .boxed()
+            .into_any()
     }
 }

crates/picker/src/picker.rs 🔗

@@ -4,7 +4,7 @@ use gpui::{
     geometry::vector::{vec2f, Vector2F},
     keymap_matcher::KeymapContext,
     platform::{CursorStyle, MouseButton},
-    AnyViewHandle, AppContext, Axis, Element, Entity, MouseState, Task, View, ViewContext,
+    AnyElement, AnyViewHandle, AppContext, Axis, Entity, MouseState, Task, View, ViewContext,
     ViewHandle,
 };
 use menu::{Cancel, Confirm, SelectFirst, SelectIndex, SelectLast, SelectNext, SelectPrev};
@@ -41,7 +41,7 @@ pub trait PickerDelegate: Sized + 'static {
         state: &mut MouseState,
         selected: bool,
         cx: &AppContext,
-    ) -> Element<Picker<Self>>;
+    ) -> AnyElement<Picker<Self>>;
     fn center_selection_after_match_updates(&self) -> bool {
         false
     }
@@ -56,7 +56,7 @@ impl<D: PickerDelegate> View for Picker<D> {
         "Picker"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let theme = (self.theme.lock())(&cx.global::<settings::Settings>().theme);
         let query = self.query(cx);
         let match_count = self.delegate.match_count();
@@ -75,8 +75,7 @@ impl<D: PickerDelegate> View for Picker<D> {
             .with_child(
                 ChildView::new(&self.query_editor, cx)
                     .contained()
-                    .with_style(editor_style)
-                    .boxed(),
+                    .with_style(editor_style),
             )
             .with_children(if match_count == 0 {
                 if query.is_empty() {
@@ -86,7 +85,7 @@ impl<D: PickerDelegate> View for Picker<D> {
                         Label::new("No matches", theme.no_matches.label.clone())
                             .contained()
                             .with_style(theme.no_matches.container)
-                            .boxed(),
+                            .into_any(),
                     )
                 }
             } else {
@@ -109,14 +108,14 @@ impl<D: PickerDelegate> View for Picker<D> {
                                     cx.dispatch_action(SelectIndex(ix))
                                 })
                                 .with_cursor_style(CursorStyle::PointingHand)
-                                .boxed()
+                                .into_any()
                             }));
                         },
                     )
                     .contained()
                     .with_margin_top(6.0)
                     .flex(1., false)
-                    .boxed(),
+                    .into_any(),
                 )
             })
             .contained()
@@ -124,7 +123,7 @@ impl<D: PickerDelegate> View for Picker<D> {
             .constrained()
             .with_max_width(self.max_size.x())
             .with_max_height(self.max_size.y())
-            .named("picker")
+            .into_any_named("picker")
     }
 
     fn keymap_context(&self, _: &AppContext) -> KeymapContext {

crates/project_panel/src/project_panel.rs 🔗

@@ -6,14 +6,14 @@ use gpui::{
     actions,
     anyhow::{anyhow, Result},
     elements::{
-        AnchorCorner, ChildView, ConstrainedBox, ContainerStyle, Empty, Flex, Label,
-        MouseEventHandler, ParentElement, ScrollTarget, Stack, Svg, UniformList, UniformListState,
+        AnchorCorner, ChildView, ContainerStyle, Empty, Flex, Label, MouseEventHandler,
+        ParentElement, ScrollTarget, Stack, Svg, UniformList, UniformListState,
     },
     geometry::vector::Vector2F,
     impl_internal_actions,
     keymap_matcher::KeymapContext,
     platform::{CursorStyle, MouseButton, PromptLevel},
-    AppContext, ClipboardItem, Drawable, Element, Entity, ModelHandle, Task, View, ViewContext,
+    AnyElement, AppContext, ClipboardItem, Element, Entity, ModelHandle, Task, View, ViewContext,
     ViewHandle,
 };
 use menu::{Confirm, SelectNext, SelectPrev};
@@ -1098,31 +1098,27 @@ impl ProjectPanel {
         row_container_style: ContainerStyle,
         style: &ProjectPanelEntry,
         cx: &mut ViewContext<V>,
-    ) -> Element<V> {
+    ) -> AnyElement<V> {
         let kind = details.kind;
         let show_editor = details.is_editing && !details.is_processing;
 
         Flex::row()
             .with_child(
-                ConstrainedBox::new(if kind == EntryKind::Dir {
+                if kind == EntryKind::Dir {
                     if details.is_expanded {
-                        Svg::new("icons/chevron_down_8.svg")
-                            .with_color(style.icon_color)
-                            .boxed()
+                        Svg::new("icons/chevron_down_8.svg").with_color(style.icon_color)
                     } else {
-                        Svg::new("icons/chevron_right_8.svg")
-                            .with_color(style.icon_color)
-                            .boxed()
+                        Svg::new("icons/chevron_right_8.svg").with_color(style.icon_color)
                     }
+                    .constrained()
                 } else {
-                    Empty::new().boxed()
-                })
+                    Empty::new().constrained()
+                }
                 .with_max_width(style.icon_size)
                 .with_max_height(style.icon_size)
                 .aligned()
                 .constrained()
-                .with_width(style.icon_size)
-                .boxed(),
+                .with_width(style.icon_size),
             )
             .with_child(if show_editor && editor.is_some() {
                 ChildView::new(editor.as_ref().unwrap(), cx)
@@ -1131,21 +1127,21 @@ impl ProjectPanel {
                     .aligned()
                     .left()
                     .flex(1.0, true)
-                    .boxed()
+                    .into_any()
             } else {
                 Label::new(details.filename.clone(), style.text.clone())
                     .contained()
                     .with_margin_left(style.icon_spacing)
                     .aligned()
                     .left()
-                    .boxed()
+                    .into_any()
             })
             .constrained()
             .with_height(style.height)
             .contained()
             .with_style(row_container_style)
             .with_padding_left(padding)
-            .boxed()
+            .into_any_named("project panel entry visual element")
     }
 
     fn render_entry(
@@ -1155,7 +1151,7 @@ impl ProjectPanel {
         dragged_entry_destination: &mut Option<Arc<Path>>,
         theme: &theme::ProjectPanel,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         let kind = details.kind;
         let path = details.path.clone();
         let padding = theme.container.padding.left + details.depth as f32 * theme.indent_width;
@@ -1259,7 +1255,7 @@ impl ProjectPanel {
             }
         })
         .with_cursor_style(CursorStyle::PointingHand)
-        .boxed()
+        .into_any_named("project panel entry")
     }
 }
 
@@ -1268,7 +1264,7 @@ impl View for ProjectPanel {
         "ProjectPanel"
     }
 
-    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::Element<Self> {
+    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::AnyElement<Self> {
         enum ProjectPanel {}
         let theme = &cx.global::<Settings>().theme.project_panel;
         let mut container_style = theme.container;
@@ -1310,7 +1306,6 @@ impl View for ProjectPanel {
                         .contained()
                         .with_style(container_style)
                         .expanded()
-                        .boxed()
                     })
                     .on_down(MouseButton::Right, move |e, _, cx| {
                         // When deploying the context menu anywhere below the last project entry,
@@ -1321,11 +1316,10 @@ impl View for ProjectPanel {
                                 position: e.position,
                             })
                         }
-                    })
-                    .boxed(),
+                    }),
                 )
-                .with_child(ChildView::new(&self.context_menu, cx).boxed())
-                .boxed()
+                .with_child(ChildView::new(&self.context_menu, cx))
+                .into_any_named("project panel")
         } else {
             Flex::column()
                 .with_child(
@@ -1345,18 +1339,16 @@ impl View for ProjectPanel {
                                 Box::new(workspace::Open),
                                 cx,
                             )
-                            .boxed()
                         }
                     })
                     .on_click(MouseButton::Left, move |_, _, cx| {
                         cx.dispatch_action(workspace::Open)
                     })
-                    .with_cursor_style(CursorStyle::PointingHand)
-                    .boxed(),
+                    .with_cursor_style(CursorStyle::PointingHand),
                 )
                 .contained()
                 .with_style(container_style)
-                .boxed()
+                .into_any_named("empty project panel")
         }
     }
 

crates/project_symbols/src/project_symbols.rs 🔗

@@ -201,7 +201,7 @@ impl PickerDelegate for ProjectSymbolsDelegate {
         mouse_state: &mut MouseState,
         selected: bool,
         cx: &AppContext,
-    ) -> Element<Picker<Self>> {
+    ) -> AnyElement<Picker<Self>> {
         let string_match = &self.matches[ix];
         let settings = cx.global::<Settings>();
         let style = &settings.theme.picker.item;
@@ -231,17 +231,16 @@ impl PickerDelegate for ProjectSymbolsDelegate {
                         current_style.label.text.clone().into(),
                         syntax_runs,
                         &string_match.positions,
-                    ))
-                    .boxed(),
+                    )),
             )
             .with_child(
                 // Avoid styling the path differently when it is selected, since
                 // the symbol's syntax highlighting doesn't change when selected.
-                Label::new(path.to_string(), style.default.label.clone()).boxed(),
+                Label::new(path.to_string(), style.default.label.clone()),
             )
             .contained()
             .with_style(current_style.container)
-            .boxed()
+            .into_any()
     }
 }
 

crates/recent_projects/src/highlighted_workspace_location.rs 🔗

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

crates/recent_projects/src/recent_projects.rs 🔗

@@ -5,7 +5,7 @@ use gpui::{
     actions,
     anyhow::Result,
     elements::{Flex, ParentElement},
-    AppContext, Drawable, Element, Task, ViewContext,
+    AnyElement, AppContext, Element, Task, ViewContext,
 };
 use highlighted_workspace_location::HighlightedWorkspaceLocation;
 use ordered_float::OrderedFloat;
@@ -156,7 +156,7 @@ impl PickerDelegate for RecentProjectsDelegate {
         mouse_state: &mut gpui::MouseState,
         selected: bool,
         cx: &gpui::AppContext,
-    ) -> Element<Picker<Self>> {
+    ) -> AnyElement<Picker<Self>> {
         let settings = cx.global::<Settings>();
         let string_match = &self.matches[ix];
         let style = settings.theme.picker.item.style_for(mouse_state, selected);
@@ -177,6 +177,6 @@ impl PickerDelegate for RecentProjectsDelegate {
             .flex(1., false)
             .contained()
             .with_style(style.container)
-            .named("match")
+            .into_any_named("match")
     }
 }

crates/search/src/buffer_search.rs 🔗

@@ -92,7 +92,7 @@ impl View for BufferSearchBar {
         }
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let theme = cx.global::<Settings>().theme.clone();
         let editor_container = if self.query_contains_error {
             theme.search.invalid_editor
@@ -114,8 +114,7 @@ impl View for BufferSearchBar {
                                 ChildView::new(&self.query_editor, cx)
                                     .aligned()
                                     .left()
-                                    .flex(1., true)
-                                    .boxed(),
+                                    .flex(1., true),
                             )
                             .with_children(self.active_searchable_item.as_ref().and_then(
                                 |searchable_item| {
@@ -132,8 +131,7 @@ impl View for BufferSearchBar {
                                         Label::new(message, theme.search.match_index.text.clone())
                                             .contained()
                                             .with_style(theme.search.match_index.container)
-                                            .aligned()
-                                            .boxed(),
+                                            .aligned(),
                                     )
                                 },
                             ))
@@ -143,15 +141,13 @@ impl View for BufferSearchBar {
                             .constrained()
                             .with_min_width(theme.search.editor.min_width)
                             .with_max_width(theme.search.editor.max_width)
-                            .flex(1., false)
-                            .boxed(),
+                            .flex(1., false),
                     )
                     .with_child(
                         Flex::row()
                             .with_child(self.render_nav_button("<", Direction::Prev, cx))
                             .with_child(self.render_nav_button(">", Direction::Next, cx))
-                            .aligned()
-                            .boxed(),
+                            .aligned(),
                     )
                     .with_child(
                         Flex::row()
@@ -175,16 +171,14 @@ impl View for BufferSearchBar {
                             ))
                             .contained()
                             .with_style(theme.search.option_button_group)
-                            .aligned()
-                            .boxed(),
+                            .aligned(),
                     )
-                    .flex(1., true)
-                    .boxed(),
+                    .flex(1., true),
             )
             .with_child(self.render_close_button(&theme.search, cx))
             .contained()
             .with_style(theme.search.container)
-            .named("search bar")
+            .into_any_named("search bar")
     }
 }
 
@@ -325,7 +319,7 @@ impl BufferSearchBar {
         icon: &'static str,
         option: SearchOption,
         cx: &mut ViewContext<Self>,
-    ) -> Option<Element<Self>> {
+    ) -> Option<AnyElement<Self>> {
         if !option_supported {
             return None;
         }
@@ -343,7 +337,6 @@ impl BufferSearchBar {
                 Label::new(icon, style.text.clone())
                     .contained()
                     .with_style(style.container)
-                    .boxed()
             })
             .on_click(MouseButton::Left, move |_, _, cx| {
                 cx.dispatch_any_action(option.to_toggle_action())
@@ -356,7 +349,7 @@ impl BufferSearchBar {
                 tooltip_style,
                 cx,
             )
-            .boxed(),
+            .into_any(),
         )
     }
 
@@ -365,7 +358,7 @@ impl BufferSearchBar {
         icon: &'static str,
         direction: Direction,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         let action: Box<dyn Action>;
         let tooltip;
         match direction {
@@ -391,7 +384,6 @@ impl BufferSearchBar {
             Label::new(icon, style.text.clone())
                 .contained()
                 .with_style(style.container)
-                .boxed()
         })
         .on_click(MouseButton::Left, {
             let action = action.boxed_clone();
@@ -405,14 +397,14 @@ impl BufferSearchBar {
             tooltip_style,
             cx,
         )
-        .boxed()
+        .into_any()
     }
 
     fn render_close_button(
         &self,
         theme: &theme::Search,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         let action = Box::new(Dismiss);
         let tooltip = "Dismiss Buffer Search";
         let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
@@ -429,7 +421,6 @@ impl BufferSearchBar {
                 .with_width(style.button_width)
                 .contained()
                 .with_style(style.container)
-                .boxed()
         })
         .on_click(MouseButton::Left, {
             let action = action.boxed_clone();
@@ -437,7 +428,7 @@ impl BufferSearchBar {
         })
         .with_cursor_style(CursorStyle::PointingHand)
         .with_tooltip::<CloseButton>(0, tooltip.to_string(), Some(action), tooltip_style, cx)
-        .boxed()
+        .into_any()
     }
 
     fn deploy(pane: &mut Pane, action: &Deploy, cx: &mut ViewContext<Pane>) {

crates/search/src/project_search.rs 🔗

@@ -12,7 +12,7 @@ use gpui::{
     actions,
     elements::*,
     platform::{CursorStyle, MouseButton},
-    Action, AnyViewHandle, AppContext, Element, Entity, ModelContext, ModelHandle, Subscription,
+    Action, AnyElement, AnyViewHandle, AppContext, Entity, ModelContext, ModelHandle, Subscription,
     Task, View, ViewContext, ViewHandle, WeakModelHandle, WeakViewHandle,
 };
 use menu::Confirm;
@@ -178,7 +178,7 @@ impl View for ProjectSearchView {
         "ProjectSearchView"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let model = &self.model.read(cx);
         if model.match_ranges.is_empty() {
             enum Status {}
@@ -197,16 +197,15 @@ impl View for ProjectSearchView {
                     .contained()
                     .with_background_color(theme.editor.background)
                     .flex(1., true)
-                    .boxed()
             })
             .on_down(MouseButton::Left, |_, _, cx| {
                 cx.focus_parent_view();
             })
-            .boxed()
+            .into_any_named("project search view")
         } else {
             ChildView::new(&self.results_editor, cx)
                 .flex(1., true)
-                .boxed()
+                .into_any_named("project search view")
         }
     }
 
@@ -254,7 +253,7 @@ impl Item for ProjectSearchView {
         _detail: Option<usize>,
         tab_theme: &theme::Tab,
         cx: &AppContext,
-    ) -> Element<T> {
+    ) -> AnyElement<T> {
         Flex::row()
             .with_child(
                 Svg::new("icons/magnifying_glass_12.svg")
@@ -263,17 +262,14 @@ impl Item for ProjectSearchView {
                     .with_width(tab_theme.type_icon_width)
                     .aligned()
                     .contained()
-                    .with_margin_right(tab_theme.spacing)
-                    .boxed(),
+                    .with_margin_right(tab_theme.spacing),
             )
             .with_children(self.model.read(cx).active_query.as_ref().map(|query| {
                 let query_text = util::truncate_and_trailoff(query.as_str(), MAX_TAB_TITLE_LEN);
 
-                Label::new(query_text, tab_theme.label.clone())
-                    .aligned()
-                    .boxed()
+                Label::new(query_text, tab_theme.label.clone()).aligned()
             }))
-            .boxed()
+            .into_any()
     }
 
     fn for_each_project_item(&self, cx: &AppContext, f: &mut dyn FnMut(usize, &dyn project::Item)) {
@@ -752,7 +748,7 @@ impl ProjectSearchBar {
         icon: &'static str,
         direction: Direction,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         let action: Box<dyn Action>;
         let tooltip;
         match direction {
@@ -778,7 +774,6 @@ impl ProjectSearchBar {
             Label::new(icon, style.text.clone())
                 .contained()
                 .with_style(style.container)
-                .boxed()
         })
         .on_click(MouseButton::Left, {
             let action = action.boxed_clone();
@@ -792,7 +787,7 @@ impl ProjectSearchBar {
             tooltip_style,
             cx,
         )
-        .boxed()
+        .into_any()
     }
 
     fn render_option_button(
@@ -800,7 +795,7 @@ impl ProjectSearchBar {
         icon: &'static str,
         option: SearchOption,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<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| {
@@ -813,7 +808,6 @@ impl ProjectSearchBar {
             Label::new(icon, style.text.clone())
                 .contained()
                 .with_style(style.container)
-                .boxed()
         })
         .on_click(MouseButton::Left, move |_, _, cx| {
             cx.dispatch_any_action(option.to_toggle_action())
@@ -826,7 +820,7 @@ impl ProjectSearchBar {
             tooltip_style,
             cx,
         )
-        .boxed()
+        .into_any()
     }
 
     fn is_option_enabled(&self, option: SearchOption, cx: &AppContext) -> bool {
@@ -852,7 +846,7 @@ impl View for ProjectSearchBar {
         "ProjectSearchBar"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         if let Some(search) = self.active_project_search.as_ref() {
             let search = search.read(cx);
             let theme = cx.global::<Settings>().theme.clone();
@@ -868,8 +862,7 @@ impl View for ProjectSearchBar {
                             ChildView::new(&search.query_editor, cx)
                                 .aligned()
                                 .left()
-                                .flex(1., true)
-                                .boxed(),
+                                .flex(1., true),
                         )
                         .with_children(search.active_match_index.map(|match_ix| {
                             Label::new(
@@ -883,7 +876,6 @@ impl View for ProjectSearchBar {
                             .contained()
                             .with_style(theme.search.match_index.container)
                             .aligned()
-                            .boxed()
                         }))
                         .contained()
                         .with_style(editor_container)
@@ -891,15 +883,13 @@ impl View for ProjectSearchBar {
                         .constrained()
                         .with_min_width(theme.search.editor.min_width)
                         .with_max_width(theme.search.editor.max_width)
-                        .flex(1., false)
-                        .boxed(),
+                        .flex(1., false),
                 )
                 .with_child(
                     Flex::row()
                         .with_child(self.render_nav_button("<", Direction::Prev, cx))
                         .with_child(self.render_nav_button(">", Direction::Next, cx))
-                        .aligned()
-                        .boxed(),
+                        .aligned(),
                 )
                 .with_child(
                     Flex::row()
@@ -912,16 +902,15 @@ impl View for ProjectSearchBar {
                         .with_child(self.render_option_button("Regex", SearchOption::Regex, cx))
                         .contained()
                         .with_style(theme.search.option_button_group)
-                        .aligned()
-                        .boxed(),
+                        .aligned(),
                 )
                 .contained()
                 .with_style(theme.search.container)
                 .aligned()
                 .left()
-                .named("project search")
+                .into_any_named("project search")
         } else {
-            Empty::new().boxed()
+            Empty::new().into_any()
         }
     }
 }

crates/settings/src/settings_file.rs 🔗

@@ -94,8 +94,8 @@ mod tests {
             "TestView"
         }
 
-        fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-            Empty::new().boxed()
+        fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+            Empty::new().into_any()
         }
     }
 

crates/terminal_view/src/terminal_button.rs 🔗

@@ -3,7 +3,7 @@ use gpui::{
     elements::*,
     impl_internal_actions,
     platform::{CursorStyle, MouseButton},
-    AppContext, Drawable, Element, Entity, View, ViewContext, ViewHandle, WeakModelHandle,
+    AnyElement, AppContext, Element, Entity, View, ViewContext, ViewHandle, WeakModelHandle,
     WeakViewHandle,
 };
 use settings::Settings;
@@ -42,11 +42,11 @@ impl View for TerminalButton {
         "TerminalButton"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let workspace = self.workspace.upgrade(cx);
         let project = match workspace {
             Some(workspace) => workspace.read(cx).project().read(cx),
-            None => return Empty::new().boxed(),
+            None => return Empty::new().into_any(),
         };
 
         let focused_view = cx.focused_view_id();
@@ -79,20 +79,18 @@ impl View for TerminalButton {
                                     .constrained()
                                     .with_width(style.icon_size)
                                     .aligned()
-                                    .named("terminals-icon"),
+                                    .into_any_named("terminals-icon"),
                             )
                             .with_children(has_terminals.then(|| {
                                 Label::new(terminal_count.to_string(), style.label.text.clone())
                                     .contained()
                                     .with_style(style.label.container)
                                     .aligned()
-                                    .boxed()
                             }))
                             .constrained()
                             .with_height(style.icon_size)
                             .contained()
                             .with_style(style.container)
-                            .boxed()
                     }
                 })
                 .with_cursor_style(CursorStyle::PointingHand)
@@ -111,17 +109,10 @@ impl View for TerminalButton {
                     Some(Box::new(FocusDock)),
                     theme.tooltip.clone(),
                     cx,
-                )
-                .boxed(),
+                ),
             )
-            .with_child(
-                ChildView::new(&self.popup_menu, cx)
-                    .aligned()
-                    .top()
-                    .right()
-                    .boxed(),
-            )
-            .boxed()
+            .with_child(ChildView::new(&self.popup_menu, cx).aligned().top().right())
+            .into_any_named("terminal button")
     }
 }
 

crates/terminal_view/src/terminal_element.rs 🔗

@@ -10,7 +10,7 @@ use gpui::{
     platform::{CursorStyle, MouseButton},
     serde_json::json,
     text_layout::{Line, RunStyle},
-    Drawable, Element, EventContext, FontCache, ModelContext, MouseRegion, Quad, SceneBuilder,
+    AnyElement, Element, EventContext, FontCache, ModelContext, MouseRegion, Quad, SceneBuilder,
     SizeConstraint, TextLayoutCache, ViewContext, WeakModelHandle,
 };
 use itertools::Itertools;
@@ -45,7 +45,7 @@ pub struct LayoutState {
     size: TerminalSize,
     mode: TermMode,
     display_offset: usize,
-    hyperlink_tooltip: Option<Element<TerminalView>>,
+    hyperlink_tooltip: Option<AnyElement<TerminalView>>,
     gutter: f32,
 }
 
@@ -552,7 +552,7 @@ impl TerminalElement {
     }
 }
 
-impl Drawable<TerminalView> for TerminalElement {
+impl Element<TerminalView> for TerminalElement {
     type LayoutState = LayoutState;
     type PaintState = ();
 
@@ -605,11 +605,10 @@ impl Drawable<TerminalView> for TerminalElement {
                     .constrained()
                     .with_width(dimensions.width())
                     .with_height(dimensions.height())
-                    .with_tooltip::<TerminalElement>(id, uri, None, tooltip_style, cx)
-                    .boxed(),
+                    .with_tooltip::<TerminalElement>(id, uri, None, tooltip_style, cx),
             )
             .with_position_mode(gpui::elements::OverlayPositionMode::Local)
-            .boxed();
+            .into_any();
 
             tooltip.layout(
                 SizeConstraint::new(Vector2F::zero(), cx.window_size()),

crates/terminal_view/src/terminal_view.rs 🔗

@@ -18,7 +18,7 @@ use gpui::{
     impl_actions, impl_internal_actions,
     keymap_matcher::{KeymapContext, Keystroke},
     platform::KeyDownEvent,
-    AnyViewHandle, AppContext, Drawable, Element, Entity, ModelHandle, Task, View, ViewContext,
+    AnyElement, AnyViewHandle, AppContext, Element, Entity, ModelHandle, Task, View, ViewContext,
     ViewHandle, WeakViewHandle,
 };
 use project::{LocalWorktree, Project};
@@ -387,7 +387,7 @@ impl View for TerminalView {
         "Terminal"
     }
 
-    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> AnyElement<Self> {
         let terminal_handle = self.terminal.clone().downgrade();
 
         let self_id = cx.view_id();
@@ -403,11 +403,10 @@ impl View for TerminalView {
                     focused,
                     self.should_show_cursor(focused, cx),
                 )
-                .contained()
-                .boxed(),
+                .contained(),
             )
-            .with_child(ChildView::new(&self.context_menu, cx).boxed())
-            .boxed()
+            .with_child(ChildView::new(&self.context_menu, cx))
+            .into_any()
     }
 
     fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
@@ -550,7 +549,7 @@ impl Item for TerminalView {
         _detail: Option<usize>,
         tab_theme: &theme::Tab,
         cx: &gpui::AppContext,
-    ) -> Element<T> {
+    ) -> AnyElement<T> {
         let title = self.terminal().read(cx).title();
 
         Flex::row()
@@ -561,11 +560,10 @@ impl Item for TerminalView {
                     .with_width(tab_theme.type_icon_width)
                     .aligned()
                     .contained()
-                    .with_margin_right(tab_theme.spacing)
-                    .boxed(),
+                    .with_margin_right(tab_theme.spacing),
             )
-            .with_child(Label::new(title, tab_theme.label.clone()).aligned().boxed())
-            .boxed()
+            .with_child(Label::new(title, tab_theme.label.clone()).aligned())
+            .into_any()
     }
 
     fn clone_on_split(

crates/theme/src/ui.rs 🔗

@@ -11,7 +11,7 @@ use gpui::{
     platform,
     platform::MouseButton,
     scene::MouseClick,
-    Action, Drawable, Element, EventContext, MouseState, View, ViewContext,
+    Action, Element, EventContext, MouseState, View, ViewContext,
 };
 use serde::Deserialize;
 
@@ -36,14 +36,13 @@ pub fn checkbox<Tag: 'static, V: View>(
 ) -> MouseEventHandler<Tag, V> {
     let label = Label::new(label, style.label.text.clone())
         .contained()
-        .with_style(style.label.container)
-        .boxed();
+        .with_style(style.label.container);
 
     checkbox_with_label(label, style, checked, cx, change)
 }
 
-pub fn checkbox_with_label<Tag: 'static, V: View>(
-    label: Element<V>,
+pub fn checkbox_with_label<Tag: 'static, D: Element<V>, V: View>(
+    label: D,
     style: &CheckboxStyle,
     checked: bool,
     cx: &mut ViewContext<V>,
@@ -60,27 +59,21 @@ pub fn checkbox_with_label<Tag: 'static, V: View>(
         };
 
         Flex::row()
-            .with_children([
-                indicator
-                    .contained()
-                    .with_style(if checked {
-                        if state.hovered() {
-                            style.hovered_and_checked
-                        } else {
-                            style.checked
-                        }
-                    } else {
-                        if state.hovered() {
-                            style.hovered
-                        } else {
-                            style.default
-                        }
-                    })
-                    .boxed(),
-                label,
-            ])
+            .with_child(indicator.contained().with_style(if checked {
+                if state.hovered() {
+                    style.hovered_and_checked
+                } else {
+                    style.checked
+                }
+            } else {
+                if state.hovered() {
+                    style.hovered
+                } else {
+                    style.default
+                }
+            }))
+            .with_child(label)
             .align_children_center()
-            .boxed()
     })
     .on_click(platform::MouseButton::Left, move |_, _, cx| {
         change(!checked, cx)
@@ -151,21 +144,16 @@ pub fn keystroke_label_for<V: View>(
     action: Box<dyn Action>,
 ) -> Container<V> {
     Flex::row()
+        .with_child(Label::new(label_text, label_style.text.clone()).contained())
         .with_child(
-            Label::new(label_text, label_style.text.clone())
-                .contained()
-                .boxed(),
-        )
-        .with_child({
             KeystrokeLabel::new(
                 view_id,
                 action,
                 keystroke_style.container,
                 keystroke_style.text.clone(),
             )
-            .flex_float()
-            .boxed()
-        })
+            .flex_float(),
+        )
         .contained()
         .with_style(label_style.container)
 }
@@ -178,7 +166,7 @@ pub fn cta_button<L, A, V>(
     max_width: f32,
     style: &ButtonStyle,
     cx: &mut ViewContext<V>,
-) -> Element<V>
+) -> MouseEventHandler<A, V>
 where
     L: Into<Cow<'static, str>>,
     A: 'static + Action + Clone,
@@ -187,7 +175,6 @@ where
     cta_button_with_click::<A, _, _, _>(label, max_width, style, cx, move |_, _, cx| {
         cx.dispatch_action(action.clone())
     })
-    .boxed()
 }
 
 pub fn cta_button_with_click<Tag, L, V, F>(
@@ -211,7 +198,6 @@ where
             .with_style(style.container)
             .constrained()
             .with_max_width(max_width)
-            .boxed()
     })
     .on_click(MouseButton::Left, f)
     .with_cursor_style(platform::CursorStyle::PointingHand)
@@ -232,17 +218,18 @@ impl ModalStyle {
     }
 }
 
-pub fn modal<Tag, V, I, F>(
+pub fn modal<Tag, V, I, D, F>(
     title: I,
     style: &ModalStyle,
     cx: &mut ViewContext<V>,
     build_modal: F,
-) -> Element<V>
+) -> impl Element<V>
 where
     Tag: 'static,
     V: View,
     I: Into<Cow<'static, str>>,
-    F: FnOnce(&mut gpui::ViewContext<V>) -> Element<V>,
+    D: Element<V>,
+    F: FnOnce(&mut gpui::ViewContext<V>) -> D,
 {
     const TITLEBAR_HEIGHT: f32 = 28.;
     // let active = cx.window_is_active(cx.window_id());
@@ -250,43 +237,39 @@ where
     Flex::column()
         .with_child(
             Stack::new()
-                .with_children([
-                    Label::new(
-                        title,
-                        style
-                            .title_text
-                            .style_for(&mut MouseState::default(), false)
-                            .clone(),
-                    )
-                    .boxed(),
+                .with_child(Label::new(
+                    title,
+                    style
+                        .title_text
+                        .style_for(&mut MouseState::default(), false)
+                        .clone(),
+                ))
+                .with_child(
                     // FIXME: Get a better tag type
                     MouseEventHandler::<Tag, V>::new(999999, cx, |state, _cx| {
                         let style = style.close_icon.style_for(state, false);
-                        icon(style).boxed()
+                        icon(style)
                     })
                     .on_click(platform::MouseButton::Left, move |_, _, cx| {
                         cx.remove_window();
                     })
                     .with_cursor_style(platform::CursorStyle::PointingHand)
                     .aligned()
-                    .right()
-                    .boxed(),
-                ])
+                    .right(),
+                )
                 .contained()
                 .with_style(style.titlebar)
                 .constrained()
-                .with_height(TITLEBAR_HEIGHT)
-                .boxed(),
+                .with_height(TITLEBAR_HEIGHT),
         )
         .with_child(
-            Container::new(build_modal(cx))
+            build_modal(cx)
+                .contained()
                 .with_style(style.container)
                 .constrained()
                 .with_width(style.dimensions().x())
-                .with_height(style.dimensions().y() - TITLEBAR_HEIGHT)
-                .boxed(),
+                .with_height(style.dimensions().y() - TITLEBAR_HEIGHT),
         )
         .constrained()
         .with_height(style.dimensions().y())
-        .boxed()
 }

crates/theme_selector/src/theme_selector.rs 🔗

@@ -1,5 +1,5 @@
 use fuzzy::{match_strings, StringMatch, StringMatchCandidate};
-use gpui::{actions, elements::*, AppContext, Drawable, Element, MouseState, ViewContext};
+use gpui::{actions, elements::*, AnyElement, AppContext, Element, MouseState, ViewContext};
 use picker::{Picker, PickerDelegate, PickerEvent};
 use settings::{settings_file::SettingsFile, Settings};
 use staff_mode::StaffMode;
@@ -207,7 +207,7 @@ impl PickerDelegate for ThemeSelectorDelegate {
         mouse_state: &mut MouseState,
         selected: bool,
         cx: &AppContext,
-    ) -> Element<Picker<Self>> {
+    ) -> AnyElement<Picker<Self>> {
         let settings = cx.global::<Settings>();
         let theme = &settings.theme;
         let theme_match = &self.matches[ix];
@@ -217,6 +217,6 @@ impl PickerDelegate for ThemeSelectorDelegate {
             .with_highlights(theme_match.positions.clone())
             .contained()
             .with_style(style.container)
-            .boxed()
+            .into_any()
     }
 }

crates/theme_testbench/src/theme_testbench.rs 🔗

@@ -2,11 +2,11 @@ use gpui::{
     actions,
     color::Color,
     elements::{
-        Canvas, Container, ContainerStyle, Element, Flex, Label, Margin, MouseEventHandler,
+        AnyElement, Canvas, Container, ContainerStyle, Flex, Label, Margin, MouseEventHandler,
         Padding, ParentElement,
     },
     fonts::TextStyle,
-    AppContext, Border, Drawable, Entity, ModelHandle, Quad, Task, View, ViewContext, ViewHandle,
+    AppContext, Border, Element, 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>) -> Element<ThemeTestbench> {
+        fn display_ramp(ramp: &Vec<Color>) -> AnyElement<ThemeTestbench> {
             Flex::row()
                 .with_children(ramp.iter().cloned().map(|color| {
                     Canvas::new(move |scene, bounds, _, _, _| {
@@ -46,10 +46,9 @@ impl ThemeTestbench {
                         });
                     })
                     .flex(1.0, false)
-                    .boxed()
                 }))
                 .flex(1.0, false)
-                .boxed()
+                .into_any()
         }
 
         Flex::column()
@@ -71,39 +70,30 @@ impl ThemeTestbench {
     ) -> Container<Self> {
         Flex::column()
             .with_child(
-                Self::render_button_set(0, layer_index, "base", &layer.base, cx)
-                    .flex(1., false)
-                    .boxed(),
+                Self::render_button_set(0, layer_index, "base", &layer.base, cx).flex(1., false),
             )
             .with_child(
                 Self::render_button_set(1, layer_index, "variant", &layer.variant, cx)
-                    .flex(1., false)
-                    .boxed(),
+                    .flex(1., false),
             )
             .with_child(
-                Self::render_button_set(2, layer_index, "on", &layer.on, cx)
-                    .flex(1., false)
-                    .boxed(),
+                Self::render_button_set(2, layer_index, "on", &layer.on, cx).flex(1., false),
             )
             .with_child(
                 Self::render_button_set(3, layer_index, "accent", &layer.accent, cx)
-                    .flex(1., false)
-                    .boxed(),
+                    .flex(1., false),
             )
             .with_child(
                 Self::render_button_set(4, layer_index, "positive", &layer.positive, cx)
-                    .flex(1., false)
-                    .boxed(),
+                    .flex(1., false),
             )
             .with_child(
                 Self::render_button_set(5, layer_index, "warning", &layer.warning, cx)
-                    .flex(1., false)
-                    .boxed(),
+                    .flex(1., false),
             )
             .with_child(
                 Self::render_button_set(6, layer_index, "negative", &layer.negative, cx)
-                    .flex(1., false)
-                    .boxed(),
+                    .flex(1., false),
             )
             .contained()
             .with_style(ContainerStyle {
@@ -183,7 +173,7 @@ impl ThemeTestbench {
         style_set: &StyleSet,
         style_override: Option<fn(&StyleSet) -> &Style>,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         enum TestBenchButton {}
         MouseEventHandler::<TestBenchButton, _>::new(layer_index + button_index, cx, |state, cx| {
             let style = if let Some(style_override) = style_override {
@@ -224,10 +214,9 @@ impl ThemeTestbench {
                     corner_radius: 2.,
                     ..Default::default()
                 })
-                .boxed()
         })
         .flex(1., true)
-        .boxed()
+        .into_any()
     }
 
     fn render_label(text: String, style: &Style, cx: &mut ViewContext<Self>) -> Label {
@@ -262,7 +251,7 @@ impl View for ThemeTestbench {
         "ThemeTestbench"
     }
 
-    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> AnyElement<Self> {
         let color_scheme = &cx.global::<Settings>().theme.clone().color_scheme;
 
         Flex::row()
@@ -270,30 +259,16 @@ impl View for ThemeTestbench {
                 Self::render_ramps(color_scheme)
                     .contained()
                     .with_margin_right(10.)
-                    .flex(0.1, false)
-                    .boxed(),
+                    .flex(0.1, false),
             )
             .with_child(
                 Flex::column()
-                    .with_child(
-                        Self::render_layer(100, &color_scheme.lowest, cx)
-                            .flex(1., true)
-                            .boxed(),
-                    )
-                    .with_child(
-                        Self::render_layer(200, &color_scheme.middle, cx)
-                            .flex(1., true)
-                            .boxed(),
-                    )
-                    .with_child(
-                        Self::render_layer(300, &color_scheme.highest, cx)
-                            .flex(1., true)
-                            .boxed(),
-                    )
-                    .flex(1., false)
-                    .boxed(),
+                    .with_child(Self::render_layer(100, &color_scheme.lowest, cx).flex(1., true))
+                    .with_child(Self::render_layer(200, &color_scheme.middle, cx).flex(1., true))
+                    .with_child(Self::render_layer(300, &color_scheme.highest, cx).flex(1., true))
+                    .flex(1., false),
             )
-            .boxed()
+            .into_any()
     }
 }
 
@@ -303,11 +278,11 @@ impl Item for ThemeTestbench {
         _: Option<usize>,
         style: &theme::Tab,
         _: &AppContext,
-    ) -> Element<T> {
+    ) -> AnyElement<T> {
         Label::new("Theme Testbench", style.label.clone())
             .aligned()
             .contained()
-            .boxed()
+            .into_any()
     }
 
     fn serialized_item_kind() -> Option<&'static str> {

crates/welcome/src/base_keymap_picker.rs 🔗

@@ -3,7 +3,7 @@ use std::sync::Arc;
 use fuzzy::{match_strings, StringMatch, StringMatchCandidate};
 use gpui::{
     actions,
-    elements::{Drawable as _, Label},
+    elements::{Element as _, Label},
     AppContext, Task, ViewContext,
 };
 use picker::{Picker, PickerDelegate, PickerEvent};
@@ -134,7 +134,7 @@ impl PickerDelegate for BaseKeymapSelectorDelegate {
         mouse_state: &mut gpui::MouseState,
         selected: bool,
         cx: &gpui::AppContext,
-    ) -> gpui::Element<Picker<Self>> {
+    ) -> gpui::AnyElement<Picker<Self>> {
         let theme = &cx.global::<Settings>().theme;
         let keymap_match = &self.matches[ix];
         let style = theme.picker.item.style_for(mouse_state, selected);
@@ -143,6 +143,6 @@ impl PickerDelegate for BaseKeymapSelectorDelegate {
             .with_highlights(keymap_match.positions.clone())
             .contained()
             .with_style(style.container)
-            .boxed()
+            .into_any()
     }
 }

crates/welcome/src/welcome.rs 🔗

@@ -5,7 +5,7 @@ use std::{borrow::Cow, sync::Arc};
 use db::kvp::KEY_VALUE_STORE;
 use gpui::{
     elements::{Flex, Label, ParentElement},
-    AppContext, Drawable, Element, Entity, Subscription, View, ViewContext,
+    AnyElement, AppContext, 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>) -> Element<Self> {
+    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> AnyElement<Self> {
         let self_handle = cx.handle();
         let settings = cx.global::<Settings>();
         let theme = settings.theme.clone();
@@ -73,78 +73,77 @@ impl View for WelcomePage {
         PaneBackdrop::new(
             self_handle.id(),
             Flex::column()
-                .with_children([
+                .with_child(
                     Flex::column()
-                        .with_children([
+                        .with_child(
                             theme::ui::svg(&theme.welcome.logo)
                                 .aligned()
                                 .contained()
-                                .aligned()
-                                .boxed(),
+                                .aligned(),
+                        )
+                        .with_child(
                             Label::new(
                                 "Code at the speed of thought",
                                 theme.welcome.logo_subheading.text.clone(),
                             )
                             .aligned()
                             .contained()
-                            .with_style(theme.welcome.logo_subheading.container)
-                            .boxed(),
-                        ])
+                            .with_style(theme.welcome.logo_subheading.container),
+                        )
                         .contained()
                         .with_style(theme.welcome.heading_group)
                         .constrained()
-                        .with_width(width)
-                        .boxed(),
+                        .with_width(width),
+                )
+                .with_child(
                     Flex::column()
-                        .with_children([
-                            theme::ui::cta_button(
-                                "Choose a theme",
-                                theme_selector::Toggle,
-                                width,
-                                &theme.welcome.button,
-                                cx,
-                            ),
-                            theme::ui::cta_button(
-                                "Choose a keymap",
-                                ToggleBaseKeymapSelector,
-                                width,
-                                &theme.welcome.button,
-                                cx,
-                            ),
-                            theme::ui::cta_button(
-                                "Install the CLI",
-                                install_cli::Install,
-                                width,
-                                &theme.welcome.button,
-                                cx,
-                            ),
-                        ])
+                        .with_child(theme::ui::cta_button(
+                            "Choose a theme",
+                            theme_selector::Toggle,
+                            width,
+                            &theme.welcome.button,
+                            cx,
+                        ))
+                        .with_child(theme::ui::cta_button(
+                            "Choose a keymap",
+                            ToggleBaseKeymapSelector,
+                            width,
+                            &theme.welcome.button,
+                            cx,
+                        ))
+                        .with_child(theme::ui::cta_button(
+                            "Install the CLI",
+                            install_cli::Install,
+                            width,
+                            &theme.welcome.button,
+                            cx,
+                        ))
                         .contained()
                         .with_style(theme.welcome.button_group)
                         .constrained()
-                        .with_width(width)
-                        .boxed(),
+                        .with_width(width),
+                )
+                .with_child(
                     Flex::column()
-                        .with_children([
-                            theme::ui::checkbox_with_label::<Metrics, Self>(
+                        .with_child(
+                            theme::ui::checkbox_with_label::<Metrics, _, Self>(
                                 Flex::column()
-                                    .with_children([
+                                    .with_child(
                                         Label::new(
                                             "Send anonymous usage data",
                                             theme.welcome.checkbox.label.text.clone(),
                                         )
                                         .contained()
-                                        .with_style(theme.welcome.checkbox.label.container)
-                                        .boxed(),
+                                        .with_style(theme.welcome.checkbox.label.container),
+                                    )
+                                    .with_child(
                                         Label::new(
                                             "Help > View Telemetry",
                                             theme.welcome.usage_note.text.clone(),
                                         )
                                         .contained()
-                                        .with_style(theme.welcome.usage_note.container)
-                                        .boxed(),
-                                    ])
-                                    .boxed(),
+                                        .with_style(theme.welcome.usage_note.container),
+                                    ),
                                 &theme.welcome.checkbox,
                                 metrics,
                                 cx,
@@ -155,8 +154,9 @@ impl View for WelcomePage {
                                 },
                             )
                             .contained()
-                            .with_style(theme.welcome.checkbox_container)
-                            .boxed(),
+                            .with_style(theme.welcome.checkbox_container),
+                        )
+                        .with_child(
                             theme::ui::checkbox::<Diagnostics, Self>(
                                 "Send crash reports",
                                 &theme.welcome.checkbox,
@@ -169,23 +169,21 @@ impl View for WelcomePage {
                                 },
                             )
                             .contained()
-                            .with_style(theme.welcome.checkbox_container)
-                            .boxed(),
-                        ])
+                            .with_style(theme.welcome.checkbox_container),
+                        )
                         .contained()
                         .with_style(theme.welcome.checkbox_group)
                         .constrained()
-                        .with_width(width)
-                        .boxed(),
-                ])
+                        .with_width(width),
+                )
                 .constrained()
                 .with_max_width(width)
                 .contained()
                 .with_uniform_padding(10.)
                 .aligned()
-                .boxed(),
+                .into_any(),
         )
-        .boxed()
+        .into_any_named("welcome page")
     }
 }
 
@@ -207,15 +205,14 @@ impl Item for WelcomePage {
         _detail: Option<usize>,
         style: &theme::Tab,
         _cx: &gpui::AppContext,
-    ) -> Element<T> {
+    ) -> AnyElement<T> {
         Flex::row()
             .with_child(
                 Label::new("Welcome to Zed!", style.label.clone())
                     .aligned()
-                    .contained()
-                    .boxed(),
+                    .contained(),
             )
-            .boxed()
+            .into_any()
     }
 
     fn show_toolbar(&self) -> bool {

crates/workspace/src/dock.rs 🔗

@@ -5,11 +5,11 @@ use serde::Deserialize;
 use collections::HashMap;
 use gpui::{
     actions,
-    elements::{ChildView, Container, Empty, MouseEventHandler, ParentElement, Side, Stack},
+    elements::{ChildView, Empty, MouseEventHandler, ParentElement, Side, Stack},
     geometry::vector::Vector2F,
     impl_internal_actions,
     platform::{CursorStyle, MouseButton},
-    AppContext, Border, Drawable, Element, SizeConstraint, ViewContext, ViewHandle,
+    AnyElement, AppContext, Border, 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<Element<Workspace>> {
+    ) -> Option<AnyElement<Workspace>> {
         let style = &theme.workspace.dock;
 
         self.position
@@ -348,7 +348,8 @@ impl Dock {
 
                     enum DockResizeHandle {}
 
-                    let resizable = Container::new(ChildView::new(&self.pane, cx).boxed())
+                    let resizable = ChildView::new(&self.pane, cx)
+                        .contained()
                         .with_style(panel_style)
                         .with_resize_handle::<DockResizeHandle>(
                             resize_side as usize,
@@ -367,26 +368,21 @@ impl Dock {
                     });
 
                     if anchor == DockAnchor::Right {
-                        resizable
-                            .constrained()
-                            .dynamically(|constraint, _, cx| {
-                                SizeConstraint::new(
-                                    Vector2F::new(20., constraint.min.y()),
-                                    Vector2F::new(cx.window_size().x() * 0.8, constraint.max.y()),
-                                )
-                            })
-                            .boxed()
+                        resizable.constrained().dynamically(|constraint, _, cx| {
+                            SizeConstraint::new(
+                                Vector2F::new(20., constraint.min.y()),
+                                Vector2F::new(cx.window_size().x() * 0.8, constraint.max.y()),
+                            )
+                        })
                     } else {
-                        resizable
-                            .constrained()
-                            .dynamically(|constraint, _, cx| {
-                                SizeConstraint::new(
-                                    Vector2F::new(constraint.min.x(), 50.),
-                                    Vector2F::new(constraint.max.x(), cx.window_size().y() * 0.8),
-                                )
-                            })
-                            .boxed()
+                        resizable.constrained().dynamically(|constraint, _, cx| {
+                            SizeConstraint::new(
+                                Vector2F::new(constraint.min.x(), 50.),
+                                Vector2F::new(constraint.max.x(), cx.window_size().y() * 0.8),
+                            )
+                        })
                     }
+                    .into_any()
                 }
                 DockAnchor::Expanded => {
                     enum ExpandedDockWash {}
@@ -398,27 +394,24 @@ impl Dock {
                                 Empty::new()
                                     .contained()
                                     .with_background_color(style.wash_color)
-                                    .boxed()
                             })
                             .capture_all()
                             .on_down(MouseButton::Left, |_, _, cx| {
                                 cx.dispatch_action(HideDock);
                             })
-                            .with_cursor_style(CursorStyle::Arrow)
-                            .boxed(),
+                            .with_cursor_style(CursorStyle::Arrow),
                         )
                         .with_child(
                             MouseEventHandler::<ExpandedDockPane, _>::new(0, cx, |_state, cx| {
-                                ChildView::new(&self.pane, cx).boxed()
+                                ChildView::new(&self.pane, cx)
                             })
                             // Make sure all events directly under the dock pane
                             // are captured
                             .capture_all()
                             .contained()
-                            .with_style(style.maximized)
-                            .boxed(),
+                            .with_style(style.maximized),
                         )
-                        .boxed()
+                        .into_any()
                 }
             })
     }

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

@@ -2,7 +2,7 @@ use gpui::{
     elements::{Empty, MouseEventHandler, Svg},
     platform::CursorStyle,
     platform::MouseButton,
-    Drawable, Element, Entity, View, ViewContext, ViewHandle, WeakViewHandle,
+    AnyElement, Element, Entity, View, ViewContext, ViewHandle, WeakViewHandle,
 };
 use settings::Settings;
 
@@ -34,11 +34,11 @@ impl View for ToggleDockButton {
         "Dock Toggle"
     }
 
-    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> AnyElement<Self> {
         let workspace = self.workspace.upgrade(cx);
 
         if workspace.is_none() {
-            return Empty::new().boxed();
+            return Empty::new().into_any();
         }
 
         let workspace = workspace.unwrap();
@@ -64,7 +64,6 @@ impl View for ToggleDockButton {
                     .with_height(style.icon_size)
                     .contained()
                     .with_style(style.container)
-                    .boxed()
             }
         })
         .with_cursor_style(CursorStyle::PointingHand)
@@ -98,7 +97,7 @@ impl View for ToggleDockButton {
                     cx,
                 )
         }
-        .boxed()
+        .into_any()
     }
 }
 

crates/workspace/src/item.rs 🔗

@@ -6,7 +6,7 @@ use crate::{
 use anyhow::{anyhow, Result};
 use client::{proto, Client};
 use gpui::{
-    fonts::HighlightStyle, AnyViewHandle, AppContext, Element, ModelHandle, Task, View,
+    fonts::HighlightStyle, AnyElement, AnyViewHandle, AppContext, ModelHandle, Task, View,
     ViewContext, ViewHandle, WeakViewHandle, WindowContext,
 };
 use project::{Project, ProjectEntryId, ProjectPath};
@@ -59,7 +59,7 @@ pub trait Item: View {
         detail: Option<usize>,
         style: &theme::Tab,
         cx: &AppContext,
-    ) -> Element<V>;
+    ) -> AnyElement<V>;
     fn for_each_project_item(&self, _: &AppContext, _: &mut dyn FnMut(usize, &dyn project::Item)) {}
     fn is_singleton(&self, _cx: &AppContext) -> bool {
         false
@@ -180,13 +180,13 @@ pub trait ItemHandle: 'static + fmt::Debug {
         detail: Option<usize>,
         style: &theme::Tab,
         cx: &AppContext,
-    ) -> Element<Pane>;
+    ) -> AnyElement<Pane>;
     fn dragged_tab_content(
         &self,
         detail: Option<usize>,
         style: &theme::Tab,
         cx: &AppContext,
-    ) -> Element<Workspace>;
+    ) -> AnyElement<Workspace>;
     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]>;
@@ -283,7 +283,7 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
         detail: Option<usize>,
         style: &theme::Tab,
         cx: &AppContext,
-    ) -> Element<Pane> {
+    ) -> AnyElement<Pane> {
         self.read(cx).tab_content(detail, style, cx)
     }
 
@@ -292,7 +292,7 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
         detail: Option<usize>,
         style: &theme::Tab,
         cx: &AppContext,
-    ) -> Element<Workspace> {
+    ) -> AnyElement<Workspace> {
         self.read(cx).tab_content(detail, style, cx)
     }
 
@@ -770,7 +770,7 @@ pub(crate) mod test {
     use super::{Item, ItemEvent};
     use crate::{sidebar::SidebarItem, ItemId, ItemNavHistory, Pane, Workspace, WorkspaceId};
     use gpui::{
-        elements::Empty, AppContext, Drawable, Element, Entity, ModelHandle, Task, View,
+        elements::Empty, AnyElement, AppContext, Element, Entity, ModelHandle, Task, View,
         ViewContext, ViewHandle, WeakViewHandle,
     };
     use project::{Project, ProjectEntryId, ProjectPath, WorktreeId};
@@ -929,8 +929,8 @@ pub(crate) mod test {
             "TestItem"
         }
 
-        fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
-            Empty::new().boxed()
+        fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
+            Empty::new().into_any()
         }
     }
 
@@ -947,9 +947,9 @@ pub(crate) mod test {
             detail: Option<usize>,
             _: &theme::Tab,
             _: &AppContext,
-        ) -> Element<V> {
+        ) -> AnyElement<V> {
             self.tab_detail.set(detail);
-            Empty::new().boxed()
+            Empty::new().into_any()
         }
 
         fn for_each_project_item(

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, Drawable, Entity, View, ViewContext,
+        Action, AppContext, Element, 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::Element<Self> {
+        fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::AnyElement<Self> {
             let theme = cx.global::<Settings>().theme.clone();
             let theme = &theme.simple_message_notification;
 
@@ -255,8 +255,7 @@ pub mod simple_message_notification {
                                     .aligned()
                                     .top()
                                     .left()
-                                    .flex(1., true)
-                                    .boxed(),
+                                    .flex(1., true),
                             )
                             .with_child(
                                 MouseEventHandler::<Cancel, _>::new(0, cx, |state, _| {
@@ -271,7 +270,6 @@ pub mod simple_message_notification {
                                         .constrained()
                                         .with_width(style.button_width)
                                         .with_height(style.button_width)
-                                        .boxed()
                                 })
                                 .with_padding(Padding::uniform(5.))
                                 .on_click(MouseButton::Left, move |_, _, cx| {
@@ -285,23 +283,18 @@ pub mod simple_message_notification {
                                 )
                                 .aligned()
                                 .top()
-                                .flex_float()
-                                .boxed(),
-                            )
-                            .boxed(),
+                                .flex_float(),
+                            ),
                     )
                     .with_children({
                         let style = theme.action_message.style_for(state, false);
                         if let Some(click_message) = click_message {
                             Some(
-                                Flex::row()
-                                    .with_child(
-                                        Text::new(click_message, style.text.clone())
-                                            .contained()
-                                            .with_style(style.container)
-                                            .boxed(),
-                                    )
-                                    .boxed(),
+                                Flex::row().with_child(
+                                    Text::new(click_message, style.text.clone())
+                                        .contained()
+                                        .with_style(style.container),
+                                ),
                             )
                         } else {
                             None
@@ -309,7 +302,6 @@ pub mod simple_message_notification {
                         .into_iter()
                     })
                     .contained()
-                    .boxed()
             })
             // Since we're not using a proper overlay, we have to capture these extra events
             .on_down(MouseButton::Left, |_, _, _| {})
@@ -325,7 +317,7 @@ pub mod simple_message_notification {
             } else {
                 CursorStyle::Arrow
             })
-            .boxed()
+            .into_any()
         }
     }
 

crates/workspace/src/pane.rs 🔗

@@ -1360,7 +1360,7 @@ impl Pane {
         });
     }
 
-    fn render_tabs(&mut self, cx: &mut ViewContext<Self>) -> impl Drawable<Self> {
+    fn render_tabs(&mut self, cx: &mut ViewContext<Self>) -> impl Element<Self> {
         let theme = cx.global::<Settings>().theme.clone();
 
         let pane = cx.handle().downgrade();
@@ -1387,7 +1387,7 @@ impl Pane {
             row.add_child({
                 enum TabDragReceiver {}
                 let mut receiver =
-                    dragged_item_receiver::<TabDragReceiver, _>(ix, ix, true, None, cx, {
+                    dragged_item_receiver::<TabDragReceiver, _, _>(ix, ix, true, None, cx, {
                         let item = item.clone();
                         let pane = pane.clone();
                         let detail = detail.clone();
@@ -1441,7 +1441,7 @@ impl Pane {
                                 );
 
                             if let Some(tab_tooltip_text) = tab_tooltip_text {
-                                return mouse_event_handler
+                                mouse_event_handler
                                     .with_tooltip::<Self>(
                                         ix,
                                         tab_tooltip_text,
@@ -1449,10 +1449,10 @@ impl Pane {
                                         tooltip_theme,
                                         cx,
                                     )
-                                    .boxed();
+                                    .into_any()
+                            } else {
+                                mouse_event_handler.into_any()
                             }
-
-                            mouse_event_handler.boxed()
                         }
                     });
 
@@ -1460,31 +1460,29 @@ impl Pane {
                     receiver = receiver.with_cursor_style(CursorStyle::PointingHand);
                 }
 
-                receiver
-                    .as_draggable(
-                        DraggedItem {
-                            item,
-                            pane: pane.clone(),
-                        },
-                        {
-                            let theme = cx.global::<Settings>().theme.clone();
-
-                            let detail = detail.clone();
-                            move |dragged_item: &DraggedItem, cx: &mut ViewContext<Workspace>| {
-                                let tab_style = &theme.workspace.tab_bar.dragged_tab;
-                                Self::render_dragged_tab(
-                                    &dragged_item.item,
-                                    dragged_item.pane.clone(),
-                                    false,
-                                    detail,
-                                    false,
-                                    &tab_style,
-                                    cx,
-                                )
-                            }
-                        },
-                    )
-                    .boxed()
+                receiver.as_draggable(
+                    DraggedItem {
+                        item,
+                        pane: pane.clone(),
+                    },
+                    {
+                        let theme = cx.global::<Settings>().theme.clone();
+
+                        let detail = detail.clone();
+                        move |dragged_item: &DraggedItem, cx: &mut ViewContext<Workspace>| {
+                            let tab_style = &theme.workspace.tab_bar.dragged_tab;
+                            Self::render_dragged_tab(
+                                &dragged_item.item,
+                                dragged_item.pane.clone(),
+                                false,
+                                detail,
+                                false,
+                                &tab_style,
+                                cx,
+                            )
+                        }
+                    },
+                )
             })
         }
 
@@ -1494,15 +1492,14 @@ impl Pane {
         let filler_style = theme.workspace.tab_bar.tab_style(pane_active, false);
         enum Filler {}
         row.add_child(
-            dragged_item_receiver::<Filler, _>(0, filler_index, true, None, cx, |_, _| {
+            dragged_item_receiver::<Filler, _, _>(0, filler_index, true, None, cx, |_, _| {
                 Empty::new()
                     .contained()
                     .with_style(filler_style.container)
                     .with_border(filler_style.container.border)
-                    .boxed()
             })
             .flex(1., true)
-            .named("filler"),
+            .into_any_named("filler"),
         );
 
         row
@@ -1553,7 +1550,7 @@ impl Pane {
         hovered: bool,
         tab_style: &theme::Tab,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         let title = item.tab_content(detail, &tab_style, cx);
         Self::render_tab_with_title(title, item, pane, first, hovered, tab_style, cx)
     }
@@ -1566,118 +1563,103 @@ impl Pane {
         hovered: bool,
         tab_style: &theme::Tab,
         cx: &mut ViewContext<Workspace>,
-    ) -> Element<Workspace> {
+    ) -> AnyElement<Workspace> {
         let title = item.dragged_tab_content(detail, &tab_style, cx);
         Self::render_tab_with_title(title, item, pane, first, hovered, tab_style, cx)
     }
 
     fn render_tab_with_title<T: View>(
-        title: Element<T>,
+        title: AnyElement<T>,
         item: &Box<dyn ItemHandle>,
         pane: WeakViewHandle<Pane>,
         first: bool,
         hovered: bool,
         tab_style: &theme::Tab,
         cx: &mut ViewContext<T>,
-    ) -> Element<T> {
+    ) -> AnyElement<T> {
         let mut container = tab_style.container.clone();
         if first {
             container.border.left = false;
         }
 
         Flex::row()
-            .with_child(
-                Align::new({
-                    let diameter = 7.0;
-                    let icon_color = if item.has_conflict(cx) {
-                        Some(tab_style.icon_conflict)
-                    } else if item.is_dirty(cx) {
-                        Some(tab_style.icon_dirty)
-                    } else {
-                        None
-                    };
-
-                    ConstrainedBox::new(
-                        Canvas::new(move |scene, bounds, _, _, _| {
-                            if let Some(color) = icon_color {
-                                let square = RectF::new(bounds.origin(), vec2f(diameter, diameter));
-                                scene.push_quad(Quad {
-                                    bounds: square,
-                                    background: Some(color),
-                                    border: Default::default(),
-                                    corner_radius: diameter / 2.,
-                                });
-                            }
-                        })
-                        .boxed(),
-                    )
-                    .with_width(diameter)
-                    .with_height(diameter)
-                    .boxed()
+            .with_child({
+                let diameter = 7.0;
+                let icon_color = if item.has_conflict(cx) {
+                    Some(tab_style.icon_conflict)
+                } else if item.is_dirty(cx) {
+                    Some(tab_style.icon_dirty)
+                } else {
+                    None
+                };
+
+                Canvas::new(move |scene, bounds, _, _, _| {
+                    if let Some(color) = icon_color {
+                        let square = RectF::new(bounds.origin(), vec2f(diameter, diameter));
+                        scene.push_quad(Quad {
+                            bounds: square,
+                            background: Some(color),
+                            border: Default::default(),
+                            corner_radius: diameter / 2.,
+                        });
+                    }
                 })
-                .boxed(),
-            )
+                .constrained()
+                .with_width(diameter)
+                .with_height(diameter)
+                .aligned()
+            })
+            .with_child(title.aligned().contained().with_style(ContainerStyle {
+                margin: Margin {
+                    left: tab_style.spacing,
+                    right: tab_style.spacing,
+                    ..Default::default()
+                },
+                ..Default::default()
+            }))
             .with_child(
-                Container::new(Align::new(title).boxed())
-                    .with_style(ContainerStyle {
-                        margin: Margin {
-                            left: tab_style.spacing,
-                            right: tab_style.spacing,
-                            ..Default::default()
-                        },
-                        ..Default::default()
+                if hovered {
+                    let item_id = item.id();
+                    enum TabCloseButton {}
+                    let icon = Svg::new("icons/x_mark_8.svg");
+                    MouseEventHandler::<TabCloseButton, _>::new(item_id, cx, |mouse_state, _| {
+                        if mouse_state.hovered() {
+                            icon.with_color(tab_style.icon_close_active)
+                        } else {
+                            icon.with_color(tab_style.icon_close)
+                        }
                     })
-                    .boxed(),
-            )
-            .with_child(
-                Align::new(
-                    ConstrainedBox::new(if hovered {
-                        let item_id = item.id();
-                        enum TabCloseButton {}
-                        let icon = Svg::new("icons/x_mark_8.svg");
-                        MouseEventHandler::<TabCloseButton, _>::new(
-                            item_id,
-                            cx,
-                            |mouse_state, _| {
-                                if mouse_state.hovered() {
-                                    icon.with_color(tab_style.icon_close_active).boxed()
-                                } else {
-                                    icon.with_color(tab_style.icon_close).boxed()
-                                }
-                            },
-                        )
-                        .with_padding(Padding::uniform(4.))
-                        .with_cursor_style(CursorStyle::PointingHand)
-                        .on_click(MouseButton::Left, {
-                            let pane = pane.clone();
-                            move |_, _, cx| {
-                                cx.dispatch_action(CloseItemById {
-                                    item_id,
-                                    pane: pane.clone(),
-                                })
-                            }
-                        })
-                        .named("close-tab-icon")
-                    } else {
-                        Empty::new().boxed()
+                    .with_padding(Padding::uniform(4.))
+                    .with_cursor_style(CursorStyle::PointingHand)
+                    .on_click(MouseButton::Left, {
+                        let pane = pane.clone();
+                        move |_, _, cx| {
+                            cx.dispatch_action(CloseItemById {
+                                item_id,
+                                pane: pane.clone(),
+                            })
+                        }
                     })
-                    .with_width(tab_style.close_icon_width)
-                    .boxed(),
-                )
-                .boxed(),
+                    .into_any_named("close-tab-icon")
+                    .constrained()
+                } else {
+                    Empty::new().constrained()
+                }
+                .with_width(tab_style.close_icon_width)
+                .aligned(),
             )
             .contained()
             .with_style(container)
             .constrained()
             .with_height(tab_style.height)
-            .boxed()
+            .into_any()
     }
 
     fn render_tab_bar_buttons(
         &mut self,
         theme: &Theme,
         cx: &mut ViewContext<Self>,
-    ) -> Element<Self> {
+    ) -> AnyElement<Self> {
         Flex::row()
             // New menu
             .with_child(render_tab_bar_button(
@@ -1723,15 +1705,19 @@ impl Pane {
             .contained()
             .with_style(theme.workspace.tab_bar.pane_button_container)
             .flex(1., false)
-            .boxed()
+            .into_any()
     }
 
-    fn render_blank_pane(&mut self, theme: &Theme, _cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render_blank_pane(
+        &mut self,
+        theme: &Theme,
+        _cx: &mut ViewContext<Self>,
+    ) -> AnyElement<Self> {
         let background = theme.workspace.background;
         Empty::new()
             .contained()
             .with_background_color(background)
-            .boxed()
+            .into_any()
     }
 }
 
@@ -1744,116 +1730,106 @@ impl View for Pane {
         "Pane"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         enum MouseNavigationHandler {}
 
-        Stack::new()
-            .with_child(
-                MouseEventHandler::<MouseNavigationHandler, _>::new(0, cx, |_, cx| {
-                    let active_item_index = self.active_item_index;
-
-                    if let Some(active_item) = self.active_item() {
-                        Flex::column()
-                            .with_child({
-                                let theme = cx.global::<Settings>().theme.clone();
+        MouseEventHandler::<MouseNavigationHandler, _>::new(0, cx, |_, cx| {
+            let active_item_index = self.active_item_index;
 
-                                let mut stack = Stack::new();
+            if let Some(active_item) = self.active_item() {
+                Flex::column()
+                    .with_child({
+                        let theme = cx.global::<Settings>().theme.clone();
 
-                                enum TabBarEventHandler {}
-                                stack.add_child(
-                                    MouseEventHandler::<TabBarEventHandler, _>::new(
-                                        0,
-                                        cx,
-                                        |_, _| {
-                                            Empty::new()
-                                                .contained()
-                                                .with_style(theme.workspace.tab_bar.container)
-                                                .boxed()
-                                        },
-                                    )
-                                    .on_down(MouseButton::Left, move |_, _, cx| {
-                                        cx.dispatch_action(ActivateItem(active_item_index));
-                                    })
-                                    .boxed(),
-                                );
+                        let mut stack = Stack::new();
 
-                                let mut tab_row = Flex::row()
-                                    .with_child(self.render_tabs(cx).flex(1., true).named("tabs"));
+                        enum TabBarEventHandler {}
+                        stack.add_child(
+                            MouseEventHandler::<TabBarEventHandler, _>::new(0, cx, |_, _| {
+                                Empty::new()
+                                    .contained()
+                                    .with_style(theme.workspace.tab_bar.container)
+                            })
+                            .on_down(
+                                MouseButton::Left,
+                                move |_, _, cx| {
+                                    cx.dispatch_action(ActivateItem(active_item_index));
+                                },
+                            ),
+                        );
+
+                        let mut tab_row = Flex::row()
+                            .with_child(self.render_tabs(cx).flex(1., true).into_any_named("tabs"));
+
+                        if self.is_active {
+                            tab_row.add_child(self.render_tab_bar_buttons(&theme, cx))
+                        }
 
-                                if self.is_active {
-                                    tab_row.add_child(self.render_tab_bar_buttons(&theme, cx))
+                        stack.add_child(tab_row);
+                        stack
+                            .constrained()
+                            .with_height(theme.workspace.tab_bar.height)
+                            .flex(1., false)
+                            .into_any_named("tab bar")
+                    })
+                    .with_child({
+                        enum PaneContentTabDropTarget {}
+                        dragged_item_receiver::<PaneContentTabDropTarget, _, _>(
+                            0,
+                            self.active_item_index + 1,
+                            false,
+                            if self.docked.is_some() {
+                                None
+                            } else {
+                                Some(100.)
+                            },
+                            cx,
+                            {
+                                let toolbar = self.toolbar.clone();
+                                let toolbar_hidden = toolbar.read(cx).hidden();
+                                move |_, cx| {
+                                    Flex::column()
+                                        .with_children(
+                                            (!toolbar_hidden)
+                                                .then(|| ChildView::new(&toolbar, cx).expanded()),
+                                        )
+                                        .with_child(
+                                            ChildView::new(active_item.as_any(), cx).flex(1., true),
+                                        )
                                 }
+                            },
+                        )
+                        .flex(1., true)
+                    })
+                    .with_child(ChildView::new(&self.tab_context_menu, cx))
+                    .into_any()
+            } else {
+                enum EmptyPane {}
+                let theme = cx.global::<Settings>().theme.clone();
 
-                                stack.add_child(tab_row.boxed());
-                                stack
-                                    .constrained()
-                                    .with_height(theme.workspace.tab_bar.height)
-                                    .flex(1., false)
-                                    .named("tab bar")
-                            })
-                            .with_child({
-                                enum PaneContentTabDropTarget {}
-                                dragged_item_receiver::<PaneContentTabDropTarget, _>(
-                                    0,
-                                    self.active_item_index + 1,
-                                    false,
-                                    if self.docked.is_some() {
-                                        None
-                                    } else {
-                                        Some(100.)
-                                    },
-                                    cx,
-                                    {
-                                        let toolbar = self.toolbar.clone();
-                                        let toolbar_hidden = toolbar.read(cx).hidden();
-                                        move |_, cx| {
-                                            Flex::column()
-                                                .with_children((!toolbar_hidden).then(|| {
-                                                    ChildView::new(&toolbar, cx).expanded().boxed()
-                                                }))
-                                                .with_child(
-                                                    ChildView::new(active_item.as_any(), cx)
-                                                        .flex(1., true)
-                                                        .boxed(),
-                                                )
-                                                .boxed()
-                                        }
-                                    },
-                                )
-                                .flex(1., true)
-                                .boxed()
-                            })
-                            .with_child(ChildView::new(&self.tab_context_menu, cx).boxed())
-                            .boxed()
-                    } else {
-                        enum EmptyPane {}
-                        let theme = cx.global::<Settings>().theme.clone();
-
-                        dragged_item_receiver::<EmptyPane, _>(0, 0, false, None, cx, |_, cx| {
-                            self.render_blank_pane(&theme, cx)
-                        })
-                        .on_down(MouseButton::Left, |_, _, cx| {
-                            cx.focus_parent_view();
-                        })
-                        .boxed()
-                    }
+                dragged_item_receiver::<EmptyPane, _, _>(0, 0, false, None, cx, |_, cx| {
+                    self.render_blank_pane(&theme, cx)
                 })
-                .on_down(
-                    MouseButton::Navigate(NavigationDirection::Back),
-                    move |_, _, cx| {
-                        let pane = cx.weak_handle();
-                        cx.dispatch_action(GoBack { pane: Some(pane) });
-                    },
-                )
-                .on_down(MouseButton::Navigate(NavigationDirection::Forward), {
-                    move |_, _, cx| {
-                        let pane = cx.weak_handle();
-                        cx.dispatch_action(GoForward { pane: Some(pane) })
-                    }
+                .on_down(MouseButton::Left, |_, _, cx| {
+                    cx.focus_parent_view();
                 })
-                .boxed(),
-            )
-            .named("pane")
+                .into_any()
+            }
+        })
+        .on_down(
+            MouseButton::Navigate(NavigationDirection::Back),
+            move |_, _, cx| {
+                let pane = cx.weak_handle();
+                cx.dispatch_action(GoBack { pane: Some(pane) });
+            },
+        )
+        .on_down(MouseButton::Navigate(NavigationDirection::Forward), {
+            move |_, _, cx| {
+                let pane = cx.weak_handle();
+                cx.dispatch_action(GoForward { pane: Some(pane) })
+            }
+        })
+        .into_any_named("pane")
     }
 
     fn focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext<Self>) {
@@ -1905,7 +1881,7 @@ fn render_tab_bar_button<A: Action + Clone>(
     cx: &mut ViewContext<Pane>,
     action: A,
     context_menu: Option<ViewHandle<ContextMenu>>,
-) -> Element<Pane> {
+) -> AnyElement<Pane> {
     enum TabBarButton {}
 
     Stack::new()
@@ -1921,19 +1897,17 @@ fn render_tab_bar_button<A: Action + Clone>(
                     .constrained()
                     .with_width(style.button_width)
                     .with_height(style.button_width)
-                    .boxed()
             })
             .with_cursor_style(CursorStyle::PointingHand)
             .on_click(MouseButton::Left, move |_, _, cx| {
                 cx.dispatch_action(action.clone());
-            })
-            .boxed(),
+            }),
         )
         .with_children(
-            context_menu.map(|menu| ChildView::new(&menu, cx).aligned().bottom().right().boxed()),
+            context_menu.map(|menu| ChildView::new(&menu, cx).aligned().bottom().right()),
         )
         .flex(1., false)
-        .boxed()
+        .into_any_named("tab bar button")
 }
 
 impl ItemNavHistory {
@@ -2039,11 +2013,11 @@ impl NavHistory {
 
 pub struct PaneBackdrop<V: View> {
     child_view: usize,
-    child: Element<V>,
+    child: AnyElement<V>,
 }
 
 impl<V: View> PaneBackdrop<V> {
-    pub fn new(pane_item_view: usize, child: Element<V>) -> Self {
+    pub fn new(pane_item_view: usize, child: AnyElement<V>) -> Self {
         PaneBackdrop {
             child,
             child_view: pane_item_view,
@@ -2051,7 +2025,7 @@ impl<V: View> PaneBackdrop<V> {
     }
 }
 
-impl<V: View> Drawable<V> for PaneBackdrop<V> {
+impl<V: View> Element<V> for PaneBackdrop<V> {
     type LayoutState = ();
 
     type PaintState = ();

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

@@ -5,8 +5,7 @@ use gpui::{
     geometry::{rect::RectF, vector::Vector2F},
     platform::MouseButton,
     scene::MouseUp,
-    AppContext, Drawable, Element, EventContext, MouseState, Quad, View, ViewContext,
-    WeakViewHandle,
+    AppContext, Element, EventContext, MouseState, Quad, View, ViewContext, WeakViewHandle,
 };
 use project::ProjectEntryId;
 use settings::Settings;
@@ -18,7 +17,7 @@ use crate::{
 
 use super::DraggedItem;
 
-pub fn dragged_item_receiver<Tag, F>(
+pub fn dragged_item_receiver<Tag, D, F>(
     region_id: usize,
     drop_index: usize,
     allow_same_pane: bool,
@@ -28,7 +27,8 @@ pub fn dragged_item_receiver<Tag, F>(
 ) -> MouseEventHandler<Tag, Pane>
 where
     Tag: 'static,
-    F: FnOnce(&mut MouseState, &mut ViewContext<Pane>) -> Element<Pane>,
+    D: Element<Pane>,
+    F: FnOnce(&mut MouseState, &mut ViewContext<Pane>) -> D,
 {
     MouseEventHandler::<Tag, _>::above(region_id, cx, |state, cx| {
         // Observing hovered will cause a render when the mouse enters regardless
@@ -69,9 +69,7 @@ where
                         });
                     }
                 })
-                .boxed()
             }))
-            .boxed()
     })
     .on_up(MouseButton::Left, {
         move |event, _, cx| {

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>,
-    ) -> Element<Workspace> {
+    ) -> AnyElement<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>,
-    ) -> Element<Workspace> {
+    ) -> AnyElement<Workspace> {
         enum FollowIntoExternalProject {}
 
         match self {
@@ -165,7 +165,7 @@ impl Member {
                     Border::default()
                 };
 
-                let prompt = if let Some((_, leader)) = leader {
+                let leader_status_box = if let Some((_, leader)) = leader {
                     match leader.location {
                         ParticipantLocation::SharedProject {
                             project_id: leader_project_id,
@@ -195,7 +195,6 @@ impl Member {
                                             .with_style(
                                                 theme.workspace.external_location_message.container,
                                             )
-                                            .boxed()
                                         },
                                     )
                                     .with_cursor_style(CursorStyle::PointingHand)
@@ -208,7 +207,7 @@ impl Member {
                                     .aligned()
                                     .bottom()
                                     .right()
-                                    .boxed(),
+                                    .into_any(),
                                 )
                             }
                         }
@@ -225,7 +224,7 @@ impl Member {
                             .aligned()
                             .bottom()
                             .right()
-                            .boxed(),
+                            .into_any(),
                         ),
                         ParticipantLocation::External => Some(
                             Label::new(
@@ -240,7 +239,7 @@ impl Member {
                             .aligned()
                             .bottom()
                             .right()
-                            .boxed(),
+                            .into_any(),
                         ),
                     }
                 } else {
@@ -248,14 +247,9 @@ impl Member {
                 };
 
                 Stack::new()
-                    .with_child(
-                        ChildView::new(pane, cx)
-                            .contained()
-                            .with_border(border)
-                            .boxed(),
-                    )
-                    .with_children(prompt)
-                    .boxed()
+                    .with_child(ChildView::new(pane, cx).contained().with_border(border))
+                    .with_children(leader_status_box)
+                    .into_any()
             }
             Member::Axis(axis) => axis.render(
                 project,
@@ -367,7 +361,7 @@ impl PaneAxis {
         active_call: Option<&ModelHandle<ActiveCall>>,
         active_pane: &ViewHandle<Pane>,
         cx: &mut ViewContext<Workspace>,
-    ) -> Element<Workspace> {
+    ) -> AnyElement<Workspace> {
         let last_member_ix = self.members.len() - 1;
         Flex::new(self.axis)
             .with_children(self.members.iter().enumerate().map(|(ix, member)| {
@@ -388,12 +382,12 @@ impl PaneAxis {
                         Axis::Vertical => border.bottom = true,
                         Axis::Horizontal => border.right = true,
                     }
-                    member = Container::new(member).with_border(border).boxed();
+                    member = member.contained().with_border(border).into_any();
                 }
 
-                FlexItem::new(member).flex(flex, true).boxed()
+                FlexItem::new(member).flex(flex, true)
             }))
-            .boxed()
+            .into_any()
     }
 }
 

crates/workspace/src/shared_screen.rs 🔗

@@ -69,7 +69,7 @@ impl View for SharedScreen {
         "SharedScreen"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         enum Focus {}
 
         let frame = self.frame.clone();
@@ -89,10 +89,9 @@ impl View for SharedScreen {
             })
             .contained()
             .with_style(cx.global::<Settings>().theme.shared_screen)
-            .boxed()
         })
         .on_down(MouseButton::Left, |_, _, cx| cx.focus_parent_view())
-        .boxed()
+        .into_any()
     }
 }
 
@@ -111,7 +110,7 @@ impl Item for SharedScreen {
         _: Option<usize>,
         style: &theme::Tab,
         _: &AppContext,
-    ) -> gpui::Element<V> {
+    ) -> gpui::AnyElement<V> {
         Flex::row()
             .with_child(
                 Svg::new("icons/disable_screen_sharing_12.svg")
@@ -120,18 +119,16 @@ impl Item for SharedScreen {
                     .with_width(style.type_icon_width)
                     .aligned()
                     .contained()
-                    .with_margin_right(style.spacing)
-                    .boxed(),
+                    .with_margin_right(style.spacing),
             )
             .with_child(
                 Label::new(
                     format!("{}'s screen", self.user.github_login),
                     style.label.clone(),
                 )
-                .aligned()
-                .boxed(),
+                .aligned(),
             )
-            .boxed()
+            .into_any()
     }
 
     fn set_nav_history(&mut self, history: ItemNavHistory, _: &mut ViewContext<Self>) {

crates/workspace/src/sidebar.rs 🔗

@@ -188,7 +188,7 @@ impl View for Sidebar {
         "Sidebar"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         if let Some(active_item) = self.active_item() {
             enum ResizeHandleTag {}
             let style = &cx.global::<Settings>().theme.workspace.sidebar;
@@ -202,9 +202,9 @@ impl View for Sidebar {
                     style.initial_size,
                     cx,
                 )
-                .boxed()
+                .into_any()
         } else {
-            Empty::new().boxed()
+            Empty::new().into_any()
         }
     }
 }
@@ -225,7 +225,7 @@ impl View for SidebarButtons {
         "SidebarToggleButton"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let theme = &cx.global::<Settings>().theme;
         let tooltip_style = theme.tooltip.clone();
         let theme = &theme.workspace.status_bar.sidebar_buttons;
@@ -258,7 +258,7 @@ impl View for SidebarButtons {
                         let is_active = is_open && ix == active_ix;
                         let style = item_style.style_for(state, is_active);
                         Stack::new()
-                            .with_child(Svg::new(icon_path).with_color(style.icon_color).boxed())
+                            .with_child(Svg::new(icon_path).with_color(style.icon_color))
                             .with_children(if !is_active && item_view.should_show_badge(cx) {
                                 Some(
                                     Empty::new()
@@ -267,8 +267,7 @@ impl View for SidebarButtons {
                                         .with_style(badge_style)
                                         .aligned()
                                         .bottom()
-                                        .right()
-                                        .boxed(),
+                                        .right(),
                                 )
                             } else {
                                 None
@@ -278,7 +277,6 @@ impl View for SidebarButtons {
                             .with_height(style.icon_size)
                             .contained()
                             .with_style(style.container)
-                            .boxed()
                     })
                     .with_cursor_style(CursorStyle::PointingHand)
                     .on_click(MouseButton::Left, {
@@ -292,12 +290,11 @@ impl View for SidebarButtons {
                         tooltip_style.clone(),
                         cx,
                     )
-                    .boxed()
                 },
             ))
             .contained()
             .with_style(group_style)
-            .boxed()
+            .into_any()
     }
 }
 

crates/workspace/src/status_bar.rs 🔗

@@ -8,8 +8,8 @@ use gpui::{
         vector::{vec2f, Vector2F},
     },
     json::{json, ToJson},
-    AnyViewHandle, Element, Entity, SceneBuilder, SizeConstraint, Subscription, View, ViewContext,
-    ViewHandle, WindowContext,
+    AnyElement, AnyViewHandle, Entity, SceneBuilder, SizeConstraint, Subscription, View,
+    ViewContext, ViewHandle, WindowContext,
 };
 use settings::Settings;
 
@@ -46,7 +46,7 @@ impl View for StatusBar {
         "StatusBar"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let theme = &cx.global::<Settings>().theme.workspace.status_bar;
 
         StatusBarElement {
@@ -56,9 +56,8 @@ impl View for StatusBar {
                         .aligned()
                         .contained()
                         .with_margin_right(theme.item_spacing)
-                        .boxed()
                 }))
-                .boxed(),
+                .into_any(),
 
             right: Flex::row()
                 .with_children(self.right_items.iter().rev().map(|i| {
@@ -66,15 +65,14 @@ impl View for StatusBar {
                         .aligned()
                         .contained()
                         .with_margin_left(theme.item_spacing)
-                        .boxed()
                 }))
-                .boxed(),
+                .into_any(),
         }
         .contained()
         .with_style(theme.container)
         .constrained()
         .with_height(theme.height)
-        .boxed()
+        .into_any()
     }
 }
 
@@ -147,11 +145,11 @@ impl From<&dyn StatusItemViewHandle> for AnyViewHandle {
 }
 
 struct StatusBarElement {
-    left: Element<StatusBar>,
-    right: Element<StatusBar>,
+    left: AnyElement<StatusBar>,
+    right: AnyElement<StatusBar>,
 }
 
-impl Drawable<StatusBar> for StatusBarElement {
+impl Element<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,
-    Element, Entity, View, ViewContext, ViewHandle, WeakViewHandle, WindowContext,
+    elements::*, platform::CursorStyle, platform::MouseButton, Action, AnyElement, AnyViewHandle,
+    AppContext, Entity, View, ViewContext, ViewHandle, WeakViewHandle, WindowContext,
 };
 use settings::Settings;
 
@@ -59,7 +59,7 @@ impl View for Toolbar {
         "Toolbar"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let theme = &cx.global::<Settings>().theme.workspace.toolbar;
 
         let mut primary_left_items = Vec::new();
@@ -77,9 +77,9 @@ impl View for Toolbar {
                         .contained()
                         .with_margin_right(spacing);
                     if let Some((flex, expanded)) = flex {
-                        primary_left_items.push(left_item.flex(flex, expanded).boxed());
+                        primary_left_items.push(left_item.flex(flex, expanded).into_any());
                     } else {
-                        primary_left_items.push(left_item.boxed());
+                        primary_left_items.push(left_item.into_any());
                     }
                 }
 
@@ -90,9 +90,9 @@ impl View for Toolbar {
                         .with_margin_left(spacing)
                         .flex_float();
                     if let Some((flex, expanded)) = flex {
-                        primary_right_items.push(right_item.flex(flex, expanded).boxed());
+                        primary_right_items.push(right_item.flex(flex, expanded).into_any());
                     } else {
-                        primary_right_items.push(right_item.boxed());
+                        primary_right_items.push(right_item.into_any());
                     }
                 }
 
@@ -101,7 +101,7 @@ impl View for Toolbar {
                         ChildView::new(item.as_any(), cx)
                             .constrained()
                             .with_height(theme.height)
-                            .boxed(),
+                            .into_any(),
                     );
                 }
             }
@@ -151,13 +151,12 @@ impl View for Toolbar {
                     .with_children(primary_left_items)
                     .with_children(primary_right_items)
                     .constrained()
-                    .with_height(height)
-                    .boxed(),
+                    .with_height(height),
             )
             .with_children(secondary_item)
             .contained()
             .with_style(container_style)
-            .boxed()
+            .into_any_named("toolbar")
     }
 }
 
@@ -172,7 +171,7 @@ fn nav_button<A: Action + Clone>(
     tooltip_action: A,
     action_name: &str,
     cx: &mut ViewContext<Toolbar>,
-) -> Element<Toolbar> {
+) -> AnyElement<Toolbar> {
     MouseEventHandler::<A, _>::new(0, cx, |state, _| {
         let style = if enabled {
             style.style_for(state, false)
@@ -190,7 +189,6 @@ fn nav_button<A: Action + Clone>(
             .with_width(style.button_width)
             .with_height(style.button_width)
             .aligned()
-            .boxed()
     })
     .with_cursor_style(if enabled {
         CursorStyle::PointingHand
@@ -209,7 +207,7 @@ fn nav_button<A: Action + Clone>(
     )
     .contained()
     .with_margin_right(spacing)
-    .boxed()
+    .into_any_named("nav button")
 }
 
 impl Toolbar {

crates/workspace/src/workspace.rs 🔗

@@ -2075,7 +2075,7 @@ impl Workspace {
         self.leader_state.followers.contains(&peer_id)
     }
 
-    fn render_titlebar(&self, theme: &Theme, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render_titlebar(&self, theme: &Theme, cx: &mut ViewContext<Self>) -> AnyElement<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();
@@ -2088,29 +2088,24 @@ impl Workspace {
         };
 
         enum TitleBar {}
-        ConstrainedBox::new(
-            MouseEventHandler::<TitleBar, _>::new(0, cx, |_, cx| {
-                Container::new(
-                    Stack::new()
-                        .with_children(
-                            self.titlebar_item
-                                .as_ref()
-                                .map(|item| ChildView::new(item, cx).boxed()),
-                        )
-                        .boxed(),
+        MouseEventHandler::<TitleBar, _>::new(0, cx, |_, cx| {
+            Stack::new()
+                .with_children(
+                    self.titlebar_item
+                        .as_ref()
+                        .map(|item| ChildView::new(item, cx)),
                 )
+                .contained()
                 .with_style(container_theme)
-                .boxed()
-            })
-            .on_click(MouseButton::Left, |event, _, cx| {
-                if event.click_count == 2 {
-                    cx.zoom_window();
-                }
-            })
-            .boxed(),
-        )
+        })
+        .on_click(MouseButton::Left, |event, _, cx| {
+            if event.click_count == 2 {
+                cx.zoom_window();
+            }
+        })
+        .constrained()
         .with_height(theme.workspace.titlebar.height)
-        .named("titlebar")
+        .into_any_named("titlebar")
     }
 
     fn active_item_path_changed(&mut self, cx: &mut ViewContext<Self>) {
@@ -2178,7 +2173,7 @@ impl Workspace {
     fn render_disconnected_overlay(
         &self,
         cx: &mut ViewContext<Workspace>,
-    ) -> Option<Element<Workspace>> {
+    ) -> Option<AnyElement<Workspace>> {
         if self.project.read(cx).is_read_only() {
             enum DisconnectedOverlay {}
             Some(
@@ -2191,11 +2186,10 @@ impl Workspace {
                     .aligned()
                     .contained()
                     .with_style(theme.workspace.disconnected_overlay.container)
-                    .boxed()
                 })
                 .with_cursor_style(CursorStyle::Arrow)
                 .capture_all()
-                .boxed(),
+                .into_any_named("disconnected overlay"),
             )
         } else {
             None
@@ -2206,7 +2200,7 @@ impl Workspace {
         &self,
         theme: &theme::Workspace,
         cx: &AppContext,
-    ) -> Option<Element<Workspace>> {
+    ) -> Option<AnyElement<Workspace>> {
         if self.notifications.is_empty() {
             None
         } else {
@@ -2216,7 +2210,6 @@ impl Workspace {
                         ChildView::new(notification.as_any(), cx)
                             .contained()
                             .with_style(theme.notification)
-                            .boxed()
                     }))
                     .constrained()
                     .with_width(theme.notifications.width)
@@ -2225,7 +2218,7 @@ impl Workspace {
                     .aligned()
                     .bottom()
                     .right()
-                    .boxed(),
+                    .into_any(),
             )
         }
     }
@@ -2833,7 +2826,7 @@ impl View for Workspace {
         "Workspace"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         let theme = cx.global::<Settings>().theme.clone();
         Stack::new()
             .with_child(
@@ -2857,8 +2850,7 @@ impl View for Workspace {
                                                                 constraint.max.y(),
                                                             ),
                                                         )
-                                                    })
-                                                    .boxed(),
+                                                    }),
                                             )
                                         } else {
                                             None
@@ -2876,18 +2868,15 @@ impl View for Workspace {
                                                         self.active_pane(),
                                                         cx,
                                                     ))
-                                                    .flex(1., true)
-                                                    .boxed(),
+                                                    .flex(1., true),
                                                 )
                                                 .with_children(self.dock.render(
                                                     &theme,
                                                     DockAnchor::Bottom,
                                                     cx,
-                                                ))
-                                                .boxed(),
+                                                )),
                                         )
-                                        .flex(1., true)
-                                        .boxed(),
+                                        .flex(1., true),
                                     )
                                     .with_children(self.dock.render(&theme, DockAnchor::Right, cx))
                                     .with_children(
@@ -2903,49 +2892,38 @@ impl View for Workspace {
                                                                 constraint.max.y(),
                                                             ),
                                                         )
-                                                    })
-                                                    .boxed(),
+                                                    }),
                                             )
                                         } else {
                                             None
                                         },
                                     )
-                                    .boxed()
                             })
-                            .with_child(
-                                Overlay::new(
-                                    Stack::new()
-                                        .with_children(self.dock.render(
-                                            &theme,
-                                            DockAnchor::Expanded,
-                                            cx,
-                                        ))
-                                        .with_children(self.modal.as_ref().map(|modal| {
-                                            ChildView::new(modal, cx)
-                                                .contained()
-                                                .with_style(theme.workspace.modal)
-                                                .aligned()
-                                                .top()
-                                                .boxed()
-                                        }))
-                                        .with_children(
-                                            self.render_notifications(&theme.workspace, cx),
-                                        )
-                                        .boxed(),
-                                )
-                                .boxed(),
-                            )
-                            .flex(1.0, true)
-                            .boxed(),
+                            .with_child(Overlay::new(
+                                Stack::new()
+                                    .with_children(self.dock.render(
+                                        &theme,
+                                        DockAnchor::Expanded,
+                                        cx,
+                                    ))
+                                    .with_children(self.modal.as_ref().map(|modal| {
+                                        ChildView::new(modal, cx)
+                                            .contained()
+                                            .with_style(theme.workspace.modal)
+                                            .aligned()
+                                            .top()
+                                    }))
+                                    .with_children(self.render_notifications(&theme.workspace, cx)),
+                            ))
+                            .flex(1.0, true),
                     )
-                    .with_child(ChildView::new(&self.status_bar, cx).boxed())
+                    .with_child(ChildView::new(&self.status_bar, cx))
                     .contained()
-                    .with_background_color(theme.workspace.background)
-                    .boxed(),
+                    .with_background_color(theme.workspace.background),
             )
             .with_children(DragAndDrop::render(cx))
             .with_children(self.render_disconnected_overlay(cx))
-            .named("workspace")
+            .into_any_named("workspace")
     }
 
     fn focus_in(&mut self, view: AnyViewHandle, cx: &mut ViewContext<Self>) {