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))
Unified · Split
| @@ -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 | }; |
| 43 | use ui::{v_flex, ContextMenu}; | 43 | use ui::{v_flex, ContextMenu}; |
| 44 | use util::{maybe, truncate_and_remove_front, ResultExt}; | 44 | use 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 | ||
| 223 | pub struct ActivationHistoryEntry { | 224 | pub 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 file | 1389 | pane.update(cx, |pane, _| { |
| 1383 | _ => return Ok(false), // Cancel | 1390 | 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 | } |