This commit is contained in:
Nathan Sobo 2023-11-02 07:46:49 -06:00
parent d4e199cab1
commit 52e195b47c
4 changed files with 118 additions and 108 deletions

View file

@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize};
use std::sync::Arc; use std::sync::Arc;
pub trait Panel: Render + EventEmitter { pub trait Panel: Render + EventEmitter {
fn persistent_name(&self) -> &'static str;
fn position(&self, cx: &WindowContext) -> DockPosition; fn position(&self, cx: &WindowContext) -> DockPosition;
fn position_is_valid(&self, position: DockPosition) -> bool; fn position_is_valid(&self, position: DockPosition) -> bool;
fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>); fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>);
@ -42,6 +43,7 @@ pub trait Panel: Render + EventEmitter {
pub trait PanelHandle: Send + Sync { pub trait PanelHandle: Send + Sync {
fn id(&self) -> EntityId; fn id(&self) -> EntityId;
fn persistent_name(&self, cx: &WindowContext) -> &'static str;
fn position(&self, cx: &WindowContext) -> DockPosition; fn position(&self, cx: &WindowContext) -> DockPosition;
fn position_is_valid(&self, position: DockPosition, cx: &WindowContext) -> bool; fn position_is_valid(&self, position: DockPosition, cx: &WindowContext) -> bool;
fn set_position(&self, position: DockPosition, cx: &mut WindowContext); fn set_position(&self, position: DockPosition, cx: &mut WindowContext);
@ -65,6 +67,10 @@ where
self.entity_id() self.entity_id()
} }
fn persistent_name(&self, cx: &WindowContext) -> &'static str {
self.read(cx).persistent_name()
}
fn position(&self, cx: &WindowContext) -> DockPosition { fn position(&self, cx: &WindowContext) -> DockPosition {
self.read(cx).position(cx) self.read(cx).position(cx)
} }
@ -77,14 +83,6 @@ where
self.update(cx, |this, cx| this.set_position(position, cx)) self.update(cx, |this, cx| this.set_position(position, cx))
} }
fn size(&self, cx: &WindowContext) -> f32 {
self.read(cx).size(cx)
}
fn set_size(&self, size: Option<f32>, cx: &mut WindowContext) {
self.update(cx, |this, cx| this.set_size(size, cx))
}
fn is_zoomed(&self, cx: &WindowContext) -> bool { fn is_zoomed(&self, cx: &WindowContext) -> bool {
self.read(cx).is_zoomed(cx) self.read(cx).is_zoomed(cx)
} }
@ -97,6 +95,14 @@ where
self.update(cx, |this, cx| this.set_active(active, cx)) self.update(cx, |this, cx| this.set_active(active, cx))
} }
fn size(&self, cx: &WindowContext) -> f32 {
self.read(cx).size(cx)
}
fn set_size(&self, size: Option<f32>, cx: &mut WindowContext) {
self.update(cx, |this, cx| this.set_size(size, cx))
}
fn icon_path(&self, cx: &WindowContext) -> Option<&'static str> { fn icon_path(&self, cx: &WindowContext) -> Option<&'static str> {
self.read(cx).icon_path(cx) self.read(cx).icon_path(cx)
} }
@ -662,6 +668,10 @@ pub mod test {
} }
impl Panel for TestPanel { impl Panel for TestPanel {
fn persistent_name(&self) -> &'static str {
"TestPanel"
}
fn position(&self, _: &gpui2::WindowContext) -> super::DockPosition { fn position(&self, _: &gpui2::WindowContext) -> super::DockPosition {
self.position self.position
} }
@ -675,18 +685,6 @@ pub mod test {
cx.emit(TestPanelEvent::PositionChanged); cx.emit(TestPanelEvent::PositionChanged);
} }
fn is_zoomed(&self, _: &WindowContext) -> bool {
self.zoomed
}
fn set_zoomed(&mut self, zoomed: bool, _cx: &mut ViewContext<Self>) {
self.zoomed = zoomed;
}
fn set_active(&mut self, active: bool, _cx: &mut ViewContext<Self>) {
self.active = active;
}
fn size(&self, _: &WindowContext) -> f32 { fn size(&self, _: &WindowContext) -> f32 {
self.size self.size
} }
@ -715,6 +713,18 @@ pub mod test {
matches!(event, TestPanelEvent::ZoomOut) matches!(event, TestPanelEvent::ZoomOut)
} }
fn is_zoomed(&self, _: &WindowContext) -> bool {
self.zoomed
}
fn set_zoomed(&mut self, zoomed: bool, _cx: &mut ViewContext<Self>) {
self.zoomed = zoomed;
}
fn set_active(&mut self, active: bool, _cx: &mut ViewContext<Self>) {
self.active = active;
}
fn should_activate_on_event(event: &Self::Event) -> bool { fn should_activate_on_event(event: &Self::Event) -> bool {
matches!(event, TestPanelEvent::Activated) matches!(event, TestPanelEvent::Activated)
} }

