Detailed changes
@@ -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<Item = usize> + '_ {
self.windows.keys().copied()
}
@@ -1648,6 +1656,18 @@ impl AppContext {
window
}
+ pub fn replace_root_view<V, F>(
+ &mut self,
+ window_id: usize,
+ build_root_view: F,
+ ) -> Option<ViewHandle<V>>
+ where
+ V: View,
+ F: FnOnce(&mut ViewContext<V>) -> V,
+ {
+ self.update_window(window_id, |cx| cx.replace_root_view(build_root_view))
+ }
+
pub fn add_view<S, F>(&mut self, parent: &AnyViewHandle, build_view: F) -> ViewHandle<S>
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<AnyViewHandle>) -> bool {
let view = view.into();
if self.window_id != view.window_id {
@@ -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<M: Entity, R>(
+ &mut self,
+ handle: &ModelHandle<M>,
+ update: &mut dyn FnMut(&mut M, &mut ModelContext<M>) -> R,
+ ) -> R {
+ self.app_context.update_model(handle, update)
+ }
+}
+
+impl ReadView for WindowContext<'_, '_> {
+ fn read_view<W: View>(&self, handle: &crate::ViewHandle<W>) -> &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<usize>) -> Option<RectF> {
- 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<json::Value> {
- 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) {
@@ -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<V: View> DerefMut 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)
+ }
+}
+
pub type HandlerCallback = Rc<dyn Fn(MouseEvent, &mut dyn Any, &mut WindowContext, usize) -> bool>;
#[derive(Clone, PartialEq, Eq, Hash)]
@@ -315,7 +315,7 @@ impl Dock {
theme: &Theme,
anchor: DockAnchor,
cx: &mut ViewContext<Workspace>,
- ) -> Option<ElementBox<Self>> {
+ ) -> Option<ElementBox<Workspace>> {
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::<DockResizeHandle, _>(
+ .with_resize_handle::<DockResizeHandle>(
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::<ExpandedDockWash>::new(0, cx, |_, _| {
+ MouseEventHandler::<ExpandedDockWash, _>::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::<ExpandedDockPane>::new(0, cx, |_state, cx| {
+ MouseEventHandler::<ExpandedDockPane, _>::new(0, cx, |_state, cx| {
ChildView::new(&self.pane, cx).boxed()
})
// Make sure all events directly under the dock pane
@@ -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::<Settings>().theme.clone();
- let button = MouseEventHandler::<Self>::new(0, cx, {
+ let button = MouseEventHandler::<Self, _>::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::<Self, _>(
+ .with_tooltip::<Self>(
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::<Self, _>(
+ .with_tooltip::<Self>(
0,
"Focus Dock".into(),
Some(Box::new(FocusDock)),
@@ -52,7 +52,7 @@ pub trait Item: View {
detail: Option<usize>,
style: &theme::Tab,
cx: &AppContext,
- ) -> ElementBox<Self>;
+ ) -> ElementBox<Pane>;
fn for_each_project_item(&self, _: &AppContext, _: &mut dyn FnMut(usize, &dyn project::Item)) {}
fn is_singleton(&self, _cx: &AppContext) -> bool {
false
@@ -134,7 +134,7 @@ pub trait Item: View {
ToolbarItemLocation::Hidden
}
- fn breadcrumbs(&self, _theme: &Theme, _cx: &AppContext) -> Option<Vec<ElementBox<Self>>> {
+ fn breadcrumbs(&self, _theme: &Theme, _cx: &AppContext) -> Option<Vec<ElementBox<Pane>>> {
None
}
@@ -591,7 +591,7 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
self.read(cx).breadcrumb_location()
}
- fn breadcrumbs(&self, theme: &Theme, cx: &AppContext) -> Option<Vec<ElementBox<Self>>> {
+ fn breadcrumbs(&self, theme: &Theme, cx: &AppContext) -> Option<Vec<ElementBox<Pane>>> {
self.read(cx).breadcrumbs(theme, cx)
}
@@ -925,7 +925,7 @@ pub(crate) mod test {
detail: Option<usize>,
_: &theme::Tab,
_: &AppContext,
- ) -> ElementBox<Self> {
+ ) -> ElementBox<Pane> {
self.tab_detail.set(detail);
Empty::new().boxed()
}
@@ -244,7 +244,7 @@ pub mod simple_message_notification {
let has_click_action = click_action.is_some();
- MouseEventHandler::<MessageNotificationTag>::new(0, cx, |state, cx| {
+ MouseEventHandler::<MessageNotificationTag, _>::new(0, cx, |state, cx| {
Flex::column()
.with_child(
Flex::row()
@@ -259,7 +259,7 @@ pub mod simple_message_notification {
.boxed(),
)
.with_child(
- MouseEventHandler::<Cancel>::new(0, cx, |state, _| {
+ MouseEventHandler::<Cancel, _>::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)
@@ -1220,10 +1220,10 @@ impl Pane {
});
}
- fn render_tabs(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
+ fn render_tabs(&mut self, cx: &mut ViewContext<Self>) -> impl Element<Self> {
let theme = cx.global::<Settings>().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::<Tabs, _>(1, autoscroll, cx);
+ let mut row = Flex::row().scrollable::<Tabs>(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::<Tab>::new(ix, cx, |_, cx| {
- Self::render_tab(
+ MouseEventHandler::<Tab, Pane>::new(ix, cx, |_, cx| {
+ Self::render_tab::<Pane>(
&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<Self>| {
cx.dispatch_action(CloseItem {
item_id: item.id(),
pane: pane.clone(),
@@ -1301,9 +1301,9 @@ impl Pane {
let theme = cx.global::<Settings>().theme.clone();
let detail = detail.clone();
- move |dragged_item, cx: &mut ViewContext<Workspace>| {
+ move |dragged_item: &DraggedItem, cx: &mut ViewContext<Pane>| {
let tab_style = &theme.workspace.tab_bar.dragged_tab;
- Self::render_tab(
+ Self::render_tab::<Pane>(
&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::<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()
- }
- })
+ 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| {
+ 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<Self>) -> ElementBox<Self> {
- let this = cx.handle();
+ let this = cx.handle().downgrade();
enum MouseNavigationHandler {}
Stack::new()
.with_child(
- MouseEventHandler::<MouseNavigationHandler>::new(0, cx, |_, cx| {
+ MouseEventHandler::<MouseNavigationHandler, _>::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::<TabBarEventHandler>::new(0, cx, |_, _| {
- Empty::new()
- .contained()
- .with_style(theme.workspace.tab_bar.container)
- .boxed()
- })
- .on_down(MouseButton::Left, move |_, cx| {
+ 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(),
@@ -1635,7 +1643,7 @@ impl View for Pane {
dragged_item_receiver::<EmptyPane, _>(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<A: Action + Clone>(
Stack::new()
.with_child(
- MouseEventHandler::<TabBarButton>::new(index, cx, |mouse_state, cx| {
+ MouseEventHandler::<TabBarButton, _>::new(index, cx, |mouse_state, cx| {
let theme = &cx.global::<Settings>().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<A: Action + Clone>(
.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<Pane> for PaneBackdrop {
scene.push_mouse_region(
MouseRegion::new::<Self>(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))
},
),
);
@@ -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<Pane>) -> ElementBox<Pane>,
{
- MouseEventHandler::<Tag>::above(region_id, cx, |state, _, cx| {
+ MouseEventHandler::<Tag, _>::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::<DragAndDrop<Workspace>>();
if drag_and_drop
@@ -96,13 +97,13 @@ where
})
}
-pub fn handle_dropped_item(
+pub fn handle_dropped_item<V: View>(
event: MouseUp,
pane: &WeakViewHandle<Pane>,
index: usize,
allow_same_pane: bool,
split_margin: Option<f32>,
- cx: &mut ViewContext<Pane>,
+ cx: &mut EventContext<V>,
) {
enum Action {
Move(WeakViewHandle<Pane>, usize),
@@ -176,7 +176,7 @@ impl Member {
let leader_user = leader.user.clone();
let leader_user_id = leader.user.id;
Some(
- MouseEventHandler::<FollowIntoExternalProject>::new(
+ MouseEventHandler::<FollowIntoExternalProject, _>::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,
@@ -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::<Focus>::new(0, cx, |_, cx| {
- Canvas::new(move |scene, bounds, _, cx| {
+ MouseEventHandler::<Focus, _>::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::<Settings>().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<usize>,
style: &theme::Tab,
_: &AppContext,
- ) -> gpui::ElementBox<Self> {
+ ) -> gpui::ElementBox<Pane> {
Flex::row()
.with_child(
Svg::new("icons/disable_screen_sharing_12.svg")
@@ -195,7 +195,7 @@ impl View for Sidebar {
ChildView::new(active_item.as_any(), cx)
.contained()
.with_style(style.container)
- .with_resize_handle::<ResizeHandleTag, _>(
+ .with_resize_handle::<ResizeHandleTag>(
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::<Self>::new(ix, cx, |state, cx| {
+ MouseEventHandler::<Self, _>::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::<Self, _>(
+ .with_tooltip::<Self>(
ix,
tooltip,
Some(Box::new(action)),
@@ -170,7 +170,7 @@ fn nav_button<A: Action + Clone>(
action_name: &str,
cx: &mut ViewContext<Toolbar>,
) -> ElementBox<Toolbar> {
- MouseEventHandler::<A>::new(0, cx, |state, _| {
+ MouseEventHandler::<A, _>::new(0, cx, |state, _| {
let style = if enabled {
style.style_for(state, false)
} else {
@@ -194,10 +194,10 @@ fn nav_button<A: Action + Clone>(
} else {
CursorStyle::default()
})
- .on_click(MouseButton::Left, move |_, cx| {
+ .on_click(MouseButton::Left, move |_, _, cx| {
cx.dispatch_action(action.clone())
})
- .with_tooltip::<A, _>(
+ .with_tooltip::<A>(
0,
action_name.to_string(),
Some(Box::new(tooltip_action)),
@@ -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::<Workspace>())
+ .collect::<Vec<_>>()
+ .into_iter()
+ .filter_map(|window_id| {
+ cx.app_context()
+ .root_view(window_id)?
+ .clone()
+ .downcast::<Workspace>()
+ })
.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::<ProjectItemBuilders>()
@@ -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::<TitleBar>::new(0, cx, |_, cx| {
+ MouseEventHandler::<TitleBar, _>::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::<DisconnectedOverlay>::new(0, cx, |_, cx| {
+ MouseEventHandler::<DisconnectedOverlay, _>::new(0, cx, |_, cx| {
let theme = &cx.global::<Settings>().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<Project>) -> bool,
) -> Option<ViewHandle<Workspace>> {
for window_id in cx.window_ids().collect::<Vec<_>>() {
- if let Some(workspace_handle) = cx.root_view(window_id)?.downcast_ref::<Workspace>() {
- 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::<Workspace>() {
+ 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