Detailed changes
@@ -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);
@@ -481,7 +481,6 @@ impl ConfigurationView {
cx: &mut Context<Self>,
) -> 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);
}
})
@@ -1992,7 +1992,7 @@ impl EditPredictionStore {
}
fn currently_following(project: &Entity<Project>, 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;
};
@@ -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;
@@ -1418,9 +1418,9 @@ pub fn get_available_providers(cx: &mut App) -> Vec<EditPredictionProvider> {
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);
};
@@ -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(
@@ -1852,7 +1852,6 @@ impl RemoteServerProjects {
cx: &mut Context<Self>,
) {
let replace_window = window.window_handle().downcast::<MultiWorkspace>();
-
let app_state = Arc::downgrade(&app_state);
cx.spawn_in(window, async move |entity, cx| {
let (connection, starting_dir) =
@@ -235,9 +235,6 @@ impl WslOpenModal {
cx: &mut Context<Self>,
) {
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(),
@@ -710,12 +710,9 @@ fn render_github_copilot_provider(window: &mut Window, cx: &mut App) -> Option<i
let configuration_view = window.use_state(cx, |_, cx| {
copilot_ui::ConfigurationView::new(
move |cx| {
- if let Some(app_state) = AppState::global(cx).upgrade() {
- copilot::GlobalCopilotAuth::try_get_or_init(app_state, cx)
- .is_some_and(|copilot| copilot.0.read(cx).is_authenticated())
- } else {
- false
- }
+ let app_state = AppState::global(cx);
+ copilot::GlobalCopilotAuth::try_get_or_init(app_state, cx)
+ .is_some_and(|copilot| copilot.0.read(cx).is_authenticated())
},
copilot_ui::ConfigurationMode::EditPrediction,
cx,
@@ -1394,17 +1394,14 @@ impl PartialEq for ActionLink {
}
fn all_language_names(cx: &App) -> Vec<SharedString> {
- 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<Entity<Workspace>> = app_state
- .workspace_store
- .read(cx)
- .workspaces()
- .filter_map(|weak| weak.upgrade())
- .collect();
+ let app_state = AppState::global(cx);
+ let workspaces: Vec<Entity<Workspace>> = 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<Item = Entity<Project>> {
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>| 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::<Vec<_>>()
- }),
- )
- .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>| 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::<Vec<_>>()
+ }),
+ )
+ .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
});
@@ -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<AppState>, 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<AppSession>,
}
-struct GlobalAppState(Weak<AppState>);
+struct GlobalAppState(Arc<AppState>);
impl Global for GlobalAppState {}
@@ -1110,14 +1102,14 @@ struct Follower {
impl AppState {
#[track_caller]
- pub fn global(cx: &App) -> Weak<Self> {
+ pub fn global(cx: &App) -> Arc<Self> {
cx.global::<GlobalAppState>().0.clone()
}
- pub fn try_global(cx: &App) -> Option<Weak<Self>> {
+ pub fn try_global(cx: &App) -> Option<Arc<Self>> {
cx.try_global::<GlobalAppState>()
.map(|state| state.0.clone())
}
- pub fn set_global(state: Weak<AppState>, cx: &mut App) {
+ pub fn set_global(state: Arc<AppState>, 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);
}
}
}
@@ -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);
@@ -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<AppState> {
build_window_options: |_, _| Default::default(),
session,
});
- AppState::set_global(Arc::downgrade(&app_state), cx);
+ AppState::set_global(app_state.clone(), cx);
app_state
}
@@ -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::<MultiWorkspace>() 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);
}
});