diff --git a/crates/component_preview/examples/component_preview.rs b/crates/component_preview/examples/component_preview.rs index 463eb976b667012f58186e385f719b27c4cd2702..8deaff1a8a61a404f482ac30f071164807267f5b 100644 --- a/crates/component_preview/examples/component_preview.rs +++ b/crates/component_preview/examples/component_preview.rs @@ -65,7 +65,7 @@ fn main() { node_runtime, session, }); - AppState::set_global(Arc::downgrade(&app_state), cx); + AppState::set_global(app_state.clone(), cx); workspace::init(app_state.clone(), cx); init(app_state.clone(), cx); diff --git a/crates/copilot_ui/src/sign_in.rs b/crates/copilot_ui/src/sign_in.rs index 033effd230d65fee7594d0241b2828a41908a432..09267020e5c3599675807f01777097d23b4d9ab0 100644 --- a/crates/copilot_ui/src/sign_in.rs +++ b/crates/copilot_ui/src/sign_in.rs @@ -481,7 +481,6 @@ impl ConfigurationView { cx: &mut Context, ) -> Self { let copilot = AppState::try_global(cx) - .and_then(|state| state.upgrade()) .and_then(|state| GlobalCopilotAuth::try_get_or_init(state, cx)); Self { @@ -578,9 +577,8 @@ impl ConfigurationView { ) .when(edit_prediction, |this| this.tab_index(0isize)) .on_click(|_, window, cx| { - if let Some(app_state) = AppState::global(cx).upgrade() - && let Some(copilot) = GlobalCopilotAuth::try_get_or_init(app_state, cx) - { + let app_state = AppState::global(cx); + if let Some(copilot) = GlobalCopilotAuth::try_get_or_init(app_state, cx) { initiate_sign_in(copilot.0, window, cx) } }) @@ -608,9 +606,8 @@ impl ConfigurationView { .color(Color::Muted), ) .on_click(|_, window, cx| { - if let Some(app_state) = AppState::global(cx).upgrade() - && let Some(copilot) = GlobalCopilotAuth::try_get_or_init(app_state, cx) - { + let app_state = AppState::global(cx); + if let Some(copilot) = GlobalCopilotAuth::try_get_or_init(app_state, cx) { reinstall_and_sign_in(copilot.0, window, cx); } }) diff --git a/crates/edit_prediction/src/edit_prediction.rs b/crates/edit_prediction/src/edit_prediction.rs index 3ae4eb72b3a60ab56d865a235c43e2f0e3adab31..34980e00cedb7da6b6273e69ec64b35b0d7e9785 100644 --- a/crates/edit_prediction/src/edit_prediction.rs +++ b/crates/edit_prediction/src/edit_prediction.rs @@ -1992,7 +1992,7 @@ impl EditPredictionStore { } fn currently_following(project: &Entity, cx: &App) -> bool { - let Some(app_state) = AppState::try_global(cx).and_then(|app_state| app_state.upgrade()) else { + let Some(app_state) = AppState::try_global(cx) else { return false; }; diff --git a/crates/edit_prediction/src/edit_prediction_tests.rs b/crates/edit_prediction/src/edit_prediction_tests.rs index 7583ba629bc2c490c5f8e8dd83218c200025fe7c..6fe61338e764a40aec9cf6f3191f1191bafe9200 100644 --- a/crates/edit_prediction/src/edit_prediction_tests.rs +++ b/crates/edit_prediction/src/edit_prediction_tests.rs @@ -204,7 +204,7 @@ async fn test_diagnostics_refresh_suppressed_while_following(cx: &mut TestAppCon let app_state = cx.update(|cx| { let app_state = AppState::test(cx); - AppState::set_global(Arc::downgrade(&app_state), cx); + AppState::set_global(app_state.clone(), cx); app_state }); @@ -214,7 +214,7 @@ async fn test_diagnostics_refresh_suppressed_while_following(cx: &mut TestAppCon .read_with(cx, |multi_workspace, _| multi_workspace.workspace().clone()) .unwrap(); cx.update(|cx| { - AppState::set_global(Arc::downgrade(workspace.read(cx).app_state()), cx); + AppState::set_global(workspace.read(cx).app_state().clone(), cx); }); let _ = app_state; diff --git a/crates/edit_prediction_ui/src/edit_prediction_button.rs b/crates/edit_prediction_ui/src/edit_prediction_button.rs index e6e65012123c0fdf3571115bded43f8840f997ee..377e53da265e4c2b6ada252b68402960f39b18dc 100644 --- a/crates/edit_prediction_ui/src/edit_prediction_button.rs +++ b/crates/edit_prediction_ui/src/edit_prediction_button.rs @@ -1418,9 +1418,9 @@ pub fn get_available_providers(cx: &mut App) -> Vec { providers.push(EditPredictionProvider::Zed); - if let Some(app_state) = workspace::AppState::global(cx).upgrade() - && copilot::GlobalCopilotAuth::try_get_or_init(app_state, cx) - .is_some_and(|copilot| copilot.0.read(cx).is_authenticated()) + let app_state = workspace::AppState::global(cx); + if copilot::GlobalCopilotAuth::try_get_or_init(app_state, cx) + .is_some_and(|copilot| copilot.0.read(cx).is_authenticated()) { providers.push(EditPredictionProvider::Copilot); }; diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 3ebfb52637107e95729d4be84145e7334411ce82..405924edb227e4c561caafeee2f8cd3e51567023 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -354,32 +354,26 @@ pub fn init(cx: &mut App) { cx.on_action(move |_: &workspace::NewFile, cx| { let app_state = workspace::AppState::global(cx); - if let Some(app_state) = app_state.upgrade() { - workspace::open_new( - Default::default(), - app_state, - cx, - |workspace, window, cx| { - Editor::new_file(workspace, &Default::default(), window, cx) - }, - ) - .detach_and_log_err(cx); - } + workspace::open_new( + Default::default(), + app_state, + cx, + |workspace, window, cx| Editor::new_file(workspace, &Default::default(), window, cx), + ) + .detach_and_log_err(cx); }) .on_action(move |_: &workspace::NewWindow, cx| { let app_state = workspace::AppState::global(cx); - if let Some(app_state) = app_state.upgrade() { - workspace::open_new( - Default::default(), - app_state, - cx, - |workspace, window, cx| { - cx.activate(true); - Editor::new_file(workspace, &Default::default(), window, cx) - }, - ) - .detach_and_log_err(cx); - } + workspace::open_new( + Default::default(), + app_state, + cx, + |workspace, window, cx| { + cx.activate(true); + Editor::new_file(workspace, &Default::default(), window, cx) + }, + ) + .detach_and_log_err(cx); }); _ = ui_input::ERASED_EDITOR_FACTORY.set(|window, cx| { Arc::new(ErasedEditorImpl( diff --git a/crates/recent_projects/src/remote_servers.rs b/crates/recent_projects/src/remote_servers.rs index 4569492d4c73b6e8087cf8363db805a645e5314e..2d285cbd36396b8cc30d456c7b37f4b5f187aeb3 100644 --- a/crates/recent_projects/src/remote_servers.rs +++ b/crates/recent_projects/src/remote_servers.rs @@ -1852,7 +1852,6 @@ impl RemoteServerProjects { cx: &mut Context, ) { let replace_window = window.window_handle().downcast::(); - let app_state = Arc::downgrade(&app_state); cx.spawn_in(window, async move |entity, cx| { let (connection, starting_dir) = diff --git a/crates/recent_projects/src/wsl_picker.rs b/crates/recent_projects/src/wsl_picker.rs index 7f2a69eb68cb93742d98f438f75f74c95bf3f7d5..d366f1090dac91ac0e778c578ceb864dac80cf86 100644 --- a/crates/recent_projects/src/wsl_picker.rs +++ b/crates/recent_projects/src/wsl_picker.rs @@ -235,9 +235,6 @@ impl WslOpenModal { cx: &mut Context, ) { let app_state = workspace::AppState::global(cx); - let Some(app_state) = app_state.upgrade() else { - return; - }; let connection_options = RemoteConnectionOptions::Wsl(WslConnectionOptions { distro_name: distro.to_string(), diff --git a/crates/settings_ui/src/pages/edit_prediction_provider_setup.rs b/crates/settings_ui/src/pages/edit_prediction_provider_setup.rs index 0357f2040b0125d39d34fd36b1aca3d299a8501b..193be67aad4760763637f116fad23066438b5b61 100644 --- a/crates/settings_ui/src/pages/edit_prediction_provider_setup.rs +++ b/crates/settings_ui/src/pages/edit_prediction_provider_setup.rs @@ -710,12 +710,9 @@ fn render_github_copilot_provider(window: &mut Window, cx: &mut App) -> Option Vec { - workspace::AppState::global(cx) - .upgrade() - .map_or(vec![], |state| { - state - .languages - .language_names() - .into_iter() - .filter(|name| name.as_ref() != "Zed Keybind Context") - .map(Into::into) - .collect() - }) + let state = workspace::AppState::global(cx); + state + .languages + .language_names() + .into_iter() + .filter(|name| name.as_ref() != "Zed Keybind Context") + .map(Into::into) + .collect() } #[allow(unused)] @@ -1535,29 +1532,26 @@ impl SettingsWindow { }) .detach(); - if let Some(app_state) = AppState::global(cx).upgrade() { - let workspaces: Vec> = app_state - .workspace_store - .read(cx) - .workspaces() - .filter_map(|weak| weak.upgrade()) - .collect(); + let app_state = AppState::global(cx); + let workspaces: Vec> = app_state + .workspace_store + .read(cx) + .workspaces() + .filter_map(|weak| weak.upgrade()) + .collect(); - for workspace in workspaces { - let project = workspace.read(cx).project().clone(); - cx.observe_release_in(&project, window, |this, _, window, cx| { - this.fetch_files(window, cx) - }) - .detach(); - cx.subscribe_in(&project, window, Self::handle_project_event) - .detach(); - cx.observe_release_in(&workspace, window, |this, _, window, cx| { - this.fetch_files(window, cx) - }) + for workspace in workspaces { + let project = workspace.read(cx).project().clone(); + cx.observe_release_in(&project, window, |this, _, window, cx| { + this.fetch_files(window, cx) + }) + .detach(); + cx.subscribe_in(&project, window, Self::handle_project_event) .detach(); - } - } else { - log::error!("App state doesn't exist when creating a new settings window"); + cx.observe_release_in(&workspace, window, |this, _, window, cx| { + this.fetch_files(window, cx) + }) + .detach(); } let this_weak = cx.weak_entity(); @@ -3362,9 +3356,7 @@ impl SettingsWindow { } SettingsUiFile::Project((worktree_id, path)) => { let settings_path = path.join(paths::local_settings_file_relative_path()); - let Some(app_state) = workspace::AppState::global(cx).upgrade() else { - return; - }; + let app_state = workspace::AppState::global(cx); let Some((workspace_window, worktree, corresponding_workspace)) = app_state .workspace_store @@ -3745,31 +3737,26 @@ fn all_projects( cx: &App, ) -> impl Iterator> { let mut seen_project_ids = std::collections::HashSet::new(); - workspace::AppState::global(cx) - .upgrade() - .map(|app_state| { - app_state - .workspace_store - .read(cx) - .workspaces() - .filter_map(|weak| weak.upgrade()) - .map(|workspace: Entity| workspace.read(cx).project().clone()) - .chain( - window - .and_then(|handle| handle.read(cx).ok()) - .into_iter() - .flat_map(|multi_workspace| { - multi_workspace - .workspaces() - .iter() - .map(|workspace| workspace.read(cx).project().clone()) - .collect::>() - }), - ) - .filter(move |project| seen_project_ids.insert(project.entity_id())) - }) - .into_iter() - .flatten() + let app_state = workspace::AppState::global(cx); + app_state + .workspace_store + .read(cx) + .workspaces() + .filter_map(|weak| weak.upgrade()) + .map(|workspace: Entity| workspace.read(cx).project().clone()) + .chain( + window + .and_then(|handle| handle.read(cx).ok()) + .into_iter() + .flat_map(|multi_workspace| { + multi_workspace + .workspaces() + .iter() + .map(|workspace| workspace.read(cx).project().clone()) + .collect::>() + }), + ) + .filter(move |project| seen_project_ids.insert(project.entity_id())) } fn open_user_settings_in_workspace( @@ -4723,7 +4710,7 @@ pub mod test { let app_state = cx.update(|cx| { let app_state = AppState::test(cx); - AppState::set_global(Arc::downgrade(&app_state), cx); + AppState::set_global(app_state.clone(), cx); app_state }); @@ -4897,7 +4884,7 @@ pub mod test { let app_state = cx.update(|cx| { let app_state = AppState::test(cx); - AppState::set_global(Arc::downgrade(&app_state), cx); + AppState::set_global(app_state.clone(), cx); app_state }); diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 2d56be01c48139168d2fda5fead3929872c1c2d9..4328fb3e307295fb5123be79999a60285e208f4b 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -124,7 +124,7 @@ use std::{ process::ExitStatus, rc::Rc, sync::{ - Arc, LazyLock, Weak, + Arc, LazyLock, atomic::{AtomicBool, AtomicUsize}, }, time::Duration, @@ -732,40 +732,32 @@ pub fn init(app_state: Arc, cx: &mut App) { cx.on_action(|_: &CloseWindow, cx| Workspace::close_global(cx)) .on_action(|_: &Reload, cx| reload(cx)) - .on_action({ - let app_state = Arc::downgrade(&app_state); - move |_: &Open, cx: &mut App| { - if let Some(app_state) = app_state.upgrade() { - prompt_and_open_paths( - app_state, - PathPromptOptions { - files: true, - directories: true, - multiple: true, - prompt: None, - }, - cx, - ); - } - } + .on_action(|_: &Open, cx: &mut App| { + let app_state = AppState::global(cx); + prompt_and_open_paths( + app_state, + PathPromptOptions { + files: true, + directories: true, + multiple: true, + prompt: None, + }, + cx, + ); }) - .on_action({ - let app_state = Arc::downgrade(&app_state); - move |_: &OpenFiles, cx: &mut App| { - let directories = cx.can_select_mixed_files_and_dirs(); - if let Some(app_state) = app_state.upgrade() { - prompt_and_open_paths( - app_state, - PathPromptOptions { - files: true, - directories, - multiple: true, - prompt: None, - }, - cx, - ); - } - } + .on_action(|_: &OpenFiles, cx: &mut App| { + let directories = cx.can_select_mixed_files_and_dirs(); + let app_state = AppState::global(cx); + prompt_and_open_paths( + app_state, + PathPromptOptions { + files: true, + directories, + multiple: true, + prompt: None, + }, + cx, + ); }); } @@ -1074,7 +1066,7 @@ pub struct AppState { pub session: Entity, } -struct GlobalAppState(Weak); +struct GlobalAppState(Arc); impl Global for GlobalAppState {} @@ -1110,14 +1102,14 @@ struct Follower { impl AppState { #[track_caller] - pub fn global(cx: &App) -> Weak { + pub fn global(cx: &App) -> Arc { cx.global::().0.clone() } - pub fn try_global(cx: &App) -> Option> { + pub fn try_global(cx: &App) -> Option> { cx.try_global::() .map(|state| state.0.clone()) } - pub fn set_global(state: Weak, cx: &mut App) { + pub fn set_global(state: Arc, cx: &mut App) { cx.set_global(GlobalAppState(state)); } @@ -10320,15 +10312,13 @@ pub fn with_active_or_new_workspace( } None => { let app_state = AppState::global(cx); - if let Some(app_state) = app_state.upgrade() { - open_new( - OpenOptions::default(), - app_state, - cx, - move |workspace, window, cx| f(workspace, window, cx), - ) - .detach_and_log_err(cx); - } + open_new( + OpenOptions::default(), + app_state, + cx, + move |workspace, window, cx| f(workspace, window, cx), + ) + .detach_and_log_err(cx); } } } diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index ebe2d2c07b303657f26c83e04c7484bbaf794bd5..f80608b8aaa4c0bd2b4513de766dc42a73876ab8 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -441,10 +441,8 @@ fn main() { } }); app.on_reopen(move |cx| { - if let Some(app_state) = AppState::try_global(cx).and_then(|app_state| app_state.upgrade()) - { + if let Some(app_state) = AppState::try_global(cx) { cx.spawn({ - let app_state = app_state; async move |cx| { if let Err(e) = restore_or_create_workspace(app_state, cx).await { fail_to_open_window_async(e, cx) @@ -626,7 +624,7 @@ fn main() { node_runtime, session: app_session, }); - AppState::set_global(Arc::downgrade(&app_state), cx); + AppState::set_global(app_state.clone(), cx); auto_update::init(client.clone(), cx); dap_adapters::init(cx); diff --git a/crates/zed/src/visual_test_runner.rs b/crates/zed/src/visual_test_runner.rs index ecee1190ce8865f54dc68f0c0052c9a7c1b5b59c..cb70a8573f831c5da20afc15fd0e55cd6ca2c3e6 100644 --- a/crates/zed/src/visual_test_runner.rs +++ b/crates/zed/src/visual_test_runner.rs @@ -170,7 +170,7 @@ fn run_visual_tests(project_path: PathBuf, update_baseline: bool) -> Result<()> // Set the global app state so settings_ui and other subsystems can find it cx.update(|cx| { - AppState::set_global(Arc::downgrade(&app_state), cx); + AppState::set_global(app_state.clone(), cx); }); // Initialize all Zed subsystems @@ -978,7 +978,7 @@ fn init_app_state(cx: &mut App) -> Arc { build_window_options: |_, _| Default::default(), session, }); - AppState::set_global(Arc::downgrade(&app_state), cx); + AppState::set_global(app_state.clone(), cx); app_state } diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index de90cc0cacf8c0c94acbd799475129b1dd49e706..a560a077220500259d72101f7890bc8edd2cf552 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -1072,104 +1072,99 @@ fn register_actions( }, ) .register_action({ - let app_state = Arc::downgrade(&app_state); + let app_state = app_state.clone(); move |_, _: &NewWindow, _, cx| { - if let Some(app_state) = app_state.upgrade() { - open_new( - Default::default(), - app_state, - cx, - |workspace, window, cx| { - cx.activate(true); - // Create buffer synchronously to avoid flicker - let project = workspace.project().clone(); - let buffer = project.update(cx, |project, cx| { - project.create_local_buffer("", None, true, cx) - }); - let editor = cx.new(|cx| { - Editor::for_buffer(buffer, Some(project), window, cx) - }); - workspace.add_item_to_active_pane( - Box::new(editor), - None, - true, - window, - cx, - ); - }, - ) - .detach(); - } + open_new( + Default::default(), + app_state.clone(), + cx, + |workspace, window, cx| { + cx.activate(true); + // Create buffer synchronously to avoid flicker + let project = workspace.project().clone(); + let buffer = project.update(cx, |project, cx| { + project.create_local_buffer("", None, true, cx) + }); + let editor = cx.new(|cx| { + Editor::for_buffer(buffer, Some(project), window, cx) + }); + workspace.add_item_to_active_pane( + Box::new(editor), + None, + true, + window, + cx, + ); + }, + ) + .detach(); } }) .register_action({ - let app_state = Arc::downgrade(&app_state); + let app_state = app_state.clone(); move |_workspace, _: &CloseProject, window, cx| { let Some(window_handle) = window.window_handle().downcast::() else { return; }; - if let Some(app_state) = app_state.upgrade() { - cx.spawn_in(window, async move |this, cx| { - let should_continue = this - .update_in(cx, |workspace, window, cx| { - workspace.prepare_to_close( - CloseIntent::ReplaceWindow, - window, - cx, - ) - })? - .await?; - if should_continue { - let task = cx.update(|_window, cx| { - open_new( - workspace::OpenOptions { - replace_window: Some(window_handle), - ..Default::default() - }, - app_state, - cx, - |workspace, window, cx| { - cx.activate(true); - let project = workspace.project().clone(); - let buffer = project.update(cx, |project, cx| { - project.create_local_buffer("", None, true, cx) - }); - let editor = cx.new(|cx| { - Editor::for_buffer(buffer, Some(project), window, cx) - }); - workspace.add_item_to_active_pane( - Box::new(editor), - None, - true, - window, - cx, - ); - }, - ) - })?; - task.await - } else { - Ok(()) - } - }) - .detach_and_log_err(cx); - } + let app_state = app_state.clone(); + cx.spawn_in(window, async move |this, cx| { + let should_continue = this + .update_in(cx, |workspace, window, cx| { + workspace.prepare_to_close( + CloseIntent::ReplaceWindow, + window, + cx, + ) + })? + .await?; + if should_continue { + let task = cx.update(|_window, cx| { + open_new( + workspace::OpenOptions { + replace_window: Some(window_handle), + ..Default::default() + }, + app_state, + cx, + |workspace, window, cx| { + cx.activate(true); + let project = workspace.project().clone(); + let buffer = project.update(cx, |project, cx| { + project.create_local_buffer("", None, true, cx) + }); + let editor = cx.new(|cx| { + Editor::for_buffer(buffer, Some(project), window, cx) + }); + workspace.add_item_to_active_pane( + Box::new(editor), + None, + true, + window, + cx, + ); + }, + ) + })?; + task.await + } else { + Ok(()) + } + }) + .detach_and_log_err(cx); } }) .register_action({ - let app_state = Arc::downgrade(&app_state); + let app_state = app_state.clone(); move |_, _: &NewFile, _, cx| { - if let Some(app_state) = app_state.upgrade() { - open_new( - Default::default(), - app_state, - cx, - |workspace, window, cx| { - Editor::new_file(workspace, &Default::default(), window, cx) - }, - ) - .detach_and_log_err(cx); - } + open_new( + Default::default(), + app_state.clone(), + cx, + |workspace, window, cx| { + Editor::new_file(workspace, &Default::default(), window, cx) + }, + ) + .detach_and_log_err(cx); } });