diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 333948f956..4ac114331d 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -226,6 +226,7 @@ pub struct AppContext { pub(crate) entities: EntityMap, pub(crate) new_view_observers: SubscriberSet, pub(crate) windows: SlotMap>, + pub(crate) window_handles: FxHashMap, pub(crate) keymap: Rc>, pub(crate) global_action_listeners: FxHashMap>>, @@ -285,6 +286,7 @@ impl AppContext { globals_by_type: FxHashMap::default(), entities, new_view_observers: SubscriberSet::new(), + window_handles: FxHashMap::default(), windows: SlotMap::with_key(), keymap: Rc::new(RefCell::new(Keymap::default())), global_action_listeners: FxHashMap::default(), @@ -324,6 +326,7 @@ impl AppContext { } self.windows.clear(); + self.window_handles.clear(); self.flush_effects(); let futures = futures::future::join_all(futures); @@ -468,8 +471,8 @@ impl AppContext { /// To find all windows of a given type, you could filter on pub fn windows(&self) -> Vec { self.windows - .values() - .filter_map(|window| Some(window.as_ref()?.handle)) + .keys() + .flat_map(|window_id| self.window_handles.get(&window_id).copied()) .collect() } @@ -492,6 +495,7 @@ impl AppContext { let mut window = Window::new(handle.into(), options, cx); let root_view = build_root_view(&mut WindowContext::new(cx, &mut window)); window.root_view.replace(root_view.into()); + cx.window_handles.insert(id, window.handle); cx.windows.get_mut(id).unwrap().replace(window); handle }) @@ -1245,6 +1249,7 @@ impl Context for AppContext { let result = update(root_view, &mut WindowContext::new(cx, &mut window)); if window.removed { + cx.window_handles.remove(&handle.id); cx.windows.remove(handle.id); } else { cx.windows diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index c6951ff7a3..351ab15bba 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -2528,11 +2528,11 @@ impl WindowHandle { /// Check if this window is 'active'. /// - /// Will return `None` if the window is closed. - pub fn is_active(&self, cx: &AppContext) -> Option { - cx.windows - .get(self.id) - .and_then(|window| window.as_ref().map(|window| window.active.get())) + /// Will return `None` if the window is closed or currently + /// borrowed. + pub fn is_active(&self, cx: &mut AppContext) -> Option { + cx.update_window(self.any_handle, |_, cx| cx.is_window_active()) + .ok() } } diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index c9205dc8f3..d76574039a 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -422,8 +422,8 @@ fn quit(_: &Quit, cx: &mut AppContext) { // If multiple windows have unsaved changes, and need a save prompt, // prompt in the active window before switching to a different window. - cx.update(|cx| { - workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false)); + cx.update(|mut cx| { + workspace_windows.sort_by_key(|window| window.is_active(&mut cx) == Some(false)); }) .log_err();