diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index 78ee56f188..19fed4bf59 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -458,14 +458,26 @@ impl StatusItemView for ToggleDockButton { #[cfg(test)] mod tests { - use std::ops::{Deref, DerefMut}; + use std::{ + ops::{Deref, DerefMut}, + path::PathBuf, + }; use gpui::{AppContext, TestAppContext, UpdateView, ViewContext}; use project::{FakeFs, Project}; use settings::Settings; use super::*; - use crate::{item::test::TestItem, sidebar::Sidebar, ItemHandle, Workspace}; + use crate::{ + dock, + item::test::TestItem, + persistence::model::{ + SerializedItem, SerializedPane, SerializedPaneGroup, SerializedWorkspace, + }, + register_deserializable_item, + sidebar::Sidebar, + ItemHandle, Workspace, + }; pub fn default_item_factory( _workspace: &mut Workspace, @@ -474,6 +486,51 @@ mod tests { Some(Box::new(cx.add_view(|_| TestItem::new()))) } + #[gpui::test] + async fn test_dock_workspace_infinite_loop(cx: &mut TestAppContext) { + cx.foreground().forbid_parking(); + Settings::test_async(cx); + + cx.update(|cx| { + register_deserializable_item::(cx); + }); + + let serialized_workspace = SerializedWorkspace { + id: 0, + location: Vec::::new().into(), + dock_position: dock::DockPosition::Shown(DockAnchor::Expanded), + center_group: SerializedPaneGroup::Pane(SerializedPane { + active: false, + children: vec![], + }), + dock_pane: SerializedPane { + active: true, + children: vec![SerializedItem { + active: true, + item_id: 0, + kind: "test".into(), + }], + }, + left_sidebar_open: false, + }; + + let fs = FakeFs::new(cx.background()); + let project = Project::test(fs, [], cx).await; + + let (_, _workspace) = cx.add_window(|cx| { + Workspace::new( + Some(serialized_workspace), + 0, + project.clone(), + default_item_factory, + cx, + ) + }); + + cx.foreground().run_until_parked(); + //Should terminate + } + #[gpui::test] async fn test_dock_hides_when_pane_empty(cx: &mut TestAppContext) { let mut cx = DockTestContext::new(cx).await; diff --git a/crates/workspace/src/item.rs b/crates/workspace/src/item.rs index e44e7ca09d..14f847fd54 100644 --- a/crates/workspace/src/item.rs +++ b/crates/workspace/src/item.rs @@ -681,6 +681,7 @@ pub(crate) mod test { use super::{Item, ItemEvent}; pub struct TestItem { + pub workspace_id: WorkspaceId, pub state: String, pub label: String, pub save_count: usize, @@ -716,6 +717,7 @@ pub(crate) mod test { nav_history: None, tab_descriptions: None, tab_detail: Default::default(), + workspace_id: self.workspace_id, } } } @@ -736,9 +738,16 @@ pub(crate) mod test { nav_history: None, tab_descriptions: None, tab_detail: Default::default(), + workspace_id: 0, } } + pub fn new_deserialized(id: WorkspaceId) -> Self { + let mut this = Self::new(); + this.workspace_id = id; + this + } + pub fn with_label(mut self, state: &str) -> Self { self.label = state.to_string(); self @@ -893,11 +902,12 @@ pub(crate) mod test { fn deserialize( _project: ModelHandle, _workspace: WeakViewHandle, - _workspace_id: WorkspaceId, + workspace_id: WorkspaceId, _item_id: ItemId, - _cx: &mut ViewContext, + cx: &mut ViewContext, ) -> Task>> { - unreachable!("Cannot deserialize test item") + let view = cx.add_view(|_cx| Self::new_deserialized(workspace_id)); + Task::Ready(Some(anyhow::Ok(view))) } } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index d38cf96ed2..6dd5c9c4fa 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -2371,7 +2371,12 @@ impl Workspace { workspace.toggle_sidebar(SidebarSide::Left, cx); } - // Dock::set_dock_position(workspace, serialized_workspace.dock_position, cx); + // Note that without after_window, the focus_self() and + // the focus the dock generates start generating alternating + // focus due to the deferred execution each triggering each other + cx.after_window_update(move |workspace, cx| { + Dock::set_dock_position(workspace, serialized_workspace.dock_position, cx); + }); cx.notify(); }); @@ -2695,7 +2700,7 @@ mod tests { _workspace: &mut Workspace, _cx: &mut ViewContext, ) -> Option> { - unimplemented!(); + unimplemented!() } #[gpui::test]