View file

@ -167,7 +167,7 @@ impl SerializedPaneGroup {
let mut items = Vec::new(); let mut items = Vec::new();
for child in children { for child in children {
if let Some((new_member, active_pane, new_items)) = child if let Some((new_member, active_pane, new_items)) = child
.deserialize(project, workspace_id, workspace, cx) .deserialize(project, workspace_id, workspace.clone(), cx)
.await .await
{ {
members.push(new_member); members.push(new_member);
@ -196,7 +196,7 @@ impl SerializedPaneGroup {
.log_err()?; .log_err()?;
let active = serialized_pane.active; let active = serialized_pane.active;
let new_items = serialized_pane let new_items = serialized_pane
.deserialize_to(project, &pane, workspace_id, workspace, cx) .deserialize_to(project, &pane, workspace_id, workspace.clone(), cx)
.await .await
.log_err()?; .log_err()?;

View file

@ -916,10 +916,8 @@ impl Workspace {
notify_if_database_failed(window, &mut cx); notify_if_database_failed(window, &mut cx);
let opened_items = window let opened_items = window
.update(&mut cx, |_workspace, cx| { .update(&mut cx, |_workspace, cx| {
let workspace = cx.view().downgrade();
open_items( open_items(
serialized_workspace, serialized_workspace,
// &workspace,
project_paths, project_paths,
app_state, app_state,
cx, cx,
@ -3306,13 +3304,9 @@ impl Workspace {
) -> DockStructure { ) -> DockStructure {
let left_dock = this.left_dock.read(cx); let left_dock = this.left_dock.read(cx);
let left_visible = left_dock.is_open(); let left_visible = left_dock.is_open();
let left_active_panel = left_dock.visible_panel().and_then(|panel| { let left_active_panel = left_dock
todo!() .visible_panel()
// Some( .and_then(|panel| Some(panel.persistent_name(cx).to_string()));
// cx.view_ui_name(panel.as_any().window(), panel.id())?
// .to_string(),
// )
});
let left_dock_zoom = left_dock let left_dock_zoom = left_dock
.visible_panel() .visible_panel()
.map(|panel| panel.is_zoomed(cx)) .map(|panel| panel.is_zoomed(cx))
@ -3320,13 +3314,9 @@ impl Workspace {
let right_dock = this.right_dock.read(cx); let right_dock = this.right_dock.read(cx);
let right_visible = right_dock.is_open(); let right_visible = right_dock.is_open();
let right_active_panel = right_dock.visible_panel().and_then(|panel| { let right_active_panel = right_dock
todo!() .visible_panel()
// Some( .and_then(|panel| Some(panel.persistent_name(cx).to_string()));
// cx.view_ui_name(panel.as_any().window(), panel.id())?
// .to_string(),
// )
});
let right_dock_zoom = right_dock let right_dock_zoom = right_dock
.visible_panel() .visible_panel()
.map(|panel| panel.is_zoomed(cx)) .map(|panel| panel.is_zoomed(cx))
@ -3334,13 +3324,9 @@ impl Workspace {
let bottom_dock = this.bottom_dock.read(cx); let bottom_dock = this.bottom_dock.read(cx);
let bottom_visible = bottom_dock.is_open(); let bottom_visible = bottom_dock.is_open();
let bottom_active_panel = bottom_dock.visible_panel().and_then(|panel| { let bottom_active_panel = bottom_dock
todo!() .visible_panel()
// Some( .and_then(|panel| Some(panel.persistent_name(cx).to_string()));
// cx.view_ui_name(panel.as_any().window(), panel.id())?
// .to_string(),
// )
});
let bottom_dock_zoom = bottom_dock let bottom_dock_zoom = bottom_dock
.visible_panel() .visible_panel()
.map(|panel| panel.is_zoomed(cx)) .map(|panel| panel.is_zoomed(cx))
@ -3407,7 +3393,12 @@ impl Workspace {
// Traverse the splits tree and add to things // Traverse the splits tree and add to things
if let Some((group, active_pane, items)) = serialized_workspace if let Some((group, active_pane, items)) = serialized_workspace
.center_group .center_group
.deserialize(&project, serialized_workspace.id, workspace, &mut cx) .deserialize(
&project,
serialized_workspace.id,
workspace.clone(),
&mut cx,
)
.await .await
{ {
center_items = Some(items); center_items = Some(items);
@ -3443,7 +3434,7 @@ impl Workspace {
workspace.center = PaneGroup::with_root(center_group); workspace.center = PaneGroup::with_root(center_group);
// Change the focus to the workspace first so that we retrigger focus in on the pane. // Change the focus to the workspace first so that we retrigger focus in on the pane.
todo!() // todo!()
// cx.focus_self(); // cx.focus_self();
// if let Some(active_pane) = active_pane { // if let Some(active_pane) = active_pane {
// cx.focus(&active_pane); // cx.focus(&active_pane);
@ -3451,7 +3442,7 @@ impl Workspace {
// cx.focus(workspace.panes.last().unwrap()); // cx.focus(workspace.panes.last().unwrap());
// } // }
} else { } else {
todo!() // todo!()
// let old_center_handle = old_center_pane.and_then(|weak| weak.upgrade()); // let old_center_handle = old_center_pane.and_then(|weak| weak.upgrade());
// if let Some(old_center_handle) = old_center_handle { // if let Some(old_center_handle) = old_center_handle {
// cx.focus(&old_center_handle) // cx.focus(&old_center_handle)
@ -3471,7 +3462,7 @@ impl Workspace {
dock.active_panel() dock.active_panel()
.map(|panel| panel.set_zoomed(docks.left.zoom, cx)); .map(|panel| panel.set_zoomed(docks.left.zoom, cx));
if docks.left.visible && docks.left.zoom { if docks.left.visible && docks.left.zoom {
todo!() // todo!()
// cx.focus_self() // cx.focus_self()
} }
}); });
@ -3487,7 +3478,7 @@ impl Workspace {
.map(|panel| panel.set_zoomed(docks.right.zoom, cx)); .map(|panel| panel.set_zoomed(docks.right.zoom, cx));
if docks.right.visible && docks.right.zoom { if docks.right.visible && docks.right.zoom {
todo!() // todo!()
// cx.focus_self() // cx.focus_self()
} }
}); });
@ -3503,7 +3494,7 @@ impl Workspace {
.map(|panel| panel.set_zoomed(docks.bottom.zoom, cx)); .map(|panel| panel.set_zoomed(docks.bottom.zoom, cx));
if docks.bottom.visible && docks.bottom.zoom { if docks.bottom.visible && docks.bottom.zoom {
todo!() // todo!()
// cx.focus_self() // cx.focus_self()
} }
}); });
@ -3587,14 +3578,12 @@ fn window_bounds_env_override(cx: &AsyncAppContext) -> Option<WindowBounds> {
fn open_items( fn open_items(
serialized_workspace: Option<SerializedWorkspace>, serialized_workspace: Option<SerializedWorkspace>,
project_paths_to_open: Vec<(PathBuf, Option<ProjectPath>)>, mut project_paths_to_open: Vec<(PathBuf, Option<ProjectPath>)>,
app_state: Arc<AppState>, app_state: Arc<AppState>,
cx: &mut ViewContext<Workspace>, cx: &mut ViewContext<Workspace>,
) -> impl Future<Output = Result<Vec<Option<Result<Box<dyn ItemHandle>>>>>> { ) -> impl 'static + Future<Output = Result<Vec<Option<Result<Box<dyn ItemHandle>>>>>> {
let mut opened_items = Vec::with_capacity(project_paths_to_open.len()); let restored_items = serialized_workspace.map(|serialized_workspace| {
Workspace::load_workspace(
if let Some(serialized_workspace) = serialized_workspace {
let restored_items = Workspace::load_workspace(
serialized_workspace, serialized_workspace,
project_paths_to_open project_paths_to_open
.iter() .iter()
@ -3603,61 +3592,72 @@ fn open_items(
.collect(), .collect(),
cx, cx,
) )
.await?; });
let restored_project_paths = restored_items cx.spawn(|workspace, mut cx| async move {
.iter() let mut opened_items = Vec::with_capacity(project_paths_to_open.len());
.filter_map(|item| item.as_ref()?.project_path(cx))
.collect::<HashSet<_>>();
for restored_item in restored_items { if let Some(restored_items) = restored_items {
opened_items.push(restored_item.map(Ok)); let restored_items = restored_items.await?;
}
project_paths_to_open let restored_project_paths = restored_items
.iter_mut() .iter()
.for_each(|(_, project_path)| { .filter_map(|item| {
if let Some(project_path_to_open) = project_path { cx.update(|_, cx| item.as_ref()?.project_path(cx))
if restored_project_paths.contains(project_path_to_open) { .ok()
*project_path = None; .flatten()
} })
} .collect::<HashSet<_>>();
});
} else {
for _ in 0..project_paths_to_open.len() {
opened_items.push(None);
}
}
assert!(opened_items.len() == project_paths_to_open.len());
let tasks = for restored_item in restored_items {
project_paths_to_open opened_items.push(restored_item.map(Ok));
.into_iter() }
.enumerate()
.map(|(i, (abs_path, project_path))| { project_paths_to_open
cx.spawn(|workspace, mut cx| { .iter_mut()
let fs = app_state.fs.clone(); .for_each(|(_, project_path)| {
async move { if let Some(project_path_to_open) = project_path {
let file_project_path = project_path?; if restored_project_paths.contains(project_path_to_open) {
if fs.is_file(&abs_path).await { *project_path = None;
Some((
i,
workspace
.update(&mut cx, |workspace, cx| {
workspace.open_path(file_project_path, None, true, cx)
})
.log_err()?
.await,
))
} else {
None
} }
} }
}) });
}); } else {
for _ in 0..project_paths_to_open.len() {
opened_items.push(None);
}
}
assert!(opened_items.len() == project_paths_to_open.len());
let tasks =
project_paths_to_open
.into_iter()
.enumerate()
.map(|(i, (abs_path, project_path))| {
let workspace = workspace.clone();
cx.spawn(|mut cx| {
let fs = app_state.fs.clone();
async move {
let file_project_path = project_path?;
if fs.is_file(&abs_path).await {
Some((
i,
workspace
.update(&mut cx, |workspace, cx| {
workspace.open_path(file_project_path, None, true, cx)
})
.log_err()?
.await,
))
} else {
None
}
}
})
});
let tasks = tasks.collect::<Vec<_>>();
let tasks = tasks.collect::<Vec<_>>();
async move {
let tasks = futures::future::join_all(tasks.into_iter()); let tasks = futures::future::join_all(tasks.into_iter());
for maybe_opened_path in tasks.await.into_iter() { for maybe_opened_path in tasks.await.into_iter() {
if let Some((i, path_open_result)) = maybe_opened_path { if let Some((i, path_open_result)) = maybe_opened_path {
@ -3666,7 +3666,7 @@ fn open_items(
} }
Ok(opened_items) Ok(opened_items)
} })
} }
// fn notify_of_new_dock(workspace: &WeakView<Workspace>, cx: &mut AsyncAppContext) { // fn notify_of_new_dock(workspace: &WeakView<Workspace>, cx: &mut AsyncAppContext) {

View file

@ -141,7 +141,8 @@ pub async fn handle_cli_connection(
}), }),
) )
.detach(); .detach();
}); })
.ok();
item_release_futures.push(released.1); item_release_futures.push(released.1);
} }
Some(Err(err)) => { Some(Err(err)) => {
@ -170,7 +171,6 @@ pub async fn handle_cli_connection(
let _ = done_tx.send(()); let _ = done_tx.send(());
}) })
}); });
drop(workspace);
let _ = done_rx.await; let _ = done_rx.await;
} else { } else {
let _ = futures::future::try_join_all(item_release_futures) let _ = futures::future::try_join_all(item_release_futures)