Disallow multiple save modals for the same pane item (#11931)

Fixes https://github.com/zed-industries/zed/issues/10192


Release Notes:

- Fixed multiple save modals appearing for the same file being closed
([10192](https://github.com/zed-industries/zed/issues/10192))
This commit is contained in:
Kirill Bulatov 2024-05-16 22:55:05 +03:00 committed by GitHub
parent 6513886867
commit decfbc69a5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -41,7 +41,7 @@ use ui::{
IconSize, Indicator, Label, Tab, TabBar, TabPosition, Tooltip, IconSize, Indicator, Label, Tab, TabBar, TabPosition, Tooltip,
}; };
use ui::{v_flex, ContextMenu}; use ui::{v_flex, ContextMenu};
use util::{maybe, truncate_and_remove_front, ResultExt}; use util::{debug_panic, maybe, truncate_and_remove_front, ResultExt};
#[derive(PartialEq, Clone, Copy, Deserialize, Debug)] #[derive(PartialEq, Clone, Copy, Deserialize, Debug)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
@ -218,6 +218,7 @@ pub struct Pane {
/// Otherwise, when `display_nav_history_buttons` is Some, it determines whether nav buttons should be displayed. /// Otherwise, when `display_nav_history_buttons` is Some, it determines whether nav buttons should be displayed.
display_nav_history_buttons: Option<bool>, display_nav_history_buttons: Option<bool>,
double_click_dispatch_action: Box<dyn Action>, double_click_dispatch_action: Box<dyn Action>,
save_modals_spawned: HashSet<EntityId>,
} }
pub struct ActivationHistoryEntry { pub struct ActivationHistoryEntry {
@ -401,6 +402,7 @@ impl Pane {
), ),
_subscriptions: subscriptions, _subscriptions: subscriptions,
double_click_dispatch_action, double_click_dispatch_action,
save_modals_spawned: HashSet::default(),
} }
} }
@ -1367,20 +1369,37 @@ impl Pane {
) && Self::can_autosave_item(item, cx) ) && Self::can_autosave_item(item, cx)
})?; })?;
if !will_autosave { if !will_autosave {
let answer = pane.update(cx, |pane, cx| { let item_id = item.item_id();
pane.activate_item(item_ix, true, true, cx); let answer_task = pane.update(cx, |pane, cx| {
let prompt = dirty_message_for(item.project_path(cx)); if pane.save_modals_spawned.insert(item_id) {
cx.prompt( pane.activate_item(item_ix, true, true, cx);
PromptLevel::Warning, let prompt = dirty_message_for(item.project_path(cx));
&prompt, Some(cx.prompt(
None, PromptLevel::Warning,
&["Save", "Don't Save", "Cancel"], &prompt,
) None,
&["Save", "Don't Save", "Cancel"],
))
} else {
None
}
})?; })?;
match answer.await { if let Some(answer_task) = answer_task {
Ok(0) => {} let answer = answer_task.await;
Ok(1) => return Ok(true), // Don't save this file pane.update(cx, |pane, _| {
_ => return Ok(false), // Cancel if !pane.save_modals_spawned.remove(&item_id) {
debug_panic!(
"save modal was not present in spawned modals after awaiting for its answer"
)
}
})?;
match answer {
Ok(0) => {}
Ok(1) => return Ok(true), // Don't save this file
_ => return Ok(false), // Cancel
}
} else {
return Ok(false);
} }
} }
} }