From f374038da0e9dbe81e29b42df29f6c42ab39c378 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Tue, 10 Sep 2024 19:19:21 -0400 Subject: [PATCH] pane: Serialize pinned tab state (#17670) Release Notes: - Tab pin state is now persisted across Zed runs. --- crates/workspace/src/pane.rs | 8 ++++++ crates/workspace/src/persistence.rs | 34 ++++++++++++++++++----- crates/workspace/src/persistence/model.rs | 13 +++++++-- crates/workspace/src/workspace.rs | 5 ++-- 4 files changed, 49 insertions(+), 11 deletions(-) diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 23148d6376f4561b13e805e7dd5a57b37d72dc07..cc752f7aec9ff646893cda5f6eef454d4e9ab95c 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -715,6 +715,14 @@ impl Pane { } } + pub(crate) fn set_pinned_count(&mut self, count: usize) { + self.pinned_tab_count = count; + } + + pub(crate) fn pinned_count(&self) -> usize { + self.pinned_tab_count + } + pub fn handle_item_edit(&mut self, item_id: EntityId, cx: &AppContext) { if let Some(preview_item) = self.preview_item() { if preview_item.item_id() == item_id && !preview_item.preserve_preview(cx) { diff --git a/crates/workspace/src/persistence.rs b/crates/workspace/src/persistence.rs index d035b35c1079e14bb48b96ca96dd52e17f215bc2..88ede4228d622d5a2acf7de6a69f500aa997b8e4 100644 --- a/crates/workspace/src/persistence.rs +++ b/crates/workspace/src/persistence.rs @@ -13,7 +13,7 @@ use sqlez::{ }; use ui::px; -use util::ResultExt; +use util::{maybe, ResultExt}; use uuid::Uuid; use crate::WorkspaceId; @@ -352,6 +352,9 @@ define_connection! { sql!( ALTER TABLE workspaces ADD COLUMN window_id INTEGER DEFAULT NULL; ), + sql!( + ALTER TABLE panes ADD COLUMN pinned_count INTEGER DEFAULT 0; + ) ]; } @@ -846,6 +849,7 @@ impl WorkspaceDb { SerializedPaneGroup::Pane(SerializedPane { active: true, children: vec![], + pinned_count: 0, }) })) } @@ -861,15 +865,17 @@ impl WorkspaceDb { Option, Option, Option, + Option, Option, ); self.select_bound::(sql!( - SELECT group_id, axis, pane_id, active, flexes + SELECT group_id, axis, pane_id, active, pinned_count, flexes FROM (SELECT group_id, axis, NULL as pane_id, NULL as active, + NULL as pinned_count, position, parent_group_id, workspace_id, @@ -881,6 +887,7 @@ impl WorkspaceDb { NULL, center_panes.pane_id, panes.active as active, + pinned_count, position, parent_group_id, panes.workspace_id as workspace_id, @@ -891,7 +898,8 @@ impl WorkspaceDb { ORDER BY position ))?((group_id, workspace_id))? .into_iter() - .map(|(group_id, axis, pane_id, active, flexes)| { + .map(|(group_id, axis, pane_id, active, pinned_count, flexes)| { + let maybe_pane = maybe!({ Some((pane_id?, active?, pinned_count?)) }); if let Some((group_id, axis)) = group_id.zip(axis) { let flexes = flexes .map(|flexes: String| serde_json::from_str::>(&flexes)) @@ -902,10 +910,11 @@ impl WorkspaceDb { children: self.get_pane_group(workspace_id, Some(group_id))?, flexes, }) - } else if let Some((pane_id, active)) = pane_id.zip(active) { + } else if let Some((pane_id, active, pinned_count)) = maybe_pane { Ok(SerializedPaneGroup::Pane(SerializedPane::new( self.get_items(pane_id)?, active, + pinned_count, ))) } else { bail!("Pane Group Child was neither a pane group or a pane"); @@ -977,10 +986,10 @@ impl WorkspaceDb { parent: Option<(GroupId, usize)>, ) -> Result { let pane_id = conn.select_row_bound::<_, i64>(sql!( - INSERT INTO panes(workspace_id, active) - VALUES (?, ?) + INSERT INTO panes(workspace_id, active, pinned_count) + VALUES (?, ?, ?) RETURNING pane_id - ))?((workspace_id, pane.active))? + ))?((workspace_id, pane.active, pane.pinned_count))? .ok_or_else(|| anyhow!("Could not retrieve inserted pane_id"))?; let (parent_id, order) = parent.unzip(); @@ -1219,6 +1228,7 @@ mod tests { SerializedItem::new("Terminal", 6, true, false), ], false, + 0, )), SerializedPaneGroup::Pane(SerializedPane::new( vec![ @@ -1226,6 +1236,7 @@ mod tests { SerializedItem::new("Terminal", 8, false, false), ], false, + 0, )), ], ), @@ -1235,6 +1246,7 @@ mod tests { SerializedItem::new("Terminal", 10, true, false), ], false, + 0, )), ], ); @@ -1523,6 +1535,7 @@ mod tests { SerializedItem::new("Terminal", 2, true, false), ], false, + 0, )), SerializedPaneGroup::Pane(SerializedPane::new( vec![ @@ -1530,6 +1543,7 @@ mod tests { SerializedItem::new("Terminal", 3, true, false), ], true, + 0, )), ], ), @@ -1539,6 +1553,7 @@ mod tests { SerializedItem::new("Terminal", 6, false, false), ], false, + 0, )), ], ); @@ -1570,6 +1585,7 @@ mod tests { SerializedItem::new("Terminal", 2, true, false), ], false, + 0, )), SerializedPaneGroup::Pane(SerializedPane::new( vec![ @@ -1577,6 +1593,7 @@ mod tests { SerializedItem::new("Terminal", 3, true, false), ], true, + 0, )), ], ), @@ -1586,6 +1603,7 @@ mod tests { SerializedItem::new("Terminal", 6, true, false), ], false, + 0, )), ], ); @@ -1605,6 +1623,7 @@ mod tests { SerializedItem::new("Terminal", 2, true, false), ], false, + 0, )), SerializedPaneGroup::Pane(SerializedPane::new( vec![ @@ -1612,6 +1631,7 @@ mod tests { SerializedItem::new("Terminal", 3, false, false), ], true, + 0, )), ], ); diff --git a/crates/workspace/src/persistence/model.rs b/crates/workspace/src/persistence/model.rs index 8b6d66f3cb4d6e2ee46fd95296b89cca0096ff68..d6f8001f25fc3edb70d5263e1411005e64317bd0 100644 --- a/crates/workspace/src/persistence/model.rs +++ b/crates/workspace/src/persistence/model.rs @@ -297,6 +297,7 @@ impl Default for SerializedPaneGroup { Self::Pane(SerializedPane { children: vec![SerializedItem::default()], active: false, + pinned_count: 0, }) } } @@ -379,11 +380,16 @@ impl SerializedPaneGroup { pub struct SerializedPane { pub(crate) active: bool, pub(crate) children: Vec, + pub(crate) pinned_count: usize, } impl SerializedPane { - pub fn new(children: Vec, active: bool) -> Self { - SerializedPane { children, active } + pub fn new(children: Vec, active: bool, pinned_count: usize) -> Self { + SerializedPane { + children, + active, + pinned_count, + } } pub async fn deserialize_to( @@ -442,6 +448,9 @@ impl SerializedPane { } })?; } + pane.update(cx, |pane, _| { + pane.set_pinned_count(self.pinned_count); + })?; anyhow::Ok(items) } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 219f75624c8ffdfa903d04a46da5349352941f98..7371e56cee2376afaaafdeb8869764a9bfc537a6 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -4025,7 +4025,7 @@ impl Workspace { }; fn serialize_pane_handle(pane_handle: &View, cx: &WindowContext) -> SerializedPane { - let (items, active) = { + let (items, active, pinned_count) = { let pane = pane_handle.read(cx); let active_item_id = pane.active_item().map(|item| item.item_id()); ( @@ -4042,10 +4042,11 @@ impl Workspace { }) .collect::>(), pane.has_focus(cx), + pane.pinned_count(), ) }; - SerializedPane::new(items, active) + SerializedPane::new(items, active, pinned_count) } fn build_serialized_pane_group(