Replace ViewContext::spawn with ViewContext::spawn_weak

This commit is contained in:
Antonio Scandurra 2023-04-26 10:23:27 +02:00
parent 09f7e41907
commit 94c2eaad23
20 changed files with 83 additions and 73 deletions

View File

@ -63,7 +63,7 @@ impl ActivityIndicator {
let auto_updater = AutoUpdater::get(cx); let auto_updater = AutoUpdater::get(cx);
let this = cx.add_view(|cx: &mut ViewContext<Self>| { let this = cx.add_view(|cx: &mut ViewContext<Self>| {
let mut status_events = languages.language_server_binary_statuses(); let mut status_events = languages.language_server_binary_statuses();
cx.spawn_weak(|this, mut cx| async move { cx.spawn(|this, mut cx| async move {
while let Some((language, event)) = status_events.next().await { while let Some((language, event)) = status_events.next().await {
if let Some(this) = this.upgrade(&cx) { if let Some(this) = this.upgrade(&cx) {
this.update(&mut cx, |this, cx| { this.update(&mut cx, |this, cx| {

View File

@ -79,7 +79,7 @@ impl IncomingCallNotification {
let join = active_call.update(cx, |active_call, cx| active_call.accept_incoming(cx)); let join = active_call.update(cx, |active_call, cx| active_call.accept_incoming(cx));
let caller_user_id = self.call.calling_user.id; let caller_user_id = self.call.calling_user.id;
let initial_project_id = self.call.initial_project.as_ref().map(|project| project.id); let initial_project_id = self.call.initial_project.as_ref().map(|project| project.id);
cx.spawn_weak(|_, mut cx| async move { cx.spawn(|_, mut cx| async move {
join.await?; join.await?;
if let Some(project_id) = initial_project_id { if let Some(project_id) = initial_project_id {
cx.update(|cx| { cx.update(|cx| {

View File

@ -1,4 +1,5 @@
use gpui::{ use gpui::{
anyhow,
elements::*, elements::*,
geometry::vector::Vector2F, geometry::vector::Vector2F,
impl_internal_actions, impl_internal_actions,
@ -209,7 +210,8 @@ impl ContextMenu {
cx.notify(); cx.notify();
cx.spawn(|this, mut cx| async move { cx.spawn(|this, mut cx| async move {
cx.background().timer(Duration::from_millis(50)).await; cx.background().timer(Duration::from_millis(50)).await;
this.update(&mut cx, |this, cx| this.cancel(&Default::default(), cx)) this.update(&mut cx, |this, cx| this.cancel(&Default::default(), cx))?;
anyhow::Ok(())
}) })
.detach_and_log_err(cx); .detach_and_log_err(cx);
} }

View File

@ -2477,7 +2477,7 @@ impl Editor {
}); });
let id = post_inc(&mut self.next_completion_id); let id = post_inc(&mut self.next_completion_id);
let task = cx.spawn_weak(|this, mut cx| { let task = cx.spawn(|this, mut cx| {
async move { async move {
let menu = if let Some(completions) = completions.await.log_err() { let menu = if let Some(completions) = completions.await.log_err() {
let mut menu = CompletionsMenu { let mut menu = CompletionsMenu {
@ -2669,7 +2669,7 @@ impl Editor {
let deployed_from_indicator = action.deployed_from_indicator; let deployed_from_indicator = action.deployed_from_indicator;
let mut task = self.code_actions_task.take(); let mut task = self.code_actions_task.take();
cx.spawn_weak(|this, mut cx| async move { cx.spawn(|this, mut cx| async move {
while let Some(prev_task) = task { while let Some(prev_task) = task {
prev_task.await; prev_task.await;
task = this task = this
@ -2731,7 +2731,7 @@ impl Editor {
async fn open_project_transaction( async fn open_project_transaction(
this: ViewHandle<Editor>, this: ViewHandle<Editor>,
workspace: ViewHandle<Workspace>, workspace: WeakViewHandle<Workspace>,
transaction: ProjectTransaction, transaction: ProjectTransaction,
title: String, title: String,
mut cx: AsyncAppContext, mut cx: AsyncAppContext,
@ -2826,7 +2826,7 @@ impl Editor {
let actions = project.update(cx, |project, cx| { let actions = project.update(cx, |project, cx| {
project.code_actions(&start_buffer, start..end, cx) project.code_actions(&start_buffer, start..end, cx)
}); });
self.code_actions_task = Some(cx.spawn_weak(|this, mut cx| async move { self.code_actions_task = Some(cx.spawn(|this, mut cx| async move {
let actions = actions.await; let actions = actions.await;
if let Some(this) = this.upgrade(&cx) { if let Some(this) = this.upgrade(&cx) {
this.update(&mut cx, |this, cx| { this.update(&mut cx, |this, cx| {
@ -2865,7 +2865,7 @@ impl Editor {
project.document_highlights(&cursor_buffer, cursor_buffer_position, cx) project.document_highlights(&cursor_buffer, cursor_buffer_position, cx)
}); });
self.document_highlights_task = Some(cx.spawn_weak(|this, mut cx| async move { self.document_highlights_task = Some(cx.spawn(|this, mut cx| async move {
let highlights = highlights.log_err().await; let highlights = highlights.log_err().await;
if let Some((this, highlights)) = this.upgrade(&cx).zip(highlights) { if let Some((this, highlights)) = this.upgrade(&cx).zip(highlights) {
this.update(&mut cx, |this, cx| { this.update(&mut cx, |this, cx| {
@ -2961,7 +2961,7 @@ impl Editor {
let (buffer, buffer_position) = let (buffer, buffer_position) =
self.buffer.read(cx).text_anchor_for_position(cursor, cx)?; self.buffer.read(cx).text_anchor_for_position(cursor, cx)?;
self.copilot_state.pending_refresh = cx.spawn_weak(|this, mut cx| async move { self.copilot_state.pending_refresh = cx.spawn(|this, mut cx| async move {
if debounce { if debounce {
cx.background().timer(COPILOT_DEBOUNCE_TIMEOUT).await; cx.background().timer(COPILOT_DEBOUNCE_TIMEOUT).await;
} }
@ -3014,7 +3014,7 @@ impl Editor {
let cursor = self.selections.newest_anchor().head(); let cursor = self.selections.newest_anchor().head();
let (buffer, buffer_position) = let (buffer, buffer_position) =
self.buffer.read(cx).text_anchor_for_position(cursor, cx)?; self.buffer.read(cx).text_anchor_for_position(cursor, cx)?;
self.copilot_state.pending_cycling_refresh = cx.spawn_weak(|this, mut cx| async move { self.copilot_state.pending_cycling_refresh = cx.spawn(|this, mut cx| async move {
let completions = copilot let completions = copilot
.update(&mut cx, |copilot, cx| { .update(&mut cx, |copilot, cx| {
copilot.completions_cycling(&buffer, buffer_position, cx) copilot.completions_cycling(&buffer, buffer_position, cx)
@ -6770,7 +6770,7 @@ impl Editor {
let editor = workspace.open_path(action.path.clone(), None, true, cx); let editor = workspace.open_path(action.path.clone(), None, true, cx);
let position = action.position; let position = action.position;
let anchor = action.anchor; let anchor = action.anchor;
cx.spawn_weak(|_, mut cx| async move { cx.spawn(|_, mut cx| async move {
let editor = editor let editor = editor
.await? .await?
.downcast::<Editor>() .downcast::<Editor>()

View File

@ -149,7 +149,7 @@ fn show_hover(
} }
} }
let task = cx.spawn_weak(|this, mut cx| { let task = cx.spawn(|this, mut cx| {
async move { async move {
// If we need to delay, delay a set amount initially before making the lsp request // If we need to delay, delay a set amount initially before making the lsp request
let delay = if !ignore_timeout { let delay = if !ignore_timeout {

View File

@ -3,7 +3,7 @@ use crate::{
movement::surrounding_word, persistence::DB, scroll::ScrollAnchor, Anchor, Autoscroll, Editor, movement::surrounding_word, persistence::DB, scroll::ScrollAnchor, Anchor, Autoscroll, Editor,
Event, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, NavigationData, ToPoint as _, Event, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, NavigationData, ToPoint as _,
}; };
use anyhow::{Context, Result}; use anyhow::{anyhow, Context, Result};
use collections::HashSet; use collections::HashSet;
use futures::future::try_join_all; use futures::future::try_join_all;
use gpui::{ use gpui::{
@ -286,6 +286,9 @@ impl FollowableItem for Editor {
let update_view::Variant::Editor(message) = message; let update_view::Variant::Editor(message) = message;
let project = project.clone(); let project = project.clone();
cx.spawn(|this, mut cx| async move { cx.spawn(|this, mut cx| async move {
let this = this
.upgrade(&cx)
.ok_or_else(|| anyhow!("editor was dropped"))?;
update_editor_from_message(this, project, message, &mut cx).await update_editor_from_message(this, project, message, &mut cx).await
}) })
} }
@ -863,7 +866,9 @@ impl Item for Editor {
let buffer = project_item let buffer = project_item
.downcast::<Buffer>() .downcast::<Buffer>()
.context("Project item at stored path was not a buffer")?; .context("Project item at stored path was not a buffer")?;
let pane = pane
.upgrade(&cx)
.ok_or_else(|| anyhow!("pane was dropped"))?;
Ok(cx.update(|cx| { Ok(cx.update(|cx| {
cx.add_view(&pane, |cx| { cx.add_view(&pane, |cx| {
let mut editor = Editor::for_buffer(buffer, Some(project), cx); let mut editor = Editor::for_buffer(buffer, Some(project), cx);

View File

@ -171,7 +171,7 @@ pub fn show_link_definition(
} }
} }
let task = cx.spawn_weak(|this, mut cx| { let task = cx.spawn(|this, mut cx| {
async move { async move {
// query the LSP for definition info // query the LSP for definition info
let definition_request = cx.update(|cx| { let definition_request = cx.update(|cx| {

View File

@ -245,7 +245,7 @@ impl ScrollManager {
} }
if cx.default_global::<ScrollbarAutoHide>().0 { if cx.default_global::<ScrollbarAutoHide>().0 {
self.hide_scrollbar_task = Some(cx.spawn_weak(|editor, mut cx| async move { self.hide_scrollbar_task = Some(cx.spawn(|editor, mut cx| async move {
cx.background().timer(SCROLLBAR_SHOW_INTERVAL).await; cx.background().timer(SCROLLBAR_SHOW_INTERVAL).await;
if let Some(editor) = editor.upgrade(&cx) { if let Some(editor) = editor.upgrade(&cx) {
editor editor

View File

@ -3262,26 +3262,16 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> {
pub fn spawn_labeled<F, Fut, S>(&mut self, task_label: &'static str, f: F) -> Task<S> pub fn spawn_labeled<F, Fut, S>(&mut self, task_label: &'static str, f: F) -> Task<S>
where where
F: FnOnce(ViewHandle<V>, AsyncAppContext) -> Fut, F: FnOnce(WeakViewHandle<V>, AsyncAppContext) -> Fut,
Fut: 'static + Future<Output = S>, Fut: 'static + Future<Output = S>,
S: 'static, S: 'static,
{ {
let handle = self.handle(); let handle = self.weak_handle();
self.window_context self.window_context
.spawn_labeled(task_label, |cx| f(handle, cx)) .spawn_labeled(task_label, |cx| f(handle, cx))
} }
pub fn spawn<F, Fut, S>(&mut self, f: F) -> Task<S> pub fn spawn<F, Fut, S>(&mut self, f: F) -> Task<S>
where
F: FnOnce(ViewHandle<V>, AsyncAppContext) -> Fut,
Fut: 'static + Future<Output = S>,
S: 'static,
{
let handle = self.handle();
self.window_context.spawn(|cx| f(handle, cx))
}
pub fn spawn_weak<F, Fut, S>(&mut self, f: F) -> Task<S>
where where
F: FnOnce(WeakViewHandle<V>, AsyncAppContext) -> Fut, F: FnOnce(WeakViewHandle<V>, AsyncAppContext) -> Fut,
Fut: 'static + Future<Output = S>, Fut: 'static + Future<Output = S>,
@ -4094,15 +4084,31 @@ impl<V: View> WeakViewHandle<V> {
cx.read_with(|cx| cx.upgrade_view_handle(self)) cx.read_with(|cx| cx.upgrade_view_handle(self))
} }
pub fn read_with<T>(
&self,
cx: &impl BorrowAppContext,
read: impl FnOnce(&V, &ViewContext<V>) -> T,
) -> Result<T> {
cx.read_with(|cx| {
let handle = cx
.upgrade_view_handle(self)
.ok_or_else(|| anyhow!("view {} was dropped", V::ui_name()))?;
cx.read_window(self.window_id, |cx| handle.read_with(cx, read))
.ok_or_else(|| anyhow!("window was removed"))
})
}
pub fn update<T>( pub fn update<T>(
&self, &self,
cx: &mut impl BorrowAppContext, cx: &mut impl BorrowAppContext,
update: impl FnOnce(&mut V, &mut ViewContext<V>) -> T, update: impl FnOnce(&mut V, &mut ViewContext<V>) -> T,
) -> Option<T> { ) -> Result<T> {
cx.update(|cx| { cx.update(|cx| {
let handle = cx.upgrade_view_handle(self)?; let handle = cx
.upgrade_view_handle(self)
.ok_or_else(|| anyhow!("view {} was dropped", V::ui_name()))?;
cx.update_window(self.window_id, |cx| handle.update(cx, update)) cx.update_window(self.window_id, |cx| handle.update(cx, update))
.ok_or_else(|| anyhow!("window was removed"))
}) })
} }
} }

View File

@ -99,7 +99,7 @@ impl<V: View> Tooltip<V> {
let mut debounce = state.debounce.borrow_mut(); let mut debounce = state.debounce.borrow_mut();
if debounce.is_none() { if debounce.is_none() {
*debounce = Some(cx.spawn_weak({ *debounce = Some(cx.spawn({
let state = state.clone(); let state = state.clone();
|view, mut cx| async move { |view, mut cx| async move {
cx.background().timer(DEBOUNCE_TIMEOUT).await; cx.background().timer(DEBOUNCE_TIMEOUT).await;

View File

@ -102,7 +102,7 @@ impl PickerDelegate for LanguageSelectorDelegate {
let language = self.language_registry.language_for_name(language_name); let language = self.language_registry.language_for_name(language_name);
let project = self.project.downgrade(); let project = self.project.downgrade();
let buffer = self.buffer.downgrade(); let buffer = self.buffer.downgrade();
cx.spawn_weak(|_, mut cx| async move { cx.spawn(|_, mut cx| async move {
let language = language.await?; let language = language.await?;
let project = project let project = project
.upgrade(&cx) .upgrade(&cx)
@ -138,7 +138,7 @@ impl PickerDelegate for LanguageSelectorDelegate {
) -> gpui::Task<()> { ) -> gpui::Task<()> {
let background = cx.background().clone(); let background = cx.background().clone();
let candidates = self.candidates.clone(); let candidates = self.candidates.clone();
cx.spawn_weak(|this, mut cx| async move { cx.spawn(|this, mut cx| async move {
let matches = if query.is_empty() { let matches = if query.is_empty() {
candidates candidates
.into_iter() .into_iter()

View File

@ -238,7 +238,7 @@ impl<D: PickerDelegate> Picker<D> {
pub fn update_matches(&mut self, query: String, cx: &mut ViewContext<Self>) { pub fn update_matches(&mut self, query: String, cx: &mut ViewContext<Self>) {
let update = self.delegate.update_matches(query, cx); let update = self.delegate.update_matches(query, cx);
self.matches_updated(cx); self.matches_updated(cx);
self.pending_update_matches = cx.spawn_weak(|this, mut cx| async move { self.pending_update_matches = cx.spawn(|this, mut cx| async move {
update.await; update.await;
this.upgrade(&cx)? this.upgrade(&cx)?
.update(&mut cx, |this, cx| this.matches_updated(cx)) .update(&mut cx, |this, cx| this.matches_updated(cx))

View File

@ -117,7 +117,7 @@ impl PickerDelegate for ProjectSymbolsDelegate {
}); });
let symbol = symbol.clone(); let symbol = symbol.clone();
let workspace = self.workspace.clone(); let workspace = self.workspace.clone();
cx.spawn_weak(|_, mut cx| async move { cx.spawn(|_, mut cx| async move {
let buffer = buffer.await?; let buffer = buffer.await?;
let workspace = workspace let workspace = workspace
.upgrade(&cx) .upgrade(&cx)
@ -161,7 +161,7 @@ impl PickerDelegate for ProjectSymbolsDelegate {
let symbols = self let symbols = self
.project .project
.update(cx, |project, cx| project.symbols(&query, cx)); .update(cx, |project, cx| project.symbols(&query, cx));
cx.spawn_weak(|this, mut cx| async move { cx.spawn(|this, mut cx| async move {
let symbols = symbols.await.log_err(); let symbols = symbols.await.log_err();
if let Some(this) = this.upgrade(&cx) { if let Some(this) = this.upgrade(&cx) {
if let Some(symbols) = symbols { if let Some(symbols) = symbols {

View File

@ -582,7 +582,7 @@ impl BufferSearchBar {
let matches = active_searchable_item.find_matches(query, cx); let matches = active_searchable_item.find_matches(query, cx);
let active_searchable_item = active_searchable_item.downgrade(); let active_searchable_item = active_searchable_item.downgrade();
self.pending_search = Some(cx.spawn_weak(|this, mut cx| async move { self.pending_search = Some(cx.spawn(|this, mut cx| async move {
let matches = matches.await; let matches = matches.await;
if let Some(this) = this.upgrade(&cx) { if let Some(this) = this.upgrade(&cx) {
this.update(&mut cx, |this, cx| { this.update(&mut cx, |this, cx| {

View File

@ -2,13 +2,7 @@ mod persistence;
pub mod terminal_button; pub mod terminal_button;
pub mod terminal_element; pub mod terminal_element;
use std::{ use anyhow::anyhow;
borrow::Cow,
ops::RangeInclusive,
path::{Path, PathBuf},
time::Duration,
};
use context_menu::{ContextMenu, ContextMenuItem}; use context_menu::{ContextMenu, ContextMenuItem};
use dirs::home_dir; use dirs::home_dir;
use gpui::{ use gpui::{
@ -26,6 +20,12 @@ use serde::Deserialize;
use settings::{Settings, TerminalBlink, WorkingDirectory}; use settings::{Settings, TerminalBlink, WorkingDirectory};
use smallvec::{smallvec, SmallVec}; use smallvec::{smallvec, SmallVec};
use smol::Timer; use smol::Timer;
use std::{
borrow::Cow,
ops::RangeInclusive,
path::{Path, PathBuf},
time::Duration,
};
use terminal::{ use terminal::{
alacritty_terminal::{ alacritty_terminal::{
index::Point, index::Point,
@ -275,14 +275,11 @@ impl TerminalView {
cx.notify(); cx.notify();
let epoch = self.next_blink_epoch(); let epoch = self.next_blink_epoch();
cx.spawn(|this, mut cx| { cx.spawn(|this, mut cx| async move {
let this = this.downgrade(); Timer::after(CURSOR_BLINK_INTERVAL).await;
async move { if let Some(this) = this.upgrade(&cx) {
Timer::after(CURSOR_BLINK_INTERVAL).await; this.update(&mut cx, |this, cx| this.blink_cursors(epoch, cx))
if let Some(this) = this.upgrade(&cx) { .log_err();
this.update(&mut cx, |this, cx| this.blink_cursors(epoch, cx))
.log_err();
}
} }
}) })
.detach(); .detach();
@ -294,14 +291,11 @@ impl TerminalView {
cx.notify(); cx.notify();
let epoch = self.next_blink_epoch(); let epoch = self.next_blink_epoch();
cx.spawn(|this, mut cx| { cx.spawn(|this, mut cx| async move {
let this = this.downgrade(); Timer::after(CURSOR_BLINK_INTERVAL).await;
async move { if let Some(this) = this.upgrade(&cx) {
Timer::after(CURSOR_BLINK_INTERVAL).await; this.update(&mut cx, |this, cx| this.resume_cursor_blinking(epoch, cx))
if let Some(this) = this.upgrade(&cx) { .log_err();
this.update(&mut cx, |this, cx| this.resume_cursor_blinking(epoch, cx))
.log_err();
}
} }
}) })
.detach(); .detach();
@ -646,6 +640,9 @@ impl Item for TerminalView {
}) })
}); });
let pane = pane
.upgrade(&cx)
.ok_or_else(|| anyhow!("pane was dropped"))?;
cx.update(|cx| { cx.update(|cx| {
let terminal = project.update(cx, |project, cx| { let terminal = project.update(cx, |project, cx| {
project.create_terminal(cwd, window_id, cx) project.create_terminal(cwd, window_id, cx)

View File

@ -163,7 +163,7 @@ impl PickerDelegate for ThemeSelectorDelegate {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
cx.spawn_weak(|this, mut cx| async move { cx.spawn(|this, mut cx| async move {
let matches = if query.is_empty() { let matches = if query.is_empty() {
candidates candidates
.into_iter() .into_iter()

View File

@ -81,7 +81,7 @@ impl PickerDelegate for BaseKeymapSelectorDelegate {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
cx.spawn_weak(|this, mut cx| async move { cx.spawn(|this, mut cx| async move {
let matches = if query.is_empty() { let matches = if query.is_empty() {
candidates candidates
.into_iter() .into_iter()

View File

@ -479,7 +479,7 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
}, },
); );
} else { } else {
cx.spawn_weak(|workspace, mut cx| async move { cx.spawn(|workspace, mut cx| async move {
workspace workspace
.upgrade(&cx) .upgrade(&cx)
.ok_or_else(|| anyhow!("workspace was dropped"))? .ok_or_else(|| anyhow!("workspace was dropped"))?

View File

@ -314,7 +314,7 @@ pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
Some(workspace.prepare_to_close(false, cx)) Some(workspace.prepare_to_close(false, cx))
}; };
Some(cx.spawn_weak(|_, mut cx| async move { Some(cx.spawn(|_, mut cx| async move {
let window_id_to_replace = if let Some(close_task) = close_task { let window_id_to_replace = if let Some(close_task) = close_task {
if !close_task.await? { if !close_task.await? {
return Ok(()); return Ok(());
@ -588,7 +588,7 @@ impl DelayedDebouncedEditAction {
self.cancel_channel = Some(sender); self.cancel_channel = Some(sender);
let previous_task = self.task.take(); let previous_task = self.task.take();
self.task = Some(cx.spawn_weak(|workspace, mut cx| async move { self.task = Some(cx.spawn(|workspace, mut cx| async move {
let mut timer = cx.background().timer(delay).fuse(); let mut timer = cx.background().timer(delay).fuse();
if let Some(previous_task) = previous_task { if let Some(previous_task) = previous_task {
previous_task.await; previous_task.await;
@ -733,7 +733,7 @@ impl Workspace {
let client = project.read(cx).client(); let client = project.read(cx).client();
let mut current_user = user_store.read(cx).watch_current_user(); let mut current_user = user_store.read(cx).watch_current_user();
let mut connection_status = client.status(); let mut connection_status = client.status();
let _observe_current_user = cx.spawn_weak(|this, mut cx| async move { let _observe_current_user = cx.spawn(|this, mut cx| async move {
current_user.recv().await; current_user.recv().await;
connection_status.recv().await; connection_status.recv().await;
let mut stream = let mut stream =
@ -752,7 +752,7 @@ impl Workspace {
// that each asynchronous operation can be run in order. // that each asynchronous operation can be run in order.
let (leader_updates_tx, mut leader_updates_rx) = let (leader_updates_tx, mut leader_updates_rx) =
mpsc::unbounded::<(PeerId, proto::UpdateFollowers)>(); mpsc::unbounded::<(PeerId, proto::UpdateFollowers)>();
let _apply_leader_updates = cx.spawn_weak(|this, mut cx| async move { let _apply_leader_updates = cx.spawn(|this, mut cx| async move {
while let Some((leader_id, update)) = leader_updates_rx.next().await { while let Some((leader_id, update)) = leader_updates_rx.next().await {
let Some(this) = this.upgrade(&cx) else { break }; let Some(this) = this.upgrade(&cx) else { break };
Self::process_leader_update(this, leader_id, update, &mut cx) Self::process_leader_update(this, leader_id, update, &mut cx)
@ -1129,7 +1129,7 @@ impl Workspace {
) -> Option<Task<Result<()>>> { ) -> Option<Task<Result<()>>> {
let window_id = cx.window_id(); let window_id = cx.window_id();
let prepare = self.prepare_to_close(false, cx); let prepare = self.prepare_to_close(false, cx);
Some(cx.spawn_weak(|_, mut cx| async move { Some(cx.spawn(|_, mut cx| async move {
if prepare.await? { if prepare.await? {
cx.remove_window(window_id); cx.remove_window(window_id);
} }
@ -1220,7 +1220,7 @@ impl Workspace {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let project = self.project.clone(); let project = self.project.clone();
cx.spawn_weak(|_, mut cx| async move { cx.spawn(|_, mut cx| async move {
for (pane, item) in dirty_items { for (pane, item) in dirty_items {
let (singleton, project_entry_ids) = let (singleton, project_entry_ids) =
cx.read(|cx| (item.is_singleton(cx), item.project_entry_ids(cx))); cx.read(|cx| (item.is_singleton(cx), item.project_entry_ids(cx)));
@ -1975,7 +1975,7 @@ impl Workspace {
leader_id: Some(leader_id), leader_id: Some(leader_id),
}); });
Some(cx.spawn_weak(|this, mut cx| async move { Some(cx.spawn(|this, mut cx| async move {
let response = request.await?; let response = request.await?;
if let Some(this) = this.upgrade(&cx) { if let Some(this) = this.upgrade(&cx) {
this.update(&mut cx, |this, _| { this.update(&mut cx, |this, _| {

View File

@ -503,7 +503,7 @@ fn open_log_file(
workspace workspace
.with_local_workspace(&app_state.clone(), cx, move |_, cx| { .with_local_workspace(&app_state.clone(), cx, move |_, cx| {
cx.spawn_weak(|workspace, mut cx| async move { cx.spawn(|workspace, mut cx| async move {
let (old_log, new_log) = futures::join!( let (old_log, new_log) = futures::join!(
app_state.fs.load(&paths::OLD_LOG), app_state.fs.load(&paths::OLD_LOG),
app_state.fs.load(&paths::LOG) app_state.fs.load(&paths::LOG)
@ -558,7 +558,7 @@ fn open_telemetry_log_file(
cx: &mut ViewContext<Workspace>, cx: &mut ViewContext<Workspace>,
) { ) {
workspace.with_local_workspace(&app_state.clone(), cx, move |_, cx| { workspace.with_local_workspace(&app_state.clone(), cx, move |_, cx| {
cx.spawn_weak(|workspace, mut cx| async move { cx.spawn(|workspace, mut cx| async move {
let workspace = workspace.upgrade(&cx)?; let workspace = workspace.upgrade(&cx)?;
async fn fetch_log_string(app_state: &Arc<AppState>) -> Option<String> { async fn fetch_log_string(app_state: &Arc<AppState>) -> Option<String> {