From b2d9ccc0a2f97a8ad4cde4fa15aa9bd500bfc63e Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Aug 2023 11:38:07 -0600 Subject: [PATCH] Move more window methods off AsyncAppContext --- crates/collab_ui/src/contact_list.rs | 4 +- crates/command_palette/src/command_palette.rs | 13 ++-- crates/context_menu/src/context_menu.rs | 14 +++- crates/gpui/src/app.rs | 71 +++++++++---------- crates/search/src/project_search.rs | 12 ++-- crates/workspace/src/dock.rs | 7 +- crates/workspace/src/workspace.rs | 12 ++-- crates/zed/src/zed.rs | 4 +- 8 files changed, 73 insertions(+), 64 deletions(-) diff --git a/crates/collab_ui/src/contact_list.rs b/crates/collab_ui/src/contact_list.rs index a2b281856d..4978452384 100644 --- a/crates/collab_ui/src/contact_list.rs +++ b/crates/collab_ui/src/contact_list.rs @@ -312,11 +312,11 @@ impl ContactList { .update(&mut cx, |store, cx| store.remove_contact(user_id, cx)) .await { - cx.prompt( - window, + window.prompt( PromptLevel::Info, &format!("Failed to remove contact: {}", e), &["Ok"], + &mut cx, ); } } diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index 0d398fcce9..101d4dc545 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/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, AnyWindowHandle, AppContext, Element, - MouseState, ViewContext, + actions, anyhow::anyhow, elements::*, keymap_matcher::Keystroke, Action, AnyWindowHandle, + AppContext, Element, MouseState, ViewContext, }; use picker::{Picker, PickerDelegate, PickerEvent}; use std::cmp; @@ -83,9 +83,10 @@ impl PickerDelegate for CommandPaletteDelegate { let view_id = self.focused_view_id; let window = cx.window(); cx.spawn(move |picker, mut cx| async move { - let actions = cx - .available_actions(window, view_id) + let actions = window + .available_actions(view_id, &cx) .into_iter() + .flatten() .filter_map(|(name, action, bindings)| { let filtered = cx.read(|cx| { if cx.has_global::() { @@ -168,7 +169,9 @@ impl PickerDelegate for CommandPaletteDelegate { let action = self.actions.remove(action_ix).action; cx.app_context() .spawn(move |mut cx| async move { - cx.dispatch_action(window, focused_view_id, action.as_ref()) + window + .dispatch_action(focused_view_id, action.as_ref(), &mut cx) + .ok_or_else(|| anyhow!("window was closed")) }) .detach_and_log_err(cx); } diff --git a/crates/context_menu/src/context_menu.rs b/crates/context_menu/src/context_menu.rs index 75cfd872b2..a5534b6262 100644 --- a/crates/context_menu/src/context_menu.rs +++ b/crates/context_menu/src/context_menu.rs @@ -1,5 +1,5 @@ use gpui::{ - anyhow, + anyhow::{self, anyhow}, elements::*, geometry::vector::Vector2F, keymap_matcher::KeymapContext, @@ -223,7 +223,9 @@ impl ContextMenu { let action = action.boxed_clone(); cx.app_context() .spawn(|mut cx| async move { - cx.dispatch_action(window, view_id, action.as_ref()) + window + .dispatch_action(view_id, action.as_ref(), &mut cx) + .ok_or_else(|| anyhow!("window was closed")) }) .detach_and_log_err(cx); } @@ -486,7 +488,13 @@ impl ContextMenu { let action = action.boxed_clone(); cx.app_context() .spawn(|mut cx| async move { - cx.dispatch_action(window, view_id, action.as_ref()) + window + .dispatch_action( + view_id, + action.as_ref(), + &mut cx, + ) + .ok_or_else(|| anyhow!("window was closed")) }) .detach_and_log_err(cx); } diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 5eb4ed744c..e6e11ca321 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -344,29 +344,6 @@ impl AsyncAppContext { self.0.borrow().windows().collect() } - pub fn dispatch_action( - &mut self, - window: AnyWindowHandle, - view_id: usize, - action: &dyn Action, - ) -> Result<()> { - self.0 - .borrow_mut() - .update_window(window, |cx| { - cx.dispatch_action(Some(view_id), action); - }) - .ok_or_else(|| anyhow!("window not found")) - } - - pub fn available_actions( - &self, - window: AnyWindowHandle, - view_id: usize, - ) -> Vec<(&'static str, Box, SmallVec<[Binding; 1]>)> { - self.read_window(window, |cx| cx.available_actions(view_id)) - .unwrap_or_default() - } - pub fn add_model(&mut self, build_model: F) -> ModelHandle where T: Entity, @@ -387,21 +364,6 @@ impl AsyncAppContext { self.update(|cx| cx.add_window(window_options, build_root_view)) } - pub fn activate_window(&mut self, window: AnyWindowHandle) { - self.update_window(window, |cx| cx.activate_window()); - } - - // TODO: Can we eliminate this method and move it to WindowContext then call it with update_window?s - pub fn prompt( - &mut self, - window: AnyWindowHandle, - level: PromptLevel, - msg: &str, - answers: &[&str], - ) -> Option> { - self.update_window(window, |cx| cx.prompt(level, msg, answers)) - } - pub fn platform(&self) -> Arc { self.0.borrow().platform().clone() } @@ -4060,6 +4022,39 @@ impl AnyWindowHandle { }) } + pub fn activate(&mut self, cx: &mut C) -> C::Result<()> { + self.update(cx, |cx| cx.activate_window()) + } + + pub fn prompt( + &self, + level: PromptLevel, + msg: &str, + answers: &[&str], + cx: &mut C, + ) -> C::Result> { + self.update(cx, |cx| cx.prompt(level, msg, answers)) + } + + pub fn dispatch_action( + &self, + view_id: usize, + action: &dyn Action, + cx: &mut C, + ) -> C::Result<()> { + self.update(cx, |cx| { + cx.dispatch_action(Some(view_id), action); + }) + } + + pub fn available_actions( + &self, + view_id: usize, + cx: &C, + ) -> C::Result, SmallVec<[Binding; 1]>)>> { + self.read_with(cx, |cx| cx.available_actions(view_id)) + } + #[cfg(any(test, feature = "test-support"))] pub fn simulate_activation(&self, cx: &mut TestAppContext) { self.update(cx, |cx| { diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 202d494560..018ab9cb11 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -1599,7 +1599,7 @@ pub mod tests { let search_view_id = search_view.id(); cx.spawn(|mut cx| async move { - cx.dispatch_action(window.into(), search_view_id, &ToggleFocus) + window.dispatch_action(search_view_id, &ToggleFocus, &mut cx); }) .detach(); deterministic.run_until_parked(); @@ -1650,9 +1650,9 @@ pub mod tests { "Search view should be focused after mismatching query had been used in search", ); }); - cx.spawn(|mut cx| async move { - cx.dispatch_action(window.into(), search_view_id, &ToggleFocus) - }) + cx.spawn( + |mut cx| async move { window.dispatch_action(search_view_id, &ToggleFocus, &mut cx) }, + ) .detach(); deterministic.run_until_parked(); search_view.update(cx, |search_view, cx| { @@ -1683,7 +1683,7 @@ pub mod tests { ); }); cx.spawn(|mut cx| async move { - cx.dispatch_action(window.into(), search_view_id, &ToggleFocus) + window.dispatch_action(search_view_id, &ToggleFocus, &mut cx); }) .detach(); deterministic.run_until_parked(); @@ -1713,7 +1713,7 @@ pub mod tests { }); cx.spawn(|mut cx| async move { - cx.dispatch_action(window.into(), search_view_id, &ToggleFocus) + window.dispatch_action(search_view_id, &ToggleFocus, &mut cx); }) .detach(); deterministic.run_until_parked(); diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index 5bb0fd93f8..e33c0a5391 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -534,8 +534,11 @@ impl View for PanelButtons { let view_id = this.workspace.id(); let tooltip_action = tooltip_action.boxed_clone(); cx.spawn(|_, mut cx| async move { - cx.dispatch_action(window, view_id, &*tooltip_action) - .ok(); + window.dispatch_action( + view_id, + &*tooltip_action, + &mut cx, + ); }) .detach(); } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index f2a7a442f4..2f884b0ceb 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1280,11 +1280,11 @@ impl Workspace { && workspace_count == 1 && active_call.read_with(&cx, |call, _| call.room().is_some()) { - let answer = cx.prompt( - window, + let answer = window.prompt( PromptLevel::Warning, "Do you want to leave the current call?", &["Close window and hang up", "Cancel"], + &mut cx, ); if let Some(mut answer) = answer { @@ -4000,7 +4000,7 @@ pub fn join_remote_project( workspace.downgrade() }; - cx.activate_window(workspace.window()); + workspace.window().activate(&mut cx); cx.platform().activate(true); workspace.update(&mut cx, |workspace, cx| { @@ -4049,12 +4049,12 @@ pub fn restart(_: &Restart, cx: &mut AppContext) { // prompt in the active window before switching to a different window. workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false)); - if let (true, Some(window)) = (should_confirm, workspace_windows.first().copied()) { - let answer = cx.prompt( - window.into(), + if let (true, Some(window)) = (should_confirm, workspace_windows.first()) { + let answer = window.prompt( PromptLevel::Info, "Are you sure you want to restart?", &["Restart", "Cancel"], + &mut cx, ); if let Some(mut answer) = answer { diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 1cde8d5b9a..8ad8080375 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -416,11 +416,11 @@ fn quit(_: &Quit, cx: &mut gpui::AppContext) { workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false)); if let (true, Some(window)) = (should_confirm, workspace_windows.first().copied()) { - let answer = cx.prompt( - window.into(), + let answer = window.prompt( PromptLevel::Info, "Are you sure you want to quit?", &["Quit", "Cancel"], + &mut cx, ); if let Some(mut answer) = answer {