diff --git a/crates/collab_ui/src/contact_list.rs b/crates/collab_ui/src/contact_list.rs index 428f2156d1..a2b281856d 100644 --- a/crates/collab_ui/src/contact_list.rs +++ b/crates/collab_ui/src/contact_list.rs @@ -305,7 +305,7 @@ impl ContactList { github_login ); let mut answer = cx.prompt(PromptLevel::Warning, &prompt_message, &["Remove", "Cancel"]); - let window_id = cx.window_id(); + let window = cx.window(); cx.spawn(|_, mut cx| async move { if answer.next().await == Some(0) { if let Err(e) = user_store @@ -313,7 +313,7 @@ impl ContactList { .await { cx.prompt( - window_id, + window, PromptLevel::Info, &format!("Failed to remove contact: {}", e), &["Ok"], diff --git a/crates/collab_ui/src/project_shared_notification.rs b/crates/collab_ui/src/project_shared_notification.rs index d5e7c877f7..63922f2b65 100644 --- a/crates/collab_ui/src/project_shared_notification.rs +++ b/crates/collab_ui/src/project_shared_notification.rs @@ -5,7 +5,7 @@ use gpui::{ elements::*, geometry::{rect::RectF, vector::vec2f}, platform::{CursorStyle, MouseButton, WindowBounds, WindowKind, WindowOptions}, - AppContext, BorrowWindowContext, Entity, View, ViewContext, + AppContext, Entity, View, ViewContext, }; use std::sync::{Arc, Weak}; use workspace::AppState; @@ -52,20 +52,20 @@ pub fn init(app_state: &Arc, cx: &mut AppContext) { notification_windows .entry(*project_id) .or_insert(Vec::new()) - .push(window.id()); + .push(window); } } room::Event::RemoteProjectUnshared { project_id } => { - if let Some(window_ids) = notification_windows.remove(&project_id) { - for window_id in window_ids { - cx.update_window(window_id, |cx| cx.remove_window()); + if let Some(windows) = notification_windows.remove(&project_id) { + for window in windows { + window.remove(cx); } } } room::Event::Left => { - for (_, window_ids) in notification_windows.drain() { - for window_id in window_ids { - cx.update_window(window_id, |cx| cx.remove_window()); + for (_, windows) in notification_windows.drain() { + for window in windows { + window.remove(cx); } } } diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index f51a6c9238..b3703aa64a 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/crates/command_palette/src/command_palette.rs @@ -80,11 +80,11 @@ impl PickerDelegate for CommandPaletteDelegate { query: String, cx: &mut ViewContext>, ) -> gpui::Task<()> { - let window_id = cx.window_id(); let view_id = self.focused_view_id; + let window = cx.window(); cx.spawn(move |picker, mut cx| async move { let actions = cx - .available_actions(window_id, view_id) + .available_actions(window, view_id) .into_iter() .filter_map(|(name, action, bindings)| { let filtered = cx.read(|cx| { @@ -162,13 +162,13 @@ impl PickerDelegate for CommandPaletteDelegate { fn confirm(&mut self, _: bool, cx: &mut ViewContext>) { if !self.matches.is_empty() { - let window_id = cx.window_id(); + let window = cx.window(); let focused_view_id = self.focused_view_id; let action_ix = self.matches[self.selected_ix].candidate_id; let action = self.actions.remove(action_ix).action; cx.app_context() .spawn(move |mut cx| async move { - cx.dispatch_action(window_id, focused_view_id, action.as_ref()) + cx.dispatch_action(window, focused_view_id, action.as_ref()) }) .detach_and_log_err(cx); } diff --git a/crates/context_menu/src/context_menu.rs b/crates/context_menu/src/context_menu.rs index f58afab361..75cfd872b2 100644 --- a/crates/context_menu/src/context_menu.rs +++ b/crates/context_menu/src/context_menu.rs @@ -218,12 +218,12 @@ impl ContextMenu { if let Some(ContextMenuItem::Item { action, .. }) = self.items.get(ix) { match action { ContextMenuItemAction::Action(action) => { - let window_id = cx.window_id(); + let window = cx.window(); let view_id = self.parent_view_id; let action = action.boxed_clone(); cx.app_context() .spawn(|mut cx| async move { - cx.dispatch_action(window_id, view_id, action.as_ref()) + cx.dispatch_action(window, view_id, action.as_ref()) }) .detach_and_log_err(cx); } @@ -480,17 +480,13 @@ impl ContextMenu { .on_down(MouseButton::Left, |_, _, _| {}) // Capture these events .on_click(MouseButton::Left, move |_, menu, cx| { menu.cancel(&Default::default(), cx); - let window_id = cx.window_id(); + let window = cx.window(); match &action { ContextMenuItemAction::Action(action) => { let action = action.boxed_clone(); cx.app_context() .spawn(|mut cx| async move { - cx.dispatch_action( - window_id, - view_id, - action.as_ref(), - ) + cx.dispatch_action(window, view_id, action.as_ref()) }) .detach_and_log_err(cx); } diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index 12bf324262..523d6e8a5c 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -619,7 +619,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - cx.dispatch_action(window.id(), Toggle); + cx.dispatch_action(window.into(), Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); finder @@ -632,8 +632,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window.id(), SelectNext); - cx.dispatch_action(window.id(), Confirm); + cx.dispatch_action(window.into(), SelectNext); + cx.dispatch_action(window.into(), Confirm); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) .await; @@ -674,7 +674,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - cx.dispatch_action(window.id(), Toggle); + cx.dispatch_action(window.into(), Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); let file_query = &first_file_name[..3]; @@ -706,8 +706,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window.id(), SelectNext); - cx.dispatch_action(window.id(), Confirm); + cx.dispatch_action(window.into(), SelectNext); + cx.dispatch_action(window.into(), Confirm); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) .await; @@ -758,7 +758,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - cx.dispatch_action(window.id(), Toggle); + cx.dispatch_action(window.into(), Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); let file_query = &first_file_name[..3]; @@ -790,8 +790,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window.id(), SelectNext); - cx.dispatch_action(window.id(), Confirm); + cx.dispatch_action(window.into(), SelectNext); + cx.dispatch_action(window.into(), Confirm); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) .await; @@ -1168,7 +1168,6 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); let worktree_id = cx.read(|cx| { let worktrees = workspace.read(cx).worktrees(cx).collect::>(); assert_eq!(worktrees.len(), 1); @@ -1186,7 +1185,7 @@ mod tests { "fir", 1, "first.rs", - window_id, + window.into(), &workspace, &deterministic, cx, @@ -1201,7 +1200,7 @@ mod tests { "sec", 1, "second.rs", - window_id, + window.into(), &workspace, &deterministic, cx, @@ -1223,7 +1222,7 @@ mod tests { "thi", 1, "third.rs", - window_id, + window.into(), &workspace, &deterministic, cx, @@ -1255,7 +1254,7 @@ mod tests { "sec", 1, "second.rs", - window_id, + window.into(), &workspace, &deterministic, cx, @@ -1294,7 +1293,7 @@ mod tests { "thi", 1, "third.rs", - window_id, + window.into(), &workspace, &deterministic, cx, @@ -1376,7 +1375,6 @@ mod tests { let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); let worktree_id = cx.read(|cx| { let worktrees = workspace.read(cx).worktrees(cx).collect::>(); assert_eq!(worktrees.len(), 1,); @@ -1411,7 +1409,7 @@ mod tests { "sec", 1, "second.rs", - window_id, + window.into(), &workspace, &deterministic, cx, @@ -1433,7 +1431,7 @@ mod tests { "fir", 1, "first.rs", - window_id, + window.into(), &workspace, &deterministic, cx, @@ -1465,12 +1463,12 @@ mod tests { input: &str, expected_matches: usize, expected_editor_title: &str, - window_id: usize, + window: gpui::AnyWindowHandle, workspace: &ViewHandle, deterministic: &gpui::executor::Deterministic, cx: &mut gpui::TestAppContext, ) -> Vec { - cx.dispatch_action(window_id, Toggle); + cx.dispatch_action(window, Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); finder .update(cx, |finder, cx| { @@ -1487,8 +1485,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window_id, SelectNext); - cx.dispatch_action(window_id, Confirm); + cx.dispatch_action(window, SelectNext); + cx.dispatch_action(window, Confirm); deterministic.run_until_parked(); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) diff --git a/crates/go_to_line/src/go_to_line.rs b/crates/go_to_line/src/go_to_line.rs index fa42a52374..1d3b44fa43 100644 --- a/crates/go_to_line/src/go_to_line.rs +++ b/crates/go_to_line/src/go_to_line.rs @@ -135,16 +135,14 @@ impl Entity for GoToLine { fn release(&mut self, cx: &mut AppContext) { let scroll_position = self.prev_scroll_position.take(); - if let Some(window) = self.active_editor.window(cx) { - window.update(cx, |cx| { - self.active_editor.update(cx, |editor, cx| { - editor.highlight_rows(None); - if let Some(scroll_position) = scroll_position { - editor.set_scroll_position(scroll_position, cx); - } - }) - }); - } + self.active_editor.window().update(cx, |cx| { + self.active_editor.update(cx, |editor, cx| { + editor.highlight_rows(None); + if let Some(scroll_position) = scroll_position { + editor.set_scroll_position(scroll_position, cx); + } + }) + }); } } diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index ff8e343c2c..e0f46b036a 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -134,16 +134,16 @@ pub trait BorrowAppContext { pub trait BorrowWindowContext { type Result; - fn read_window(&self, window_id: usize, f: F) -> Self::Result + fn read_window(&self, window: AnyWindowHandle, f: F) -> Self::Result where F: FnOnce(&WindowContext) -> T; - fn read_window_optional(&self, window_id: usize, f: F) -> Option + fn read_window_optional(&self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option; - fn update_window(&mut self, window_id: usize, f: F) -> Self::Result + fn update_window(&mut self, window: AnyWindowHandle, f: F) -> Self::Result where F: FnOnce(&mut WindowContext) -> T; - fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + fn update_window_optional(&mut self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&mut WindowContext) -> Option; } @@ -308,12 +308,12 @@ impl App { result } - fn update_window(&mut self, window_id: usize, callback: F) -> Option + fn update_window(&mut self, window: AnyWindowHandle, callback: F) -> Option where F: FnOnce(&mut WindowContext) -> T, { let mut state = self.0.borrow_mut(); - let result = state.update_window(window_id, callback); + let result = state.update_window(window, callback); state.pending_notifications.clear(); result } @@ -346,22 +346,22 @@ impl AsyncAppContext { pub fn read_window T>( &self, - window_id: usize, + window: AnyWindowHandle, callback: F, ) -> Option { - self.0.borrow_mut().read_window(window_id, callback) + self.0.borrow_mut().read_window(window, callback) } pub fn update_window T>( &mut self, - window_id: usize, + window: AnyWindowHandle, callback: F, ) -> Option { - self.0.borrow_mut().update_window(window_id, callback) + self.0.borrow_mut().update_window(window, callback) } - pub fn debug_elements(&self, window_id: usize) -> Option { - self.0.borrow().read_window(window_id, |cx| { + pub fn debug_elements(&self, window: AnyWindowHandle) -> Option { + self.0.borrow().read_window(window, |cx| { let root_view = cx.window.root_view(); let root_element = cx.window.rendered_views.get(&root_view.id())?; root_element.debug(cx).log_err() @@ -370,13 +370,13 @@ impl AsyncAppContext { pub fn dispatch_action( &mut self, - window_id: usize, + window: AnyWindowHandle, view_id: usize, action: &dyn Action, ) -> Result<()> { self.0 .borrow_mut() - .update_window(window_id, |cx| { + .update_window(window, |cx| { cx.dispatch_action(Some(view_id), action); }) .ok_or_else(|| anyhow!("window not found")) @@ -384,10 +384,10 @@ impl AsyncAppContext { pub fn available_actions( &self, - window_id: usize, + window: AnyWindowHandle, view_id: usize, ) -> Vec<(&'static str, Box, SmallVec<[Binding; 1]>)> { - self.read_window(window_id, |cx| cx.available_actions(view_id)) + self.read_window(window, |cx| cx.available_actions(view_id)) .unwrap_or_default() } @@ -411,23 +411,23 @@ impl AsyncAppContext { self.update(|cx| cx.add_window(window_options, build_root_view)) } - pub fn remove_window(&mut self, window_id: usize) { - self.update_window(window_id, |cx| cx.remove_window()); + pub fn remove_window(&mut self, window: AnyWindowHandle) { + self.update_window(window, |cx| cx.remove_window()); } - pub fn activate_window(&mut self, window_id: usize) { - self.update_window(window_id, |cx| cx.activate_window()); + pub fn activate_window(&mut self, window: AnyWindowHandle) { + self.update_window(window, |cx| cx.activate_window()); } // TODO: Can we eliminate this method and move it to WindowContext then call it with update_window?s pub fn prompt( &mut self, - window_id: usize, + window: AnyWindowHandle, level: PromptLevel, msg: &str, answers: &[&str], ) -> Option> { - self.update_window(window_id, |cx| cx.prompt(level, msg, answers)) + self.update_window(window, |cx| cx.prompt(level, msg, answers)) } pub fn platform(&self) -> Arc { @@ -456,38 +456,36 @@ impl BorrowAppContext for AsyncAppContext { impl BorrowWindowContext for AsyncAppContext { type Result = Option; - fn read_window(&self, window_id: usize, f: F) -> Self::Result + fn read_window(&self, window: AnyWindowHandle, f: F) -> Self::Result where F: FnOnce(&WindowContext) -> T, { - self.0.borrow().read_with(|cx| cx.read_window(window_id, f)) + self.0.borrow().read_with(|cx| cx.read_window(window, f)) } - fn read_window_optional(&self, window_id: usize, f: F) -> Option + fn read_window_optional(&self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option, { self.0 .borrow_mut() - .update(|cx| cx.read_window_optional(window_id, f)) + .update(|cx| cx.read_window_optional(window, f)) } - fn update_window(&mut self, window_id: usize, f: F) -> Self::Result + fn update_window(&mut self, window: AnyWindowHandle, f: F) -> Self::Result where F: FnOnce(&mut WindowContext) -> T, { - self.0 - .borrow_mut() - .update(|cx| cx.update_window(window_id, f)) + self.0.borrow_mut().update(|cx| cx.update_window(window, f)) } - fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + fn update_window_optional(&mut self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&mut WindowContext) -> Option, { self.0 .borrow_mut() - .update(|cx| cx.update_window_optional(window_id, f)) + .update(|cx| cx.update_window_optional(window, f)) } } @@ -534,7 +532,7 @@ pub struct AppContext { global_actions: HashMap>, keystroke_matcher: KeymapMatcher, next_id: usize, - // next_window_id: usize, + // next_window: AnyWindowHandle, next_subscription_id: usize, frame_count: usize, @@ -794,13 +792,13 @@ impl AppContext { } } - pub fn view_ui_name(&self, window_id: usize, view_id: usize) -> Option<&'static str> { - Some(self.views.get(&(window_id, view_id))?.ui_name()) + pub fn view_ui_name(&self, window: AnyWindowHandle, view_id: usize) -> Option<&'static str> { + Some(self.views.get(&(window.id(), view_id))?.ui_name()) } - pub fn view_type_id(&self, window_id: usize, view_id: usize) -> Option { + pub fn view_type_id(&self, window: AnyWindowHandle, view_id: usize) -> Option { self.views_metadata - .get(&(window_id, view_id)) + .get(&(window.id(), view_id)) .map(|metadata| metadata.type_id) } @@ -823,11 +821,11 @@ impl AppContext { fn read_window T>( &self, - window_id: usize, + handle: AnyWindowHandle, callback: F, ) -> Option { - let window = self.windows.get(&window_id)?; - let window_context = WindowContext::immutable(self, &window, window_id); + let window = self.windows.get(&handle.id())?; + let window_context = WindowContext::immutable(self, &window, handle); Some(callback(&window_context)) } @@ -835,9 +833,8 @@ impl AppContext { &mut self, callback: F, ) -> Option { - self.platform - .main_window_id() - .and_then(|id| self.update_window(id, callback)) + self.main_window() + .and_then(|window| window.update(self, callback)) } pub fn prompt_for_paths( @@ -1075,10 +1072,10 @@ impl AppContext { } } - fn notify_view(&mut self, window_id: usize, view_id: usize) { + fn notify_view(&mut self, window: AnyWindowHandle, view_id: usize) { if self.pending_notifications.insert(view_id) { self.pending_effects - .push_back(Effect::ViewNotification { window_id, view_id }); + .push_back(Effect::ViewNotification { window, view_id }); } } @@ -1096,13 +1093,13 @@ impl AppContext { pub fn is_action_available(&self, action: &dyn Action) -> bool { let mut available_in_window = false; let action_id = action.id(); - if let Some(window_id) = self.platform.main_window_id() { + if let Some(window) = self.main_window() { available_in_window = self - .read_window(window_id, |cx| { + .read_window(window, |cx| { if let Some(focused_view_id) = cx.focused_view_id() { for view_id in cx.ancestors(focused_view_id) { if let Some(view_metadata) = - cx.views_metadata.get(&(window_id, view_id)) + cx.views_metadata.get(&(cx.window_handle.id(), view_id)) { if let Some(actions) = cx.actions.get(&view_metadata.type_id) { if actions.contains_key(&action_id) { @@ -1367,13 +1364,12 @@ impl AppContext { F: FnOnce(&mut ViewContext) -> V, { let handle: AnyWindowHandle = handle.into(); - let window_id = handle.id(); { let mut app = self.upgrade(); platform_window.on_event(Box::new(move |event| { - app.update_window(window_id, |cx| { + app.update_window(handle, |cx| { if let Event::KeyDown(KeyDownEvent { keystroke, .. }) = &event { if cx.dispatch_keystroke(keystroke) { return true; @@ -1389,35 +1385,35 @@ impl AppContext { { let mut app = self.upgrade(); platform_window.on_active_status_change(Box::new(move |is_active| { - app.update(|cx| cx.window_changed_active_status(window_id, is_active)) + app.update(|cx| cx.window_changed_active_status(handle, is_active)) })); } { let mut app = self.upgrade(); platform_window.on_resize(Box::new(move || { - app.update(|cx| cx.window_was_resized(window_id)) + app.update(|cx| cx.window_was_resized(handle)) })); } { let mut app = self.upgrade(); platform_window.on_moved(Box::new(move || { - app.update(|cx| cx.window_was_moved(window_id)) + app.update(|cx| cx.window_was_moved(handle)) })); } { let mut app = self.upgrade(); platform_window.on_fullscreen(Box::new(move |is_fullscreen| { - app.update(|cx| cx.window_was_fullscreen_changed(window_id, is_fullscreen)) + app.update(|cx| cx.window_was_fullscreen_changed(handle, is_fullscreen)) })); } { let mut app = self.upgrade(); platform_window.on_close(Box::new(move || { - app.update(|cx| cx.update_window(window_id, |cx| cx.remove_window())); + app.update(|cx| cx.update_window(handle, |cx| cx.remove_window())); })); } @@ -1432,8 +1428,8 @@ impl AppContext { window: handle, })); - let mut window = Window::new(window_id, platform_window, self, build_root_view); - let mut cx = WindowContext::mutable(self, &mut window, window_id); + let mut window = Window::new(handle, platform_window, self, build_root_view); + let mut cx = WindowContext::mutable(self, &mut window, handle); cx.layout(false).expect("initial layout should not error"); let scene = cx.paint().expect("initial paint should not error"); window.platform_window.present_scene(scene); @@ -1455,7 +1451,7 @@ impl AppContext { } pub fn read_view(&self, handle: &ViewHandle) -> &T { - if let Some(view) = self.views.get(&(handle.window_id, handle.view_id)) { + if let Some(view) = self.views.get(&(handle.window.id(), handle.view_id)) { view.as_any().downcast_ref().expect("downcast is type safe") } else { panic!("circular view reference for type {}", type_name::()); @@ -1465,7 +1461,7 @@ impl AppContext { fn upgrade_view_handle(&self, handle: &WeakViewHandle) -> Option> { if self.ref_counts.lock().is_entity_alive(handle.view_id) { Some(ViewHandle::new( - handle.window_id, + handle.window, handle.view_id, &self.ref_counts, )) @@ -1477,7 +1473,7 @@ impl AppContext { fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option { if self.ref_counts.lock().is_entity_alive(handle.view_id) { Some(AnyViewHandle::new( - handle.window_id, + handle.window, handle.view_id, handle.view_type, self.ref_counts.clone(), @@ -1585,9 +1581,10 @@ impl AppContext { observations.emit(model_id, |callback| callback(self)); } - Effect::ViewNotification { window_id, view_id } => { - self.handle_view_notification_effect(window_id, view_id) - } + Effect::ViewNotification { + window: window_id, + view_id, + } => self.handle_view_notification_effect(window_id, view_id), Effect::GlobalNotification { type_id } => { let mut subscriptions = self.global_observations.clone(); @@ -1618,13 +1615,13 @@ impl AppContext { Effect::Focus(mut effect) => { if focus_effects - .get(&effect.window_id()) + .get(&effect.window().id()) .map_or(false, |prev_effect| prev_effect.is_forced()) { effect.force(); } - focus_effects.insert(effect.window_id(), effect); + focus_effects.insert(effect.window().id(), effect); } Effect::FocusObservation { @@ -1639,42 +1636,38 @@ impl AppContext { ); } - Effect::ResizeWindow { window_id } => { - if let Some(window) = self.windows.get_mut(&window_id) { + Effect::ResizeWindow { window } => { + if let Some(window) = self.windows.get_mut(&window.id()) { window .invalidation .get_or_insert(WindowInvalidation::default()); } - self.handle_window_moved(window_id); + self.handle_window_moved(window); } - Effect::MoveWindow { window_id } => { - self.handle_window_moved(window_id); + Effect::MoveWindow { window } => { + self.handle_window_moved(window); } Effect::WindowActivationObservation { - window_id, + window, subscription_id, callback, } => self.window_activation_observations.add_callback( - window_id, + window.id(), subscription_id, callback, ), - Effect::ActivateWindow { - window_id, - is_active, - } => { - if self.handle_window_activation_effect(window_id, is_active) - && is_active + Effect::ActivateWindow { window, is_active } => { + if self.handle_window_activation_effect(window, is_active) && is_active { focus_effects - .entry(window_id) + .entry(window.id()) .or_insert_with(|| FocusEffect::View { - window_id, + window, view_id: self - .read_window(window_id, |cx| cx.focused_view_id()) + .read_window(window, |cx| cx.focused_view_id()) .flatten(), is_forced: true, }) @@ -1683,26 +1676,26 @@ impl AppContext { } Effect::WindowFullscreenObservation { - window_id, + window, subscription_id, callback, } => self.window_fullscreen_observations.add_callback( - window_id, + window.id(), subscription_id, callback, ), Effect::FullscreenWindow { - window_id, + window, is_fullscreen, - } => self.handle_fullscreen_effect(window_id, is_fullscreen), + } => self.handle_fullscreen_effect(window, is_fullscreen), Effect::WindowBoundsObservation { - window_id, + window, subscription_id, callback, } => self.window_bounds_observations.add_callback( - window_id, + window.id(), subscription_id, callback, ), @@ -1714,18 +1707,15 @@ impl AppContext { Effect::ActionDispatchNotification { action_id } => { self.handle_action_dispatch_notification_effect(action_id) } - Effect::WindowShouldCloseSubscription { - window_id, - callback, - } => { - self.handle_window_should_close_subscription_effect(window_id, callback) + Effect::WindowShouldCloseSubscription { window, callback } => { + self.handle_window_should_close_subscription_effect(window, callback) } Effect::Keystroke { - window_id, + window, keystroke, handled_by, result, - } => self.handle_keystroke_effect(window_id, keystroke, handled_by, result), + } => self.handle_keystroke_effect(window, keystroke, handled_by, result), Effect::ActiveLabeledTasksChanged => { self.handle_active_labeled_tasks_changed_effect() } @@ -1740,8 +1730,8 @@ impl AppContext { } self.pending_notifications.clear(); } else { - for window_id in self.windows.keys().cloned().collect::>() { - self.update_window(window_id, |cx| { + for window in self.windows().collect::>() { + self.update_window(window, |cx| { let invalidation = if refreshing { let mut invalidation = cx.window.invalidation.take().unwrap_or_default(); @@ -1757,7 +1747,7 @@ impl AppContext { let appearance = cx.window.platform_window.appearance(); cx.invalidate(invalidation, appearance); if let Some(old_parents) = cx.layout(refreshing).log_err() { - updated_windows.insert(window_id); + updated_windows.insert(window); if let Some(focused_view_id) = cx.focused_view_id() { let old_ancestors = std::iter::successors( @@ -1772,7 +1762,7 @@ impl AppContext { for old_ancestor in old_ancestors.iter().copied() { if !new_ancestors.contains(&old_ancestor) { if let Some(mut view) = - cx.views.remove(&(window_id, old_ancestor)) + cx.views.remove(&(window.id(), old_ancestor)) { view.focus_out( focused_view_id, @@ -1780,7 +1770,7 @@ impl AppContext { old_ancestor, ); cx.views - .insert((window_id, old_ancestor), view); + .insert((window.id(), old_ancestor), view); } } } @@ -1789,7 +1779,7 @@ impl AppContext { for new_ancestor in new_ancestors.iter().copied() { if !old_ancestors.contains(&new_ancestor) { if let Some(mut view) = - cx.views.remove(&(window_id, new_ancestor)) + cx.views.remove(&(window.id(), new_ancestor)) { view.focus_in( focused_view_id, @@ -1797,7 +1787,7 @@ impl AppContext { new_ancestor, ); cx.views - .insert((window_id, new_ancestor), view); + .insert((window.id(), new_ancestor), view); } } } @@ -1806,13 +1796,15 @@ impl AppContext { // there isn't any pending focus, focus the root view. let root_view_id = cx.window.root_view().id(); if focused_view_id != root_view_id - && !cx.views.contains_key(&(window_id, focused_view_id)) - && !focus_effects.contains_key(&window_id) + && !cx + .views + .contains_key(&(window.id(), focused_view_id)) + && !focus_effects.contains_key(&window.id()) { focus_effects.insert( - window_id, + window.id(), FocusEffect::View { - window_id, + window, view_id: Some(root_view_id), is_forced: false, }, @@ -1833,8 +1825,8 @@ impl AppContext { callback(self); } - for window_id in updated_windows.drain() { - self.update_window(window_id, |cx| { + for window in updated_windows.drain() { + self.update_window(window, |cx| { if let Some(scene) = cx.paint().log_err() { cx.window.platform_window.present_scene(scene); } @@ -1855,39 +1847,37 @@ impl AppContext { } } - fn window_was_resized(&mut self, window_id: usize) { + fn window_was_resized(&mut self, window: AnyWindowHandle) { self.pending_effects - .push_back(Effect::ResizeWindow { window_id }); + .push_back(Effect::ResizeWindow { window }); } - fn window_was_moved(&mut self, window_id: usize) { + fn window_was_moved(&mut self, window: AnyWindowHandle) { self.pending_effects - .push_back(Effect::MoveWindow { window_id }); + .push_back(Effect::MoveWindow { window }); } - fn window_was_fullscreen_changed(&mut self, window_id: usize, is_fullscreen: bool) { + fn window_was_fullscreen_changed(&mut self, window: AnyWindowHandle, is_fullscreen: bool) { self.pending_effects.push_back(Effect::FullscreenWindow { - window_id, + window, is_fullscreen, }); } - fn window_changed_active_status(&mut self, window_id: usize, is_active: bool) { - self.pending_effects.push_back(Effect::ActivateWindow { - window_id, - is_active, - }); + fn window_changed_active_status(&mut self, window: AnyWindowHandle, is_active: bool) { + self.pending_effects + .push_back(Effect::ActivateWindow { window, is_active }); } fn keystroke( &mut self, - window_id: usize, + window: AnyWindowHandle, keystroke: Keystroke, handled_by: Option>, result: MatchResult, ) { self.pending_effects.push_back(Effect::Keystroke { - window_id, + window, keystroke, handled_by, result, @@ -1910,16 +1900,16 @@ impl AppContext { fn handle_view_notification_effect( &mut self, - observed_window_id: usize, + observed_window: AnyWindowHandle, observed_view_id: usize, ) { - let view_key = (observed_window_id, observed_view_id); + let view_key = (observed_window.id(), observed_view_id); if let Some((view, mut view_metadata)) = self .views .remove(&view_key) .zip(self.views_metadata.remove(&view_key)) { - if let Some(window) = self.windows.get_mut(&observed_window_id) { + if let Some(window) = self.windows.get_mut(&observed_window.id()) { window .invalidation .get_or_insert_with(Default::default) @@ -1946,17 +1936,17 @@ impl AppContext { }) } - fn handle_fullscreen_effect(&mut self, window_id: usize, is_fullscreen: bool) { - self.update_window(window_id, |cx| { + fn handle_fullscreen_effect(&mut self, window: AnyWindowHandle, is_fullscreen: bool) { + self.update_window(window, |cx| { cx.window.is_fullscreen = is_fullscreen; let mut fullscreen_observations = cx.window_fullscreen_observations.clone(); - fullscreen_observations.emit(window_id, |callback| callback(is_fullscreen, cx)); + fullscreen_observations.emit(window.id(), |callback| callback(is_fullscreen, cx)); if let Some(uuid) = cx.window_display_uuid() { let bounds = cx.window_bounds(); let mut bounds_observations = cx.window_bounds_observations.clone(); - bounds_observations.emit(window_id, |callback| callback(bounds, uuid, cx)); + bounds_observations.emit(window.id(), |callback| callback(bounds, uuid, cx)); } Some(()) @@ -1965,42 +1955,42 @@ impl AppContext { fn handle_keystroke_effect( &mut self, - window_id: usize, + window: AnyWindowHandle, keystroke: Keystroke, handled_by: Option>, result: MatchResult, ) { - self.update_window(window_id, |cx| { + self.update_window(window, |cx| { let mut observations = cx.keystroke_observations.clone(); - observations.emit(window_id, move |callback| { + observations.emit(window.id(), move |callback| { callback(&keystroke, &result, handled_by.as_ref(), cx) }); }); } - fn handle_window_activation_effect(&mut self, window_id: usize, active: bool) -> bool { - self.update_window(window_id, |cx| { + fn handle_window_activation_effect(&mut self, window: AnyWindowHandle, active: bool) -> bool { + self.update_window(window, |cx| { if cx.window.is_active == active { return false; } cx.window.is_active = active; let mut observations = cx.window_activation_observations.clone(); - observations.emit(window_id, |callback| callback(active, cx)); + observations.emit(window.id(), |callback| callback(active, cx)); true }) .unwrap_or(false) } fn handle_focus_effect(&mut self, effect: FocusEffect) { - let window_id = effect.window_id(); - self.update_window(window_id, |cx| { + let window = effect.window(); + self.update_window(window, |cx| { // Ensure the newly-focused view still exists, otherwise focus // the root view instead. let focused_id = match effect { FocusEffect::View { view_id, .. } => { if let Some(view_id) = view_id { - if cx.views.contains_key(&(window_id, view_id)) { + if cx.views.contains_key(&(window.id(), view_id)) { Some(view_id) } else { Some(cx.root_view().id()) @@ -2025,9 +2015,9 @@ impl AppContext { if focus_changed { if let Some(blurred_id) = blurred_id { for view_id in cx.ancestors(blurred_id).collect::>() { - if let Some(mut view) = cx.views.remove(&(window_id, view_id)) { + if let Some(mut view) = cx.views.remove(&(window.id(), view_id)) { view.focus_out(blurred_id, cx, view_id); - cx.views.insert((window_id, view_id), view); + cx.views.insert((window.id(), view_id), view); } } @@ -2039,9 +2029,9 @@ impl AppContext { if focus_changed || effect.is_forced() { if let Some(focused_id) = focused_id { for view_id in cx.ancestors(focused_id).collect::>() { - if let Some(mut view) = cx.views.remove(&(window_id, view_id)) { + if let Some(mut view) = cx.views.remove(&(window.id(), view_id)) { view.focus_in(focused_id, cx, view_id); - cx.views.insert((window_id, view_id), view); + cx.views.insert((window.id(), view_id), view); } } @@ -2063,24 +2053,24 @@ impl AppContext { fn handle_window_should_close_subscription_effect( &mut self, - window_id: usize, + window: AnyWindowHandle, mut callback: WindowShouldCloseSubscriptionCallback, ) { let mut app = self.upgrade(); - if let Some(window) = self.windows.get_mut(&window_id) { + if let Some(window) = self.windows.get_mut(&window.id()) { window .platform_window .on_should_close(Box::new(move || app.update(|cx| callback(cx)))) } } - fn handle_window_moved(&mut self, window_id: usize) { - self.update_window(window_id, |cx| { + fn handle_window_moved(&mut self, window: AnyWindowHandle) { + self.update_window(window, |cx| { if let Some(display) = cx.window_display_uuid() { let bounds = cx.window_bounds(); cx.window_bounds_observations .clone() - .emit(window_id, move |callback| { + .emit(window.id(), move |callback| { callback(bounds, display, cx); true }); @@ -2097,10 +2087,10 @@ impl AppContext { }); } - pub fn focus(&mut self, window_id: usize, view_id: Option) { + pub fn focus(&mut self, window: AnyWindowHandle, view_id: Option) { self.pending_effects .push_back(Effect::Focus(FocusEffect::View { - window_id, + window, view_id, is_forced: false, })); @@ -2185,40 +2175,40 @@ impl BorrowAppContext for AppContext { impl BorrowWindowContext for AppContext { type Result = Option; - fn read_window(&self, window_id: usize, f: F) -> Self::Result + fn read_window(&self, window: AnyWindowHandle, f: F) -> Self::Result where F: FnOnce(&WindowContext) -> T, { - AppContext::read_window(self, window_id, f) + AppContext::read_window(self, window, f) } - fn read_window_optional(&self, window_id: usize, f: F) -> Option + fn read_window_optional(&self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option, { - AppContext::read_window(self, window_id, f).flatten() + AppContext::read_window(self, window, f).flatten() } - fn update_window(&mut self, window_id: usize, f: F) -> Self::Result + fn update_window(&mut self, handle: AnyWindowHandle, f: F) -> Self::Result where F: FnOnce(&mut WindowContext) -> T, { self.update(|app_context| { - let mut window = app_context.windows.remove(&window_id)?; - let mut window_context = WindowContext::mutable(app_context, &mut window, window_id); + let mut window = app_context.windows.remove(&handle.id())?; + let mut window_context = WindowContext::mutable(app_context, &mut window, handle); let result = f(&mut window_context); if !window_context.removed { - app_context.windows.insert(window_id, window); + app_context.windows.insert(handle.id(), window); } Some(result) }) } - fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + fn update_window_optional(&mut self, handle: AnyWindowHandle, f: F) -> Option where F: FnOnce(&mut WindowContext) -> Option, { - AppContext::update_window(self, window_id, f).flatten() + AppContext::update_window(self, handle, f).flatten() } } @@ -2242,22 +2232,22 @@ pub struct WindowInvalidation { #[derive(Debug)] pub enum FocusEffect { View { - window_id: usize, + window: AnyWindowHandle, view_id: Option, is_forced: bool, }, ViewParent { - window_id: usize, + window: AnyWindowHandle, view_id: usize, is_forced: bool, }, } impl FocusEffect { - fn window_id(&self) -> usize { + fn window(&self) -> AnyWindowHandle { match self { - FocusEffect::View { window_id, .. } => *window_id, - FocusEffect::ViewParent { window_id, .. } => *window_id, + FocusEffect::View { window, .. } => *window, + FocusEffect::ViewParent { window, .. } => *window, } } @@ -2303,7 +2293,7 @@ pub enum Effect { model_id: usize, }, ViewNotification { - window_id: usize, + window: AnyWindowHandle, view_id: usize, }, Deferred { @@ -2328,36 +2318,36 @@ pub enum Effect { callback: FocusObservationCallback, }, ResizeWindow { - window_id: usize, + window: AnyWindowHandle, }, MoveWindow { - window_id: usize, + window: AnyWindowHandle, }, ActivateWindow { - window_id: usize, + window: AnyWindowHandle, is_active: bool, }, WindowActivationObservation { - window_id: usize, + window: AnyWindowHandle, subscription_id: usize, callback: WindowActivationCallback, }, FullscreenWindow { - window_id: usize, + window: AnyWindowHandle, is_fullscreen: bool, }, WindowFullscreenObservation { - window_id: usize, + window: AnyWindowHandle, subscription_id: usize, callback: WindowFullscreenCallback, }, WindowBoundsObservation { - window_id: usize, + window: AnyWindowHandle, subscription_id: usize, callback: WindowBoundsCallback, }, Keystroke { - window_id: usize, + window: AnyWindowHandle, keystroke: Keystroke, handled_by: Option>, result: MatchResult, @@ -2367,7 +2357,7 @@ pub enum Effect { action_id: TypeId, }, WindowShouldCloseSubscription { - window_id: usize, + window: AnyWindowHandle, callback: WindowShouldCloseSubscriptionCallback, }, ActiveLabeledTasksChanged, @@ -2419,9 +2409,9 @@ impl Debug for Effect { .debug_struct("Effect::ModelNotification") .field("model_id", model_id) .finish(), - Effect::ViewNotification { window_id, view_id } => f + Effect::ViewNotification { window, view_id } => f .debug_struct("Effect::ViewNotification") - .field("window_id", window_id) + .field("window_id", &window.id()) .field("view_id", view_id) .finish(), Effect::GlobalNotification { type_id } => f @@ -2451,71 +2441,68 @@ impl Debug for Effect { .debug_struct("Effect::ActionDispatchNotification") .field("action_id", action_id) .finish(), - Effect::ResizeWindow { window_id } => f + Effect::ResizeWindow { window } => f .debug_struct("Effect::RefreshWindow") - .field("window_id", window_id) + .field("window_id", &window.id()) .finish(), - Effect::MoveWindow { window_id } => f + Effect::MoveWindow { window } => f .debug_struct("Effect::MoveWindow") - .field("window_id", window_id) + .field("window_id", &window.id()) .finish(), Effect::WindowActivationObservation { - window_id, + window, subscription_id, .. } => f .debug_struct("Effect::WindowActivationObservation") - .field("window_id", window_id) + .field("window_id", &window.id()) .field("subscription_id", subscription_id) .finish(), - Effect::ActivateWindow { - window_id, - is_active, - } => f + Effect::ActivateWindow { window, is_active } => f .debug_struct("Effect::ActivateWindow") - .field("window_id", window_id) + .field("window_id", &window.id()) .field("is_active", is_active) .finish(), Effect::FullscreenWindow { - window_id, + window, is_fullscreen, } => f .debug_struct("Effect::FullscreenWindow") - .field("window_id", window_id) + .field("window_id", &window.id()) .field("is_fullscreen", is_fullscreen) .finish(), Effect::WindowFullscreenObservation { - window_id, + window, subscription_id, callback: _, } => f .debug_struct("Effect::WindowFullscreenObservation") - .field("window_id", window_id) + .field("window_id", &window.id()) .field("subscription_id", subscription_id) .finish(), Effect::WindowBoundsObservation { - window_id, + window, subscription_id, callback: _, } => f .debug_struct("Effect::WindowBoundsObservation") - .field("window_id", window_id) + .field("window_id", &window.id()) .field("subscription_id", subscription_id) .finish(), Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(), - Effect::WindowShouldCloseSubscription { window_id, .. } => f + Effect::WindowShouldCloseSubscription { window, .. } => f .debug_struct("Effect::WindowShouldCloseSubscription") - .field("window_id", window_id) + .field("window_id", &window.id()) .finish(), Effect::Keystroke { - window_id, + window, keystroke, handled_by, result, } => f .debug_struct("Effect::Keystroke") - .field("window_id", window_id) + .field("window_id", &window.id()) .field("keystroke", keystroke) .field( "keystroke", @@ -2613,9 +2600,14 @@ pub trait AnyView { cx: &mut WindowContext, view_id: usize, ); - fn any_handle(&self, window_id: usize, view_id: usize, cx: &AppContext) -> AnyViewHandle { + fn any_handle( + &self, + window: AnyWindowHandle, + view_id: usize, + cx: &AppContext, + ) -> AnyViewHandle { AnyViewHandle::new( - window_id, + window, view_id, self.as_any().type_id(), cx.ref_counts.clone(), @@ -2653,7 +2645,7 @@ where fn render(&mut self, cx: &mut WindowContext, view_id: usize) -> Box { let mut view_context = ViewContext::mutable(cx, view_id); let element = V::render(self, &mut view_context); - let view = WeakViewHandle::new(cx.window_id, view_id); + let view = WeakViewHandle::new(cx.window_handle, view_id); Box::new(RootElement::new(element, view)) } @@ -2664,11 +2656,11 @@ where } else { let focused_type = cx .views_metadata - .get(&(cx.window_id, focused_id)) + .get(&(cx.window_handle.id(), focused_id)) .unwrap() .type_id; AnyViewHandle::new( - cx.window_id, + cx.window_handle, focused_id, focused_type, cx.ref_counts.clone(), @@ -2684,11 +2676,11 @@ where } else { let blurred_type = cx .views_metadata - .get(&(cx.window_id, blurred_id)) + .get(&(cx.window_handle.id(), blurred_id)) .unwrap() .type_id; AnyViewHandle::new( - cx.window_id, + cx.window_handle, blurred_id, blurred_type, cx.ref_counts.clone(), @@ -2995,18 +2987,22 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { pub fn handle(&self) -> ViewHandle { ViewHandle::new( - self.window_id, + self.window_handle, self.view_id, &self.window_context.ref_counts, ) } pub fn weak_handle(&self) -> WeakViewHandle { - WeakViewHandle::new(self.window_id, self.view_id) + WeakViewHandle::new(self.window_handle, self.view_id) } pub fn window_id(&self) -> usize { - self.window_id + self.window_handle.id() + } + + pub fn window(&self) -> AnyWindowHandle { + self.window_handle } pub fn view_id(&self) -> usize { @@ -3054,11 +3050,11 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { } pub fn focus_parent(&mut self) { - let window_id = self.window_id; + let window = self.window_handle; let view_id = self.view_id; self.pending_effects .push_back(Effect::Focus(FocusEffect::ViewParent { - window_id, + window, view_id, is_forced: false, })); @@ -3072,13 +3068,13 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { where F: 'static + FnMut(&mut V, &mut ViewContext) -> bool, { - let window_id = self.window_id; + let window = self.window_handle; let view = self.weak_handle(); self.pending_effects .push_back(Effect::WindowShouldCloseSubscription { - window_id, + window, callback: Box::new(move |cx| { - cx.update_window(window_id, |cx| { + cx.update_window(window, |cx| { if let Some(view) = view.upgrade(cx) { view.update(cx, |view, cx| callback(view, cx)) } else { @@ -3117,11 +3113,11 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { H: Handle, F: 'static + FnMut(&mut V, H, &mut ViewContext), { - let window_id = self.window_id; + let window = self.window_handle; let observer = self.weak_handle(); self.window_context .observe_internal(handle, move |observed, cx| { - cx.update_window(window_id, |cx| { + cx.update_window(window, |cx| { if let Some(observer) = observer.upgrade(cx) { observer.update(cx, |observer, cx| { callback(observer, observed, cx); @@ -3140,10 +3136,10 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { G: Any, F: 'static + FnMut(&mut V, &mut ViewContext), { - let window_id = self.window_id; + let window = self.window_handle; let observer = self.weak_handle(); self.window_context.observe_global::(move |cx| { - cx.update_window(window_id, |cx| { + cx.update_window(window, |cx| { if let Some(observer) = observer.upgrade(cx) { observer.update(cx, |observer, cx| callback(observer, cx)); } @@ -3176,11 +3172,11 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { H: Handle, F: 'static + FnMut(&mut V, &E, &mut ViewContext), { - let window_id = self.window_id; + let window = self.window_handle; let observer = self.weak_handle(); self.window_context .observe_release(handle, move |released, cx| { - cx.update_window(window_id, |cx| { + cx.update_window(window, |cx| { if let Some(observer) = observer.upgrade(cx) { observer.update(cx, |observer, cx| { callback(observer, released, cx); @@ -3194,10 +3190,10 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { where F: 'static + FnMut(&mut V, TypeId, &mut ViewContext), { - let window_id = self.window_id; + let window = self.window_handle; let observer = self.weak_handle(); self.window_context.observe_actions(move |action_id, cx| { - cx.update_window(window_id, |cx| { + cx.update_window(window, |cx| { if let Some(observer) = observer.upgrade(cx) { observer.update(cx, |observer, cx| { callback(observer, action_id, cx); @@ -3289,10 +3285,10 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { where F: 'static + FnMut(&mut V, &mut ViewContext), { - let window_id = self.window_id; + let window = self.window_handle; let observer = self.weak_handle(); self.window_context.observe_active_labeled_tasks(move |cx| { - cx.update_window(window_id, |cx| { + cx.update_window(window, |cx| { if let Some(observer) = observer.upgrade(cx) { observer.update(cx, |observer, cx| { callback(observer, cx); @@ -3316,9 +3312,9 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { } pub fn notify(&mut self) { - let window_id = self.window_id; + let window = self.window_handle; let view_id = self.view_id; - self.window_context.notify_view(window_id, view_id); + self.window_context.notify_view(window, view_id); } pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut V, &mut ViewContext)) { @@ -3331,10 +3327,10 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { &mut self, callback: impl 'static + FnOnce(&mut V, &mut ViewContext), ) { - let window_id = self.window_id; + let window = self.window_handle; let handle = self.handle(); self.window_context.after_window_update(move |cx| { - cx.update_window(window_id, |cx| { + cx.update_window(window, |cx| { handle.update(cx, |view, cx| { callback(view, cx); }) @@ -3422,30 +3418,30 @@ impl BorrowAppContext for ViewContext<'_, '_, V> { impl BorrowWindowContext for ViewContext<'_, '_, V> { type Result = T; - fn read_window T>(&self, window_id: usize, f: F) -> T { - BorrowWindowContext::read_window(&*self.window_context, window_id, f) + fn read_window T>(&self, window: AnyWindowHandle, f: F) -> T { + BorrowWindowContext::read_window(&*self.window_context, window, f) } - fn read_window_optional(&self, window_id: usize, f: F) -> Option + fn read_window_optional(&self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option, { - BorrowWindowContext::read_window_optional(&*self.window_context, window_id, f) + BorrowWindowContext::read_window_optional(&*self.window_context, window, f) } fn update_window T>( &mut self, - window_id: usize, + window: AnyWindowHandle, f: F, ) -> T { - BorrowWindowContext::update_window(&mut *self.window_context, window_id, f) + BorrowWindowContext::update_window(&mut *self.window_context, window, f) } - fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + fn update_window_optional(&mut self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&mut WindowContext) -> Option, { - BorrowWindowContext::update_window_optional(&mut *self.window_context, window_id, f) + BorrowWindowContext::update_window_optional(&mut *self.window_context, window, f) } } @@ -3483,11 +3479,11 @@ impl<'a, 'b, 'c, V: View> LayoutContext<'a, 'b, 'c, V> { ) -> Option> { self.notify_if_view_ancestors_change(view_id); - let window_id = self.window_id; + let window = self.window_handle; let mut contexts = Vec::new(); let mut handler_depth = None; for (i, view_id) in self.ancestors(view_id).enumerate() { - if let Some(view_metadata) = self.views_metadata.get(&(window_id, view_id)) { + if let Some(view_metadata) = self.views_metadata.get(&(window.id(), view_id)) { if let Some(actions) = self.actions.get(&view_metadata.type_id) { if actions.contains_key(&action.id()) { handler_depth = Some(i); @@ -3547,30 +3543,30 @@ impl BorrowAppContext for LayoutContext<'_, '_, '_, V> { impl BorrowWindowContext for LayoutContext<'_, '_, '_, V> { type Result = T; - fn read_window T>(&self, window_id: usize, f: F) -> T { - BorrowWindowContext::read_window(&*self.view_context, window_id, f) + fn read_window T>(&self, window: AnyWindowHandle, f: F) -> T { + BorrowWindowContext::read_window(&*self.view_context, window, f) } - fn read_window_optional(&self, window_id: usize, f: F) -> Option + fn read_window_optional(&self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option, { - BorrowWindowContext::read_window_optional(&*self.view_context, window_id, f) + BorrowWindowContext::read_window_optional(&*self.view_context, window, f) } fn update_window T>( &mut self, - window_id: usize, + window: AnyWindowHandle, f: F, ) -> T { - BorrowWindowContext::update_window(&mut *self.view_context, window_id, f) + BorrowWindowContext::update_window(&mut *self.view_context, window, f) } - fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + fn update_window_optional(&mut self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&mut WindowContext) -> Option, { - BorrowWindowContext::update_window_optional(&mut *self.view_context, window_id, f) + BorrowWindowContext::update_window_optional(&mut *self.view_context, window, f) } } @@ -3619,30 +3615,30 @@ impl BorrowAppContext for EventContext<'_, '_, '_, V> { impl BorrowWindowContext for EventContext<'_, '_, '_, V> { type Result = T; - fn read_window T>(&self, window_id: usize, f: F) -> T { - BorrowWindowContext::read_window(&*self.view_context, window_id, f) + fn read_window T>(&self, window: AnyWindowHandle, f: F) -> T { + BorrowWindowContext::read_window(&*self.view_context, window, f) } - fn read_window_optional(&self, window_id: usize, f: F) -> Option + fn read_window_optional(&self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option, { - BorrowWindowContext::read_window_optional(&*self.view_context, window_id, f) + BorrowWindowContext::read_window_optional(&*self.view_context, window, f) } fn update_window T>( &mut self, - window_id: usize, + window: AnyWindowHandle, f: F, ) -> T { - BorrowWindowContext::update_window(&mut *self.view_context, window_id, f) + BorrowWindowContext::update_window(&mut *self.view_context, window, f) } - fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + fn update_window_optional(&mut self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&mut WindowContext) -> Option, { - BorrowWindowContext::update_window_optional(&mut *self.view_context, window_id, f) + BorrowWindowContext::update_window_optional(&mut *self.view_context, window, f) } } @@ -3977,7 +3973,7 @@ impl WindowHandle { C: BorrowWindowContext, F: FnOnce(&mut V, &mut ViewContext) -> R, { - cx.update_window(self.id(), |cx| { + cx.update_window(self.any_handle, |cx| { cx.root_view() .clone() .downcast::() @@ -3991,7 +3987,7 @@ impl WindowHandle { C: BorrowWindowContext, F: FnOnce(&mut ViewContext) -> V, { - cx.update_window(self.id(), |cx| { + cx.update_window(self.any_handle, |cx| { let root_view = self.add_view(cx, |cx| build_root(cx)); cx.window.root_view = Some(root_view.clone().into_any()); cx.window.focused_view_id = Some(root_view.id()); @@ -4006,7 +4002,7 @@ impl Into for WindowHandle { } } -#[derive(Copy, Clone, Eq, PartialEq, Hash)] +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct AnyWindowHandle { window_id: usize, root_view_type: TypeId, @@ -4029,7 +4025,7 @@ impl AnyWindowHandle { C: BorrowWindowContext, F: FnOnce(&WindowContext) -> R, { - cx.read_window(self.window_id, |cx| read(cx)) + cx.read_window(*self, |cx| read(cx)) } pub fn read_optional_with(&self, cx: &C, read: F) -> Option @@ -4037,7 +4033,7 @@ impl AnyWindowHandle { C: BorrowWindowContext, F: FnOnce(&WindowContext) -> Option, { - cx.read_window_optional(self.window_id, |cx| read(cx)) + cx.read_window_optional(*self, |cx| read(cx)) } pub fn update(&self, cx: &mut C, update: F) -> C::Result @@ -4045,7 +4041,7 @@ impl AnyWindowHandle { C: BorrowWindowContext, F: FnOnce(&mut WindowContext) -> R, { - cx.update_window(self.window_id, update) + cx.update_window(*self, update) } pub fn update_optional(&self, cx: &mut C, update: F) -> Option @@ -4053,7 +4049,7 @@ impl AnyWindowHandle { C: BorrowWindowContext, F: FnOnce(&mut WindowContext) -> Option, { - cx.update_window_optional(self.window_id, update) + cx.update_window_optional(*self, update) } pub fn add_view(&self, cx: &mut C, build_view: F) -> C::Result> @@ -4092,24 +4088,22 @@ impl AnyWindowHandle { pub fn simulate_activation(&self, cx: &mut TestAppContext) { self.update(cx, |cx| { let other_window_ids = cx - .windows - .keys() - .filter(|window_id| **window_id != self.window_id) - .copied() + .windows() + .filter(|window| *window != *self) .collect::>(); - for window_id in other_window_ids { - cx.window_changed_active_status(window_id, false) + for window in other_window_ids { + cx.window_changed_active_status(window, false) } - cx.window_changed_active_status(self.window_id, true) + cx.window_changed_active_status(*self, true) }); } #[cfg(any(test, feature = "test-support"))] pub fn simulate_deactivation(&self, cx: &mut TestAppContext) { self.update(cx, |cx| { - cx.window_changed_active_status(self.window_id, false); + cx.window_changed_active_status(*self, false); }) } } @@ -4129,20 +4123,15 @@ impl Deref for ViewHandle { } impl ViewHandle { - fn new(window_id: usize, view_id: usize, ref_counts: &Arc>) -> Self { + fn new(window: AnyWindowHandle, view_id: usize, ref_counts: &Arc>) -> Self { Self { - any_handle: AnyViewHandle::new( - window_id, - view_id, - TypeId::of::(), - ref_counts.clone(), - ), + any_handle: AnyViewHandle::new(window, view_id, TypeId::of::(), ref_counts.clone()), view_type: PhantomData, } } pub fn downgrade(&self) -> WeakViewHandle { - WeakViewHandle::new(self.window_id, self.view_id) + WeakViewHandle::new(self.window, self.view_id) } pub fn into_any(self) -> AnyViewHandle { @@ -4150,13 +4139,11 @@ impl ViewHandle { } pub fn window_id(&self) -> usize { - self.window_id + self.window.id() } - pub fn window(&self, cx: &C) -> C::Result { - cx.read_window(self.window_id, |cx| { - AnyWindowHandle::new(self.window_id, cx.window.root_view.type_id()) - }) + pub fn window(&self) -> AnyWindowHandle { + self.window } pub fn id(&self) -> usize { @@ -4172,7 +4159,7 @@ impl ViewHandle { C: BorrowWindowContext, F: FnOnce(&T, &ViewContext) -> S, { - cx.read_window(self.window_id, |cx| { + cx.read_window(self.window, |cx| { let cx = ViewContext::immutable(cx, self.view_id); read(cx.read_view(self), &cx) }) @@ -4185,7 +4172,7 @@ impl ViewHandle { { let mut update = Some(update); - cx.update_window(self.window_id, |cx| { + cx.update_window(self.window, |cx| { cx.update_view(self, &mut |view, cx| { let update = update.take().unwrap(); update(view, cx) @@ -4200,31 +4187,31 @@ impl ViewHandle { impl Clone for ViewHandle { fn clone(&self) -> Self { - ViewHandle::new(self.window_id, self.view_id, &self.ref_counts) + ViewHandle::new(self.window, self.view_id, &self.ref_counts) } } impl PartialEq for ViewHandle { fn eq(&self, other: &Self) -> bool { - self.window_id == other.window_id && self.view_id == other.view_id + self.window == other.window && self.view_id == other.view_id } } impl PartialEq for ViewHandle { fn eq(&self, other: &AnyViewHandle) -> bool { - self.window_id == other.window_id && self.view_id == other.view_id + self.window == other.window && self.view_id == other.view_id } } impl PartialEq> for ViewHandle { fn eq(&self, other: &WeakViewHandle) -> bool { - self.window_id == other.window_id && self.view_id == other.view_id + self.window == other.window && self.view_id == other.view_id } } impl PartialEq> for WeakViewHandle { fn eq(&self, other: &ViewHandle) -> bool { - self.window_id == other.window_id && self.view_id == other.view_id + self.window == other.window && self.view_id == other.view_id } } @@ -4232,7 +4219,7 @@ impl Eq for ViewHandle {} impl Hash for ViewHandle { fn hash(&self, state: &mut H) { - self.window_id.hash(state); + self.window.hash(state); self.view_id.hash(state); } } @@ -4240,7 +4227,7 @@ impl Hash for ViewHandle { impl Debug for ViewHandle { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct(&format!("ViewHandle<{}>", type_name::())) - .field("window_id", &self.window_id) + .field("window_id", &self.window) .field("view_id", &self.view_id) .finish() } @@ -4254,7 +4241,7 @@ impl Handle for ViewHandle { } fn location(&self) -> EntityLocation { - EntityLocation::View(self.window_id, self.view_id) + EntityLocation::View(self.window.id(), self.view_id) } fn downgrade(&self) -> Self::Weak { @@ -4270,7 +4257,7 @@ impl Handle for ViewHandle { } pub struct AnyViewHandle { - window_id: usize, + window: AnyWindowHandle, view_id: usize, view_type: TypeId, ref_counts: Arc>, @@ -4281,12 +4268,12 @@ pub struct AnyViewHandle { impl AnyViewHandle { fn new( - window_id: usize, + window: AnyWindowHandle, view_id: usize, view_type: TypeId, ref_counts: Arc>, ) -> Self { - ref_counts.lock().inc_view(window_id, view_id); + ref_counts.lock().inc_view(window.id(), view_id); #[cfg(any(test, feature = "test-support"))] let handle_id = ref_counts @@ -4296,7 +4283,7 @@ impl AnyViewHandle { .handle_created(None, view_id); Self { - window_id, + window, view_id, view_type, ref_counts, @@ -4305,8 +4292,12 @@ impl AnyViewHandle { } } + pub fn window(&self) -> AnyWindowHandle { + self.window + } + pub fn window_id(&self) -> usize { - self.window_id + self.window.id() } pub fn id(&self) -> usize { @@ -4338,7 +4329,7 @@ impl AnyViewHandle { pub fn downgrade(&self) -> AnyWeakViewHandle { AnyWeakViewHandle { - window_id: self.window_id, + window: self.window, view_id: self.view_id, view_type: self.view_type, } @@ -4350,7 +4341,7 @@ impl AnyViewHandle { pub fn debug_json<'a, 'b>(&self, cx: &'b WindowContext<'a>) -> serde_json::Value { cx.views - .get(&(self.window_id, self.view_id)) + .get(&(self.window.id(), self.view_id)) .map_or_else(|| serde_json::Value::Null, |view| view.debug_json(cx)) } } @@ -4358,7 +4349,7 @@ impl AnyViewHandle { impl Clone for AnyViewHandle { fn clone(&self) -> Self { Self::new( - self.window_id, + self.window, self.view_id, self.view_type, self.ref_counts.clone(), @@ -4368,13 +4359,13 @@ impl Clone for AnyViewHandle { impl PartialEq for AnyViewHandle { fn eq(&self, other: &Self) -> bool { - self.window_id == other.window_id && self.view_id == other.view_id + self.window == other.window && self.view_id == other.view_id } } impl PartialEq> for AnyViewHandle { fn eq(&self, other: &ViewHandle) -> bool { - self.window_id == other.window_id && self.view_id == other.view_id + self.window == other.window && self.view_id == other.view_id } } @@ -4382,7 +4373,7 @@ impl Drop for AnyViewHandle { fn drop(&mut self) { self.ref_counts .lock() - .dec_view(self.window_id, self.view_id); + .dec_view(self.window.id(), self.view_id); #[cfg(any(test, feature = "test-support"))] self.ref_counts .lock() @@ -4395,7 +4386,7 @@ impl Drop for AnyViewHandle { impl Debug for AnyViewHandle { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("AnyViewHandle") - .field("window_id", &self.window_id) + .field("window_id", &self.window.id()) .field("view_id", &self.view_id) .finish() } @@ -4531,10 +4522,10 @@ impl WeakHandle for WeakViewHandle { } impl WeakViewHandle { - fn new(window_id: usize, view_id: usize) -> Self { + fn new(window: AnyWindowHandle, view_id: usize) -> Self { Self { any_handle: AnyWeakViewHandle { - window_id, + window, view_id, view_type: TypeId::of::(), }, @@ -4546,8 +4537,12 @@ impl WeakViewHandle { self.view_id } + pub fn window(&self) -> AnyWindowHandle { + self.window + } + pub fn window_id(&self) -> usize { - self.window_id + self.window.id() } pub fn into_any(self) -> AnyWeakViewHandle { @@ -4567,7 +4562,7 @@ impl WeakViewHandle { let handle = cx .upgrade_view_handle(self) .ok_or_else(|| anyhow!("view {} was dropped", V::ui_name()))?; - cx.read_window(self.window_id, |cx| handle.read_with(cx, read)) + cx.read_window(self.window, |cx| handle.read_with(cx, read)) .ok_or_else(|| anyhow!("window was removed")) }) } @@ -4581,7 +4576,7 @@ impl WeakViewHandle { let handle = cx .upgrade_view_handle(self) .ok_or_else(|| anyhow!("view {} was dropped", V::ui_name()))?; - cx.update_window(self.window_id, |cx| handle.update(cx, update)) + cx.update_window(self.window, |cx| handle.update(cx, update)) .ok_or_else(|| anyhow!("window was removed")) }) } @@ -4606,7 +4601,7 @@ impl Clone for WeakViewHandle { impl PartialEq for WeakViewHandle { fn eq(&self, other: &Self) -> bool { - self.window_id == other.window_id && self.view_id == other.view_id + self.window == other.window && self.view_id == other.view_id } } @@ -4620,7 +4615,7 @@ impl Hash for WeakViewHandle { #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub struct AnyWeakViewHandle { - window_id: usize, + window: AnyWindowHandle, view_id: usize, view_type: TypeId, } @@ -4652,7 +4647,7 @@ impl AnyWeakViewHandle { impl Hash for AnyWeakViewHandle { fn hash(&self, state: &mut H) { - self.window_id.hash(state); + self.window.hash(state); self.view_id.hash(state); self.view_type.hash(state); } @@ -6393,7 +6388,7 @@ mod tests { // Check that global actions do not have a binding, even if a binding does exist in another view assert_eq!( - &available_actions(window.id(), view_1.id(), cx), + &available_actions(window.into(), view_1.id(), cx), &[ ("test::Action1", vec![Keystroke::parse("a").unwrap()]), ("test::GlobalAction", vec![]) @@ -6402,7 +6397,7 @@ mod tests { // Check that view 1 actions and bindings are available even when called from view 2 assert_eq!( - &available_actions(window.id(), view_2.id(), cx), + &available_actions(window.into(), view_2.id(), cx), &[ ("test::Action1", vec![Keystroke::parse("a").unwrap()]), ("test::Action2", vec![Keystroke::parse("b").unwrap()]), @@ -6412,11 +6407,11 @@ mod tests { // Produces a list of actions and key bindings fn available_actions( - window_id: usize, + window: AnyWindowHandle, view_id: usize, cx: &TestAppContext, ) -> Vec<(&'static str, Vec)> { - cx.available_actions(window_id, view_id) + cx.available_actions(window.into(), view_id) .into_iter() .map(|(action_name, _, bindings)| { ( @@ -6465,7 +6460,7 @@ mod tests { ]); }); - let actions = cx.available_actions(window.id(), view.id()); + let actions = cx.available_actions(window.into(), view.id()); assert_eq!( actions[0].1.as_any().downcast_ref::(), Some(&ActionWithArg { arg: false }) diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index ff988607b0..b1729d89b8 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -72,8 +72,8 @@ impl TestAppContext { cx } - pub fn dispatch_action(&mut self, window_id: usize, action: A) { - self.update_window(window_id, |window| { + pub fn dispatch_action(&mut self, window: AnyWindowHandle, action: A) { + self.update_window(window, |window| { window.dispatch_action(window.focused_view_id(), &action); }) .expect("window not found"); @@ -81,10 +81,10 @@ impl TestAppContext { pub fn available_actions( &self, - window_id: usize, + window: AnyWindowHandle, view_id: usize, ) -> Vec<(&'static str, Box, SmallVec<[Binding; 1]>)> { - self.read_window(window_id, |cx| cx.available_actions(view_id)) + self.read_window(window, |cx| cx.available_actions(view_id)) .unwrap_or_default() } @@ -127,18 +127,18 @@ impl TestAppContext { pub fn read_window T>( &self, - window_id: usize, + window: AnyWindowHandle, callback: F, ) -> Option { - self.cx.borrow().read_window(window_id, callback) + self.cx.borrow().read_window(window, callback) } pub fn update_window T>( &mut self, - window_id: usize, + window: AnyWindowHandle, callback: F, ) -> Option { - self.cx.borrow_mut().update_window(window_id, callback) + self.cx.borrow_mut().update_window(window, callback) } pub fn add_model(&mut self, build_model: F) -> ModelHandle @@ -317,36 +317,36 @@ impl BorrowAppContext for TestAppContext { impl BorrowWindowContext for TestAppContext { type Result = T; - fn read_window T>(&self, window_id: usize, f: F) -> T { + fn read_window T>(&self, window: AnyWindowHandle, f: F) -> T { self.cx .borrow() - .read_window(window_id, f) + .read_window(window, f) .expect("window was closed") } - fn read_window_optional(&self, window_id: usize, f: F) -> Option + fn read_window_optional(&self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option, { - BorrowWindowContext::read_window(self, window_id, f) + BorrowWindowContext::read_window(self, window, f) } fn update_window T>( &mut self, - window_id: usize, + window: AnyWindowHandle, f: F, ) -> T { self.cx .borrow_mut() - .update_window(window_id, f) + .update_window(window, f) .expect("window was closed") } - fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + fn update_window_optional(&mut self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&mut WindowContext) -> Option, { - BorrowWindowContext::update_window(self, window_id, f) + BorrowWindowContext::update_window(self, window, f) } } diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 70d02c1fa1..44a3c5cfdc 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -13,9 +13,9 @@ use crate::{ }, text_layout::TextLayoutCache, util::post_inc, - Action, AnyView, AnyViewHandle, AppContext, BorrowAppContext, BorrowWindowContext, Effect, - Element, Entity, Handle, LayoutContext, MouseRegion, MouseRegionId, SceneBuilder, Subscription, - View, ViewContext, ViewHandle, WindowHandle, WindowInvalidation, + Action, AnyView, AnyViewHandle, AnyWindowHandle, AppContext, BorrowAppContext, + BorrowWindowContext, Effect, Element, Entity, Handle, LayoutContext, MouseRegion, + MouseRegionId, SceneBuilder, Subscription, View, ViewContext, ViewHandle, WindowInvalidation, }; use anyhow::{anyhow, bail, Result}; use collections::{HashMap, HashSet}; @@ -60,7 +60,7 @@ pub struct Window { impl Window { pub fn new( - window_id: usize, + handle: AnyWindowHandle, platform_window: Box, cx: &mut AppContext, build_view: F, @@ -92,7 +92,7 @@ impl Window { appearance, }; - let mut window_context = WindowContext::mutable(cx, &mut window, window_id); + let mut window_context = WindowContext::mutable(cx, &mut window, handle); let root_view = window_context.add_view(|cx| build_view(cx)); if let Some(invalidation) = window_context.window.invalidation.take() { window_context.invalidate(invalidation, appearance); @@ -113,7 +113,7 @@ impl Window { pub struct WindowContext<'a> { pub(crate) app_context: Reference<'a, AppContext>, pub(crate) window: Reference<'a, Window>, - pub(crate) window_id: usize, + pub(crate) window_handle: AnyWindowHandle, pub(crate) removed: bool, } @@ -144,15 +144,15 @@ impl BorrowAppContext for WindowContext<'_> { impl BorrowWindowContext for WindowContext<'_> { type Result = T; - fn read_window T>(&self, window_id: usize, f: F) -> T { - if self.window_id == window_id { + fn read_window T>(&self, handle: AnyWindowHandle, f: F) -> T { + if self.window_handle == handle { f(self) } else { panic!("read_with called with id of window that does not belong to this context") } } - fn read_window_optional(&self, window_id: usize, f: F) -> Option + fn read_window_optional(&self, window_id: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option, { @@ -161,21 +161,21 @@ impl BorrowWindowContext for WindowContext<'_> { fn update_window T>( &mut self, - window_id: usize, + handle: AnyWindowHandle, f: F, ) -> T { - if self.window_id == window_id { + if self.window_handle == handle { f(self) } else { panic!("update called with id of window that does not belong to this context") } } - fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + fn update_window_optional(&mut self, handle: AnyWindowHandle, f: F) -> Option where F: FnOnce(&mut WindowContext) -> Option, { - BorrowWindowContext::update_window(self, window_id, f) + BorrowWindowContext::update_window(self, handle, f) } } @@ -183,21 +183,25 @@ impl<'a> WindowContext<'a> { pub fn mutable( app_context: &'a mut AppContext, window: &'a mut Window, - window_id: usize, + handle: AnyWindowHandle, ) -> Self { Self { app_context: Reference::Mutable(app_context), window: Reference::Mutable(window), - window_id, + window_handle: handle, removed: false, } } - pub fn immutable(app_context: &'a AppContext, window: &'a Window, window_id: usize) -> Self { + pub fn immutable( + app_context: &'a AppContext, + window: &'a Window, + handle: AnyWindowHandle, + ) -> Self { Self { app_context: Reference::Immutable(app_context), window: Reference::Immutable(window), - window_id, + window_handle: handle, removed: false, } } @@ -207,17 +211,11 @@ impl<'a> WindowContext<'a> { } pub fn window_id(&self) -> usize { - self.window_id + self.window_handle.id() } - pub fn window(&self) -> Option> { - self.window.root_view.as_ref().and_then(|root_view| { - if root_view.is::() { - Some(WindowHandle::new(self.window_id)) - } else { - None - } - }) + pub fn window(&self) -> AnyWindowHandle { + self.window_handle } pub fn app_context(&mut self) -> &mut AppContext { @@ -240,10 +238,10 @@ impl<'a> WindowContext<'a> { where F: FnOnce(&mut dyn AnyView, &mut Self) -> T, { - let window_id = self.window_id; - let mut view = self.views.remove(&(window_id, view_id))?; + let handle = self.window_handle; + let mut view = self.views.remove(&(handle.id(), view_id))?; let result = f(view.as_mut(), self); - self.views.insert((window_id, view_id), view); + self.views.insert((handle.id(), view_id), view); Some(result) } @@ -268,9 +266,9 @@ impl<'a> WindowContext<'a> { } pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut WindowContext)) { - let window_id = self.window_id; + let handle = self.window_handle; self.app_context.defer(move |cx| { - cx.update_window(window_id, |cx| callback(cx)); + cx.update_window(handle, |cx| callback(cx)); }) } @@ -310,10 +308,10 @@ impl<'a> WindowContext<'a> { H: Handle, F: 'static + FnMut(H, &E::Event, &mut WindowContext) -> bool, { - let window_id = self.window_id; + let window_handle = self.window_handle; self.app_context .subscribe_internal(handle, move |emitter, event, cx| { - cx.update_window(window_id, |cx| callback(emitter, event, cx)) + cx.update_window(window_handle, |cx| callback(emitter, event, cx)) .unwrap_or(false) }) } @@ -322,17 +320,17 @@ impl<'a> WindowContext<'a> { where F: 'static + FnMut(bool, &mut WindowContext) -> bool, { - let window_id = self.window_id; + let handle = self.window_handle; let subscription_id = post_inc(&mut self.next_subscription_id); self.pending_effects .push_back(Effect::WindowActivationObservation { - window_id, + window: handle, subscription_id, callback: Box::new(callback), }); Subscription::WindowActivationObservation( self.window_activation_observations - .subscribe(window_id, subscription_id), + .subscribe(handle.id(), subscription_id), ) } @@ -340,17 +338,17 @@ impl<'a> WindowContext<'a> { where F: 'static + FnMut(bool, &mut WindowContext) -> bool, { - let window_id = self.window_id; + let window = self.window_handle; let subscription_id = post_inc(&mut self.next_subscription_id); self.pending_effects .push_back(Effect::WindowFullscreenObservation { - window_id, + window, subscription_id, callback: Box::new(callback), }); Subscription::WindowActivationObservation( self.window_activation_observations - .subscribe(window_id, subscription_id), + .subscribe(window.id(), subscription_id), ) } @@ -358,17 +356,17 @@ impl<'a> WindowContext<'a> { where F: 'static + FnMut(WindowBounds, Uuid, &mut WindowContext) -> bool, { - let window_id = self.window_id; + let window = self.window_handle; let subscription_id = post_inc(&mut self.next_subscription_id); self.pending_effects .push_back(Effect::WindowBoundsObservation { - window_id, + window, subscription_id, callback: Box::new(callback), }); Subscription::WindowBoundsObservation( self.window_bounds_observations - .subscribe(window_id, subscription_id), + .subscribe(window.id(), subscription_id), ) } @@ -377,13 +375,13 @@ impl<'a> WindowContext<'a> { F: 'static + FnMut(&Keystroke, &MatchResult, Option<&Box>, &mut WindowContext) -> bool, { - let window_id = self.window_id; + let window = self.window_handle; let subscription_id = post_inc(&mut self.next_subscription_id); self.keystroke_observations - .add_callback(window_id, subscription_id, Box::new(callback)); + .add_callback(window.id(), subscription_id, Box::new(callback)); Subscription::KeystrokeObservation( self.keystroke_observations - .subscribe(window_id, subscription_id), + .subscribe(window.id(), subscription_id), ) } @@ -391,11 +389,11 @@ impl<'a> WindowContext<'a> { &self, view_id: usize, ) -> Vec<(&'static str, Box, SmallVec<[Binding; 1]>)> { - let window_id = self.window_id; + let handle = self.window_handle; let mut contexts = Vec::new(); let mut handler_depths_by_action_id = HashMap::::default(); for (depth, view_id) in self.ancestors(view_id).enumerate() { - if let Some(view_metadata) = self.views_metadata.get(&(window_id, view_id)) { + if let Some(view_metadata) = self.views_metadata.get(&(handle.id(), view_id)) { contexts.push(view_metadata.keymap_context.clone()); if let Some(actions) = self.actions.get(&view_metadata.type_id) { handler_depths_by_action_id @@ -440,13 +438,13 @@ impl<'a> WindowContext<'a> { } pub(crate) fn dispatch_keystroke(&mut self, keystroke: &Keystroke) -> bool { - let window_id = self.window_id; + let handle = self.window_handle; if let Some(focused_view_id) = self.focused_view_id() { let dispatch_path = self .ancestors(focused_view_id) .filter_map(|view_id| { self.views_metadata - .get(&(window_id, view_id)) + .get(&(handle.id(), view_id)) .map(|view| (view_id, view.keymap_context.clone())) }) .collect(); @@ -471,15 +469,10 @@ impl<'a> WindowContext<'a> { } }; - self.keystroke( - window_id, - keystroke.clone(), - handled_by, - match_result.clone(), - ); + self.keystroke(handle, keystroke.clone(), handled_by, match_result.clone()); keystroke_handled } else { - self.keystroke(window_id, keystroke.clone(), None, MatchResult::None); + self.keystroke(handle, keystroke.clone(), None, MatchResult::None); false } } @@ -487,7 +480,7 @@ impl<'a> WindowContext<'a> { pub(crate) fn dispatch_event(&mut self, event: Event, event_reused: bool) -> bool { let mut mouse_events = SmallVec::<[_; 2]>::new(); let mut notified_views: HashSet = Default::default(); - let window_id = self.window_id; + let handle = self.window_handle; // 1. Handle platform event. Keyboard events get dispatched immediately, while mouse events // get mapped into the mouse-specific MouseEvent type. @@ -851,19 +844,19 @@ impl<'a> WindowContext<'a> { } for view_id in notified_views { - self.notify_view(window_id, view_id); + self.notify_view(handle, view_id); } any_event_handled } pub(crate) fn dispatch_key_down(&mut self, event: &KeyDownEvent) -> bool { - let window_id = self.window_id; + let handle = self.window_handle; if let Some(focused_view_id) = self.window.focused_view_id { for view_id in self.ancestors(focused_view_id).collect::>() { - if let Some(mut view) = self.views.remove(&(window_id, view_id)) { + if let Some(mut view) = self.views.remove(&(handle.id(), view_id)) { let handled = view.key_down(event, self, view_id); - self.views.insert((window_id, view_id), view); + self.views.insert((handle.id(), view_id), view); if handled { return true; } @@ -877,12 +870,12 @@ impl<'a> WindowContext<'a> { } pub(crate) fn dispatch_key_up(&mut self, event: &KeyUpEvent) -> bool { - let window_id = self.window_id; + let handle = self.window_handle; if let Some(focused_view_id) = self.window.focused_view_id { for view_id in self.ancestors(focused_view_id).collect::>() { - if let Some(mut view) = self.views.remove(&(window_id, view_id)) { + if let Some(mut view) = self.views.remove(&(handle.id(), view_id)) { let handled = view.key_up(event, self, view_id); - self.views.insert((window_id, view_id), view); + self.views.insert((handle.id(), view_id), view); if handled { return true; } @@ -896,12 +889,12 @@ impl<'a> WindowContext<'a> { } pub(crate) fn dispatch_modifiers_changed(&mut self, event: &ModifiersChangedEvent) -> bool { - let window_id = self.window_id; + let handle = self.window_handle; if let Some(focused_view_id) = self.window.focused_view_id { for view_id in self.ancestors(focused_view_id).collect::>() { - if let Some(mut view) = self.views.remove(&(window_id, view_id)) { + if let Some(mut view) = self.views.remove(&(handle.id(), view_id)) { let handled = view.modifiers_changed(event, self, view_id); - self.views.insert((window_id, view_id), view); + self.views.insert((handle.id(), view_id), view); if handled { return true; } @@ -936,14 +929,14 @@ impl<'a> WindowContext<'a> { } pub fn render_view(&mut self, params: RenderParams) -> Result> { - let window_id = self.window_id; + let handle = self.window_handle; let view_id = params.view_id; let mut view = self .views - .remove(&(window_id, view_id)) + .remove(&(handle.id(), view_id)) .ok_or_else(|| anyhow!("view not found"))?; let element = view.render(self, view_id); - self.views.insert((window_id, view_id), view); + self.views.insert((handle.id(), view_id), view); Ok(element) } @@ -971,9 +964,9 @@ impl<'a> WindowContext<'a> { } else if old_parent_id == new_parent_id { current_view_id = *old_parent_id.unwrap(); } else { - let window_id = self.window_id; + let handle = self.window_handle; for view_id_to_notify in view_ids_to_notify { - self.notify_view(window_id, view_id_to_notify); + self.notify_view(handle, view_id_to_notify); } break; } @@ -1141,7 +1134,7 @@ impl<'a> WindowContext<'a> { } pub fn focus(&mut self, view_id: Option) { - self.app_context.focus(self.window_id, view_id); + self.app_context.focus(self.window_handle, view_id); } pub fn window_bounds(&self) -> WindowBounds { @@ -1194,26 +1187,26 @@ impl<'a> WindowContext<'a> { T: View, F: FnOnce(&mut ViewContext) -> Option, { - let window_id = self.window_id; + let handle = self.window_handle; let view_id = post_inc(&mut self.next_id); let mut cx = ViewContext::mutable(self, view_id); let handle = if let Some(view) = build_view(&mut cx) { let mut keymap_context = KeymapContext::default(); view.update_keymap_context(&mut keymap_context, cx.app_context()); self.views_metadata.insert( - (window_id, view_id), + (handle.id(), view_id), ViewMetadata { type_id: TypeId::of::(), keymap_context, }, ); - self.views.insert((window_id, view_id), Box::new(view)); + self.views.insert((handle.id(), view_id), Box::new(view)); self.window .invalidation .get_or_insert_with(Default::default) .updated .insert(view_id); - Some(ViewHandle::new(window_id, view_id, &self.ref_counts)) + Some(ViewHandle::new(handle, view_id, &self.ref_counts)) } else { None }; @@ -1390,7 +1383,7 @@ pub struct ChildView { impl ChildView { pub fn new(view: &AnyViewHandle, cx: &AppContext) -> Self { - let view_name = cx.view_ui_name(view.window_id(), view.id()).unwrap(); + let view_name = cx.view_ui_name(view.window, view.id()).unwrap(); Self { view_id: view.id(), view_name, diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 07aaea812a..df4334a19f 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -1726,7 +1726,7 @@ impl ClipboardEntry { #[cfg(test)] mod tests { use super::*; - use gpui::{AnyWindowHandle, TestAppContext, ViewHandle}; + use gpui::{AnyWindowHandle, TestAppContext, ViewHandle, WindowHandle}; use pretty_assertions::assert_eq; use project::FakeFs; use serde_json::json; @@ -1872,7 +1872,6 @@ mod tests { let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); select_path(&panel, "root1", cx); @@ -1894,7 +1893,7 @@ mod tests { // Add a file with the root folder selected. The filename editor is placed // before the first file in the root folder. panel.update(cx, |panel, cx| panel.new_file(&NewFile, cx)); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { let panel = panel.read(cx); assert!(panel.filename_editor.is_focused(cx)); }); @@ -2225,7 +2224,6 @@ mod tests { let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); select_path(&panel, "root1", cx); @@ -2247,7 +2245,7 @@ mod tests { // Add a file with the root folder selected. The filename editor is placed // before the first file in the root folder. panel.update(cx, |panel, cx| panel.new_file(&NewFile, cx)); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { let panel = panel.read(cx); assert!(panel.filename_editor.is_focused(cx)); }); @@ -2402,7 +2400,6 @@ mod tests { let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); toggle_expand_dir(&panel, "src/test", cx); @@ -2419,7 +2416,7 @@ mod tests { " third.rs" ] ); - ensure_single_file_is_opened(window_id, &workspace, "test/first.rs", cx); + ensure_single_file_is_opened(window, "test/first.rs", cx); submit_deletion(window.into(), &panel, cx); assert_eq!( @@ -2446,9 +2443,9 @@ mod tests { " third.rs" ] ); - ensure_single_file_is_opened(window_id, &workspace, "test/second.rs", cx); + ensure_single_file_is_opened(window, "test/second.rs", cx); - cx.update_window(window_id, |cx| { + window.update(cx, |cx| { let active_items = workspace .read(cx) .panes() @@ -2493,7 +2490,6 @@ mod tests { let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); select_path(&panel, "src/", cx); @@ -2504,7 +2500,7 @@ mod tests { &["v src <== selected", " > test"] ); panel.update(cx, |panel, cx| panel.new_directory(&NewDirectory, cx)); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { let panel = panel.read(cx); assert!(panel.filename_editor.is_focused(cx)); }); @@ -2535,7 +2531,7 @@ mod tests { &["v src", " > test <== selected"] ); panel.update(cx, |panel, cx| panel.new_file(&NewFile, cx)); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { let panel = panel.read(cx); assert!(panel.filename_editor.is_focused(cx)); }); @@ -2585,7 +2581,7 @@ mod tests { ], ); panel.update(cx, |panel, cx| panel.rename(&Rename, cx)); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { let panel = panel.read(cx); assert!(panel.filename_editor.is_focused(cx)); }); @@ -2882,13 +2878,11 @@ mod tests { } fn ensure_single_file_is_opened( - window_id: usize, - workspace: &ViewHandle, + window: WindowHandle, expected_path: &str, cx: &mut TestAppContext, ) { - cx.read_window(window_id, |cx| { - let workspace = workspace.read(cx); + window.update_root(cx, |workspace, cx| { let worktrees = workspace.worktrees(cx).collect::>(); assert_eq!(worktrees.len(), 1); let worktree_id = WorktreeId::from_usize(worktrees[0].id()); diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index b20ffed6d7..c3b4f5caa6 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -1229,8 +1229,6 @@ mod tests { ); let buffer = cx.add_model(|cx| Buffer::new(0, buffer_text, cx)); let window = cx.add_window(|_| EmptyView); - let window_id = window.id(); - let editor = window.add_view(cx, |cx| Editor::for_buffer(buffer.clone(), None, cx)); let search_bar = window.add_view(cx, |cx| { @@ -1249,12 +1247,13 @@ mod tests { search_bar.activate_current_match(cx); }); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { assert!( !editor.is_focused(cx), "Initially, the editor should not be focused" ); }); + let initial_selections = editor.update(cx, |editor, cx| { let initial_selections = editor.selections.display_ranges(cx); assert_eq!( @@ -1271,7 +1270,7 @@ mod tests { cx.focus(search_bar.query_editor.as_any()); search_bar.select_all_matches(&SelectAllMatches, cx); }); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { assert!( editor.is_focused(cx), "Should focus editor after successful SelectAllMatches" @@ -1295,7 +1294,7 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_next_match(&SelectNextMatch, cx); }); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { assert!( editor.is_focused(cx), "Should still have editor focused after SelectNextMatch" @@ -1324,7 +1323,7 @@ mod tests { cx.focus(search_bar.query_editor.as_any()); search_bar.select_all_matches(&SelectAllMatches, cx); }); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { assert!( editor.is_focused(cx), "Should focus editor after successful SelectAllMatches" @@ -1348,7 +1347,7 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_prev_match(&SelectPrevMatch, cx); }); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { assert!( editor.is_focused(cx), "Should still have editor focused after SelectPrevMatch" @@ -1384,7 +1383,7 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_all_matches(&SelectAllMatches, cx); }); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { assert!( !editor.is_focused(cx), "Should not switch focus to editor if SelectAllMatches does not find any matches" diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index dffd88db14..202d494560 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -1568,7 +1568,6 @@ pub mod tests { let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); let active_item = cx.read(|cx| { workspace @@ -1599,9 +1598,9 @@ pub mod tests { }; let search_view_id = search_view.id(); - cx.spawn( - |mut cx| async move { cx.dispatch_action(window_id, search_view_id, &ToggleFocus) }, - ) + cx.spawn(|mut cx| async move { + cx.dispatch_action(window.into(), search_view_id, &ToggleFocus) + }) .detach(); deterministic.run_until_parked(); search_view.update(cx, |search_view, cx| { @@ -1651,9 +1650,9 @@ pub mod tests { "Search view should be focused after mismatching query had been used in search", ); }); - cx.spawn( - |mut cx| async move { cx.dispatch_action(window_id, search_view_id, &ToggleFocus) }, - ) + cx.spawn(|mut cx| async move { + cx.dispatch_action(window.into(), search_view_id, &ToggleFocus) + }) .detach(); deterministic.run_until_parked(); search_view.update(cx, |search_view, cx| { @@ -1683,9 +1682,9 @@ pub mod tests { "Search view with mismatching query should be focused after search results are available", ); }); - cx.spawn( - |mut cx| async move { cx.dispatch_action(window_id, search_view_id, &ToggleFocus) }, - ) + cx.spawn(|mut cx| async move { + cx.dispatch_action(window.into(), search_view_id, &ToggleFocus) + }) .detach(); deterministic.run_until_parked(); search_view.update(cx, |search_view, cx| { @@ -1713,9 +1712,9 @@ pub mod tests { ); }); - cx.spawn( - |mut cx| async move { cx.dispatch_action(window_id, search_view_id, &ToggleFocus) }, - ) + cx.spawn(|mut cx| async move { + cx.dispatch_action(window.into(), search_view_id, &ToggleFocus) + }) .detach(); deterministic.run_until_parked(); search_view.update(cx, |search_view, cx| { diff --git a/crates/vim/src/editor_events.rs b/crates/vim/src/editor_events.rs index 4fef6bd715..893f5e8a85 100644 --- a/crates/vim/src/editor_events.rs +++ b/crates/vim/src/editor_events.rs @@ -1,6 +1,6 @@ use crate::Vim; use editor::{EditorBlurred, EditorFocused, EditorReleased}; -use gpui::{AppContext, BorrowWindowContext}; +use gpui::AppContext; pub fn init(cx: &mut AppContext) { cx.subscribe_global(focused).detach(); @@ -10,7 +10,7 @@ pub fn init(cx: &mut AppContext) { fn focused(EditorFocused(editor): &EditorFocused, cx: &mut AppContext) { if let Some(previously_active_editor) = Vim::read(cx).active_editor.clone() { - cx.update_window(previously_active_editor.window_id(), |cx| { + previously_active_editor.window().update(cx, |cx| { Vim::update(cx, |vim, cx| { vim.update_active_editor(cx, |previously_active_editor, cx| { vim.unhook_vim_settings(previously_active_editor, cx) @@ -19,7 +19,7 @@ fn focused(EditorFocused(editor): &EditorFocused, cx: &mut AppContext) { }); } - cx.update_window(editor.window_id(), |cx| { + editor.window().update(cx, |cx| { Vim::update(cx, |vim, cx| { vim.set_active_editor(editor.clone(), cx); }); @@ -27,7 +27,7 @@ fn focused(EditorFocused(editor): &EditorFocused, cx: &mut AppContext) { } fn blurred(EditorBlurred(editor): &EditorBlurred, cx: &mut AppContext) { - cx.update_window(editor.window_id(), |cx| { + editor.window().update(cx, |cx| { Vim::update(cx, |vim, cx| { if let Some(previous_editor) = vim.active_editor.clone() { if previous_editor == editor.clone() { @@ -41,7 +41,7 @@ fn blurred(EditorBlurred(editor): &EditorBlurred, cx: &mut AppContext) { } fn released(EditorReleased(editor): &EditorReleased, cx: &mut AppContext) { - cx.update_window(editor.window_id(), |cx| { + editor.window().update(cx, |cx| { cx.update_default_global(|vim: &mut Vim, _| { if let Some(previous_editor) = vim.active_editor.clone() { if previous_editor == editor.clone() { diff --git a/crates/vim/src/mode_indicator.rs b/crates/vim/src/mode_indicator.rs index afd60af848..5d54a66723 100644 --- a/crates/vim/src/mode_indicator.rs +++ b/crates/vim/src/mode_indicator.rs @@ -1,6 +1,6 @@ use gpui::{ elements::{Empty, Label}, - AnyElement, Element, Entity, Subscription, View, ViewContext, BorrowWindowContext + AnyElement, Element, Entity, Subscription, View, ViewContext, }; use settings::SettingsStore; use workspace::{item::ItemHandle, StatusItemView}; @@ -20,7 +20,7 @@ impl ModeIndicator { if let Some(mode_indicator) = handle.upgrade(cx) { match event { VimEvent::ModeChanged { mode } => { - cx.update_window(mode_indicator.window_id(), |cx| { + mode_indicator.window().update(cx, |cx| { mode_indicator.update(cx, move |mode_indicator, cx| { mode_indicator.set_mode(mode, cx); }) diff --git a/crates/vim/src/test/vim_test_context.rs b/crates/vim/src/test/vim_test_context.rs index 839ab3aafc..5eaaef900e 100644 --- a/crates/vim/src/test/vim_test_context.rs +++ b/crates/vim/src/test/vim_test_context.rs @@ -85,8 +85,8 @@ impl<'a> VimTestContext<'a> { } pub fn set_state(&mut self, text: &str, mode: Mode) -> ContextHandle { - let window_id = self.window.id(); - self.update_window(window_id, |cx| { + let window = self.window; + window.update(self.cx.cx.cx, |cx| { Vim::update(cx, |vim, cx| { vim.switch_mode(mode, false, cx); }) diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index ebaf399e22..5bb0fd93f8 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -203,7 +203,7 @@ impl Dock { pub fn panel_index_for_ui_name(&self, ui_name: &str, cx: &AppContext) -> Option { self.panel_entries.iter().position(|entry| { let panel = entry.panel.as_any(); - cx.view_ui_name(panel.window_id(), panel.id()) == Some(ui_name) + cx.view_ui_name(panel.window(), panel.id()) == Some(ui_name) }) } @@ -530,16 +530,12 @@ impl View for PanelButtons { tooltip_action.as_ref().map(|action| action.boxed_clone()); move |_, this, cx| { if let Some(tooltip_action) = &tooltip_action { - let window_id = cx.window_id(); + let window = cx.window(); let view_id = this.workspace.id(); let tooltip_action = tooltip_action.boxed_clone(); cx.spawn(|_, mut cx| async move { - cx.dispatch_action( - window_id, - view_id, - &*tooltip_action, - ) - .ok(); + cx.dispatch_action(window, view_id, &*tooltip_action) + .ok(); }) .detach(); } diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 98883fac33..ecbe25acca 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -1917,8 +1917,8 @@ impl Element for PaneBackdrop { MouseRegion::new::(child_view_id, 0, visible_bounds).on_down( gpui::platform::MouseButton::Left, move |_, _: &mut V, cx| { - let window_id = cx.window_id(); - cx.app_context().focus(window_id, Some(child_view_id)) + let window = cx.window(); + cx.app_context().focus(window, Some(child_view_id)) }, ), ); diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index da708c6ea7..f099032265 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1250,11 +1250,11 @@ impl Workspace { _: &CloseWindow, cx: &mut ViewContext, ) -> Option>> { - let window_id = cx.window_id(); + let window = cx.window(); let prepare = self.prepare_to_close(false, cx); Some(cx.spawn(|_, mut cx| async move { if prepare.await? { - cx.remove_window(window_id); + cx.remove_window(window); } Ok(()) })) @@ -1266,7 +1266,7 @@ impl Workspace { cx: &mut ViewContext, ) -> Task> { let active_call = self.active_call().cloned(); - let window_id = cx.window_id(); + let window = cx.window(); cx.spawn(|this, mut cx| async move { let workspace_count = cx @@ -1281,7 +1281,7 @@ impl Workspace { && active_call.read_with(&cx, |call, _| call.room().is_some()) { let answer = cx.prompt( - window_id, + window, PromptLevel::Warning, "Do you want to leave the current call?", &["Close window and hang up", "Cancel"], @@ -1390,7 +1390,7 @@ impl Workspace { paths: Vec, cx: &mut ViewContext, ) -> Task> { - let window = cx.window::(); + let window = cx.window().downcast::(); let is_remote = self.project.read(cx).is_remote(); let has_worktree = self.project.read(cx).worktrees(cx).next().is_some(); let has_dirty_items = self.items(cx).any(|item| item.is_dirty(cx)); @@ -3181,7 +3181,7 @@ impl Workspace { let left_visible = left_dock.is_open(); let left_active_panel = left_dock.visible_panel().and_then(|panel| { Some( - cx.view_ui_name(panel.as_any().window_id(), panel.id())? + cx.view_ui_name(panel.as_any().window(), panel.id())? .to_string(), ) }); @@ -3194,7 +3194,7 @@ impl Workspace { let right_visible = right_dock.is_open(); let right_active_panel = right_dock.visible_panel().and_then(|panel| { Some( - cx.view_ui_name(panel.as_any().window_id(), panel.id())? + cx.view_ui_name(panel.as_any().window(), panel.id())? .to_string(), ) }); @@ -3207,7 +3207,7 @@ impl Workspace { let bottom_visible = bottom_dock.is_open(); let bottom_active_panel = bottom_dock.visible_panel().and_then(|panel| { Some( - cx.view_ui_name(panel.as_any().window_id(), panel.id())? + cx.view_ui_name(panel.as_any().window(), panel.id())? .to_string(), ) }); @@ -4000,7 +4000,7 @@ pub fn join_remote_project( workspace.downgrade() }; - cx.activate_window(workspace.window_id()); + cx.activate_window(workspace.window()); cx.platform().activate(true); workspace.update(&mut cx, |workspace, cx| { @@ -4049,9 +4049,9 @@ pub fn restart(_: &Restart, cx: &mut AppContext) { // prompt in the active window before switching to a different window. workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false)); - if let (true, Some(window)) = (should_confirm, workspace_windows.first()) { + if let (true, Some(window)) = (should_confirm, workspace_windows.first().copied()) { let answer = cx.prompt( - window.id(), + window.into(), PromptLevel::Info, "Are you sure you want to restart?", &["Restart", "Cancel"], diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 3435727b1e..6397a1e6b2 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -179,13 +179,12 @@ pub fn init(app_state: &Arc, cx: &mut gpui::AppContext) { move |workspace: &mut Workspace, _: &DebugElements, cx: &mut ViewContext| { let app_state = workspace.app_state().clone(); let markdown = app_state.languages.language_for_name("JSON"); - let window_id = cx.window_id(); + let window = cx.window(); cx.spawn(|workspace, mut cx| async move { let markdown = markdown.await.log_err(); - let content = to_string_pretty( - &cx.debug_elements(window_id) - .ok_or_else(|| anyhow!("could not debug elements for {window_id}"))?, - ) + let content = to_string_pretty(&cx.debug_elements(window).ok_or_else(|| { + anyhow!("could not debug elements for window {}", window.id()) + })?) .unwrap(); workspace .update(&mut cx, |workspace, cx| { @@ -416,9 +415,9 @@ fn quit(_: &Quit, cx: &mut gpui::AppContext) { // prompt in the active window before switching to a different window. workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false)); - if let (true, Some(window)) = (should_confirm, workspace_windows.first()) { + if let (true, Some(window)) = (should_confirm, workspace_windows.first().copied()) { let answer = cx.prompt( - window.id(), + window.into(), PromptLevel::Info, "Are you sure you want to quit?", &["Quit", "Cancel"], @@ -716,8 +715,8 @@ mod tests { use editor::{scroll::autoscroll::Autoscroll, DisplayPoint, Editor}; use fs::{FakeFs, Fs}; use gpui::{ - actions, elements::Empty, executor::Deterministic, Action, AnyElement, AppContext, - AssetSource, Element, Entity, TestAppContext, View, ViewHandle, + actions, elements::Empty, executor::Deterministic, Action, AnyElement, AnyWindowHandle, + AppContext, AssetSource, Element, Entity, TestAppContext, View, ViewHandle, }; use language::LanguageRegistry; use node_runtime::NodeRuntime; @@ -1317,11 +1316,10 @@ mod tests { project.update(cx, |project, _| project.languages().add(rust_lang())); let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); let worktree = cx.read(|cx| workspace.read(cx).worktrees(cx).next().unwrap()); // Create a new untitled buffer - cx.dispatch_action(window_id, NewFile); + cx.dispatch_action(window.into(), NewFile); let editor = workspace.read_with(cx, |workspace, cx| { workspace .active_item(cx) @@ -1376,7 +1374,7 @@ mod tests { // Open the same newly-created file in another pane item. The new editor should reuse // the same buffer. - cx.dispatch_action(window_id, NewFile); + cx.dispatch_action(window.into(), NewFile); workspace .update(cx, |workspace, cx| { workspace.split_and_clone( @@ -1412,10 +1410,9 @@ mod tests { project.update(cx, |project, _| project.languages().add(rust_lang())); let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); // Create a new untitled buffer - cx.dispatch_action(window_id, NewFile); + cx.dispatch_action(window.into(), NewFile); let editor = workspace.read_with(cx, |workspace, cx| { workspace .active_item(cx) @@ -1465,7 +1462,6 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); let entries = cx.read(|cx| workspace.file_project_paths(cx)); let file1 = entries[0].clone(); @@ -1487,7 +1483,7 @@ mod tests { (editor.downgrade(), buffer) }); - cx.dispatch_action(window_id, pane::SplitRight); + cx.dispatch_action(window.into(), pane::SplitRight); let editor_2 = cx.update(|cx| { let pane_2 = workspace.read(cx).active_pane().clone(); assert_ne!(pane_1, pane_2); @@ -1497,7 +1493,7 @@ mod tests { pane2_item.downcast::().unwrap().downgrade() }); - cx.dispatch_action(window_id, workspace::CloseActiveItem); + cx.dispatch_action(window.into(), workspace::CloseActiveItem); cx.foreground().run_until_parked(); workspace.read_with(cx, |workspace, _| { @@ -1505,7 +1501,7 @@ mod tests { assert_eq!(workspace.active_pane(), &pane_1); }); - cx.dispatch_action(window_id, workspace::CloseActiveItem); + cx.dispatch_action(window.into(), workspace::CloseActiveItem); cx.foreground().run_until_parked(); window.simulate_prompt_answer(1, cx); cx.foreground().run_until_parked(); @@ -2063,11 +2059,10 @@ mod tests { cx.foreground().run_until_parked(); let window = cx.add_window(|_| TestView); - let window_id = window.id(); // Test loading the keymap base at all assert_key_bindings_for( - window_id, + window.into(), cx, vec![("backspace", &A), ("k", &ActivatePreviousPane)], line!(), @@ -2094,7 +2089,7 @@ mod tests { cx.foreground().run_until_parked(); assert_key_bindings_for( - window_id, + window.into(), cx, vec![("backspace", &B), ("k", &ActivatePreviousPane)], line!(), @@ -2117,7 +2112,7 @@ mod tests { cx.foreground().run_until_parked(); assert_key_bindings_for( - window_id, + window.into(), cx, vec![("backspace", &B), ("[", &ActivatePrevItem)], line!(), @@ -2125,7 +2120,7 @@ mod tests { #[track_caller] fn assert_key_bindings_for<'a>( - window_id: usize, + window: AnyWindowHandle, cx: &TestAppContext, actions: Vec<(&'static str, &'a dyn Action)>, line: u32, @@ -2133,7 +2128,7 @@ mod tests { for (key, action) in actions { // assert that... assert!( - cx.available_actions(window_id, 0) + cx.available_actions(window, 0) .into_iter() .any(|(_, bound_action, b)| { // action names match... @@ -2234,11 +2229,10 @@ mod tests { cx.foreground().run_until_parked(); let window = cx.add_window(|_| TestView); - let window_id = window.id(); // Test loading the keymap base at all assert_key_bindings_for( - window_id, + window.into(), cx, vec![("backspace", &A), ("k", &ActivatePreviousPane)], line!(), @@ -2264,7 +2258,12 @@ mod tests { cx.foreground().run_until_parked(); - assert_key_bindings_for(window_id, cx, vec![("k", &ActivatePreviousPane)], line!()); + assert_key_bindings_for( + window.into(), + cx, + vec![("k", &ActivatePreviousPane)], + line!(), + ); // Test modifying the base, while retaining the users keymap fs.save( @@ -2282,11 +2281,11 @@ mod tests { cx.foreground().run_until_parked(); - assert_key_bindings_for(window_id, cx, vec![("[", &ActivatePrevItem)], line!()); + assert_key_bindings_for(window.into(), cx, vec![("[", &ActivatePrevItem)], line!()); #[track_caller] fn assert_key_bindings_for<'a>( - window_id: usize, + window: AnyWindowHandle, cx: &TestAppContext, actions: Vec<(&'static str, &'a dyn Action)>, line: u32, @@ -2294,7 +2293,7 @@ mod tests { for (key, action) in actions { // assert that... assert!( - cx.available_actions(window_id, 0) + cx.available_actions(window, 0) .into_iter() .any(|(_, bound_action, b)| { // action names match...