Detailed changes
@@ -3446,7 +3446,7 @@ async fn test_newline_above_or_below_does_not_move_guest_cursor(
let editor_a = window_a.add_view(cx_a, |cx| Editor::for_buffer(buffer_a, Some(project_a), cx));
let mut editor_cx_a = EditorTestContext {
cx: cx_a,
- window_id: window_a.id(),
+ window: window_a.into(),
editor: editor_a,
};
@@ -3459,7 +3459,7 @@ async fn test_newline_above_or_below_does_not_move_guest_cursor(
let editor_b = window_b.add_view(cx_b, |cx| Editor::for_buffer(buffer_b, Some(project_b), cx));
let mut editor_cx_b = EditorTestContext {
cx: cx_b,
- window_id: window_b.id(),
+ window: window_b.into(),
editor: editor_b,
};
@@ -5,7 +5,7 @@ use gpui::{
elements::*,
geometry::{rect::RectF, vector::vec2f},
platform::{CursorStyle, MouseButton, WindowBounds, WindowKind, WindowOptions},
- AppContext, Entity, View, ViewContext,
+ AppContext, BorrowWindowContext, Entity, View, ViewContext,
};
use std::sync::{Arc, Weak};
use workspace::AppState;
@@ -20,11 +20,11 @@ pub fn init(cx: &mut AppContext) {
{
status_indicator = Some(cx.add_status_bar_item(|_| SharingStatusIndicator));
}
- } else if let Some((window_id, _)) = status_indicator.take() {
- cx.update_window(window_id, |cx| cx.remove_window());
+ } else if let Some(window) = status_indicator.take() {
+ window.update(cx, |cx| cx.remove_window());
}
- } else if let Some((window_id, _)) = status_indicator.take() {
- cx.update_window(window_id, |cx| cx.remove_window());
+ } else if let Some(window) = status_indicator.take() {
+ window.update(cx, |cx| cx.remove_window());
}
})
.detach();
@@ -1290,7 +1290,7 @@ async fn test_move_start_of_paragraph_end_of_paragraph(cx: &mut gpui::TestAppCon
let mut cx = EditorTestContext::new(cx).await;
let line_height = cx.editor(|editor, cx| editor.style(cx).text.line_height(cx.font_cache()));
- cx.simulate_window_resize(cx.window_id, vec2f(100., 4. * line_height));
+ cx.simulate_window_resize(cx.window.id(), vec2f(100., 4. * line_height));
cx.set_state(
&r#"Λone
@@ -1401,7 +1401,7 @@ async fn test_scroll_page_up_page_down(cx: &mut gpui::TestAppContext) {
init_test(cx, |_| {});
let mut cx = EditorTestContext::new(cx).await;
let line_height = cx.editor(|editor, cx| editor.style(cx).text.line_height(cx.font_cache()));
- cx.simulate_window_resize(cx.window_id, vec2f(1000., 4. * line_height + 0.5));
+ cx.simulate_window_resize(cx.window.id(), vec2f(1000., 4. * line_height + 0.5));
cx.set_state(
&r#"Λone
@@ -1439,7 +1439,7 @@ async fn test_move_page_up_page_down(cx: &mut gpui::TestAppContext) {
let mut cx = EditorTestContext::new(cx).await;
let line_height = cx.editor(|editor, cx| editor.style(cx).text.line_height(cx.font_cache()));
- cx.simulate_window_resize(cx.window_id, vec2f(100., 4. * line_height));
+ cx.simulate_window_resize(cx.window.id(), vec2f(100., 4. * line_height));
cx.set_state(
&r#"
@@ -99,7 +99,7 @@ impl<'a> EditorLspTestContext<'a> {
Self {
cx: EditorTestContext {
cx,
- window_id: window.id(),
+ window: window.into(),
editor,
},
lsp,
@@ -3,7 +3,8 @@ use crate::{
};
use futures::Future;
use gpui::{
- keymap_matcher::Keystroke, AppContext, ContextHandle, ModelContext, ViewContext, ViewHandle,
+ keymap_matcher::Keystroke, AnyWindowHandle, AppContext, ContextHandle, ModelContext,
+ ViewContext, ViewHandle,
};
use indoc::indoc;
use language::{Buffer, BufferSnapshot};
@@ -21,7 +22,7 @@ use super::build_editor;
pub struct EditorTestContext<'a> {
pub cx: &'a mut gpui::TestAppContext,
- pub window_id: usize,
+ pub window: AnyWindowHandle,
pub editor: ViewHandle<Editor>,
}
@@ -39,7 +40,7 @@ impl<'a> EditorTestContext<'a> {
let editor = window.root(cx);
Self {
cx,
- window_id: window.id(),
+ window: window.into(),
editor,
}
}
@@ -111,7 +112,8 @@ impl<'a> EditorTestContext<'a> {
let keystroke_under_test_handle =
self.add_assertion_context(format!("Simulated Keystroke: {:?}", keystroke_text));
let keystroke = Keystroke::parse(keystroke_text).unwrap();
- self.cx.dispatch_keystroke(self.window_id, keystroke, false);
+
+ self.cx.dispatch_keystroke(self.window, keystroke, false);
keystroke_under_test_handle
}
@@ -135,14 +135,16 @@ impl Entity for GoToLine {
fn release(&mut self, cx: &mut AppContext) {
let scroll_position = self.prev_scroll_position.take();
- cx.update_window(self.active_editor.window_id(), |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);
- }
- })
- });
+ 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);
+ }
+ })
+ });
+ }
}
}
@@ -23,6 +23,7 @@ use std::{
};
use anyhow::{anyhow, Context, Result};
+
use derive_more::Deref;
use parking_lot::Mutex;
use postage::oneshot;
@@ -4127,6 +4128,12 @@ impl<T: View> ViewHandle<T> {
self.window_id
}
+ pub fn window<C: BorrowWindowContext>(&self, cx: &C) -> C::Result<AnyWindowHandle> {
+ cx.read_window(self.window_id, |cx| {
+ AnyWindowHandle::new(self.window_id, cx.window.root_view.type_id())
+ })
+ }
+
pub fn id(&self) -> usize {
self.view_id
}
@@ -175,7 +175,7 @@ impl BorrowWindowContext for WindowContext<'_> {
where
F: FnOnce(&mut WindowContext) -> Option<T>,
{
- BorrowWindowContext::update_window_optional(self, window_id, f)
+ BorrowWindowContext::update_window(self, window_id, f)
}
}
@@ -1,6 +1,6 @@
use crate::Vim;
use editor::{EditorBlurred, EditorFocused, EditorReleased};
-use gpui::AppContext;
+use gpui::{AppContext, BorrowWindowContext};
pub fn init(cx: &mut AppContext) {
cx.subscribe_global(focused).detach();
@@ -1,6 +1,6 @@
use gpui::{
elements::{Empty, Label},
- AnyElement, Element, Entity, Subscription, View, ViewContext,
+ AnyElement, Element, Entity, Subscription, View, ViewContext, BorrowWindowContext
};
use settings::SettingsStore;
use workspace::{item::ItemHandle, StatusItemView};
@@ -85,7 +85,7 @@ impl<'a> VimTestContext<'a> {
}
pub fn set_state(&mut self, text: &str, mode: Mode) -> ContextHandle {
- let window_id = self.window_id;
+ let window_id = self.window.id();
self.update_window(window_id, |cx| {
Vim::update(cx, |vim, cx| {
vim.switch_mode(mode, false, cx);
@@ -3827,9 +3827,9 @@ pub fn activate_workspace_for_project(
cx: &mut AsyncAppContext,
predicate: impl Fn(&mut Project, &mut ModelContext<Project>) -> bool,
) -> Option<WeakViewHandle<Workspace>> {
- for window_id in cx.window_ids() {
- let handle = cx
- .update_window(window_id, |cx| {
+ for window in cx.windows() {
+ let handle = window
+ .update(cx, |cx| {
if let Some(workspace_handle) = cx.root_view().clone().downcast::<Workspace>() {
let project = workspace_handle.read(cx).project.clone();
if project.update(cx, &predicate) {
@@ -3945,18 +3945,23 @@ pub fn join_remote_project(
) -> Task<Result<()>> {
cx.spawn(|mut cx| async move {
let existing_workspace = cx
- .window_ids()
+ .windows()
.into_iter()
- .filter_map(|window_id| cx.root_view(window_id)?.clone().downcast::<Workspace>())
- .find(|workspace| {
- cx.read_window(workspace.window_id(), |cx| {
- workspace.read(cx).project().read(cx).remote_id() == Some(project_id)
+ .find_map(|window| {
+ window.downcast::<Workspace>().and_then(|window| {
+ window.read_root_with(&cx, |workspace, cx| {
+ if workspace.project().read(cx).remote_id() == Some(project_id) {
+ Some(cx.handle().downgrade())
+ } else {
+ None
+ }
+ })
})
- .unwrap_or(false)
- });
+ })
+ .flatten();
let workspace = if let Some(existing_workspace) = existing_workspace {
- existing_workspace.downgrade()
+ existing_workspace
} else {
let active_call = cx.read(ActiveCall::global);
let room = active_call
@@ -4034,19 +4039,19 @@ pub fn join_remote_project(
pub fn restart(_: &Restart, cx: &mut AppContext) {
let should_confirm = settings::get::<WorkspaceSettings>(cx).confirm_quit;
cx.spawn(|mut cx| async move {
- let mut workspaces = cx
+ let mut workspace_windows = cx
.windows()
.into_iter()
- .filter_map(|window| Some(window.downcast::<Workspace>()?.root(&cx)?.downgrade()))
+ .filter_map(|window| window.downcast::<Workspace>())
.collect::<Vec<_>>();
// If multiple windows have unsaved changes, and need a save prompt,
// prompt in the active window before switching to a different window.
- workspaces.sort_by_key(|workspace| !cx.window_is_active(workspace.window_id()));
+ workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false));
- if let (true, Some(workspace)) = (should_confirm, workspaces.first()) {
+ if let (true, Some(window)) = (should_confirm, workspace_windows.first()) {
let answer = cx.prompt(
- workspace.window_id(),
+ window.id(),
PromptLevel::Info,
"Are you sure you want to restart?",
&["Restart", "Cancel"],
@@ -4061,14 +4066,13 @@ pub fn restart(_: &Restart, cx: &mut AppContext) {
}
// If the user cancels any save prompt, then keep the app open.
- for workspace in workspaces {
- if !workspace
- .update(&mut cx, |workspace, cx| {
- workspace.prepare_to_close(true, cx)
- })?
- .await?
- {
- return Ok(());
+ for window in workspace_windows {
+ if let Some(close) = window.update_root(&mut cx, |workspace, cx| {
+ workspace.prepare_to_close(true, cx)
+ }) {
+ if !close.await? {
+ return Ok(());
+ }
}
}
cx.platform().restart();
@@ -406,26 +406,19 @@ pub fn build_window_options(
fn quit(_: &Quit, cx: &mut gpui::AppContext) {
let should_confirm = settings::get::<WorkspaceSettings>(cx).confirm_quit;
cx.spawn(|mut cx| async move {
- let mut workspaces = cx
- .window_ids()
+ let mut workspace_windows = cx
+ .windows()
.into_iter()
- .filter_map(|window_id| {
- Some(
- cx.root_view(window_id)?
- .clone()
- .downcast::<Workspace>()?
- .downgrade(),
- )
- })
+ .filter_map(|window| window.downcast::<Workspace>())
.collect::<Vec<_>>();
// If multiple windows have unsaved changes, and need a save prompt,
// prompt in the active window before switching to a different window.
- workspaces.sort_by_key(|workspace| !cx.window_is_active(workspace.window_id()));
+ workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false));
- if let (true, Some(workspace)) = (should_confirm, workspaces.first()) {
+ if let (true, Some(window)) = (should_confirm, workspace_windows.first()) {
let answer = cx.prompt(
- workspace.window_id(),
+ window.id(),
PromptLevel::Info,
"Are you sure you want to quit?",
&["Quit", "Cancel"],
@@ -440,14 +433,13 @@ fn quit(_: &Quit, cx: &mut gpui::AppContext) {
}
// If the user cancels any save prompt, then keep the app open.
- for workspace in workspaces {
- if !workspace
- .update(&mut cx, |workspace, cx| {
- workspace.prepare_to_close(true, cx)
- })?
- .await?
- {
- return Ok(());
+ for window in workspace_windows {
+ if let Some(close) = window.update_root(&mut cx, |workspace, cx| {
+ workspace.prepare_to_close(false, cx)
+ }) {
+ if close.await? {
+ return Ok(());
+ }
}
}
cx.platform().quit();
@@ -782,17 +774,13 @@ mod tests {
})
.await
.unwrap();
- assert_eq!(cx.window_ids().len(), 1);
+ assert_eq!(cx.windows().len(), 1);
cx.update(|cx| open_paths(&[PathBuf::from("/root/a")], &app_state, None, cx))
.await
.unwrap();
- assert_eq!(cx.window_ids().len(), 1);
- let workspace_1 = cx
- .read_window(cx.window_ids()[0], |cx| cx.root_view().clone())
- .unwrap()
- .downcast::<Workspace>()
- .unwrap();
+ assert_eq!(cx.windows().len(), 1);
+ let workspace_1 = cx.windows()[0].downcast::<Workspace>().unwrap().root(cx);
workspace_1.update(cx, |workspace, cx| {
assert_eq!(workspace.worktrees(cx).count(), 2);
assert!(workspace.left_dock().read(cx).is_open());
@@ -809,28 +797,22 @@ mod tests {
})
.await
.unwrap();
- assert_eq!(cx.window_ids().len(), 2);
+ assert_eq!(cx.windows().len(), 2);
// Replace existing windows
- let window_id = cx.window_ids()[0];
- let window = cx.read_window(window_id, |cx| cx.window()).flatten();
+ let window = cx.windows()[0].downcast::<Workspace>().unwrap();
cx.update(|cx| {
open_paths(
&[PathBuf::from("/root/c"), PathBuf::from("/root/d")],
&app_state,
- window,
+ Some(window),
cx,
)
})
.await
.unwrap();
- assert_eq!(cx.window_ids().len(), 2);
- let workspace_1 = cx
- .read_window(cx.window_ids()[0], |cx| cx.root_view().clone())
- .unwrap()
- .clone()
- .downcast::<Workspace>()
- .unwrap();
+ assert_eq!(cx.windows().len(), 2);
+ let workspace_1 = cx.windows()[0].downcast::<Workspace>().unwrap().root(cx);
workspace_1.update(cx, |workspace, cx| {
assert_eq!(
workspace
@@ -856,14 +838,10 @@ mod tests {
cx.update(|cx| open_paths(&[PathBuf::from("/root/a")], &app_state, None, cx))
.await
.unwrap();
- assert_eq!(cx.window_ids().len(), 1);
+ assert_eq!(cx.windows().len(), 1);
// When opening the workspace, the window is not in a edited state.
- let workspace = cx
- .read_window(cx.window_ids()[0], |cx| cx.root_view().clone())
- .unwrap()
- .downcast::<Workspace>()
- .unwrap();
+ let workspace = cx.windows()[0].downcast::<Workspace>().unwrap().root(cx);
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
let editor = workspace.read_with(cx, |workspace, cx| {
workspace
@@ -917,12 +895,12 @@ mod tests {
// buffer having unsaved changes.
assert!(!cx.simulate_window_close(workspace.window_id()));
executor.run_until_parked();
- assert_eq!(cx.window_ids().len(), 1);
+ assert_eq!(cx.windows().len(), 1);
// The window is successfully closed after the user dismisses the prompt.
cx.simulate_prompt_answer(workspace.window_id(), 1);
executor.run_until_parked();
- assert_eq!(cx.window_ids().len(), 0);
+ assert_eq!(cx.windows().len(), 0);
}
#[gpui::test]
@@ -935,12 +913,13 @@ mod tests {
})
.await;
- let window_id = *cx.window_ids().first().unwrap();
- let workspace = cx
- .read_window(window_id, |cx| cx.root_view().clone())
+ let window = cx
+ .windows()
+ .first()
.unwrap()
.downcast::<Workspace>()
.unwrap();
+ let workspace = window.root(cx);
let editor = workspace.update(cx, |workspace, cx| {
workspace
@@ -1105,12 +1084,8 @@ mod tests {
cx.update(|cx| open_paths(&[PathBuf::from("/dir1/")], &app_state, None, cx))
.await
.unwrap();
- assert_eq!(cx.window_ids().len(), 1);
- let workspace = cx
- .read_window(cx.window_ids()[0], |cx| cx.root_view().clone())
- .unwrap()
- .downcast::<Workspace>()
- .unwrap();
+ assert_eq!(cx.windows().len(), 1);
+ let workspace = cx.windows()[0].downcast::<Workspace>().unwrap().root(cx);
#[track_caller]
fn assert_project_panel_selection(