WIP

Antonio Scandurra created

Change summary

crates/activity_indicator/src/activity_indicator.rs |  2 
crates/collab/src/tests/integration_tests.rs        | 11 --
crates/collab_ui/src/collaborator_list_popover.rs   |  1 
crates/collab_ui/src/contact_list.rs                |  2 
crates/command_palette/src/command_palette.rs       | 26 ++----
crates/copilot_button/src/copilot_button.rs         | 12 --
crates/diagnostics/src/items.rs                     |  8 +
crates/editor/src/element.rs                        | 25 +++---
crates/feedback/src/deploy_feedback_button.rs       |  2 
crates/feedback/src/feedback_editor.rs              | 13 ++-
crates/feedback/src/feedback_info_text.rs           |  2 
crates/feedback/src/submit_feedback_button.rs       |  2 
crates/file_finder/src/file_finder.rs               |  4 
crates/gpui/src/app.rs                              | 48 +++++++------
crates/gpui/src/app/test_app_context.rs             | 51 +++++----------
crates/gpui/src/app/window.rs                       | 38 +++++++---
crates/picker/src/picker.rs                         |  2 
crates/project_panel/src/project_panel.rs           |  2 
crates/search/src/buffer_search.rs                  |  8 +-
crates/search/src/project_search.rs                 |  9 +-
crates/terminal_view/src/terminal_element.rs        |  2 
crates/theme_selector/src/theme_selector.rs         |  4 
crates/vim/src/normal.rs                            | 34 +++++-----
crates/welcome/src/base_keymap_picker.rs            |  2 
crates/welcome/src/welcome.rs                       |  2 
crates/workspace/src/pane.rs                        |  2 
crates/workspace/src/shared_screen.rs               |  2 
27 files changed, 154 insertions(+), 162 deletions(-)

Detailed changes

crates/activity_indicator/src/activity_indicator.rs 🔗

