History

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))

Kirill Bulatov committed 2 years ago

Commit decfbc61 parent 65138861 file · +33 −14Browse files

Unified · Split

crates/workspace/src/pane.rs+33−14
@@ -41,7 +41,7 @@ use ui::{ · 40 unmodified lines
41 IconSize, Indicator, Label, Tab, TabBar, TabPosition, Tooltip,41 IconSize, Indicator, Label, Tab, TabBar, TabPosition, Tooltip,
42};42};
43use ui::{v_flex, ContextMenu};43use ui::{v_flex, ContextMenu};
44use util::{maybe, truncate_and_remove_front, ResultExt};44use util::{debug_panic, maybe, truncate_and_remove_front, ResultExt};
45 45
46#[derive(PartialEq, Clone, Copy, Deserialize, Debug)]46#[derive(PartialEq, Clone, Copy, Deserialize, Debug)]
47#[serde(rename_all = "camelCase")]47#[serde(rename_all = "camelCase")]
@@ -218,6 +218,7 @@ pub struct Pane { · 170 unmodified lines
218 /// Otherwise, when `display_nav_history_buttons` is Some, it determines whether nav buttons should be displayed.218 /// Otherwise, when `display_nav_history_buttons` is Some, it determines whether nav buttons should be displayed.
219 display_nav_history_buttons: Option<bool>,219 display_nav_history_buttons: Option<bool>,
220 double_click_dispatch_action: Box<dyn Action>,220 double_click_dispatch_action: Box<dyn Action>,
221 save_modals_spawned: HashSet<EntityId>,
221}222}
222 223
223pub struct ActivationHistoryEntry {224pub struct ActivationHistoryEntry {
@@ -401,6 +402,7 @@ impl Pane { · 177 unmodified lines
401 ),402 ),
402 _subscriptions: subscriptions,403 _subscriptions: subscriptions,
403 double_click_dispatch_action,404 double_click_dispatch_action,
405 save_modals_spawned: HashSet::default(),
404 }406 }
405 }407 }
406 408
@@ -1367,20 +1369,37 @@ impl Pane { · 960 unmodified lines
1367 ) && Self::can_autosave_item(item, cx)1369 ) && Self::can_autosave_item(item, cx)
1368 })?;1370 })?;
1369 if !will_autosave {1371 if !will_autosave {
1370 let answer = pane.update(cx, |pane, cx| {1372 let item_id = item.item_id();
1371 pane.activate_item(item_ix, true, true, cx);1373 let answer_task = pane.update(cx, |pane, cx| {
1372 let prompt = dirty_message_for(item.project_path(cx));1374 if pane.save_modals_spawned.insert(item_id) {
1373 cx.prompt(1375 pane.activate_item(item_ix, true, true, cx);
1374 PromptLevel::Warning,1376 let prompt = dirty_message_for(item.project_path(cx));
1375 &prompt,1377 Some(cx.prompt(
1376 None,1378 PromptLevel::Warning,
1377 &["Save", "Don't Save", "Cancel"],1379 &prompt,
1378 )1380 None,
1381 &["Save", "Don't Save", "Cancel"],
1382 ))
1383 } else {
1384 None
1385 }
1379 })?;1386 })?;
1380 match answer.await {1387 if let Some(answer_task) = answer_task {
1381 Ok(0) => {}1388 let answer = answer_task.await;
1382 Ok(1) => return Ok(true), // Don't save this file1389 pane.update(cx, |pane, _| {
1383 _ => return Ok(false), // Cancel1390 if !pane.save_modals_spawned.remove(&item_id) {
1391 debug_panic!(
1392 "save modal was not present in spawned modals after awaiting for its answer"
1393 )
1394 }
1395 })?;
1396 match answer {
1397 Ok(0) => {}
1398 Ok(1) => return Ok(true), // Don't save this file
1399 _ => return Ok(false), // Cancel
1400 }
1401 } else {
1402 return Ok(false);
1384 }1403 }
1385 }1404 }
1386 }1405 }