Reactivate the correct item in each pane when deserializing

This commit is contained in:
Kay Simmons 2022-11-30 17:28:49 -08:00 committed by Mikayla Maki
parent f68e8d4664
commit 8a48567857
5 changed files with 83 additions and 58 deletions

View file

@ -113,7 +113,6 @@ macro_rules! query {
$vis async fn $id(&self) -> $crate::anyhow::Result<()> { $vis async fn $id(&self) -> $crate::anyhow::Result<()> {
use $crate::anyhow::Context; use $crate::anyhow::Context;
self.write(|connection| { self.write(|connection| {
let sql_stmt = $crate::sqlez_macros::sql!($($sql)+); let sql_stmt = $crate::sqlez_macros::sql!($($sql)+);
@ -143,7 +142,6 @@ macro_rules! query {
$vis async fn $id(&self, $arg: $arg_type) -> $crate::anyhow::Result<()> { $vis async fn $id(&self, $arg: $arg_type) -> $crate::anyhow::Result<()> {
use $crate::anyhow::Context; use $crate::anyhow::Context;
self.write(move |connection| { self.write(move |connection| {
let sql_stmt = $crate::sqlez_macros::sql!($($sql)+); let sql_stmt = $crate::sqlez_macros::sql!($($sql)+);
@ -186,7 +184,7 @@ macro_rules! query {
)) ))
} }
}; };
($vis:vis async fn $id:ident() -> Result<Vec<$return_type:ty>> { $($sql:tt)+ }) => { ($vis:vis async fn $id:ident() -> Result<Vec<$return_type:ty>> { $($sql:tt)+ }) => {
pub async fn $id(&self) -> $crate::anyhow::Result<Vec<$return_type>> { pub async fn $id(&self) -> $crate::anyhow::Result<Vec<$return_type>> {
use $crate::anyhow::Context; use $crate::anyhow::Context;

View file

@ -137,7 +137,6 @@ impl TerminalContainer {
TerminalContainerContent::Error(view) TerminalContainerContent::Error(view)
} }
}; };
// cx.focus(content.handle());
TerminalContainer { TerminalContainer {
content, content,

View file

@ -76,6 +76,7 @@ impl Domain for Workspace {
pane_id INTEGER NOT NULL, pane_id INTEGER NOT NULL,
kind TEXT NOT NULL, kind TEXT NOT NULL,
position INTEGER NOT NULL, position INTEGER NOT NULL,
active INTEGER NOT NULL,
FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id) FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id)
ON DELETE CASCADE ON DELETE CASCADE
ON UPDATE CASCADE, ON UPDATE CASCADE,
@ -352,7 +353,7 @@ impl WorkspaceDb {
fn get_items(&self, pane_id: PaneId) -> Result<Vec<SerializedItem>> { fn get_items(&self, pane_id: PaneId) -> Result<Vec<SerializedItem>> {
Ok(self.select_bound(sql!( Ok(self.select_bound(sql!(
SELECT kind, item_id FROM items SELECT kind, item_id, active FROM items
WHERE pane_id = ? WHERE pane_id = ?
ORDER BY position ORDER BY position
))?(pane_id)?) ))?(pane_id)?)
@ -365,10 +366,9 @@ impl WorkspaceDb {
items: &[SerializedItem], items: &[SerializedItem],
) -> Result<()> { ) -> Result<()> {
let mut insert = conn.exec_bound(sql!( let mut insert = conn.exec_bound(sql!(
INSERT INTO items(workspace_id, pane_id, position, kind, item_id) VALUES (?, ?, ?, ?, ?) INSERT INTO items(workspace_id, pane_id, position, kind, item_id, active) VALUES (?, ?, ?, ?, ?, ?)
)).context("Preparing insertion")?; )).context("Preparing insertion")?;
for (position, item) in items.iter().enumerate() { for (position, item) in items.iter().enumerate() {
dbg!(item);
insert((workspace_id, pane_id, position, item))?; insert((workspace_id, pane_id, position, item))?;
} }
@ -497,6 +497,7 @@ mod tests {
workspace_2.dock_pane.children.push(SerializedItem { workspace_2.dock_pane.children.push(SerializedItem {
kind: Arc::from("Test"), kind: Arc::from("Test"),
item_id: 10, item_id: 10,
active: true,
}); });
db.save_workspace(workspace_2).await; db.save_workspace(workspace_2).await;
@ -523,10 +524,10 @@ mod tests {
let dock_pane = crate::persistence::model::SerializedPane { let dock_pane = crate::persistence::model::SerializedPane {
children: vec![ children: vec![
SerializedItem::new("Terminal", 1), SerializedItem::new("Terminal", 1, false),
SerializedItem::new("Terminal", 2), SerializedItem::new("Terminal", 2, false),
SerializedItem::new("Terminal", 3), SerializedItem::new("Terminal", 3, true),
SerializedItem::new("Terminal", 4), SerializedItem::new("Terminal", 4, false),
], ],
active: false, active: false,
}; };
@ -544,15 +545,15 @@ mod tests {
children: vec![ children: vec![
SerializedPaneGroup::Pane(SerializedPane::new( SerializedPaneGroup::Pane(SerializedPane::new(
vec![ vec![
SerializedItem::new("Terminal", 5), SerializedItem::new("Terminal", 5, false),
SerializedItem::new("Terminal", 6), SerializedItem::new("Terminal", 6, true),
], ],
false, false,
)), )),
SerializedPaneGroup::Pane(SerializedPane::new( SerializedPaneGroup::Pane(SerializedPane::new(
vec![ vec![
SerializedItem::new("Terminal", 7), SerializedItem::new("Terminal", 7, true),
SerializedItem::new("Terminal", 8), SerializedItem::new("Terminal", 8, false),
], ],
false, false,
)), )),
@ -560,8 +561,8 @@ mod tests {
}, },
SerializedPaneGroup::Pane(SerializedPane::new( SerializedPaneGroup::Pane(SerializedPane::new(
vec![ vec![
SerializedItem::new("Terminal", 9), SerializedItem::new("Terminal", 9, false),
SerializedItem::new("Terminal", 10), SerializedItem::new("Terminal", 10, true),
], ],
false, false,
)), )),
@ -689,10 +690,10 @@ mod tests {
let dock_pane = crate::persistence::model::SerializedPane::new( let dock_pane = crate::persistence::model::SerializedPane::new(
vec![ vec![
SerializedItem::new("Terminal", 1), SerializedItem::new("Terminal", 1, false),
SerializedItem::new("Terminal", 4), SerializedItem::new("Terminal", 4, false),
SerializedItem::new("Terminal", 2), SerializedItem::new("Terminal", 2, false),
SerializedItem::new("Terminal", 3), SerializedItem::new("Terminal", 3, true),
], ],
false, false,
); );
@ -725,15 +726,15 @@ mod tests {
children: vec![ children: vec![
SerializedPaneGroup::Pane(SerializedPane::new( SerializedPaneGroup::Pane(SerializedPane::new(
vec![ vec![
SerializedItem::new("Terminal", 1), SerializedItem::new("Terminal", 1, false),
SerializedItem::new("Terminal", 2), SerializedItem::new("Terminal", 2, true),
], ],
false, false,
)), )),
SerializedPaneGroup::Pane(SerializedPane::new( SerializedPaneGroup::Pane(SerializedPane::new(
vec![ vec![
SerializedItem::new("Terminal", 4), SerializedItem::new("Terminal", 4, false),
SerializedItem::new("Terminal", 3), SerializedItem::new("Terminal", 3, true),
], ],
true, true,
)), )),
@ -741,8 +742,8 @@ mod tests {
}, },
SerializedPaneGroup::Pane(SerializedPane::new( SerializedPaneGroup::Pane(SerializedPane::new(
vec![ vec![
SerializedItem::new("Terminal", 5), SerializedItem::new("Terminal", 5, true),
SerializedItem::new("Terminal", 6), SerializedItem::new("Terminal", 6, false),
], ],
false, false,
)), )),
@ -772,15 +773,15 @@ mod tests {
children: vec![ children: vec![
SerializedPaneGroup::Pane(SerializedPane::new( SerializedPaneGroup::Pane(SerializedPane::new(
vec![ vec![
SerializedItem::new("Terminal", 1), SerializedItem::new("Terminal", 1, false),
SerializedItem::new("Terminal", 2), SerializedItem::new("Terminal", 2, true),
], ],
false, false,
)), )),
SerializedPaneGroup::Pane(SerializedPane::new( SerializedPaneGroup::Pane(SerializedPane::new(
vec![ vec![
SerializedItem::new("Terminal", 4), SerializedItem::new("Terminal", 4, false),
SerializedItem::new("Terminal", 3), SerializedItem::new("Terminal", 3, true),
], ],
true, true,
)), )),
@ -788,8 +789,8 @@ mod tests {
}, },
SerializedPaneGroup::Pane(SerializedPane::new( SerializedPaneGroup::Pane(SerializedPane::new(
vec![ vec![
SerializedItem::new("Terminal", 5), SerializedItem::new("Terminal", 5, false),
SerializedItem::new("Terminal", 6), SerializedItem::new("Terminal", 6, true),
], ],
false, false,
)), )),
@ -807,15 +808,15 @@ mod tests {
children: vec![ children: vec![
SerializedPaneGroup::Pane(SerializedPane::new( SerializedPaneGroup::Pane(SerializedPane::new(
vec![ vec![
SerializedItem::new("Terminal", 1), SerializedItem::new("Terminal", 1, false),
SerializedItem::new("Terminal", 2), SerializedItem::new("Terminal", 2, true),
], ],
false, false,
)), )),
SerializedPaneGroup::Pane(SerializedPane::new( SerializedPaneGroup::Pane(SerializedPane::new(
vec![ vec![
SerializedItem::new("Terminal", 4), SerializedItem::new("Terminal", 4, true),
SerializedItem::new("Terminal", 3), SerializedItem::new("Terminal", 3, false),
], ],
true, true,
)), )),

View file

@ -147,7 +147,8 @@ impl SerializedPane {
workspace: &ViewHandle<Workspace>, workspace: &ViewHandle<Workspace>,
cx: &mut AsyncAppContext, cx: &mut AsyncAppContext,
) { ) {
for item in self.children.iter() { let mut active_item_index = None;
for (index, item) in self.children.iter().enumerate() {
let project = project.clone(); let project = project.clone();
let item_handle = pane_handle let item_handle = pane_handle
.update(cx, |_, cx| { .update(cx, |_, cx| {
@ -174,6 +175,16 @@ impl SerializedPane {
Pane::add_item(workspace, &pane_handle, item_handle, false, false, None, cx); Pane::add_item(workspace, &pane_handle, item_handle, false, false, None, cx);
}) })
} }
if item.active {
active_item_index = Some(index);
}
}
if let Some(active_item_index) = active_item_index {
pane_handle.update(cx, |pane, cx| {
pane.activate_item(active_item_index, false, false, cx);
})
} }
} }
} }
@ -186,13 +197,15 @@ pub type ItemId = usize;
pub struct SerializedItem { pub struct SerializedItem {
pub kind: Arc<str>, pub kind: Arc<str>,
pub item_id: ItemId, pub item_id: ItemId,
pub active: bool,
} }
impl SerializedItem { impl SerializedItem {
pub fn new(kind: impl AsRef<str>, item_id: ItemId) -> Self { pub fn new(kind: impl AsRef<str>, item_id: ItemId, active: bool) -> Self {
Self { Self {
kind: Arc::from(kind.as_ref()), kind: Arc::from(kind.as_ref()),
item_id, item_id,
active,
} }
} }
} }
@ -203,6 +216,7 @@ impl Default for SerializedItem {
SerializedItem { SerializedItem {
kind: Arc::from("Terminal"), kind: Arc::from("Terminal"),
item_id: 100000, item_id: 100000,
active: false,
} }
} }
} }
@ -210,7 +224,8 @@ impl Default for SerializedItem {
impl Bind for &SerializedItem { impl Bind for &SerializedItem {
fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> { fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
let next_index = statement.bind(self.kind.clone(), start_index)?; let next_index = statement.bind(self.kind.clone(), start_index)?;
statement.bind(self.item_id, next_index) let next_index = statement.bind(self.item_id, next_index)?;
statement.bind(self.active, next_index)
} }
} }
@ -218,7 +233,15 @@ impl Column for SerializedItem {
fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> { fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
let (kind, next_index) = Arc::<str>::column(statement, start_index)?; let (kind, next_index) = Arc::<str>::column(statement, start_index)?;
let (item_id, next_index) = ItemId::column(statement, next_index)?; let (item_id, next_index) = ItemId::column(statement, next_index)?;
Ok((SerializedItem { kind, item_id }, next_index)) let (active, next_index) = bool::column(statement, next_index)?;
Ok((
SerializedItem {
kind,
item_id,
active,
},
next_index,
))
} }
} }

View file

@ -2292,12 +2292,14 @@ impl Workspace {
) -> SerializedPane { ) -> SerializedPane {
let (items, active) = { let (items, active) = {
let pane = pane_handle.read(cx); let pane = pane_handle.read(cx);
let active_item_id = pane.active_item().map(|item| item.id());
( (
pane.items() pane.items()
.filter_map(|item_handle| { .filter_map(|item_handle| {
Some(SerializedItem { Some(SerializedItem {
kind: Arc::from(item_handle.serialized_item_kind()?), kind: Arc::from(item_handle.serialized_item_kind()?),
item_id: item_handle.id(), item_id: item_handle.id(),
active: Some(item_handle.id()) == active_item_id,
}) })
}) })
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
@ -2308,8 +2310,6 @@ impl Workspace {
SerializedPane::new(items, active) SerializedPane::new(items, active)
} }
let dock_pane = serialize_pane_handle(self.dock.pane(), cx);
fn build_serialized_pane_group( fn build_serialized_pane_group(
pane_group: &Member, pane_group: &Member,
cx: &AppContext, cx: &AppContext,
@ -2327,19 +2327,25 @@ impl Workspace {
} }
} }
} }
let center_group = build_serialized_pane_group(&self.center.root, cx);
let serialized_workspace = SerializedWorkspace { let location = self.location(cx);
id: self.database_id,
location: self.location(cx),
dock_position: self.dock.position(),
dock_pane,
center_group,
};
cx.background() if !location.paths().is_empty() {
.spawn(persistence::DB.save_workspace(serialized_workspace)) let dock_pane = serialize_pane_handle(self.dock.pane(), cx);
.detach(); let center_group = build_serialized_pane_group(&self.center.root, cx);
let serialized_workspace = SerializedWorkspace {
id: self.database_id,
location: self.location(cx),
dock_position: self.dock.position(),
dock_pane,
center_group,
};
cx.background()
.spawn(persistence::DB.save_workspace(serialized_workspace))
.detach();
}
} }
fn load_from_serialized_workspace( fn load_from_serialized_workspace(
@ -2380,13 +2386,11 @@ impl Workspace {
Dock::set_dock_position(workspace, serialized_workspace.dock_position, cx); Dock::set_dock_position(workspace, serialized_workspace.dock_position, cx);
if let Some(active_pane) = active_pane { if let Some(active_pane) = active_pane {
// Change the focus to the workspace first so that we retrigger focus in on the pane.
cx.focus_self();
cx.focus(active_pane); cx.focus(active_pane);
} }
if workspace.items(cx).next().is_none() {
cx.dispatch_action(NewFile);
}
cx.notify(); cx.notify();
}); });
} }