diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index f30ab75663..260aa5697d 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -802,6 +802,14 @@ impl AppContext { .is_some() } + pub fn window_is_active(&self, window_id: usize) -> bool { + self.windows.get(&window_id).map_or(false, |w| w.is_active) + } + + pub fn root_view(&self, window_id: usize) -> Option<&AnyViewHandle> { + self.windows.get(&window_id).map(|w| w.root_view()) + } + pub fn window_ids(&self) -> impl Iterator + '_ { self.windows.keys().copied() } @@ -1648,6 +1656,18 @@ impl AppContext { window } + pub fn replace_root_view( + &mut self, + window_id: usize, + build_root_view: F, + ) -> Option> + where + V: View, + F: FnOnce(&mut ViewContext) -> V, + { + self.update_window(window_id, |cx| cx.replace_root_view(build_root_view)) + } + pub fn add_view(&mut self, parent: &AnyViewHandle, build_view: F) -> ViewHandle where S: View, @@ -3326,6 +3346,22 @@ impl<'a, 'b, 'c, V: View> ViewContext<'a, 'b, 'c, V> { self.window.focused_view_id == Some(self.view_id) } + pub fn is_parent_view_focused(&self) -> bool { + if let Some(parent_view_id) = self.ancestors(self.window_id, self.view_id).next().clone() { + self.focused_view_id() == Some(parent_view_id) + } else { + false + } + } + + pub fn focus_parent_view(&mut self) { + let next = self.ancestors(self.window_id, self.view_id).next().clone(); + if let Some(parent_view_id) = next { + let window_id = self.window_id; + self.window_context.focus(window_id, Some(parent_view_id)); + } + } + pub fn is_child(&self, view: impl Into) -> bool { let view = view.into(); if self.window_id != view.window_id { diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 36e0a6bfd2..176ac3fd4b 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -12,8 +12,9 @@ use crate::{ }, text_layout::TextLayoutCache, util::post_inc, - AnyView, AnyViewHandle, AppContext, Element, ElementBox, MouseRegion, MouseRegionId, ParentId, - RenderParams, SceneBuilder, View, ViewContext, ViewHandle, WindowInvalidation, + AnyView, AnyViewHandle, AppContext, Element, ElementBox, Entity, ModelContext, ModelHandle, + MouseRegion, MouseRegionId, ParentId, ReadView, RenderParams, SceneBuilder, UpdateModel, View, + ViewContext, ViewHandle, WindowInvalidation, }; use anyhow::bail; use collections::{HashMap, HashSet}; @@ -119,6 +120,22 @@ impl DerefMut for WindowContext<'_, '_> { } } +impl UpdateModel for WindowContext<'_, '_> { + fn update_model( + &mut self, + handle: &ModelHandle, + update: &mut dyn FnMut(&mut M, &mut ModelContext) -> R, + ) -> R { + self.app_context.update_model(handle, update) + } +} + +impl ReadView for WindowContext<'_, '_> { + fn read_view(&self, handle: &crate::ViewHandle) -> &W { + self.app_context.read_view(handle) + } +} + impl<'a: 'b, 'b> WindowContext<'a, 'b> { pub fn new(app_context: &'a mut AppContext, window: &'b mut Window, window_id: usize) -> Self { Self { @@ -133,6 +150,14 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> { self.window_id } + pub fn app_context(&mut self) -> &mut AppContext { + self.app_context + } + + pub fn root_view(&self) -> &AnyViewHandle { + self.window.root_view() + } + pub fn window_size(&self) -> Vector2F { self.window.platform_window.content_size() } @@ -701,23 +726,22 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> { } pub fn rect_for_text_range(&self, range_utf16: Range) -> Option { - todo!() + let root_view_id = self.window.root_view().id(); + self.window + .rendered_views + .get(&root_view_id)? + .rect_for_text_range(range_utf16, self, root_view_id) } pub fn debug_elements(&self) -> Option { - todo!() - // let view = self.root_view()?; - // Some(json!({ - // "root_view": view.debug_json(self), - // "root_element": self.window.rendered_views.get(&view.id()) - // .map(|root_element| { - // root_element.debug(&DebugContext { - // rendered_views: &self.window.rendered_views, - // font_cache: &self.window.font_cache, - // app: self, - // }) - // }) - // })) + let view = self.window.root_view(); + Some(json!({ + "root_view": view.debug_json(self), + "root_element": self.window.rendered_views.get(&view.id()) + .map(|root_element| { + root_element.debug(self, view.id()) + }) + })) } pub fn set_window_title(&mut self, title: &str) { diff --git a/crates/gpui/src/scene/mouse_region.rs b/crates/gpui/src/scene/mouse_region.rs index b3c05c4280..275a10ae31 100644 --- a/crates/gpui/src/scene/mouse_region.rs +++ b/crates/gpui/src/scene/mouse_region.rs @@ -11,7 +11,7 @@ use collections::HashMap; use pathfinder_geometry::rect::RectF; use smallvec::SmallVec; -use crate::{platform::MouseButton, window::WindowContext, View, ViewContext}; +use crate::{platform::MouseButton, window::WindowContext, ReadView, View, ViewContext}; use super::{ mouse_event::{ @@ -234,6 +234,12 @@ impl DerefMut for EventContext<'_, '_, '_, '_, V> { } } +impl ReadView for EventContext<'_, '_, '_, '_, V> { + fn read_view(&self, handle: &crate::ViewHandle) -> &W { + self.view_context.read_view(handle) + } +} + pub type HandlerCallback = Rc bool>; #[derive(Clone, PartialEq, Eq, Hash)] diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index 87c6031a46..470125abdc 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -315,7 +315,7 @@ impl Dock { theme: &Theme, anchor: DockAnchor, cx: &mut ViewContext, - ) -> Option> { + ) -> Option> { let style = &theme.workspace.dock; self.position @@ -350,7 +350,7 @@ impl Dock { let resizable = Container::new(ChildView::new(&self.pane, cx).boxed()) .with_style(panel_style) - .with_resize_handle::( + .with_resize_handle::( resize_side as usize, resize_side, 4., @@ -362,8 +362,8 @@ impl Dock { ); let size = resizable.current_size(); - let workspace = cx.handle(); - cx.defer(move |cx| { + let workspace = cx.handle().downgrade(); + cx.defer(move |_, cx| { if let Some(workspace) = workspace.upgrade(cx) { workspace.update(cx, |workspace, _| { workspace.dock.panel_sizes.insert(anchor, size); @@ -374,20 +374,20 @@ impl Dock { if anchor == DockAnchor::Right { resizable .constrained() - .dynamically(|constraint, cx| { + .dynamically(|constraint, _, cx| { SizeConstraint::new( Vector2F::new(20., constraint.min.y()), - Vector2F::new(cx.window_size.x() * 0.8, constraint.max.y()), + Vector2F::new(cx.window_size().x() * 0.8, constraint.max.y()), ) }) .boxed() } else { resizable .constrained() - .dynamically(|constraint, cx| { + .dynamically(|constraint, _, cx| { SizeConstraint::new( Vector2F::new(constraint.min.x(), 50.), - Vector2F::new(constraint.max.x(), cx.window_size.y() * 0.8), + Vector2F::new(constraint.max.x(), cx.window_size().y() * 0.8), ) }) .boxed() @@ -399,21 +399,21 @@ impl Dock { Stack::new() .with_child( // Render wash under the dock which when clicked hides it - MouseEventHandler::::new(0, cx, |_, _| { + MouseEventHandler::::new(0, cx, |_, _| { Empty::new() .contained() .with_background_color(style.wash_color) .boxed() }) .capture_all() - .on_down(MouseButton::Left, |_, cx| { + .on_down(MouseButton::Left, |_, _, cx| { cx.dispatch_action(HideDock); }) .with_cursor_style(CursorStyle::Arrow) .boxed(), ) .with_child( - MouseEventHandler::::new(0, cx, |_state, cx| { + MouseEventHandler::::new(0, cx, |_state, cx| { ChildView::new(&self.pane, cx).boxed() }) // Make sure all events directly under the dock pane diff --git a/crates/workspace/src/dock/toggle_dock_button.rs b/crates/workspace/src/dock/toggle_dock_button.rs index 1db820ca1f..9f32048d42 100644 --- a/crates/workspace/src/dock/toggle_dock_button.rs +++ b/crates/workspace/src/dock/toggle_dock_button.rs @@ -43,11 +43,11 @@ impl View for ToggleDockButton { let workspace = workspace.unwrap(); let dock_position = workspace.read(cx).dock.position; - let dock_pane = workspace.read(cx.app).dock_pane().clone(); + let dock_pane = workspace.read(cx).dock_pane().clone(); let theme = cx.global::().theme.clone(); - let button = MouseEventHandler::::new(0, cx, { + let button = MouseEventHandler::::new(0, cx, { let theme = theme.clone(); move |state, _| { let style = theme @@ -68,17 +68,17 @@ impl View for ToggleDockButton { } }) .with_cursor_style(CursorStyle::PointingHand) - .on_up(MouseButton::Left, move |event, cx| { - let drop_index = dock_pane.read(cx.app).items_len() + 1; + .on_up(MouseButton::Left, move |event, _, cx| { + let drop_index = dock_pane.read(cx).items_len() + 1; handle_dropped_item(event, &dock_pane.downgrade(), drop_index, false, None, cx); }); if dock_position.is_visible() { button - .on_click(MouseButton::Left, |_, cx| { + .on_click(MouseButton::Left, |_, _, cx| { cx.dispatch_action(HideDock); }) - .with_tooltip::( + .with_tooltip::( 0, "Hide Dock".into(), Some(Box::new(HideDock)), @@ -87,10 +87,10 @@ impl View for ToggleDockButton { ) } else { button - .on_click(MouseButton::Left, |_, cx| { + .on_click(MouseButton::Left, |_, _, cx| { cx.dispatch_action(FocusDock); }) - .with_tooltip::( + .with_tooltip::( 0, "Focus Dock".into(), Some(Box::new(FocusDock)), diff --git a/crates/workspace/src/item.rs b/crates/workspace/src/item.rs index f1b3f608e8..da01686de7 100644 --- a/crates/workspace/src/item.rs +++ b/crates/workspace/src/item.rs @@ -52,7 +52,7 @@ pub trait Item: View { detail: Option, style: &theme::Tab, cx: &AppContext, - ) -> ElementBox; + ) -> ElementBox; fn for_each_project_item(&self, _: &AppContext, _: &mut dyn FnMut(usize, &dyn project::Item)) {} fn is_singleton(&self, _cx: &AppContext) -> bool { false @@ -134,7 +134,7 @@ pub trait Item: View { ToolbarItemLocation::Hidden } - fn breadcrumbs(&self, _theme: &Theme, _cx: &AppContext) -> Option>> { + fn breadcrumbs(&self, _theme: &Theme, _cx: &AppContext) -> Option>> { None } @@ -591,7 +591,7 @@ impl ItemHandle for ViewHandle { self.read(cx).breadcrumb_location() } - fn breadcrumbs(&self, theme: &Theme, cx: &AppContext) -> Option>> { + fn breadcrumbs(&self, theme: &Theme, cx: &AppContext) -> Option>> { self.read(cx).breadcrumbs(theme, cx) } @@ -925,7 +925,7 @@ pub(crate) mod test { detail: Option, _: &theme::Tab, _: &AppContext, - ) -> ElementBox { + ) -> ElementBox { self.tab_detail.set(detail); Empty::new().boxed() } diff --git a/crates/workspace/src/notifications.rs b/crates/workspace/src/notifications.rs index e071804186..bb91461375 100644 --- a/crates/workspace/src/notifications.rs +++ b/crates/workspace/src/notifications.rs @@ -244,7 +244,7 @@ pub mod simple_message_notification { let has_click_action = click_action.is_some(); - MouseEventHandler::::new(0, cx, |state, cx| { + MouseEventHandler::::new(0, cx, |state, cx| { Flex::column() .with_child( Flex::row() @@ -259,7 +259,7 @@ pub mod simple_message_notification { .boxed(), ) .with_child( - MouseEventHandler::::new(0, cx, |state, _| { + MouseEventHandler::::new(0, cx, |state, _| { let style = theme.dismiss_button.style_for(state, false); Svg::new("icons/x_mark_8.svg") .with_color(style.color) @@ -274,7 +274,7 @@ pub mod simple_message_notification { .boxed() }) .with_padding(Padding::uniform(5.)) - .on_click(MouseButton::Left, move |_, cx| { + .on_click(MouseButton::Left, move |_, _, cx| { cx.dispatch_action(CancelMessageNotification) }) .with_cursor_style(CursorStyle::PointingHand) @@ -312,9 +312,9 @@ pub mod simple_message_notification { .boxed() }) // Since we're not using a proper overlay, we have to capture these extra events - .on_down(MouseButton::Left, |_, _| {}) - .on_up(MouseButton::Left, |_, _| {}) - .on_click(MouseButton::Left, move |_, cx| { + .on_down(MouseButton::Left, |_, _, _| {}) + .on_up(MouseButton::Left, |_, _, _| {}) + .on_click(MouseButton::Left, move |_, _, cx| { if let Some(click_action) = click_action.as_ref() { cx.dispatch_any_action(click_action.boxed_clone()); cx.dispatch_action(CancelMessageNotification) diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 8c168e8ee2..df8290816c 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -1220,10 +1220,10 @@ impl Pane { }); } - fn render_tabs(&mut self, cx: &mut ViewContext) -> impl Element { + fn render_tabs(&mut self, cx: &mut ViewContext) -> impl Element { let theme = cx.global::().theme.clone(); - let pane = cx.handle(); + let pane = cx.handle().downgrade(); let autoscroll = if mem::take(&mut self.autoscroll) { Some(self.active_item_index) } else { @@ -1233,7 +1233,7 @@ impl Pane { let pane_active = self.is_active; enum Tabs {} - let mut row = Flex::row().scrollable::(1, autoscroll, cx); + let mut row = Flex::row().scrollable::(1, autoscroll, cx); for (ix, (item, detail)) in self .items .iter() @@ -1260,8 +1260,8 @@ impl Pane { let hovered = mouse_state.hovered(); enum Tab {} - MouseEventHandler::::new(ix, cx, |_, cx| { - Self::render_tab( + MouseEventHandler::::new(ix, cx, |_, cx| { + Self::render_tab::( &item, pane.clone(), ix == 0, @@ -1271,12 +1271,12 @@ impl Pane { cx, ) }) - .on_down(MouseButton::Left, move |_, cx| { + .on_down(MouseButton::Left, move |_, _, cx| { cx.dispatch_action(ActivateItem(ix)); }) .on_click(MouseButton::Middle, { let item = item.clone(); - move |_, cx: &mut EventContext| { + move |_, _, cx: &mut EventContext| { cx.dispatch_action(CloseItem { item_id: item.id(), pane: pane.clone(), @@ -1301,9 +1301,9 @@ impl Pane { let theme = cx.global::().theme.clone(); let detail = detail.clone(); - move |dragged_item, cx: &mut ViewContext| { + move |dragged_item: &DraggedItem, cx: &mut ViewContext| { let tab_style = &theme.workspace.tab_bar.dragged_tab; - Self::render_tab( + Self::render_tab::( &dragged_item.item, dragged_item.pane.clone(), false, @@ -1404,7 +1404,7 @@ impl Pane { }; ConstrainedBox::new( - Canvas::new(move |scene, bounds, _, cx| { + Canvas::new(move |scene, bounds, _, _, cx| { if let Some(color) = icon_color { let square = RectF::new(bounds.origin(), vec2f(diameter, diameter)); scene.push_quad(Quad { @@ -1441,18 +1441,22 @@ impl Pane { let item_id = item.id(); enum TabCloseButton {} let icon = Svg::new("icons/x_mark_8.svg"); - MouseEventHandler::::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() - } - }) + MouseEventHandler::::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| { + move |_, _, cx| { cx.dispatch_action(CloseItem { item_id, pane: pane.clone(), @@ -1551,13 +1555,13 @@ impl View for Pane { } fn render(&mut self, cx: &mut ViewContext) -> ElementBox { - let this = cx.handle(); + let this = cx.handle().downgrade(); enum MouseNavigationHandler {} Stack::new() .with_child( - MouseEventHandler::::new(0, cx, |_, cx| { + MouseEventHandler::::new(0, cx, |_, cx| { let active_item_index = self.active_item_index; if let Some(active_item) = self.active_item() { @@ -1569,13 +1573,17 @@ impl View for Pane { enum TabBarEventHandler {} stack.add_child( - MouseEventHandler::::new(0, cx, |_, _| { - Empty::new() - .contained() - .with_style(theme.workspace.tab_bar.container) - .boxed() - }) - .on_down(MouseButton::Left, move |_, cx| { + MouseEventHandler::::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(), @@ -1635,7 +1643,7 @@ impl View for Pane { dragged_item_receiver::(0, 0, false, None, cx, |_, cx| { self.render_blank_pane(&theme, cx) }) - .on_down(MouseButton::Left, |_, cx| { + .on_down(MouseButton::Left, |_, _, cx| { cx.focus_parent_view(); }) .boxed() @@ -1643,7 +1651,7 @@ impl View for Pane { }) .on_down(MouseButton::Navigate(NavigationDirection::Back), { let this = this.clone(); - move |_, cx| { + move |_, _, cx| { cx.dispatch_action(GoBack { pane: Some(this.clone()), }); @@ -1651,7 +1659,7 @@ impl View for Pane { }) .on_down(MouseButton::Navigate(NavigationDirection::Forward), { let this = this.clone(); - move |_, cx| { + move |_, _, cx| { cx.dispatch_action(GoForward { pane: Some(this.clone()), }) @@ -1716,7 +1724,7 @@ fn render_tab_bar_button( Stack::new() .with_child( - MouseEventHandler::::new(index, cx, |mouse_state, cx| { + MouseEventHandler::::new(index, cx, |mouse_state, cx| { let theme = &cx.global::().theme.workspace.tab_bar; let style = theme.pane_button.style_for(mouse_state, false); Svg::new(icon) @@ -1730,7 +1738,7 @@ fn render_tab_bar_button( .boxed() }) .with_cursor_style(CursorStyle::PointingHand) - .on_click(MouseButton::Left, move |_, cx| { + .on_click(MouseButton::Left, move |_, _, cx| { cx.dispatch_action(action.clone()); }) .boxed(), @@ -1895,9 +1903,9 @@ impl Element for PaneBackdrop { scene.push_mouse_region( MouseRegion::new::(child_view_id, 0, visible_bounds).on_down( gpui::platform::MouseButton::Left, - move |_, cx| { - let window_id = cx.window_id; - cx.focus(window_id, Some(child_view_id)) + move |_, _: &mut Pane, cx| { + let window_id = cx.window_id(); + cx.app_context().focus(window_id, Some(child_view_id)) }, ), ); diff --git a/crates/workspace/src/pane/dragged_item_receiver.rs b/crates/workspace/src/pane/dragged_item_receiver.rs index 2b529ac425..f1117cd980 100644 --- a/crates/workspace/src/pane/dragged_item_receiver.rs +++ b/crates/workspace/src/pane/dragged_item_receiver.rs @@ -5,7 +5,8 @@ use gpui::{ geometry::{rect::RectF, vector::Vector2F}, platform::MouseButton, scene::MouseUp, - AppContext, Element, ElementBox, MouseState, Quad, ViewContext, WeakViewHandle, + AppContext, Element, ElementBox, EventContext, MouseState, Quad, View, ViewContext, + WeakViewHandle, }; use project::ProjectEntryId; use settings::Settings; @@ -29,7 +30,7 @@ where Tag: 'static, F: FnOnce(&mut MouseState, &mut ViewContext) -> ElementBox, { - MouseEventHandler::::above(region_id, cx, |state, _, cx| { + MouseEventHandler::::above(region_id, cx, |state, cx| { // Observing hovered will cause a render when the mouse enters regardless // of if mouse position was accessed before let drag_position = if state.hovered() { @@ -48,7 +49,7 @@ where Stack::new() .with_child(render_child(state, cx)) .with_children(drag_position.map(|drag_position| { - Canvas::new(move |scene, bounds, _, cx| { + Canvas::new(move |scene, bounds, _, _, cx| { if bounds.contains_point(drag_position) { let overlay_region = split_margin .and_then(|split_margin| { @@ -58,7 +59,7 @@ where .map(|(dir, margin)| dir.along_edge(bounds, margin)) .unwrap_or(bounds); - scene.paint_stacking_context(None, None, |cx| { + scene.paint_stacking_context(None, None, |scene| { scene.push_quad(Quad { bounds: overlay_region, background: Some(overlay_color(cx)), @@ -73,13 +74,13 @@ where .boxed() }) .on_up(MouseButton::Left, { - let pane = cx.handle(); - move |event, cx| { + let pane = cx.handle().downgrade(); + move |event, _, cx| { handle_dropped_item(event, &pane, drop_index, allow_same_pane, split_margin, cx); cx.notify(); } }) - .on_move(|_, cx| { + .on_move(|_, _, cx| { let drag_and_drop = cx.global::>(); if drag_and_drop @@ -96,13 +97,13 @@ where }) } -pub fn handle_dropped_item( +pub fn handle_dropped_item( event: MouseUp, pane: &WeakViewHandle, index: usize, allow_same_pane: bool, split_margin: Option, - cx: &mut ViewContext, + cx: &mut EventContext, ) { enum Action { Move(WeakViewHandle, usize), diff --git a/crates/workspace/src/pane_group.rs b/crates/workspace/src/pane_group.rs index 048cb7150a..96024c09e4 100644 --- a/crates/workspace/src/pane_group.rs +++ b/crates/workspace/src/pane_group.rs @@ -176,7 +176,7 @@ impl Member { let leader_user = leader.user.clone(); let leader_user_id = leader.user.id; Some( - MouseEventHandler::::new( + MouseEventHandler::::new( pane.id(), cx, |_, _| { @@ -199,7 +199,7 @@ impl Member { }, ) .with_cursor_style(CursorStyle::PointingHand) - .on_click(MouseButton::Left, move |_, cx| { + .on_click(MouseButton::Left, move |_, _, cx| { cx.dispatch_action(JoinProject { project_id: leader_project_id, follow_user_id: leader_user_id, diff --git a/crates/workspace/src/shared_screen.rs b/crates/workspace/src/shared_screen.rs index 26db3edb01..383651b991 100644 --- a/crates/workspace/src/shared_screen.rs +++ b/crates/workspace/src/shared_screen.rs @@ -1,6 +1,6 @@ use crate::{ item::{Item, ItemEvent}, - ItemNavHistory, WorkspaceId, + ItemNavHistory, Pane, WorkspaceId, }; use call::participant::{Frame, RemoteVideoTrack}; use client::{proto::PeerId, User}; @@ -68,8 +68,8 @@ impl View for SharedScreen { enum Focus {} let frame = self.frame.clone(); - MouseEventHandler::::new(0, cx, |_, cx| { - Canvas::new(move |scene, bounds, _, cx| { + MouseEventHandler::::new(0, cx, |_, cx| { + Canvas::new(move |scene, bounds, _, _, cx| { if let Some(frame) = frame.clone() { let size = constrain_size_preserving_aspect_ratio( bounds.size(), @@ -86,7 +86,7 @@ impl View for SharedScreen { .with_style(cx.global::().theme.shared_screen) .boxed() }) - .on_down(MouseButton::Left, |_, cx| cx.focus_parent_view()) + .on_down(MouseButton::Left, |_, _, cx| cx.focus_parent_view()) .boxed() } } @@ -103,7 +103,7 @@ impl Item for SharedScreen { _: Option, style: &theme::Tab, _: &AppContext, - ) -> gpui::ElementBox { + ) -> gpui::ElementBox { Flex::row() .with_child( Svg::new("icons/disable_screen_sharing_12.svg") diff --git a/crates/workspace/src/sidebar.rs b/crates/workspace/src/sidebar.rs index e9b6250a09..ad9af37ad6 100644 --- a/crates/workspace/src/sidebar.rs +++ b/crates/workspace/src/sidebar.rs @@ -195,7 +195,7 @@ impl View for Sidebar { ChildView::new(active_item.as_any(), cx) .contained() .with_style(style.container) - .with_resize_handle::( + .with_resize_handle::( self.sidebar_side as usize, self.sidebar_side.to_resizable_side(), 4., @@ -254,7 +254,7 @@ impl View for SidebarButtons { sidebar_side, item_index: ix, }; - MouseEventHandler::::new(ix, cx, |state, cx| { + MouseEventHandler::::new(ix, cx, |state, cx| { let is_active = is_open && ix == active_ix; let style = item_style.style_for(state, is_active); Stack::new() @@ -283,9 +283,9 @@ impl View for SidebarButtons { .with_cursor_style(CursorStyle::PointingHand) .on_click(MouseButton::Left, { let action = action.clone(); - move |_, cx| cx.dispatch_action(action.clone()) + move |_, _, cx| cx.dispatch_action(action.clone()) }) - .with_tooltip::( + .with_tooltip::( ix, tooltip, Some(Box::new(action)), diff --git a/crates/workspace/src/toolbar.rs b/crates/workspace/src/toolbar.rs index 814abd30d4..8fb10737e1 100644 --- a/crates/workspace/src/toolbar.rs +++ b/crates/workspace/src/toolbar.rs @@ -170,7 +170,7 @@ fn nav_button( action_name: &str, cx: &mut ViewContext, ) -> ElementBox { - MouseEventHandler::::new(0, cx, |state, _| { + MouseEventHandler::::new(0, cx, |state, _| { let style = if enabled { style.style_for(state, false) } else { @@ -194,10 +194,10 @@ fn nav_button( } else { CursorStyle::default() }) - .on_click(MouseButton::Left, move |_, cx| { + .on_click(MouseButton::Left, move |_, _, cx| { cx.dispatch_action(action.clone()) }) - .with_tooltip::( + .with_tooltip::( 0, action_name.to_string(), Some(Box::new(tooltip_action)), diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index d107279c45..15987d647f 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -928,11 +928,7 @@ impl Workspace { workspace }; - let workspace = if let Some(window_id) = requesting_window_id { - cx.update(|cx| { - cx.replace_root_view(window_id, |cx| build_workspace(cx, serialized_workspace)) - }) - } else { + let workspace = { let (bounds, display) = if let Some(bounds) = window_bounds_override { (Some(bounds), None) } else { @@ -1133,7 +1129,14 @@ impl Workspace { let window_id = cx.window_id(); let workspace_count = cx .window_ids() - .filter_map(|window_id| cx.root_view(window_id)?.clone().downcast::()) + .collect::>() + .into_iter() + .filter_map(|window_id| { + cx.app_context() + .root_view(window_id)? + .clone() + .downcast::() + }) .count(); cx.spawn(|this, mut cx| async move { @@ -1142,23 +1145,22 @@ impl Workspace { && workspace_count == 1 && active_call.read_with(&cx, |call, _| call.room().is_some()) { - let answer = cx - .prompt( - window_id, - PromptLevel::Warning, - "Do you want to leave the current call?", - &["Close window and hang up", "Cancel"], - ) - .next() - .await; + let answer = cx.prompt( + window_id, + PromptLevel::Warning, + "Do you want to leave the current call?", + &["Close window and hang up", "Cancel"], + ); - if answer == Some(1) { - return anyhow::Ok(false); - } else { - active_call - .update(&mut cx, |call, cx| call.hang_up(cx)) - .await - .log_err(); + if let Some(mut answer) = answer { + if answer.next().await == Some(1) { + return anyhow::Ok(false); + } else { + active_call + .update(&mut cx, |call, cx| call.hang_up(cx)) + .await + .log_err(); + } } } } @@ -1621,7 +1623,7 @@ impl Workspace { > { let project = self.project().clone(); let project_item = project.update(cx, |project, cx| project.open_path(path, cx)); - cx.as_mut().spawn(|mut cx| async move { + cx.spawn(|_, mut cx| async move { let (project_entry_id, project_item) = project_item.await?; let build_item = cx.update(|cx| { cx.default_global::() @@ -1802,15 +1804,14 @@ impl Workspace { } let item = pane.read(cx).active_item()?; - let maybe_pane_handle = - if let Some(clone) = item.clone_on_split(self.database_id(), cx.as_mut()) { - let new_pane = self.add_pane(cx); - Pane::add_item(self, &new_pane, clone, true, true, None, cx); - self.center.split(&pane, &new_pane, direction).unwrap(); - Some(new_pane) - } else { - None - }; + let maybe_pane_handle = if let Some(clone) = item.clone_on_split(self.database_id(), cx) { + let new_pane = self.add_pane(cx); + Pane::add_item(self, &new_pane, clone, true, true, None, cx); + self.center.split(&pane, &new_pane, direction).unwrap(); + Some(new_pane) + } else { + None + }; cx.notify(); maybe_pane_handle } @@ -2067,7 +2068,7 @@ impl Workspace { enum TitleBar {} ConstrainedBox::new( - MouseEventHandler::::new(0, cx, |_, cx| { + MouseEventHandler::::new(0, cx, |_, cx| { Container::new( Stack::new() .with_children( @@ -2080,9 +2081,9 @@ impl Workspace { .with_style(container_theme) .boxed() }) - .on_click(MouseButton::Left, |event, cx| { + .on_click(MouseButton::Left, |event, _, cx| { if event.click_count == 2 { - cx.zoom_window(cx.window_id()); + cx.zoom_window(); } }) .boxed(), @@ -2160,7 +2161,7 @@ impl Workspace { if self.project.read(cx).is_read_only() { enum DisconnectedOverlay {} Some( - MouseEventHandler::::new(0, cx, |_, cx| { + MouseEventHandler::::new(0, cx, |_, cx| { let theme = &cx.global::().theme; Label::new( "Your connection to the remote project has been lost.", @@ -2828,11 +2829,11 @@ impl View for Workspace { Some( ChildView::new(&self.left_sidebar, cx) .constrained() - .dynamically(|constraint, cx| { + .dynamically(|constraint, _, cx| { SizeConstraint::new( Vector2F::new(20., constraint.min.y()), Vector2F::new( - cx.window_size.x() * 0.8, + cx.window_size().x() * 0.8, constraint.max.y(), ), ) @@ -2874,11 +2875,11 @@ impl View for Workspace { Some( ChildView::new(&self.right_sidebar, cx) .constrained() - .dynamically(|constraint, cx| { + .dynamically(|constraint, _, cx| { SizeConstraint::new( Vector2F::new(20., constraint.min.y()), Vector2F::new( - cx.window_size.x() * 0.8, + cx.window_size().x() * 0.8, constraint.max.y(), ), ) @@ -2998,12 +2999,21 @@ pub fn activate_workspace_for_project( predicate: impl Fn(&mut Project, &mut ModelContext) -> bool, ) -> Option> { for window_id in cx.window_ids().collect::>() { - if let Some(workspace_handle) = cx.root_view(window_id)?.downcast_ref::() { - let project = workspace_handle.read(cx).project.clone(); - if project.update(cx, &predicate) { - cx.activate_window(window_id); - return Some(workspace_handle.clone()); - } + let handle = cx + .update_window(window_id, |cx| { + if let Some(workspace_handle) = cx.root_view().clone().downcast::() { + let project = workspace_handle.read(cx).project.clone(); + if project.update(cx, &predicate) { + cx.activate_window(); + return Some(workspace_handle.clone()); + } + } + None + }) + .flatten(); + + if handle.is_some() { + return handle; } } None