diff --git a/crates/recent_projects/src/ssh_connections.rs b/crates/recent_projects/src/ssh_connections.rs index 95e0c3732c..16b0bc53d1 100644 --- a/crates/recent_projects/src/ssh_connections.rs +++ b/crates/recent_projects/src/ssh_connections.rs @@ -1,7 +1,7 @@ use std::collections::BTreeSet; use std::{path::PathBuf, sync::Arc, time::Duration}; -use anyhow::{Result, anyhow}; +use anyhow::{Context as _, Result, anyhow}; use auto_update::AutoUpdater; use editor::Editor; use extension_host::ExtensionStore; @@ -565,7 +565,23 @@ pub async fn open_ssh_project( let window = if let Some(window) = open_options.replace_window { window } else { - let options = cx.update(|cx| (app_state.build_window_options)(None, cx))?; + let workspace_position = cx + .update(|cx| { + workspace::ssh_workspace_position_from_db( + connection_options.host.clone(), + connection_options.port, + connection_options.username.clone(), + &paths, + cx, + ) + })? + .await + .context("fetching ssh workspace position from db")?; + + let mut options = + cx.update(|cx| (app_state.build_window_options)(workspace_position.display, cx))?; + options.window_bounds = workspace_position.window_bounds; + cx.open_window(options, |window, cx| { let project = project::Project::local( app_state.client.clone(), @@ -576,7 +592,11 @@ pub async fn open_ssh_project( None, cx, ); - cx.new(|cx| Workspace::new(None, project, app_state.clone(), window, cx)) + cx.new(|cx| { + let mut workspace = Workspace::new(None, project, app_state.clone(), window, cx); + workspace.centered_layout = workspace_position.centered_layout; + workspace + }) })? }; @@ -634,7 +654,7 @@ pub async fn open_ssh_project( .ok(); if let Err(e) = did_open_ssh_project { - log::error!("Failed to open project: {:?}", e); + log::error!("Failed to open project: {e:?}"); let response = window .update(cx, |_, window, cx| { window.prompt( diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index cc41355422..a0c1b2df88 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -937,7 +937,7 @@ pub struct Workspace { _schedule_serialize: Option>, pane_history_timestamp: Arc, bounds: Bounds, - centered_layout: bool, + pub centered_layout: bool, bounds_save_task_queued: Option>, on_prompt_for_new_path: Option, on_prompt_for_open_path: Option, @@ -1313,7 +1313,7 @@ impl Workspace { } } - let serialized_workspace: Option = + let serialized_workspace = persistence::DB.workspace_for_roots(paths_to_open.as_slice()); let workspace_location = serialized_workspace @@ -7445,6 +7445,64 @@ pub fn move_active_item( }); } +#[derive(Debug)] +pub struct WorkspacePosition { + pub window_bounds: Option, + pub display: Option, + pub centered_layout: bool, +} + +pub fn ssh_workspace_position_from_db( + host: String, + port: Option, + user: Option, + paths_to_open: &[PathBuf], + cx: &App, +) -> Task> { + let paths = paths_to_open + .iter() + .map(|path| path.to_string_lossy().to_string()) + .collect::>(); + + cx.background_spawn(async move { + let serialized_ssh_project = persistence::DB + .get_or_create_ssh_project(host, port, paths, user) + .await + .context("fetching serialized ssh project")?; + let serialized_workspace = + persistence::DB.workspace_for_ssh_project(&serialized_ssh_project); + + let (window_bounds, display) = if let Some(bounds) = window_bounds_env_override() { + (Some(WindowBounds::Windowed(bounds)), None) + } else { + let restorable_bounds = serialized_workspace + .as_ref() + .and_then(|workspace| Some((workspace.display?, workspace.window_bounds?))) + .or_else(|| { + let (display, window_bounds) = DB.last_window().log_err()?; + Some((display?, window_bounds?)) + }); + + if let Some((serialized_display, serialized_status)) = restorable_bounds { + (Some(serialized_status.0), Some(serialized_display)) + } else { + (None, None) + } + }; + + let centered_layout = serialized_workspace + .as_ref() + .map(|w| w.centered_layout) + .unwrap_or(false); + + Ok(WorkspacePosition { + window_bounds, + display, + centered_layout, + }) + }) +} + #[cfg(test)] mod tests { use std::{cell::RefCell, rc::Rc};