terminal: Update terminal reopening from global to per-workspace (#25336)
Closes #7145 Currently, terminal persistence is global, i.e. split configurations are restored across all workspaces. This PR changes it to per-workspace, so configurations are restored only within the same workspace. Opening a new window will start with a fresh terminal. https://github.com/user-attachments/assets/d43fe747-9f28-4723-b409-e8dbb3a23912 Release Notes: - Improved terminal reopening to be per workspace instead of global.
This commit is contained in:
parent
144d8a1db6
commit
3759e0bf55
2 changed files with 72 additions and 24 deletions
|
@ -217,35 +217,67 @@ impl TerminalPanel {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn serialization_key(workspace: &Workspace) -> Option<String> {
|
||||||
|
workspace
|
||||||
|
.database_id()
|
||||||
|
.map(|id| i64::from(id).to_string())
|
||||||
|
.or(workspace.session_id())
|
||||||
|
.map(|id| format!("{:?}-{:?}", TERMINAL_PANEL_KEY, id))
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn load(
|
pub async fn load(
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
mut cx: AsyncWindowContext,
|
mut cx: AsyncWindowContext,
|
||||||
) -> Result<Entity<Self>> {
|
) -> Result<Entity<Self>> {
|
||||||
let serialized_panel = cx
|
let mut terminal_panel = None;
|
||||||
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(TERMINAL_PANEL_KEY) })
|
|
||||||
.await
|
|
||||||
.log_err()
|
|
||||||
.flatten()
|
|
||||||
.map(|panel| serde_json::from_str::<SerializedTerminalPanel>(&panel))
|
|
||||||
.transpose()
|
|
||||||
.log_err()
|
|
||||||
.flatten();
|
|
||||||
|
|
||||||
let terminal_panel = workspace
|
match workspace
|
||||||
.update_in(&mut cx, |workspace, window, cx| {
|
.read_with(&mut cx, |workspace, _| {
|
||||||
match serialized_panel.zip(workspace.database_id()) {
|
workspace
|
||||||
Some((serialized_panel, database_id)) => deserialize_terminal_panel(
|
.database_id()
|
||||||
workspace.weak_handle(),
|
.zip(TerminalPanel::serialization_key(workspace))
|
||||||
workspace.project().clone(),
|
})
|
||||||
database_id,
|
.ok()
|
||||||
serialized_panel,
|
.flatten()
|
||||||
window,
|
{
|
||||||
cx,
|
Some((database_id, serialization_key)) => {
|
||||||
),
|
if let Some(serialized_panel) = cx
|
||||||
None => Task::ready(Ok(cx.new(|cx| TerminalPanel::new(workspace, window, cx)))),
|
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(&serialization_key) })
|
||||||
|
.await
|
||||||
|
.log_err()
|
||||||
|
.flatten()
|
||||||
|
.map(|panel| serde_json::from_str::<SerializedTerminalPanel>(&panel))
|
||||||
|
.transpose()
|
||||||
|
.log_err()
|
||||||
|
.flatten()
|
||||||
|
{
|
||||||
|
if let Ok(serialized) = workspace
|
||||||
|
.update_in(&mut cx, |workspace, window, cx| {
|
||||||
|
deserialize_terminal_panel(
|
||||||
|
workspace.weak_handle(),
|
||||||
|
workspace.project().clone(),
|
||||||
|
database_id,
|
||||||
|
serialized_panel,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
})?
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
terminal_panel = Some(serialized);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
let terminal_panel = if let Some(panel) = terminal_panel {
|
||||||
|
panel
|
||||||
|
} else {
|
||||||
|
workspace.update_in(&mut cx, |workspace, window, cx| {
|
||||||
|
cx.new(|cx| TerminalPanel::new(workspace, window, cx))
|
||||||
})?
|
})?
|
||||||
.await?;
|
};
|
||||||
|
|
||||||
if let Some(workspace) = workspace.upgrade() {
|
if let Some(workspace) = workspace.upgrade() {
|
||||||
terminal_panel
|
terminal_panel
|
||||||
|
@ -727,6 +759,16 @@ impl TerminalPanel {
|
||||||
fn serialize(&mut self, cx: &mut Context<Self>) {
|
fn serialize(&mut self, cx: &mut Context<Self>) {
|
||||||
let height = self.height;
|
let height = self.height;
|
||||||
let width = self.width;
|
let width = self.width;
|
||||||
|
let Some(serialization_key) = self
|
||||||
|
.workspace
|
||||||
|
.update(cx, |workspace, _| {
|
||||||
|
TerminalPanel::serialization_key(workspace)
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
.flatten()
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
self.pending_serialization = cx.spawn(|terminal_panel, mut cx| async move {
|
self.pending_serialization = cx.spawn(|terminal_panel, mut cx| async move {
|
||||||
cx.background_executor()
|
cx.background_executor()
|
||||||
.timer(Duration::from_millis(50))
|
.timer(Duration::from_millis(50))
|
||||||
|
@ -745,7 +787,7 @@ impl TerminalPanel {
|
||||||
async move {
|
async move {
|
||||||
KEY_VALUE_STORE
|
KEY_VALUE_STORE
|
||||||
.write_kvp(
|
.write_kvp(
|
||||||
TERMINAL_PANEL_KEY.into(),
|
serialization_key,
|
||||||
serde_json::to_string(&SerializedTerminalPanel {
|
serde_json::to_string(&SerializedTerminalPanel {
|
||||||
items,
|
items,
|
||||||
active_item_id: None,
|
active_item_id: None,
|
||||||
|
@ -1351,8 +1393,10 @@ impl Panel for TerminalPanel {
|
||||||
DockPosition::Left | DockPosition::Right => self.width = size,
|
DockPosition::Left | DockPosition::Right => self.width = size,
|
||||||
DockPosition::Bottom => self.height = size,
|
DockPosition::Bottom => self.height = size,
|
||||||
}
|
}
|
||||||
self.serialize(cx);
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
cx.defer_in(window, |this, _, cx| {
|
||||||
|
this.serialize(cx);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_zoomed(&self, _window: &Window, cx: &App) -> bool {
|
fn is_zoomed(&self, _window: &Window, cx: &App) -> bool {
|
||||||
|
|
|
@ -4385,6 +4385,10 @@ impl Workspace {
|
||||||
self.database_id
|
self.database_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn session_id(&self) -> Option<String> {
|
||||||
|
self.session_id.clone()
|
||||||
|
}
|
||||||
|
|
||||||
fn local_paths(&self, cx: &App) -> Option<Vec<Arc<Path>>> {
|
fn local_paths(&self, cx: &App) -> Option<Vec<Arc<Path>>> {
|
||||||
let project = self.project().read(cx);
|
let project = self.project().read(cx);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue