Always remember the last window size and position (#9416)

Mikayla Maki created

make new runs of zed always match the window of the previous run of Zed,
even if it's not the same workspace

fixes https://github.com/zed-industries/zed/issues/5258

Release Notes:

- Zed will always open new windows with the same position and location
as the previous instance of Zed.

Change summary

crates/db/src/query.rs              |  2 
crates/workspace/src/persistence.rs |  4 +-
crates/workspace/src/workspace.rs   | 53 +++++++++++++++++-------------
3 files changed, 33 insertions(+), 26 deletions(-)

Detailed changes

crates/db/src/query.rs 🔗

@@ -217,7 +217,7 @@ macro_rules! query {
 
             let sql_stmt = $crate::sqlez_macros::sql!($($sql)+);
 
-            self.select_row::<$return_type>(indoc! { $sql })?()
+            self.select_row::<$return_type>(sql_stmt)?()
                 .context(::std::format!(
                     "Error in {}, select_row_bound failed to execute or parse for: {}",
                     ::std::stringify!($id),

crates/workspace/src/persistence.rs 🔗

@@ -421,8 +421,8 @@ impl WorkspaceDb {
     }
 
     query! {
-        pub fn last_monitor() -> Result<Option<Uuid>> {
-            SELECT display
+        pub fn last_window() -> Result<(Option<Uuid>, Option<SerializedWindowsBounds>, Option<bool>)> {
+            SELECT display, window_state, window_x, window_y, window_width, window_height, fullscreen
             FROM workspaces
             WHERE workspace_location IS NOT NULL
             ORDER BY timestamp DESC

crates/workspace/src/workspace.rs 🔗

@@ -882,32 +882,39 @@ impl Workspace {
 
                 let (bounds, display, fullscreen) = if let Some(bounds) = window_bounds_override {
                     (Some(bounds), None, false)
-                } else if let Some((serialized_display, mut bounds, fullscreen)) =
-                    serialized_workspace.as_ref().and_then(|workspace| {
-                        Some((workspace.display?, workspace.bounds?, workspace.fullscreen))
-                    })
-                {
-                    // Stored bounds are relative to the containing display.
-                    // So convert back to global coordinates if that screen still exists
-                    let screen_bounds = cx
-                        .update(|cx| {
-                            cx.displays()
-                                .into_iter()
-                                .find(|display| display.uuid().ok() == Some(serialized_display))
+                } else {
+                    let restorable_bounds = serialized_workspace
+                        .as_ref()
+                        .and_then(|workspace| {
+                            Some((workspace.display?, workspace.bounds?, workspace.fullscreen))
                         })
-                        .ok()
-                        .flatten()
-                        .map(|screen| screen.bounds());
+                        .or_else(|| {
+                            let (display, bounds, fullscreen) = DB.last_window().log_err()?;
+                            Some((display?, bounds?.0, fullscreen.unwrap_or(false)))
+                        });
 
-                    if let Some(screen_bounds) = screen_bounds {
-                        bounds.origin.x += screen_bounds.origin.x;
-                        bounds.origin.y += screen_bounds.origin.y;
-                    }
+                    if let Some((serialized_display, mut bounds, fullscreen)) = restorable_bounds {
+                        // Stored bounds are relative to the containing display.
+                        // So convert back to global coordinates if that screen still exists
+                        let screen_bounds = cx
+                            .update(|cx| {
+                                cx.displays()
+                                    .into_iter()
+                                    .find(|display| display.uuid().ok() == Some(serialized_display))
+                            })
+                            .ok()
+                            .flatten()
+                            .map(|screen| screen.bounds());
 
-                    (Some(bounds), Some(serialized_display), fullscreen)
-                } else {
-                    let display = DB.last_monitor().log_err().flatten();
-                    (None, display, false)
+                        if let Some(screen_bounds) = screen_bounds {
+                            bounds.origin.x += screen_bounds.origin.x;
+                            bounds.origin.y += screen_bounds.origin.y;
+                        }
+
+                        (Some(bounds), Some(serialized_display), fullscreen)
+                    } else {
+                        (None, None, false)
+                    }
                 };
 
                 // Use the serialized workspace to construct the new window