Fix cx.windows() to return borrowed windows (#8086)

Fixes #8068

Release Notes:

- Fixed an error message when joining a project twice
([#8068](https://github.com/zed-industries/zed/issues/8068)).
This commit is contained in:
Conrad Irwin 2024-02-20 13:42:11 -07:00 committed by GitHub
parent 5c7cec9f85
commit 3d9503a454
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 14 additions and 9 deletions

View file

@ -226,6 +226,7 @@ pub struct AppContext {
pub(crate) entities: EntityMap, pub(crate) entities: EntityMap,
pub(crate) new_view_observers: SubscriberSet<TypeId, NewViewListener>, pub(crate) new_view_observers: SubscriberSet<TypeId, NewViewListener>,
pub(crate) windows: SlotMap<WindowId, Option<Window>>, pub(crate) windows: SlotMap<WindowId, Option<Window>>,
pub(crate) window_handles: FxHashMap<WindowId, AnyWindowHandle>,
pub(crate) keymap: Rc<RefCell<Keymap>>, pub(crate) keymap: Rc<RefCell<Keymap>>,
pub(crate) global_action_listeners: pub(crate) global_action_listeners:
FxHashMap<TypeId, Vec<Rc<dyn Fn(&dyn Any, DispatchPhase, &mut Self)>>>, FxHashMap<TypeId, Vec<Rc<dyn Fn(&dyn Any, DispatchPhase, &mut Self)>>>,
@ -285,6 +286,7 @@ impl AppContext {
globals_by_type: FxHashMap::default(), globals_by_type: FxHashMap::default(),
entities, entities,
new_view_observers: SubscriberSet::new(), new_view_observers: SubscriberSet::new(),
window_handles: FxHashMap::default(),
windows: SlotMap::with_key(), windows: SlotMap::with_key(),
keymap: Rc::new(RefCell::new(Keymap::default())), keymap: Rc::new(RefCell::new(Keymap::default())),
global_action_listeners: FxHashMap::default(), global_action_listeners: FxHashMap::default(),
@ -324,6 +326,7 @@ impl AppContext {
} }
self.windows.clear(); self.windows.clear();
self.window_handles.clear();
self.flush_effects(); self.flush_effects();
let futures = futures::future::join_all(futures); 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 /// To find all windows of a given type, you could filter on
pub fn windows(&self) -> Vec<AnyWindowHandle> { pub fn windows(&self) -> Vec<AnyWindowHandle> {
self.windows self.windows
.values() .keys()
.filter_map(|window| Some(window.as_ref()?.handle)) .flat_map(|window_id| self.window_handles.get(&window_id).copied())
.collect() .collect()
} }
@ -492,6 +495,7 @@ impl AppContext {
let mut window = Window::new(handle.into(), options, cx); let mut window = Window::new(handle.into(), options, cx);
let root_view = build_root_view(&mut WindowContext::new(cx, &mut window)); let root_view = build_root_view(&mut WindowContext::new(cx, &mut window));
window.root_view.replace(root_view.into()); window.root_view.replace(root_view.into());
cx.window_handles.insert(id, window.handle);
cx.windows.get_mut(id).unwrap().replace(window); cx.windows.get_mut(id).unwrap().replace(window);
handle handle
}) })
@ -1245,6 +1249,7 @@ impl Context for AppContext {
let result = update(root_view, &mut WindowContext::new(cx, &mut window)); let result = update(root_view, &mut WindowContext::new(cx, &mut window));
if window.removed { if window.removed {
cx.window_handles.remove(&handle.id);
cx.windows.remove(handle.id); cx.windows.remove(handle.id);
} else { } else {
cx.windows cx.windows

View file

@ -2528,11 +2528,11 @@ impl<V: 'static + Render> WindowHandle<V> {
/// Check if this window is 'active'. /// Check if this window is 'active'.
/// ///
/// Will return `None` if the window is closed. /// Will return `None` if the window is closed or currently
pub fn is_active(&self, cx: &AppContext) -> Option<bool> { /// borrowed.
cx.windows pub fn is_active(&self, cx: &mut AppContext) -> Option<bool> {
.get(self.id) cx.update_window(self.any_handle, |_, cx| cx.is_window_active())
.and_then(|window| window.as_ref().map(|window| window.active.get())) .ok()
} }
} }

View file

@ -422,8 +422,8 @@ fn quit(_: &Quit, cx: &mut AppContext) {
// If multiple windows have unsaved changes, and need a save prompt, // If multiple windows have unsaved changes, and need a save prompt,
// prompt in the active window before switching to a different window. // prompt in the active window before switching to a different window.
cx.update(|cx| { cx.update(|mut cx| {
workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false)); workspace_windows.sort_by_key(|window| window.is_active(&mut cx) == Some(false));
}) })
.log_err(); .log_err();