terminal: Persist pinned tabs in terminal (#31921)

Closes #31098

Release Notes:

- Fixed terminal pinned tab state not persisting across restarts.
This commit is contained in:
Piotr Osiewicz 2025-06-02 22:36:57 +02:00 committed by GitHub
parent 3f90bc81bd
commit f1aab1120d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 19 additions and 4 deletions

View file

@ -74,10 +74,12 @@ fn serialize_pane(pane: &Entity<Pane>, active: bool, cx: &mut App) -> Serialized
.map(|item| item.item_id().as_u64()) .map(|item| item.item_id().as_u64())
.filter(|active_id| items_to_serialize.contains(active_id)); .filter(|active_id| items_to_serialize.contains(active_id));
let pinned_count = pane.pinned_count();
SerializedPane { SerializedPane {
active, active,
children, children,
active_item, active_item,
pinned_count,
} }
} }
@ -229,10 +231,11 @@ async fn deserialize_pane_group(
}) })
.log_err()?; .log_err()?;
let active_item = serialized_pane.active_item; let active_item = serialized_pane.active_item;
let pinned_count = serialized_pane.pinned_count;
let terminal = pane let terminal = pane
.update_in(cx, |pane, window, cx| { .update_in(cx, |pane, window, cx| {
populate_pane_items(pane, new_items, active_item, window, cx); populate_pane_items(pane, new_items, active_item, window, cx);
pane.set_pinned_count(pinned_count);
// Avoid blank panes in splits // Avoid blank panes in splits
if pane.items_len() == 0 { if pane.items_len() == 0 {
let working_directory = workspace let working_directory = workspace
@ -339,6 +342,8 @@ pub(crate) struct SerializedPane {
pub active: bool, pub active: bool,
pub children: Vec<u64>, pub children: Vec<u64>,
pub active_item: Option<u64>, pub active_item: Option<u64>,
#[serde(default)]
pub pinned_count: usize,
} }
#[derive(Debug)] #[derive(Debug)]

View file

@ -325,7 +325,6 @@ impl TerminalPanel {
.ok(); .ok();
} }
} }
Ok(terminal_panel) Ok(terminal_panel)
} }
@ -393,6 +392,9 @@ impl TerminalPanel {
pane::Event::Focus => { pane::Event::Focus => {
self.active_pane = pane.clone(); self.active_pane = pane.clone();
} }
pane::Event::ItemPinned | pane::Event::ItemUnpinned => {
self.serialize(cx);
}
_ => {} _ => {}
} }

View file

@ -230,6 +230,8 @@ pub enum Event {
item: Box<dyn ItemHandle>, item: Box<dyn ItemHandle>,
}, },
Split(SplitDirection), Split(SplitDirection),
ItemPinned,
ItemUnpinned,
JoinAll, JoinAll,
JoinIntoNext, JoinIntoNext,
ChangeItemTitle, ChangeItemTitle,
@ -274,6 +276,8 @@ impl fmt::Debug for Event {
.field("item", &item.id()) .field("item", &item.id())
.field("save_intent", save_intent) .field("save_intent", save_intent)
.finish(), .finish(),
Event::ItemPinned => f.write_str("ItemPinned"),
Event::ItemUnpinned => f.write_str("ItemUnpinned"),
} }
} }
} }
@ -780,11 +784,12 @@ impl Pane {
} }
} }
pub(crate) fn set_pinned_count(&mut self, count: usize) { /// Should only be used when deserializing a pane.
pub fn set_pinned_count(&mut self, count: usize) {
self.pinned_tab_count = count; self.pinned_tab_count = count;
} }
pub(crate) fn pinned_count(&self) -> usize { pub fn pinned_count(&self) -> usize {
self.pinned_tab_count self.pinned_tab_count
} }
@ -2074,6 +2079,7 @@ impl Pane {
}) })
.ok()?; .ok()?;
} }
cx.emit(Event::ItemPinned);
Some(()) Some(())
}); });
@ -2098,6 +2104,7 @@ impl Pane {
}) })
.ok()?; .ok()?;
} }
cx.emit(Event::ItemUnpinned);
Some(()) Some(())
}); });

View file

@ -3761,6 +3761,7 @@ impl Workspace {
} }
cx.notify(); cx.notify();
} }
pane::Event::ItemPinned | pane::Event::ItemUnpinned => {}
} }
if serialize_workspace { if serialize_workspace {