diff options
| author | user <user@clank> | 2026-08-12 14:52:13 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-12 14:52:43 +0200 |
| commit | 598e77563b8c6cace224c763e00d2fdb4157a869 (patch) | |
| tree | beda042e3e355eef9513a461a48d15635c611b89 /zellij-server/src/panes/grid.rs | |
| parent | sl0p: per-pane status bar via OSC 5577 (experimental) (diff) | |
| download | sl0ppij-598e77563b8c6cace224c763e00d2fdb4157a869.tar.gz sl0ppij-598e77563b8c6cace224c763e00d2fdb4157a869.tar.xz sl0ppij-598e77563b8c6cace224c763e00d2fdb4157a869.zip | |
sl0p: serialise the pane status bar for resurrection
The status bar survived detach/reattach (it lives on Grid) but not a
serialise/restore cycle, so a resurrected pane came back blank.
It now travels the whole per-pane serialisation pipeline, mirroring the fork's
existing default_fg/default_bg: pane -> PaneLayoutMetadata ->
PaneLayoutManifest -> TiledPaneLayout -> a status_bar property in the serialised
KDL, then back through the normal layout parser and applied by LayoutApplier
when the pane is recreated.
The sanitiser moved from grid.rs into zellij-utils so both entry points share
one definition. That matters: a layout file on disk is no more trustworthy than
the escape sequence that wrote it -- it may have been hand-edited, or copied from
somewhere else -- so restored text is stripped and length-capped on the way in
just like the OSC payload was.
Verified end to end rather than by unit test alone: set the bar, waited for a
serialisation pass, confirmed status_bar="..." in session-layout.kdl, killed the
session until list-sessions reported EXITED, then attached and watched it come
back from disk. The earlier attempt only proved detach/reattach because Quit had
left the session alive.
Diffstat (limited to 'zellij-server/src/panes/grid.rs')
| -rw-r--r-- | zellij-server/src/panes/grid.rs | 24 |
1 files changed, 1 insertions, 23 deletions
diff --git a/zellij-server/src/panes/grid.rs b/zellij-server/src/panes/grid.rs index da937456..b91fa2a7 100644 --- a/zellij-server/src/panes/grid.rs +++ b/zellij-server/src/panes/grid.rs @@ -408,28 +408,6 @@ fn subtract_isize_from_usize(u: usize, i: isize) -> usize { } } -/// Longest status bar text we keep. A pane can only ever show one row of it, and -/// the string is held for the life of the pane, so there is no reason to retain -/// megabytes because a program looped. -const MAX_STATUS_BAR_TEXT: usize = 512; - -/// Make program-supplied status text safe to draw. -/// -/// The payload arrives in-band from whatever is running in the pane -- which -/// includes `cat` of a file someone else wrote -- so it is untrusted. Control -/// characters are dropped rather than escaped: a stray ESC would let the payload -/// break out of the frame row and repaint anything it liked, and a newline or -/// carriage return would corrupt the row. Truncation is by characters, not bytes, -/// so it cannot split a multi-byte one. -pub fn sanitize_status_bar_text(raw: &str) -> String { - raw.chars() - .filter(|c| !c.is_control()) - .take(MAX_STATUS_BAR_TEXT) - .collect::<String>() - .trim() - .to_owned() -} - pub fn parse_osc7_path(raw: &[u8]) -> Option<std::path::PathBuf> { let s = std::str::from_utf8(raw).ok()?; let rest = s.strip_prefix("file://")?; @@ -4152,7 +4130,7 @@ impl Perform for Grid { .flat_map(|p| str::from_utf8(p)) .collect::<Vec<&str>>() .join(";"); - let text = sanitize_status_bar_text(&text); + let text = zellij_utils::input::layout::sanitize_status_bar_text(&text); self.status_bar = if text.is_empty() { None } else { Some(text) }; }, Some(b"clear") => { |