@@ -361,7 +361,7 @@ impl View for ActivityIndicator {
         if let Some(action) = action {
             element = element
                 .with_cursor_style(CursorStyle::PointingHand)
-                .on_click(MouseButton::Left, move |_, cx| {
+                .on_click(MouseButton::Left, move |_, _, cx| {
                     cx.dispatch_any_action(action.boxed_clone())
                 });
         }

crates/collab/src/tests/integration_tests.rs 🔗

@@ -1476,12 +1476,7 @@ async fn test_host_disconnect(
         .unwrap()
         .downcast::<Editor>()
         .unwrap();
-    cx_b.read(|cx| {
-        assert_eq!(
-            cx.focused_view_id(workspace_b.window_id()),
-            Some(editor_b.id())
-        );
-    });
+    assert!(cx_b.read(|cx| editor_b.is_focused(cx)));
     editor_b.update(cx_b, |editor, cx| editor.insert("X", cx));
     assert!(cx_b.is_window_edited(workspace_b.window_id()));
 
@@ -1495,8 +1490,8 @@ async fn test_host_disconnect(
     assert!(worktree_a.read_with(cx_a, |tree, _| !tree.as_local().unwrap().is_shared()));
 
     // Ensure client B's edited state is reset and that the whole window is blurred.
-    cx_b.read(|cx| {
-        assert_eq!(cx.focused_view_id(workspace_b.window_id()), None);
+    cx_b.read_window(|cx| {
+        assert_eq!(cx.focused_view_id(), None);
     });
     assert!(!cx_b.is_window_edited(workspace_b.window_id()));
 

crates/collab_ui/src/collaborator_list_popover.rs 🔗

@@ -80,7 +80,6 @@ impl CollaboratorListPopover {
                 collaborators.len(),
                 Orientation::Top,
                 0.,
-                cx,
                 move |_, index, cx| match &collaborators[index] {
                     Collaborator::SelfUser { username } => render_collaborator_list_entry(
                         index,

crates/collab_ui/src/contact_list.rs 🔗

@@ -202,7 +202,7 @@ impl ContactList {
         })
         .detach();
 
-        let list_state = ListState::new(0, Orientation::Top, 1000., cx, move |this, ix, cx| {
+        let list_state = ListState::new(0, Orientation::Top, 1000., move |this, ix, cx| {
             let theme = cx.global::<Settings>().theme.clone();
             let is_selected = this.selection == Some(ix);
             let current_project_id = this.project.read(cx).remote_id();

crates/command_palette/src/command_palette.rs 🔗

@@ -1,10 +1,8 @@
 use collections::CommandPaletteFilter;
 use fuzzy::{StringMatch, StringMatchCandidate};
 use gpui::{
-    actions,
-    elements::{ChildView, Flex, Label, ParentElement},
-    keymap_matcher::Keystroke,
-    Action, AnyViewHandle, AppContext, Element, Entity, MouseState, View, ViewContext, ViewHandle,
+    actions, elements::*, keymap_matcher::Keystroke, Action, AnyViewHandle, AppContext, Element,
+    Entity, MouseState, View, ViewContext, ViewHandle,
 };
 use picker::{Picker, PickerDelegate};
 use settings::Settings;
@@ -78,16 +76,13 @@ impl CommandPalette {
 
     fn toggle(_: &mut Workspace, _: &Toggle, cx: &mut ViewContext<Workspace>) {
         let workspace = cx.handle();
-        let window_id = cx.window_id();
         let focused_view_id = cx.focused_view_id().unwrap_or_else(|| workspace.id());
 
-        cx.as_mut().defer(move |cx| {
-            let this = cx.add_view(&workspace, |cx| Self::new(focused_view_id, cx));
-            workspace.update(cx, |workspace, cx| {
-                workspace.toggle_modal(cx, |_, cx| {
-                    cx.subscribe(&this, Self::on_event).detach();
-                    this
-                });
+        cx.defer(move |workspace, cx| {
+            let this = cx.add_view(|cx| Self::new(focused_view_id, cx));
+            workspace.toggle_modal(cx, |_, cx| {
+                cx.subscribe(&this, Self::on_event).detach();
+                this
             });
         });
     }
@@ -109,8 +104,7 @@ impl CommandPalette {
                 let focused_view_id = *focused_view_id;
                 let action = action.boxed_clone();
                 workspace.dismiss_modal(cx);
-                cx.as_mut()
-                    .defer(move |cx| cx.dispatch_any_action_at(window_id, focused_view_id, action))
+                cx.defer(move |_, cx| cx.dispatch_any_action_at(window_id, focused_view_id, action))
             }
         }
     }
@@ -125,7 +119,7 @@ impl View for CommandPalette {
         "CommandPalette"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> gpui::ElementBox {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
         ChildView::new(&self.picker, cx).boxed()
     }
 
@@ -221,7 +215,7 @@ impl PickerDelegate for CommandPalette {
         mouse_state: &mut MouseState,
         selected: bool,
         cx: &gpui::AppContext,
-    ) -> gpui::ElementBox {
+    ) -> ElementBox<Picker<Self>> {
         let mat = &self.matches[ix];
         let command = &self.actions[mat.candidate_id];
         let settings = cx.global::<Settings>();

crates/copilot_button/src/copilot_button.rs 🔗

@@ -153,7 +153,7 @@ impl View for CopilotButton {
                 .with_cursor_style(CursorStyle::PointingHand)
                 .on_click(MouseButton::Left, {
                     let status = status.clone();
-                    move |_, cx| match status {
+                    move |_, _, cx| match status {
                         Status::Authorized => cx.dispatch_action(DeployCopilotMenu),
                         Status::Starting { ref task } => {
                             cx.dispatch_action(workspace::Toast::new(
@@ -162,7 +162,7 @@ impl View for CopilotButton {
                             ));
                             let window_id = cx.window_id();
                             let task = task.to_owned();
-                            cx.spawn(|mut cx| async move {
+                            cx.spawn(|this, mut cx| async move {
                                 task.await;
                                 cx.update(|cx| {
                                     if let Some(copilot) = Copilot::global(cx) {
@@ -199,13 +199,7 @@ impl View for CopilotButton {
                         _ => cx.dispatch_action(SignIn),
                     }
                 })
-                .with_tooltip::<Self, _>(
-                    0,
-                    "GitHub Copilot".into(),
-                    None,
-                    theme.tooltip.clone(),
-                    cx,
-                )
+                .with_tooltip::<Self>(0, "GitHub Copilot".into(), None, theme.tooltip.clone(), cx)
                 .boxed(),
             )
             .with_child(

crates/diagnostics/src/items.rs 🔗

@@ -163,8 +163,10 @@ impl View for DiagnosticIndicator {
                     .boxed()
             })
             .with_cursor_style(CursorStyle::PointingHand)
-            .on_click(MouseButton::Left, |_, cx| cx.dispatch_action(crate::Deploy))
-            .with_tooltip::<Summary, _>(
+            .on_click(MouseButton::Left, |_, _, cx| {
+                cx.dispatch_action(crate::Deploy)
+            })
+            .with_tooltip::<Summary>(
                 0,
                 "Project Diagnostics".to_string(),
                 Some(Box::new(crate::Deploy)),
@@ -200,7 +202,7 @@ impl View for DiagnosticIndicator {
                     .boxed()
                 })
                 .with_cursor_style(CursorStyle::PointingHand)
-                .on_click(MouseButton::Left, |_, cx| {
+                .on_click(MouseButton::Left, |_, _, cx| {
                     cx.dispatch_action(GoToDiagnostic)
                 })
                 .boxed(),

crates/editor/src/element.rs 🔗

@@ -2574,10 +2574,8 @@ mod tests {
 
         let layouts = editor.update(cx, |editor, cx| {
             let snapshot = editor.snapshot(cx);
-            let mut presenter = cx.build_window(window_id, 30., Default::default());
-            let layout_cx = presenter.build_layout_context(Vector2F::zero(), false, cx);
             element
-                .layout_line_numbers(0..6, &Default::default(), false, &snapshot, &layout_cx)
+                .layout_line_numbers(0..6, &Default::default(), false, &snapshot, cx)
                 .0
         });
         assert_eq!(layouts.len(), 6);
@@ -2609,14 +2607,13 @@ mod tests {
         });
 
         let mut element = EditorElement::new(editor.downgrade(), editor.read(cx).style(cx));
-
-        let mut scene = SceneBuilder::new(1.0);
-        let mut presenter = cx.build_window(window_id, 30., Default::default());
-        let mut layout_cx = presenter.build_layout_context(Vector2F::zero(), false, cx);
-        let (size, mut state) = element.layout(
-            SizeConstraint::new(vec2f(500., 500.), vec2f(500., 500.)),
-            &mut layout_cx,
-        );
+        let (size, mut state) = editor.update(cx, |editor, cx| {
+            element.layout(
+                SizeConstraint::new(vec2f(500., 500.), vec2f(500., 500.)),
+                editor,
+                cx,
+            )
+        });
 
         assert_eq!(state.position_map.line_layouts.len(), 4);
         assert_eq!(
@@ -2629,8 +2626,10 @@ mod tests {
         );
 
         // Don't panic.
+        let mut scene = SceneBuilder::new(1.0);
         let bounds = RectF::new(Default::default(), size);
-        let mut paint_cx = presenter.build_paint_context(&mut scene, bounds.size(), cx);
-        element.paint(bounds, bounds, &mut state, &mut paint_cx);
+        editor.update(cx, |editor, cx| {
+            element.paint(&mut scene, bounds, bounds, &mut state, editor, cx);
+        });
     }
 }

crates/feedback/src/deploy_feedback_button.rs 🔗

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

crates/feedback/src/feedback_editor.rs 🔗

@@ -13,7 +13,7 @@ use gpui::{
     elements::{ChildView, Flex, Label, ParentElement, Svg},
     platform::PromptLevel,
     serde_json, AnyViewHandle, AppContext, Element, ElementBox, Entity, ModelHandle, Task, View,
-    ViewContext, ViewContext, ViewHandle,
+    ViewContext, ViewHandle,
 };
 use isahc::Request;
 use language::Buffer;
@@ -25,7 +25,7 @@ use util::ResultExt;
 use workspace::{
     item::{Item, ItemHandle},
     searchable::{SearchableItem, SearchableItemHandle},
-    AppState, Workspace,
+    AppState, Pane, Workspace,
 };
 
 use crate::{submit_feedback_button::SubmitFeedbackButton, system_specs::SystemSpecs};
@@ -232,7 +232,7 @@ impl View for FeedbackEditor {
         "FeedbackEditor"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
         ChildView::new(&self.editor, cx).boxed()
     }
 
@@ -248,7 +248,12 @@ impl Entity for FeedbackEditor {
 }
 
 impl Item for FeedbackEditor {
-    fn tab_content(&self, _: Option<usize>, style: &theme::Tab, _: &AppContext) -> ElementBox {
+    fn tab_content(
+        &self,
+        _: Option<usize>,
+        style: &theme::Tab,
+        _: &AppContext,
+    ) -> ElementBox<Pane> {
         Flex::row()
             .with_child(
                 Svg::new("icons/feedback_16.svg")

crates/feedback/src/feedback_info_text.rs 🔗

@@ -29,7 +29,7 @@ impl View for FeedbackInfoText {
         "FeedbackInfoText"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
         let theme = cx.global::<Settings>().theme.clone();
 
         Flex::row()

crates/feedback/src/submit_feedback_button.rs 🔗

@@ -29,7 +29,7 @@ impl View for SubmitFeedbackButton {
         "SubmitFeedbackButton"
     }
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
         let theme = cx.global::<Settings>().theme.clone();
         enum SubmitFeedbackButton {}
         MouseEventHandler::<SubmitFeedbackButton>::new(0, cx, |state, _| {

crates/file_finder/src/file_finder.rs 🔗

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

crates/gpui/src/app.rs 🔗

@@ -936,6 +936,16 @@ impl AppContext {
         result
     }
 
+    pub fn read_window<T, F: FnOnce(&WindowContext) -> T>(
+        &self,
+        window_id: usize,
+        callback: F,
+    ) -> Option<T> {
+        let window = self.windows.get(&window_id)?;
+        let window_context = WindowContext::immutable(self, &window, window_id);
+        Some(callback(&window_context))
+    }
+
     pub fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
         &mut self,
         window_id: usize,
@@ -943,13 +953,7 @@ impl AppContext {
     ) -> Option<T> {
         self.update(|app_context| {
             let mut window = app_context.windows.remove(&window_id)?;
-            let mut window_context = WindowContext {
-                app_context,
-                window: &mut window,
-                window_id,
-                refreshing: false,
-            };
-
+            let mut window_context = WindowContext::mutable(app_context, &mut window, window_id);
             let result = callback(&mut window_context);
             app_context.windows.insert(window_id, window);
             Some(result)
@@ -1651,7 +1655,7 @@ impl AppContext {
         }));
 
         let mut window = Window::new(window_id, platform_window, self, build_root_view);
-        let scene = WindowContext::new(self, &mut window, window_id).build_scene();
+        let scene = WindowContext::mutable(self, &mut window, window_id).build_scene();
         window.platform_window.present_scene(scene);
         window
     }
@@ -3244,7 +3248,7 @@ impl<M> DerefMut for ModelContext<'_, M> {
 }
 
 pub struct ViewContext<'a, 'b, 'c, T: ?Sized> {
-    window_context: WindowContextRef<'a, 'b, 'c>,
+    window_context: Reference<'c, WindowContext<'a, 'b>>,
     view_id: usize,
     view_type: PhantomData<T>,
 }
@@ -3266,7 +3270,7 @@ impl<T: View> DerefMut for ViewContext<'_, '_, '_, T> {
 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 {
         Self {
-            window_context: WindowContextRef::Mutable(window_context),
+            window_context: Reference::Mutable(window_context),
             view_id,
             view_type: PhantomData,
         }
@@ -3274,7 +3278,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 {
         Self {
-            window_context: WindowContextRef::Immutable(window_context),
+            window_context: Reference::Immutable(window_context),
             view_id,
             view_type: PhantomData,
         }
@@ -3819,29 +3823,29 @@ impl<V: View> UpdateView for ViewContext<'_, '_, '_, V> {
     }
 }
 
-enum WindowContextRef<'a, 'b, 'c> {
-    Immutable(&'c WindowContext<'a, 'b>),
-    Mutable(&'c mut WindowContext<'a, 'b>),
+pub(crate) enum Reference<'a, T> {
+    Immutable(&'a T),
+    Mutable(&'a mut T),
 }
 
-impl<'a, 'b, 'c> Deref for WindowContextRef<'a, 'b, 'c> {
-    type Target = WindowContext<'a, 'b>;
+impl<'a, T> Deref for Reference<'a, T> {
+    type Target = T;
 
     fn deref(&self) -> &Self::Target {
         match self {
-            WindowContextRef::Immutable(window_context) => window_context,
-            WindowContextRef::Mutable(window_context) => window_context,
+            Reference::Immutable(target) => target,
+            Reference::Mutable(target) => target,
         }
     }
 }
 
-impl<'a, 'b, 'c> DerefMut for WindowContextRef<'a, 'b, 'c> {
+impl<'a, T> DerefMut for Reference<'a, T> {
     fn deref_mut(&mut self) -> &mut Self::Target {
         match self {
-            WindowContextRef::Immutable(_) => {
-                panic!("cannot mutably deref an immutable WindowContext. this is a bug in GPUI.");
+            Reference::Immutable(_) => {
+                panic!("cannot mutably deref an immutable reference. this is a bug in GPUI.");
             }
-            WindowContextRef::Mutable(window_context) => window_context,
+            Reference::Mutable(target) => target,
         }
     }
 }

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

@@ -23,7 +23,7 @@ use crate::{
     platform::{Event, InputHandler, KeyDownEvent, Platform},
     Action, AnyViewHandle, AppContext, Entity, FontCache, Handle, ModelContext, ModelHandle,
     ReadModelWith, ReadViewWith, Task, UpdateModel, UpdateView, View, ViewContext, ViewHandle,
-    WeakHandle,
+    WeakHandle, WindowContext,
 };
 use collections::BTreeMap;
 
@@ -114,6 +114,22 @@ impl TestAppContext {
         }
     }
 
+    pub fn read_window<T, F: FnOnce(&WindowContext) -> T>(
+        &self,
+        window_id: usize,
+        callback: F,
+    ) -> Option<T> {
+        self.cx.borrow().read_window(window_id, callback)
+    }
+
+    pub fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
+        &mut self,
+        window_id: usize,
+        callback: F,
+    ) -> Option<T> {
+        self.cx.borrow_mut().update_window(window_id, callback)
+    }
+
     pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
     where
         T: Entity,
@@ -147,17 +163,6 @@ impl TestAppContext {
         self.cx.borrow().window_ids().collect()
     }
 
-    pub fn root_view(&self, window_id: usize) -> Option<AnyViewHandle> {
-        Some(
-            self.cx
-                .borrow()
-                .windows
-                .get(&window_id)?
-                .root_view()
-                .clone(),
-        )
-    }
-
     pub fn read<T, F: FnOnce(&AppContext) -> T>(&self, callback: F) -> T {
         callback(&*self.cx.borrow())
     }
@@ -173,28 +178,6 @@ impl TestAppContext {
         result
     }
 
-    pub fn render<F, V, T>(&mut self, handle: &ViewHandle<V>, f: F) -> T
-    where
-        F: FnOnce(&mut V, &mut ViewContext<V>) -> T,
-        V: View,
-    {
-        todo!()
-        // handle.update(&mut *self.cx.borrow_mut(), |view, cx| {
-        //     let mut render_cx = ViewContext {
-        //         app: cx,
-        //         window_id: handle.window_id(),
-        //         view_id: handle.id(),
-        //         view_type: PhantomData,
-        //         titlebar_height: 0.,
-        //         hovered_region_ids: Default::default(),
-        //         clicked_region_ids: None,
-        //         refreshing: false,
-        //         appearance: Appearance::Light,
-        //     };
-        //     f(view, &mut render_cx)
-        // })
-    }
-
     pub fn to_async(&self) -> AsyncAppContext {
         AsyncAppContext(self.cx.clone())
     }

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

@@ -30,6 +30,8 @@ use sqlez::{
 use std::ops::{Deref, DerefMut, Range};
 use uuid::Uuid;
 
+use super::Reference;
+
 pub struct Window {
     pub(crate) root_view: Option<AnyViewHandle>,
     pub(crate) focused_view_id: Option<usize>,
@@ -83,7 +85,7 @@ impl Window {
             appearance,
         };
 
-        let mut window_context = WindowContext::new(cx, &mut window, window_id);
+        let mut window_context = WindowContext::mutable(cx, &mut window, window_id);
         let root_view = window_context
             .build_and_insert_view(ParentId::Root, |cx| Some(build_view(cx)))
             .unwrap();
@@ -101,8 +103,8 @@ impl Window {
 }
 
 pub struct WindowContext<'a: 'b, 'b> {
-    pub(crate) app_context: &'a mut AppContext,
-    pub(crate) window: &'b mut Window, // TODO: make this private?
+    pub(crate) app_context: Reference<'a, AppContext>,
+    pub(crate) window: Reference<'b, Window>,
     pub(crate) window_id: usize,
     pub(crate) refreshing: bool,
 }
@@ -111,7 +113,7 @@ impl Deref for WindowContext<'_, '_> {
     type Target = AppContext;
 
     fn deref(&self) -> &Self::Target {
-        self.app_context
+        &self.app_context
     }
 }
 
@@ -148,10 +150,23 @@ impl UpgradeViewHandle for WindowContext<'_, '_> {
 }
 
 impl<'a: 'b, 'b> WindowContext<'a, 'b> {
-    pub fn new(app_context: &'a mut AppContext, window: &'b mut Window, window_id: usize) -> Self {
+    pub fn mutable(
+        app_context: &'a mut AppContext,
+        window: &'b mut Window,
+        window_id: usize,
+    ) -> Self {
         Self {
-            app_context,
-            window,
+            app_context: Reference::Mutable(app_context),
+            window: Reference::Mutable(window),
+            window_id,
+            refreshing: false,
+        }
+    }
+
+    pub fn immutable(app_context: &'a AppContext, window: &'b Window, window_id: usize) -> Self {
+        Self {
+            app_context: Reference::Immutable(app_context),
+            window: Reference::Immutable(window),
             window_id,
             refreshing: false,
         }
@@ -162,7 +177,7 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
     }
 
     pub fn app_context(&mut self) -> &mut AppContext {
-        self.app_context
+        &mut self.app_context
     }
 
     pub fn root_view(&self) -> &AnyViewHandle {
@@ -406,7 +421,8 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
                 MouseEvent::Hover(_) => {
                     let mut highest_z_index = None;
                     let mouse_position = self.window.mouse_position.clone();
-                    for (region, z_index) in self.window.mouse_regions.iter().rev() {
+                    let window = &mut *self.window;
+                    for (region, z_index) in window.mouse_regions.iter().rev() {
                         // Allow mouse regions to appear transparent to hovers
                         if !region.hoverable {
                             continue;
@@ -424,7 +440,7 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
                         // highest_z_index is set.
                         if contains_mouse && z_index == highest_z_index.unwrap() {
                             //Ensure that hover entrance events aren't sent twice
-                            if self.window.hovered_region_ids.insert(region.id()) {
+                            if window.hovered_region_ids.insert(region.id()) {
                                 valid_regions.push(region.clone());
                                 if region.notify_on_hover {
                                     notified_views.insert(region.id().view_id());
@@ -432,7 +448,7 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
                             }
                         } else {
                             // Ensure that hover exit events aren't sent twice
-                            if self.window.hovered_region_ids.remove(&region.id()) {
+                            if window.hovered_region_ids.remove(&region.id()) {
                                 valid_regions.push(region.clone());
                                 if region.notify_on_hover {
                                     notified_views.insert(region.id().view_id());

crates/picker/src/picker.rs 🔗

@@ -33,7 +33,7 @@ pub trait PickerDelegate: View {
         state: &mut MouseState,
         selected: bool,
         cx: &AppContext,
-    ) -> ElementBox<Self>;
+    ) -> ElementBox<Picker<Self>>;
     fn center_selection_after_match_updates(&self) -> bool {
         false
     }

crates/project_panel/src/project_panel.rs 🔗

@@ -1238,7 +1238,7 @@ impl ProjectPanel {
                 .is_some()
             {
                 if let Some(this) = this.upgrade(cx) {
-                    this.update(cx, |this, _, _| {
+                    this.update(cx, |this, _| {
                         this.dragged_entry_destination = if matches!(kind, EntryKind::File(_)) {
                             path.parent().map(|parent| Arc::from(parent))
                         } else {

crates/search/src/buffer_search.rs 🔗

@@ -348,7 +348,7 @@ impl BufferSearchBar {
                 cx.dispatch_any_action(option.to_toggle_action())
             })
             .with_cursor_style(CursorStyle::PointingHand)
-            .with_tooltip::<Self, _, _>(
+            .with_tooltip::<Self>(
                 option as usize,
                 format!("Toggle {}", option.label()),
                 Some(option.to_toggle_action()),
@@ -394,10 +394,10 @@ impl BufferSearchBar {
         })
         .on_click(MouseButton::Left, {
             let action = action.boxed_clone();
-            mov_, _, cx| cx.dispatch_any_action(action.boxed_clone())
+            move |_, _, cx| cx.dispatch_any_action(action.boxed_clone())
         })
         .with_cursor_style(CursorStyle::PointingHand)
-        .with_tooltip::<NavButton,_ _,,  _>(
+        .with_tooltip::<NavButton>(
             direction as usize,
             tooltip.to_string(),
             Some(action),
@@ -432,7 +432,7 @@ impl BufferSearchBar {
         })
         .on_click(MouseButton::Left, {
             let action = action.boxed_clone();
-            move |_, _, _, cx| cx.dispatch_any_action(action.boxed_clone())
+            move |_, _, cx| cx.dispatch_any_action(action.boxed_clone())
         })
         .with_cursor_style(CursorStyle::PointingHand)
         .with_tooltip::<CloseButton>(0, tooltip.to_string(), Some(action), tooltip_style, cx)

crates/search/src/project_search.rs 🔗

@@ -198,7 +198,7 @@ impl View for ProjectSearchView {
                     .flex(1., true)
                     .boxed()
             })
-            .on_down(MouseButton::Left, |_, _, _, cx| {
+            .on_down(MouseButton::Left, |_, _, cx| {
                 cx.focus_parent_view();
             })
             .boxed()
@@ -775,12 +775,13 @@ impl ProjectSearchBar {
                 .with_style(style.container)
                 .boxed()
         })
-        .on_click(MouseButton::Le {
+        .on_click(MouseButton::Left, {
             let action = action.boxed_clone();
             move |_, _, cx| cx.dispatch_any_action(action.boxed_clone())
-    _,    })
+        })
         .with_cursor_style(CursorStyle::PointingHand)
-        .with_tooltip::<NavButton, _            direction as usize,
+        .with_tooltip::<NavButton>(
+            direction as usize,
             tooltip.to_string(),
             Some(action),
             tooltip_style,

crates/terminal_view/src/terminal_element.rs 🔗

@@ -812,7 +812,7 @@ impl Element<TerminalView> for TerminalElement {
             }
 
             if let Some(element) = &mut layout.hyperlink_tooltip {
-                Element::paint(element, scene, origin, visible_bounds, view, view, cx)
+                element.paint(scene, origin, visible_bounds, view, cx)
             }
         });
     }

crates/theme_selector/src/theme_selector.rs 🔗

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

crates/vim/src/normal.rs 🔗

@@ -570,18 +570,18 @@ mod test {
 
         cx.assert_all(indoc! {"
                 The ˇquick
-                
+
                 brown fox jumps
                 overˇ the lazy doˇg"})
             .await;
         cx.assert(indoc! {"
             The quiˇck
-            
+
             brown"})
             .await;
         cx.assert(indoc! {"
             The quiˇck
-            
+
             "})
             .await;
     }
@@ -611,16 +611,16 @@ mod test {
         let mut cx = NeovimBackedTestContext::new(cx).await.binding(["e"]);
         cx.assert_all(indoc! {"
             Thˇe quicˇkˇ-browˇn
-            
-            
+
+
             fox_jumpˇs oveˇr
             thˇe"})
             .await;
         let mut cx = cx.binding(["shift-e"]);
         cx.assert_all(indoc! {"
             Thˇe quicˇkˇ-browˇn
-            
-            
+
+
             fox_jumpˇs oveˇr
             thˇe"})
             .await;
@@ -669,7 +669,7 @@ mod test {
             ["g", "g"],
             indoc! {"
                 The qˇuick
-            
+
                 brown fox jumps
                 over ˇthe laˇzy dog"},
         )
@@ -677,8 +677,8 @@ mod test {
         cx.assert_binding_matches(
             ["g", "g"],
             indoc! {"
-                
-            
+
+
                 brown fox jumps
                 over the laˇzy dog"},
         )
@@ -687,7 +687,7 @@ mod test {
             ["2", "g", "g"],
             indoc! {"
                 ˇ
-                
+
                 brown fox jumps
                 over the lazydog"},
         )
@@ -701,7 +701,7 @@ mod test {
             ["shift-g"],
             indoc! {"
                 The qˇuick
-                
+
                 brown fox jumps
                 over ˇthe laˇzy dog"},
         )
@@ -709,8 +709,8 @@ mod test {
         cx.assert_binding_matches(
             ["shift-g"],
             indoc! {"
-                
-                
+
+
                 brown fox jumps
                 over the laˇzy dog"},
         )
@@ -719,7 +719,7 @@ mod test {
             ["2", "shift-g"],
             indoc! {"
                 ˇ
-                
+
                 brown fox jumps
                 over the lazydog"},
         )
@@ -999,7 +999,7 @@ mod test {
             let test_case = indoc! {"
                 ˇaaaˇbˇ ˇbˇ   ˇbˇbˇ aˇaaˇbaaa
                 ˇ    ˇbˇaaˇa ˇbˇbˇb
-                ˇ   
+                ˇ
                 ˇb
             "};
 
@@ -1017,7 +1017,7 @@ mod test {
         let test_case = indoc! {"
             ˇaaaˇbˇ ˇbˇ   ˇbˇbˇ aˇaaˇbaaa
             ˇ    ˇbˇaaˇa ˇbˇbˇb
-            ˇ   
+            ˇ
             ˇb
             "};
 

crates/welcome/src/base_keymap_picker.rs 🔗

@@ -74,7 +74,7 @@ impl View for BaseKeymapSelector {
         "BaseKeymapSelector"
     }
 
-    fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> gpui::ElementBox {
+    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::ElementBox<Self> {
         ChildView::new(&self.picker, cx).boxed()
     }
 

crates/welcome/src/welcome.rs 🔗

@@ -55,7 +55,7 @@ impl View for WelcomePage {
         "WelcomePage"
     }
 
-    fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> ElementBox {
+    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> ElementBox {
         let self_handle = cx.handle();
         let settings = cx.global::<Settings>();
         let theme = settings.theme.clone();

crates/workspace/src/pane.rs 🔗

@@ -1404,7 +1404,7 @@ impl Pane {
                     };
 
                     ConstrainedBox::new(
-                        Canvas::new(move |scene, bounds, _, _, cx| {
+                        Canvas::new(move |scene, bounds, _, _, _| {
                             if let Some(color) = icon_color {
                                 let square = RectF::new(bounds.origin(), vec2f(diameter, diameter));
                                 scene.push_quad(Quad {

crates/workspace/src/shared_screen.rs 🔗

@@ -69,7 +69,7 @@ impl View for SharedScreen {
 
         let frame = self.frame.clone();
         MouseEventHandler::<Focus, _>::new(0, cx, |_, cx| {
-            Canvas::new(move |scene, bounds, _, _, cx| {
+            Canvas::new(move |scene, bounds, _, _, _| {
                 if let Some(frame) = frame.clone() {
                     let size = constrain_size_preserving_aspect_ratio(
                         bounds.size(),