@@ -226,6 +226,7 @@ pub struct AppContext {
pub(crate) entities: EntityMap,
pub(crate) new_view_observers: SubscriberSet<TypeId, NewViewListener>,
pub(crate) windows: SlotMap<WindowId, Option<Window>>,
+ pub(crate) window_handles: FxHashMap<WindowId, AnyWindowHandle>,
pub(crate) keymap: Rc<RefCell<Keymap>>,
pub(crate) global_action_listeners:
FxHashMap<TypeId, Vec<Rc<dyn Fn(&dyn Any, DispatchPhase, &mut Self)>>>,
@@ -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<AnyWindowHandle> {
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
@@ -2528,11 +2528,11 @@ impl<V: 'static + Render> WindowHandle<V> {
/// Check if this window is 'active'.
///
- /// Will return `None` if the window is closed.
- pub fn is_active(&self, cx: &AppContext) -> Option<bool> {
- 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<bool> {
+ cx.update_window(self.any_handle, |_, cx| cx.is_window_active())
+ .ok()
}
}
@@ -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();