aboutsummaryrefslogtreecommitdiffstats
path: root/zellij-server/src
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2024-12-16 16:03:20 +0100
committerGitHub <noreply@github.com>2024-12-16 16:03:20 +0100
commitdd291e2a1f9b4ee3eb1a947e1501a54b10663ea7 (patch)
tree0ae41e8175d2a3fd260b3c510a30502f6386ac7f /zellij-server/src
parentdocs(changelog): multiplayer cursor fix (diff)
downloadsl0ppij-dd291e2a1f9b4ee3eb1a947e1501a54b10663ea7.tar.gz
sl0ppij-dd291e2a1f9b4ee3eb1a947e1501a54b10663ea7.tar.xz
sl0ppij-dd291e2a1f9b4ee3eb1a947e1501a54b10663ea7.zip
feat(ux): pin floating panes (#3876)
* working * ui indication * add keybinding * add to plugin panes * fix with multiple cursors * toggle with the mouse * fix e2e tests and add new one * some cleanups * add to layouts * make mouse click more lenient * allow setting a new floating pane as pinned * make toggle work throughthe command line * add to plugin api * get tests to pass * style(fmt): rustfmt
Diffstat (limited to 'zellij-server/src')
-rw-r--r--zellij-server/src/output/mod.rs24
-rw-r--r--zellij-server/src/panes/floating_panes/floating_pane_grid.rs5
-rw-r--r--zellij-server/src/panes/floating_panes/mod.rs92
-rw-r--r--zellij-server/src/panes/plugin_pane.rs24
-rw-r--r--zellij-server/src/panes/terminal_pane.rs24
-rw-r--r--zellij-server/src/panes/tiled_panes/mod.rs15
-rw-r--r--zellij-server/src/plugins/zellij_exports.rs13
-rw-r--r--zellij-server/src/route.rs5
-rw-r--r--zellij-server/src/screen.rs36
-rw-r--r--zellij-server/src/tab/mod.rs89
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__base_floating_layout_is_included_in_swap_layouts.snap6
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__can_swap_floating_layout_at_runtime.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__close_suppressing_floating_pane.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__decrease_floating_pane_size.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__drag_pane_with_mouse.snap8
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__five_new_floating_panes.snap12
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__float_embedded_pane.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__float_embedded_pane_without_pane_frames.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__floating_layout_with_plugins_and_commands_swaped_properly.snap6
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__floating_pane_above_sixel_image.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__floating_panes_persist_across_toggles.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__increase_floating_pane_size.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__mark_text_inside_floating_pane.snap12
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_down.snap12
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_left.snap10
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_right.snap12
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_up.snap10
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_with_mouse.snap12
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_with_sixel_image.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane_in_auto_layout-2.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane_in_auto_layout-3.snap6
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane_in_auto_layout.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__rename_floating_pane.snap3
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_down.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_left.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_right.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_up.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_tab_with_floating_panes.snap8
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_whole_tab_while_floting_pane_is_suppressed.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__search_floating_tab_highlight_fring.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__search_floating_tab_nothing_highlighted.snap3
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__shrink_whole_tab_with_floating_panes_horizontally_and_vertically.snap6
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__shrink_whole_tab_with_floating_panes_horizontally_and_vertically_and_expand_back.snap12
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__suppress_floating_pane.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_including_command_panes_absent_from_existing_layout.snap10
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_including_plugin_panes_absent_from_existing_layout.snap8
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_not_including_command_panes_present_in_existing_layout.snap12
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_not_including_plugin_panes_present_in_existing_layout.snap8
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__tab_with_layout_that_has_floating_panes.snap6
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__toggle_floating_panes_on.snap4
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_closing_a_floating_pane_in_auto_layout_the_focus_goes_to_last_focused_pane.snap6
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_resizing_whole_tab_with_auto_layout_and_floating_panes_the_layout_is_maintained.snap8
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_swapping_floating_layouts_in_a_damaged_state_layout_and_pane_focus_are_unchanged.snap8
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_swapping_floating_layouts_in_an_undamaged_state_pane_focuses_on_focused_node.snap8
-rw-r--r--zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_swapping_floating_layouts_in_an_undamaged_state_with_no_focus_node_pane_focuses_on_deepest_node.snap8
-rw-r--r--zellij-server/src/ui/pane_boundaries_frame.rs120
-rw-r--r--zellij-server/src/ui/pane_contents_and_ui.rs33
-rw-r--r--zellij-server/src/unit/screen_tests.rs9
-rw-r--r--zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_break_floating_pane_to_a_new_tab-2.snap4
-rw-r--r--zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_break_floating_pane_to_a_new_tab-4.snap4
-rw-r--r--zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_break_floating_pane_to_a_new_tab.snap4
-rw-r--r--zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_floating_pane_and_coordinates.snap4
-rw-r--r--zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_floating_panes-2.snap4
-rw-r--r--zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_floating_panes-4.snap4
-rw-r--r--zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_pane_embed_or_float-2.snap4
66 files changed, 606 insertions, 211 deletions
diff --git a/zellij-server/src/output/mod.rs b/zellij-server/src/output/mod.rs
index ccb5f665..32192a20 100644
--- a/zellij-server/src/output/mod.rs
+++ b/zellij-server/src/output/mod.rs
@@ -449,6 +449,12 @@ impl Output {
self.client_character_chunks.values().any(|c| !c.is_empty())
|| self.sixel_chunks.values().any(|c| !c.is_empty())
}
+ pub fn cursor_is_visible(&self, cursor_x: usize, cursor_y: usize) -> bool {
+ self.floating_panes_stack
+ .as_ref()
+ .map(|s| s.cursor_is_visible(cursor_x, cursor_y))
+ .unwrap_or(true)
+ }
}
// this struct represents the geometry of a group of floating panes
@@ -740,6 +746,24 @@ impl FloatingPanesStack {
}
uncovered_chunks
}
+ pub fn cursor_is_visible(&self, cursor_x: usize, cursor_y: usize) -> bool {
+ let z_index = 0; // TODO: receive z_index
+ let panes_to_check = self.layers.iter().skip(z_index);
+ for pane_geom in panes_to_check {
+ let pane_top_edge = pane_geom.y;
+ let pane_left_edge = pane_geom.x;
+ let pane_bottom_edge = pane_geom.y + pane_geom.rows.as_usize().saturating_sub(1);
+ let pane_right_edge = pane_geom.x + pane_geom.cols.as_usize().saturating_sub(1);
+ if pane_top_edge <= cursor_y
+ && pane_bottom_edge >= cursor_y
+ && pane_left_edge <= cursor_x
+ && pane_right_edge >= cursor_x
+ {
+ return false;
+ }
+ }
+ true
+ }
}
#[derive(Debug, Clone, Default)]
diff --git a/zellij-server/src/panes/floating_panes/floating_pane_grid.rs b/zellij-server/src/panes/floating_panes/floating_pane_grid.rs
index 75da894e..d8d9e64e 100644
--- a/zellij-server/src/panes/floating_panes/floating_pane_grid.rs
+++ b/zellij-server/src/panes/floating_panes/floating_pane_grid.rs
@@ -861,6 +861,7 @@ pub fn half_size_middle_geom(space: &Viewport, offset: usize) -> PaneGeom {
cols: Dimension::fixed(space.cols / 2),
rows: Dimension::fixed(space.rows / 2),
is_stacked: false,
+ is_pinned: false,
};
geom.cols.set_inner(space.cols / 2);
geom.rows.set_inner(space.rows / 2);
@@ -874,6 +875,7 @@ fn half_size_top_left_geom(space: &Viewport, offset: usize) -> PaneGeom {
cols: Dimension::fixed(space.cols / 3),
rows: Dimension::fixed(space.rows / 3),
is_stacked: false,
+ is_pinned: false,
};
geom.cols.set_inner(space.cols / 3);
geom.rows.set_inner(space.rows / 3);
@@ -887,6 +889,7 @@ fn half_size_top_right_geom(space: &Viewport, offset: usize) -> PaneGeom {
cols: Dimension::fixed(space.cols / 3),
rows: Dimension::fixed(space.rows / 3),
is_stacked: false,
+ is_pinned: false,
};
geom.cols.set_inner(space.cols / 3);
geom.rows.set_inner(space.rows / 3);
@@ -900,6 +903,7 @@ fn half_size_bottom_left_geom(space: &Viewport, offset: usize) -> PaneGeom {
cols: Dimension::fixed(space.cols / 3),
rows: Dimension::fixed(space.rows / 3),
is_stacked: false,
+ is_pinned: false,
};
geom.cols.set_inner(space.cols / 3);
geom.rows.set_inner(space.rows / 3);
@@ -913,6 +917,7 @@ fn half_size_bottom_right_geom(space: &Viewport, offset: usize) -> PaneGeom {
cols: Dimension::fixed(space.cols / 3),
rows: Dimension::fixed(space.rows / 3),
is_stacked: false,
+ is_pinned: false,
};
geom.cols.set_inner(space.cols / 3);
geom.rows.set_inner(space.rows / 3);
diff --git a/zellij-server/src/panes/floating_panes/mod.rs b/zellij-server/src/panes/floating_panes/mod.rs
index e896364b..d0ce41e8 100644
--- a/zellij-server/src/panes/floating_panes/mod.rs
+++ b/zellij-server/src/panes/floating_panes/mod.rs
@@ -94,10 +94,27 @@ impl FloatingPanes {
.map(|pane_id| self.panes.get(pane_id).unwrap().position_and_size())
.collect();
Some(FloatingPanesStack { layers })
+ } else if self.has_pinned_panes() {
+ let layers = self
+ .z_indices
+ .iter()
+ .filter_map(|pane_id| {
+ self.panes
+ .get(pane_id)
+ .map(|p| p.position_and_size())
+ .and_then(|p| if p.is_pinned { Some(p) } else { None })
+ })
+ .collect();
+ Some(FloatingPanesStack { layers })
} else {
None
}
}
+ pub fn has_pinned_panes(&self) -> bool {
+ self.panes
+ .iter()
+ .any(|(_, p)| p.position_and_size().is_pinned)
+ }
pub fn pane_ids(&self) -> impl Iterator<Item = &PaneId> {
self.panes.keys()
}
@@ -262,6 +279,9 @@ impl FloatingPanes {
if let Some(height) = &floating_pane_layout.height {
position.rows = Dimension::fixed(height.to_position(viewport.rows));
}
+ if let Some(is_pinned) = &floating_pane_layout.pinned {
+ position.is_pinned = *is_pinned;
+ }
if position.cols.as_usize() > viewport.cols {
position.cols = Dimension::fixed(viewport.cols);
}
@@ -317,7 +337,21 @@ impl FloatingPanes {
let err_context = || "failed to render output";
let connected_clients: Vec<ClientId> =
{ self.connected_clients.borrow().iter().copied().collect() };
- let mut floating_panes: Vec<_> = self.panes.iter_mut().collect();
+ let active_panes = if self.panes_are_visible() {
+ self.active_panes.clone_active_panes()
+ } else {
+ Default::default()
+ };
+ let mut floating_panes: Vec<_> = if self.panes_are_visible() {
+ self.panes.iter_mut().collect()
+ } else if self.has_pinned_panes() {
+ self.panes
+ .iter_mut()
+ .filter(|(_, p)| p.position_and_size().is_pinned)
+ .collect()
+ } else {
+ vec![]
+ };
floating_panes.sort_by(|(a_id, _a_pane), (b_id, _b_pane)| {
self.z_indices
.iter()
@@ -335,7 +369,7 @@ impl FloatingPanes {
});
for (z_index, (kind, pane)) in floating_panes.iter_mut().enumerate() {
- let mut active_panes = self.active_panes.clone_active_panes();
+ let mut active_panes = active_panes.clone();
let multiple_users_exist_in_session =
{ self.connected_clients_in_app.borrow().len() > 1 };
active_panes.retain(|c_id, _| self.connected_clients.borrow().contains(c_id));
@@ -357,8 +391,14 @@ impl FloatingPanes {
.get(client_id)
.unwrap_or(&self.default_mode_info)
.mode;
+ let is_floating = true;
pane_contents_and_ui
- .render_pane_frame(*client_id, client_mode, self.session_is_mirrored)
+ .render_pane_frame(
+ *client_id,
+ client_mode,
+ self.session_is_mirrored,
+ is_floating,
+ )
.with_context(err_context)?;
if let PaneId::Plugin(..) = kind {
pane_contents_and_ui
@@ -767,6 +807,52 @@ impl FloatingPanes {
.find(|(_, p)| p.contains(point))
.map(|(&id, _)| id))
}
+ pub fn get_pinned_pane_id_at(
+ &self,
+ point: &Position,
+ search_selectable: bool,
+ ) -> Result<Option<PaneId>> {
+ let _err_context = || format!("failed to determine floating pane at point {point:?}");
+
+ let mut panes: Vec<_> = if search_selectable {
+ self.panes
+ .iter()
+ .filter(|(_, p)| p.selectable())
+ .filter(|(_, p)| p.current_geom().is_pinned)
+ .collect()
+ } else {
+ self.panes
+ .iter()
+ .filter(|(_, p)| p.current_geom().is_pinned)
+ .collect()
+ };
+ panes.sort_by(|(a_id, _a_pane), (b_id, _b_pane)| {
+ // TODO: continue
+ Ord::cmp(
+ &self.z_indices.iter().position(|id| id == *b_id).unwrap(),
+ &self.z_indices.iter().position(|id| id == *a_id).unwrap(),
+ )
+ });
+ Ok(panes
+ .iter()
+ .find(|(_, p)| p.contains(point))
+ .map(|(&id, _)| id))
+ }
+ pub fn has_pinned_pane_at(&self, point: &Position) -> bool {
+ let mut panes: Vec<_> = self
+ .panes
+ .iter()
+ .filter(|(_, p)| p.current_geom().is_pinned)
+ .collect();
+
+ panes.sort_by(|(a_id, _a_pane), (b_id, _b_pane)| {
+ Ord::cmp(
+ &self.z_indices.iter().position(|id| id == *b_id).unwrap(),
+ &self.z_indices.iter().position(|id| id == *a_id).unwrap(),
+ )
+ });
+ panes.iter().find(|(_, p)| p.contains(point)).is_some()
+ }
pub fn get_pane_at_mut(
&mut self,
position: &Position,
diff --git a/zellij-server/src/panes/plugin_pane.rs b/zellij-server/src/panes/plugin_pane.rs
index 7e16ee2d..7bc2a972 100644
--- a/zellij-server/src/panes/plugin_pane.rs
+++ b/zellij-server/src/panes/plugin_pane.rs
@@ -202,7 +202,9 @@ impl Pane for PluginPane {
self.set_should_render(true);
}
fn set_geom(&mut self, position_and_size: PaneGeom) {
+ let is_pinned = self.geom.is_pinned;
self.geom = position_and_size;
+ self.geom.is_pinned = is_pinned;
self.resize_grids();
self.set_should_render(true);
}
@@ -394,12 +396,14 @@ impl Pane for PluginPane {
.cols
.set_inner(frame_geom.cols.as_usize().saturating_sub(1));
}
+ let is_pinned = frame_geom.is_pinned;
let mut frame = PaneFrame::new(
frame_geom.into(),
grid.scrollback_position_and_length(),
pane_title,
frame_params,
- );
+ )
+ .is_pinned(is_pinned);
if let Some((frame_color_override, _text)) = self.pane_frame_color_override.as_ref() {
frame.override_color(*frame_color_override);
}
@@ -700,6 +704,24 @@ impl Pane for PluginPane {
fn query_should_be_suppressed(&self) -> bool {
self.should_be_suppressed
}
+ fn toggle_pinned(&mut self) {
+ self.geom.is_pinned = !self.geom.is_pinned;
+ }
+ fn set_pinned(&mut self, should_be_pinned: bool) {
+ self.geom.is_pinned = should_be_pinned;
+ }
+ fn intercept_left_mouse_click(&mut self, position: &Position, client_id: ClientId) -> bool {
+ if self.position_is_on_frame(position) {
+ let relative_position = self.relative_position(position);
+ if let Some(client_frame) = self.frame.get_mut(&client_id) {
+ if client_frame.clicked_on_pinned(relative_position) {
+ self.toggle_pinned();
+ return true;
+ }
+ }
+ }
+ false
+ }
}
impl PluginPane {
diff --git a/zellij-server/src/panes/terminal_pane.rs b/zellij-server/src/panes/terminal_pane.rs
index ad9714a4..fe1a96ae 100644
--- a/zellij-server/src/panes/terminal_pane.rs
+++ b/zellij-server/src/panes/terminal_pane.rs
@@ -177,7 +177,9 @@ impl Pane for TerminalPane {
self.reflow_lines();
}
fn set_geom(&mut self, position_and_size: PaneGeom) {
+ let is_pinned = self.geom.is_pinned;
self.geom = position_and_size;
+ self.geom.is_pinned = is_pinned;
self.reflow_lines();
self.render_full_viewport();
}
@@ -376,12 +378,14 @@ impl Pane for TerminalPane {
};
let frame_geom = self.current_geom();
+ let is_pinned = frame_geom.is_pinned;
let mut frame = PaneFrame::new(
frame_geom.into(),
self.grid.scrollback_position_and_length(),
pane_title,
frame_params,
- );
+ )
+ .is_pinned(is_pinned);
if let Some((exit_status, is_first_run, _run_command)) = &self.is_held {
if *is_first_run {
frame.indicate_first_run();
@@ -820,6 +824,24 @@ impl Pane for TerminalPane {
None
}
}
+ fn toggle_pinned(&mut self) {
+ self.geom.is_pinned = !self.geom.is_pinned;
+ }
+ fn set_pinned(&mut self, should_be_pinned: bool) {
+ self.geom.is_pinned = should_be_pinned;
+ }
+ fn intercept_left_mouse_click(&mut self, position: &Position, client_id: ClientId) -> bool {
+ if self.position_is_on_frame(position) {
+ let relative_position = self.relative_position(position);
+ if let Some(client_frame) = self.frame.get_mut(&client_id) {
+ if client_frame.clicked_on_pinned(relative_position) {
+ self.toggle_pinned();
+ return true;
+ }
+ }
+ }
+ false
+ }
}
impl TerminalPane {
diff --git a/zellij-server/src/panes/tiled_panes/mod.rs b/zellij-server/src/panes/tiled_panes/mod.rs
index 7fcd7a40..0223a79e 100644
--- a/zellij-server/src/panes/tiled_panes/mod.rs
+++ b/zellij-server/src/panes/tiled_panes/mod.rs
@@ -699,15 +699,26 @@ impl TiledPanes {
.render_pane_contents_for_client(*client_id)
.with_context(err_context)?;
}
+ let is_floating = false;
if self.draw_pane_frames {
pane_contents_and_ui
- .render_pane_frame(*client_id, client_mode, self.session_is_mirrored)
+ .render_pane_frame(
+ *client_id,
+ client_mode,
+ self.session_is_mirrored,
+ is_floating,
+ )
.with_context(err_context)?;
} else if pane_is_stacked {
// if we have no pane frames but the pane is stacked, we need to render its
// frame which will amount to only rendering the title line
pane_contents_and_ui
- .render_pane_frame(*client_id, client_mode, self.session_is_mirrored)
+ .render_pane_frame(
+ *client_id,
+ client_mode,
+ self.session_is_mirrored,
+ is_floating,
+ )
.with_context(err_context)?;
// we also need to render its boundaries as normal
let boundaries = client_id_to_boundaries
diff --git a/zellij-server/src/plugins/zellij_exports.rs b/zellij-server/src/plugins/zellij_exports.rs
index 7da7dfa3..4cd734de 100644
--- a/zellij-server/src/plugins/zellij_exports.rs
+++ b/zellij-server/src/plugins/zellij_exports.rs
@@ -355,6 +355,9 @@ fn host_run_plugin_command(caller: Caller<'_, PluginEnv>) {
PluginCommand::ChangeHostFolder(new_host_folder) => {
change_host_folder(env, new_host_folder)
},
+ PluginCommand::SetFloatingPanePinned(pane_id, should_be_pinned) => {
+ set_floating_pane_pinned(env, pane_id.into(), should_be_pinned)
+ },
},
(PermissionStatus::Denied, permission) => {
log::error!(
@@ -1509,6 +1512,15 @@ fn change_host_folder(env: &PluginEnv, new_host_folder: PathBuf) {
});
}
+fn set_floating_pane_pinned(env: &PluginEnv, pane_id: PaneId, should_be_pinned: bool) {
+ let _ = env.senders.to_screen.as_ref().map(|sender| {
+ sender.send(ScreenInstruction::SetFloatingPanePinned(
+ pane_id,
+ should_be_pinned,
+ ))
+ });
+}
+
fn scan_host_folder(env: &PluginEnv, folder_to_scan: PathBuf) {
if !folder_to_scan.starts_with("/host") {
log::error!(
@@ -1927,6 +1939,7 @@ fn check_command_permission(
| PluginCommand::BreakPanesToTabWithIndex(..)
| PluginCommand::ReloadPlugin(..)
| PluginCommand::LoadNewPlugin { .. }
+ | PluginCommand::SetFloatingPanePinned(..)
| PluginCommand::KillSessions(..) => PermissionType::ChangeApplicationState,
PluginCommand::UnblockCliPipeInput(..)
| PluginCommand::BlockCliPipeInput(..)
diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs
index fda6a7a8..d5b7825e 100644
--- a/zellij-server/src/route.rs
+++ b/zellij-server/src/route.rs
@@ -969,6 +969,11 @@ pub(crate) fn route_action(
))
.with_context(err_context)?;
},
+ Action::TogglePanePinned => {
+ senders
+ .send_to_screen(ScreenInstruction::TogglePanePinned(client_id))
+ .with_context(err_context)?;
+ },
}
Ok(should_break)
}
diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs
index 84cc9554..82c1a341 100644
--- a/zellij-server/src/screen.rs
+++ b/zellij-server/src/screen.rs
@@ -405,6 +405,8 @@ pub enum ScreenInstruction {
client_id: ClientId,
},
ListClientsToPlugin(PluginId, ClientId),
+ TogglePanePinned(ClientId),
+ SetFloatingPanePinned(PaneId, bool),
}
impl From<&ScreenInstruction> for ScreenContext {
@@ -617,6 +619,8 @@ impl From<&ScreenInstruction> for ScreenContext {
ScreenContext::BreakPanesToTabWithIndex
},
ScreenInstruction::ListClientsToPlugin(..) => ScreenContext::ListClientsToPlugin,
+ ScreenInstruction::TogglePanePinned(..) => ScreenContext::TogglePanePinned,
+ ScreenInstruction::SetFloatingPanePinned(..) => ScreenContext::SetFloatingPanePinned,
}
}
}
@@ -2499,6 +2503,32 @@ impl Screen {
}
Ok(())
}
+ pub fn toggle_pane_pinned(&mut self, client_id: ClientId) {
+ active_tab_and_connected_client_id!(
+ self,
+ client_id,
+ |tab: &mut Tab, client_id: ClientId| {
+ tab.toggle_pane_pinned(client_id);
+ }
+ );
+ self.unblock_input().non_fatal();
+ }
+ pub fn set_floating_pane_pinned(&mut self, pane_id: PaneId, should_be_pinned: bool) {
+ let mut found = false;
+ for tab in self.tabs.values_mut() {
+ if tab.has_pane_with_pid(&pane_id) {
+ tab.set_floating_pane_pinned(pane_id, should_be_pinned);
+ found = true;
+ break;
+ }
+ }
+ if !found {
+ log::error!(
+ "Failed to find pane with id: {:?} to set as pinned",
+ pane_id
+ );
+ }
+ }
fn unblock_input(&self) -> Result<()> {
self.bus
.senders
@@ -4713,6 +4743,12 @@ pub(crate) fn screen_thread_main(
client_id,
)?;
},
+ ScreenInstruction::TogglePanePinned(client_id) => {
+ screen.toggle_pane_pinned(client_id);
+ },
+ ScreenInstruction::SetFloatingPanePinned(pane_id, should_be_pinned) => {
+ screen.set_floating_pane_pinned(pane_id, should_be_pinned);
+ },
}
}
Ok(())
diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs
index dbce1527..de5bba65 100644
--- a/zellij-server/src/tab/mod.rs
+++ b/zellij-server/src/tab/mod.rs
@@ -397,6 +397,10 @@ pub trait Pane {
}
false
}
+ fn intercept_left_mouse_click(&mut self, _position: &Position, _client_id: ClientId) -> bool {
+ let intercepted = false;
+ intercepted
+ }
fn store_pane_name(&mut self);
fn load_pane_name(&mut self);
fn set_borderless(&mut self, borderless: bool);
@@ -503,6 +507,8 @@ pub trait Pane {
fn drain_fake_cursors(&mut self) -> Option<HashSet<(usize, usize)>> {
None
}
+ fn toggle_pinned(&mut self) {}
+ fn set_pinned(&mut self, should_be_pinned: bool) {}
}
#[derive(Clone, Debug)]
@@ -823,7 +829,7 @@ impl Tab {
let display_area = *self.display_area.borrow();
// we do this so that the new swap layout has a chance to pass through the constraint system
self.tiled_panes.resize(display_area);
- self.should_clear_display_before_rendering = true;
+ self.set_should_clear_display_before_rendering();
Ok(())
}
pub fn previous_swap_layout(&mut self, client_id: Option<ClientId>) -> Result<()> {
@@ -1476,7 +1482,7 @@ impl Tab {
);
self.tiled_panes
.split_pane_horizontally(pid, Box::new(new_terminal), client_id);
- self.should_clear_display_before_rendering = true;
+ self.set_should_clear_display_before_rendering();
self.tiled_panes.focus_pane(pid, client_id);
self.swap_layouts.set_is_tiled_damaged();
}
@@ -1536,7 +1542,7 @@ impl Tab {
);
self.tiled_panes
.split_pane_vertically(pid, Box::new(new_terminal), client_id);
- self.should_clear_display_before_rendering = true;
+ self.set_should_clear_display_before_rendering();
self.tiled_panes.focus_pane(pid, client_id);
self.swap_layouts.set_is_tiled_damaged();
}
@@ -2099,6 +2105,11 @@ impl Tab {
self.tiled_panes.set_force_render();
self.floating_panes.set_force_render();
}
+ pub fn set_should_clear_display_before_rendering(&mut self) {
+ self.should_clear_display_before_rendering = true;
+ self.floating_panes.set_force_render(); // we do this to make sure pinned panes are
+ // rendered even if their surface is not visible
+ }
pub fn is_sync_panes_active(&self) -> bool {
self.synchronize_is_active
}
@@ -2147,7 +2158,9 @@ impl Tab {
self.tiled_panes
.render(output, self.floating_panes.panes_are_visible())
.with_context(err_context)?;
- if self.floating_panes.panes_are_visible() && self.floating_panes.has_active_panes() {
+ if (self.floating_panes.panes_are_visible() && self.floating_panes.has_active_panes())
+ || self.floating_panes.has_pinned_panes()
+ {
self.floating_panes
.render(output)
.with_context(err_context)?;
@@ -2182,7 +2195,19 @@ impl Tab {
let connected_clients: Vec<ClientId> =
{ self.connected_clients.borrow().iter().copied().collect() };
for client_id in connected_clients {
- match self.get_active_terminal_cursor_position(client_id) {
+ match self
+ .get_active_terminal_cursor_position(client_id)
+ .and_then(|(cursor_position_x, cursor_position_y)| {
+ // TODO: get active_pane_z_index and pass it to cursor_is_visible so we do the
+ // right thing if the cursor is in a floating pane
+ if self.floating_panes.panes_are_visible() {
+ Some((cursor_position_x, cursor_position_y))
+ } else if output.cursor_is_visible(cursor_position_x, cursor_position_y) {
+ Some((cursor_position_x, cursor_position_y))
+ } else {
+ None
+ }
+ }) {
Some((cursor_position_x, cursor_position_y)) => {
let desired_cursor_shape = self
.get_active_pane(client_id)
@@ -2308,7 +2333,7 @@ impl Tab {
self.swap_layouts.set_is_tiled_damaged();
let _ = self.relayout_tiled_panes(None, false, false, true);
}
- self.should_clear_display_before_rendering = true;
+ self.set_should_clear_display_before_rendering();
self.senders
.send_to_pty_writer(PtyWriteInstruction::ApplyCachedResizes)
.with_context(|| format!("failed to update plugins with mode info"))?;
@@ -3256,6 +3281,14 @@ impl Tab {
{
return Ok(self.floating_panes.get_pane_mut(pane_id));
}
+ } else if self.floating_panes.has_pinned_panes() {
+ if let Some(pane_id) = self
+ .floating_panes
+ .get_pinned_pane_id_at(point, search_selectable)
+ .with_context(err_context)?
+ {
+ return Ok(self.floating_panes.get_pane_mut(pane_id));
+ }
}
if let Some(pane_id) = self
.get_pane_id_at(point, search_selectable)
@@ -3305,6 +3338,31 @@ impl Tab {
)
};
+ let intercepted = self
+ .get_pane_at(position, false)
+ .with_context(err_context)?
+ .map(|pane| pane.intercept_left_mouse_click(&position, client_id))
+ .unwrap_or(false);
+ if intercepted {
+ self.set_force_render();
+ return Ok(());
+ }
+
+ if !self.floating_panes.panes_are_visible() {
+ let search_selectable = false;
+ if let Ok(Some(pane_id)) = self
+ .floating_panes
+ .get_pinned_pane_id_at(position, search_selectable)
+ {
+ // here, the floating panes are not visible, but there is a pinned pane (always
+ // visible) that has been clicked on - so we make the entire surface visible and
+ // focus it
+ self.show_floating_panes();
+ self.floating_panes.focus_pane(pane_id, client_id);
+ return Ok(());
+ }
+ }
+
self.focus_pane_at(position, client_id)
.with_context(err_context)?;
@@ -3888,7 +3946,7 @@ impl Tab {
pub fn set_pane_frames(&mut self, should_set_pane_frames: bool) {
self.tiled_panes.set_pane_frames(should_set_pane_frames);
self.draw_pane_frames = should_set_pane_frames;
- self.should_clear_display_before_rendering = true;
+ self.set_should_clear_display_before_rendering();
self.set_force_render();
}
pub fn panes_to_hide_count(&self) -> usize {
@@ -4146,6 +4204,9 @@ impl Tab {
if let Some(mut new_pane_geom) = self.floating_panes.find_room_for_new_pane() {
if let Some(floating_pane_coordinates) = floating_pane_coordinates {
let viewport = self.viewport.borrow();
+ if let Some(pinned) = floating_pane_coordinates.pinned.as_ref() {
+ pane.set_pinned(*pinned);
+ }
new_pane_geom.adjust_coordinates(floating_pane_coordinates, *viewport);
self.swap_layouts.set_is_floating_damaged();
}
@@ -4185,7 +4246,7 @@ impl Tab {
} else {
self.tiled_panes.insert_pane(pane_id, pane);
}
- self.should_clear_display_before_rendering = true;
+ self.set_should_clear_display_before_rendering();
if let Some(client_id) = client_id {
self.tiled_panes.focus_pane(pane_id, client_id);
}
@@ -4351,6 +4412,18 @@ impl Tab {
self.suppressed_panes.insert(pane_id, suppressed_pane_entry);
}
}
+ pub fn toggle_pane_pinned(&mut self, client_id: ClientId) {
+ if let Some(pane) = self.get_active_pane_mut(client_id) {
+ pane.toggle_pinned();
+ self.set_force_render();
+ }
+ }
+ pub fn set_floating_pane_pinned(&mut self, pane_id: PaneId, should_be_pinned: bool) {
+ if let Some(pane) = self.get_pane_with_id_mut(pane_id) {
+ pane.set_pinned(should_be_pinned);
+ self.set_force_render();
+ }
+ }
fn new_scrollback_editor_pane(&self, pid: u32) -> TerminalPane {
let next_terminal_position = self.get_next_terminal_position();
let mut new_pane = TerminalPane::new(
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__base_floating_layout_is_included_in_swap_layouts.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__base_floating_layout_is_included_in_swap_layouts.snap
index e60c5fd3..3645f69c 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__base_floating_layout_is_included_in_swap_layouts.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__base_floating_layout_is_included_in_swap_layouts.snap
@@ -1,9 +1,9 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 6089
+assertion_line: 7605
expression: snapshot
---
-00 (C): ┌ zellij:tab-bar ─────────────────────────────────┌ zellij:status-bar ───────────────────────────────────────┐──────────┐
+00 (C): ┌ zellij:tab-bar ─────────────────────────────────┌ zellij:status-bar ────────────────────────────── PIN [ ] ┐──────────┐
01 (C): │I am a tab bar │I am a │ │
02 (C): │ │status bar │ │
03 (C): │ │ │ │
@@ -13,7 +13,7 @@ expression: snapshot
07 (C): │ │ │ │ │
08 (C): │ │ │ │ │
09 (C): └─────────────────────────────│ └──────────────────────────────────────────────────────────┘ │
-10 (C): ┌ command1 ───────────────────│ ┌ command2 ────────────────────────────────────────────────┐ │
+10 (C): ┌ command1 ───────────────────│ ┌ command2 ─────────────────────────────────────── PIN [ ] ┐ │
11 (C): │ │ │ │ │
12 (C): │ │ │ │ │
13 (C): │ │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__can_swap_floating_layout_at_runtime.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__can_swap_floating_layout_at_runtime.snap
index 04fa9400..663d3c51 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__can_swap_floating_layout_at_runtime.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__can_swap_floating_layout_at_runtime.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 3022
+assertion_line: 3841
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
@@ -8,7 +8,7 @@ expression: snapshot
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): ┌ Pane #2 ─────────────────────────────────────────────────┐ ┌ Pane #3 ─────────────────────────────────────────────────┐
+05 (C): ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐ ┌ Pane #3 ──────────────────────────────────────── PIN [ ] ┐
06 (C): │ │ │ │
07 (C): │ │ │ │
08 (C): │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__close_suppressing_floating_pane.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__close_suppressing_floating_pane.snap
index 91910115..09127ecf 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__close_suppressing_floating_pane.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__close_suppressing_floating_pane.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 1352
+assertion_line: 2797
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
@@ -8,7 +8,7 @@ expression: snapshot
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ Pane #2 ─────────────────────────────────────────────────┐ │
+05 (C): │ ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │
07 (C): │ │ │ │
08 (C): │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__decrease_floating_pane_size.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__decrease_floating_pane_size.snap
index 65011a67..af28471d 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__decrease_floating_pane_size.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__decrease_floating_pane_size.snap
@@ -1,7 +1,7 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
+assertion_line: 1104
expression: snapshot
-
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
@@ -9,7 +9,7 @@ expression: snapshot
03 (C): │ │
04 (C): │ │
05 (C): │ │
-06 (C): │ ┌ Pane #2 ─────────────────────────────────────────────┐ │
+06 (C): │ ┌ Pane #2 ──────────────────────────────────── PIN [ ] ┐ │
07 (C): │ │ │ │
08 (C): │ │ │ │
09 (C): │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__drag_pane_with_mouse.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__drag_pane_with_mouse.snap
index bdb531d2..7450c0fd 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__drag_pane_with_mouse.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__drag_pane_with_mouse.snap
@@ -1,16 +1,16 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 1252
+assertion_line: 1944
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
-02 (C): │ ┌ Pane #5 ─────────────── SCROLL: 0/1 ┐ │
+02 (C): │ ┌ Pane #5 ───── SCROLL: 0/1 | PIN [ ] ┐ │
03 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-04 (C): │ │E┌ Pane #6 ─────────────── SCROLL: 0/1 ┐ │
+04 (C): │ │E┌ Pane #6 ───── SCROLL: 0/1 | PIN [ ] ┐ │
05 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
06 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-07 (C): │ └─│EEEEEEEEEEEEEEEEEEEEEEEEEEEEE┌ Pane #2 ─────────────────────────────────────────────────┐ │
+07 (C): │ └─│EEEEEEEEEEEEEEEEEEEEEEEEEEEEE┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐ │
08 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │ │
09 (C): │ └─────────────────────────────│ │ │
10 (C): │ │E│ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__five_new_floating_panes.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__five_new_floating_panes.snap
index a2cc2338..ddb4f100 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__five_new_floating_panes.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__five_new_floating_panes.snap
@@ -1,18 +1,18 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 682
+assertion_line: 1028
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
-02 (C): │ ┌ Pane #5 ─────────────── SCROLL: 0/1 ┐ │
+02 (C): │ ┌ Pane #5 ───── SCROLL: 0/1 | PIN [ ] ┐ │
03 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-04 (C): │ │E┌ Pane #6 ─────────────── SCROLL: 0/1 ┐ │
-05 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│─────────────────────────────────────────────┐ │
+04 (C): │ │E┌ Pane #6 ───── SCROLL: 0/1 | PIN [ ] ┐ │
+05 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│──────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │ │
-07 (C): │ └─│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│───────────────────────────────── SCROLL: 0/1 ┐ │
+07 (C): │ └─│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│─────────────────────── SCROLL: 0/1 | PIN [ ] ┐ │
08 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-09 (C): │ └──────────────────────────────────────┘─────────────────────────────────── SCROLL: 0/1 ┐ │
+09 (C): │ └──────────────────────────────────────┘───────────────────────── SCROLL: 0/1 | PIN [ ] ┐ │
10 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
11 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
12 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__float_embedded_pane.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__float_embedded_pane.snap
index ada8f530..6fe9a3f7 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__float_embedded_pane.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__float_embedded_pane.snap
@@ -1,14 +1,14 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
+assertion_line: 2386
expression: snapshot
-
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ Pane #2 ─────────────────────────────────────────────────┐ │
+05 (C): │ ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │
07 (C): │ │ │ │
08 (C): │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__float_embedded_pane_without_pane_frames.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__float_embedded_pane_without_pane_frames.snap
index c09b5e9f..e8d81d2a 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__float_embedded_pane_without_pane_frames.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__float_embedded_pane_without_pane_frames.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 1632
+assertion_line: 2445
expression: snapshot
---
00 (C):
@@ -8,7 +8,7 @@ expression: snapshot
02 (C):
03 (C):
04 (C):
-05 (C): ┌ Pane #2 ─────────────────────────────────────────────────┐
+05 (C): ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐
06 (C): │ │
07 (C): │ │
08 (C): │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__floating_layout_with_plugins_and_commands_swaped_properly.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__floating_layout_with_plugins_and_commands_swaped_properly.snap
index 1d8dfe04..e8157355 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__floating_layout_with_plugins_and_commands_swaped_properly.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__floating_layout_with_plugins_and_commands_swaped_properly.snap
@@ -1,9 +1,9 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 5995
+assertion_line: 7510
expression: snapshot
---
-00 (C): ┌ zellij:status-bar ───────────────────────────────────────┐ab-bar ──────────────────────────────────────────┐──────────┐
+00 (C): ┌ zellij:status-bar ────────────────────────────── PIN [ ] ┐ab-bar ───────────────────────────────── PIN [ ] ┐──────────┐
01 (C): │I am a │b bar │ │
02 (C): │status bar │ │ │
03 (C): │ │ │ │
@@ -13,7 +13,7 @@ expression: snapshot
07 (C): │ │ │ │
08 (C): │ │ │ │
09 (C): └──────────────────────────────────────────────────────────┘─────────────────────────────────────────────────┘ │
-10 (C): ┌ command1 ───────────────────│ ┌ command2 ────────────────────────────────────────────────┐ │
+10 (C): ┌ command1 ───────────────────│ ┌ command2 ─────────────────────────────────────── PIN [ ] ┐ │
11 (C): │ │ │ │ │
12 (C): │ │ │ │ │
13 (C): │ │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__floating_pane_above_sixel_image.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__floating_pane_above_sixel_image.snap
index 19d6feb8..30cddfa4 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__floating_pane_above_sixel_image.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__floating_pane_above_sixel_image.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 1343
+assertion_line: 2685
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────── SCROLL: 0/7 ┐
@@ -10,7 +10,7 @@ expression: snapshot
04 (C): │ixelSixelSixelSixelSixelSixelSixelSixelSixelSixelSixelSixelSixe │
05 (C): │ixelSixelSixelSixelSixelSixelSixelSixelSixelSixelSixelSixelSixe │
06 (C): │ixelSixelSixelSixelSixelSixelSixelSixelSixelSixelSixelSixelSixe │
-07 (C): │ixelSixelSixelSixelSixelSixelSixe┌ Pane #2 ─────────────────────────────────────────────────┐ │
+07 (C): │ixelSixelSixelSixelSixelSixelSixe┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐ │
08 (C): │ixelSixelSixelSixelSixelSixelSixe│ │ │
09 (C): │ixelSixelSixelSixelSixelSixelSixe│ │ │
10 (C): │ixelSixelSixelSixelSixelSixelSixe│ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__floating_panes_persist_across_toggles.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__floating_panes_persist_across_toggles.snap
index dd632a95..ec435042 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__floating_panes_persist_across_toggles.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__floating_panes_persist_across_toggles.snap
@@ -1,14 +1,14 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
+assertion_line: 881
expression: snapshot
-
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ Pane #2 ─────────────────────────────────────────────────┐ │
+05 (C): │ ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │
07 (C): │ │ │ │
08 (C): │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__increase_floating_pane_size.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__increase_floating_pane_size.snap
index 30121d19..934b5ccb 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__increase_floating_pane_size.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__increase_floating_pane_size.snap
@@ -1,13 +1,13 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
+assertion_line: 1066
expression: snapshot
-
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
02 (C): │ │
03 (C): │ │
-04 (C): │ ┌ Pane #2 ─────────────────────────────────────────────────────┐ │
+04 (C): │ ┌ Pane #2 ──────────────────────────────────────────── PIN [ ] ┐ │
05 (C): │ │ │ │
06 (C): │ │ │ │
07 (C): │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__mark_text_inside_floating_pane.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__mark_text_inside_floating_pane.snap
index 20e382fb..c7113931 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__mark_text_inside_floating_pane.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__mark_text_inside_floating_pane.snap
@@ -1,18 +1,18 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 1318
+assertion_line: 2050
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
-02 (C): │ ┌ Pane #5 ─────────────── SCROLL: 0/1 ┐ │
+02 (C): │ ┌ Pane #5 ───── SCROLL: 0/1 | PIN [ ] ┐ │
03 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-04 (C): │ │E┌ Pane #6 ─────────────── SCROLL: 0/1 ┐ │
-05 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│─────────────────────────────────────────────┐ │
+04 (C): │ │E┌ Pane #6 ───── SCROLL: 0/1 | PIN [ ] ┐ │
+05 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│──────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │ │
-07 (C): │ └─│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│───────────────────────────────── SCROLL: 0/1 ┐ │
+07 (C): │ └─│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│─────────────────────── SCROLL: 0/1 | PIN [ ] ┐ │
08 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-09 (C): │ └──────────────────────────────────────┘─────────────────────────────────── SCROLL: 0/1 ┐ │
+09 (C): │ └──────────────────────────────────────┘───────────────────────── SCROLL: 0/1 | PIN [ ] ┐ │
10 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
11 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
12 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_down.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_down.snap
index a401ba08..ecec0e66 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_down.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_down.snap
@@ -1,18 +1,18 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 1078
+assertion_line: 1650
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
-02 (C): │ ┌ Pane #5 ─────────────── SCROLL: 0/1 ┐ │
+02 (C): │ ┌ Pane #5 ───── SCROLL: 0/1 | PIN [ ] ┐ │
03 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-04 (C): │ │E┌ Pane #6 ─────────────── SCROLL: 0/1 ┐ │
-05 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│─────────────────────────────────────────────┐ │
+04 (C): │ │E┌ Pane #6 ───── SCROLL: 0/1 | PIN [ ] ┐ │
+05 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│──────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │ │
-07 (C): │ └─│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│───────────────────────────────── SCROLL: 0/1 ┐ │
+07 (C): │ └─│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│─────────────────────── SCROLL: 0/1 | PIN [ ] ┐ │
08 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-09 (C): │ └──────────────────────────────────────┘─────────────────────────────────── SCROLL: 0/1 ┐ │
+09 (C): │ └──────────────────────────────────────┘───────────────────────── SCROLL: 0/1 | PIN [ ] ┐ │
10 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
11 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
12 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_left.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_left.snap
index 98f623d7..38a5df4b 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_left.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_left.snap
@@ -1,18 +1,18 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 911
+assertion_line: 1363
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
-02 (C): │ ┌ Pane #5 ─────────────── SCROLL: 0/1 ┐ │
+02 (C): │ ┌ Pane #5 ───── SCROLL: 0/1 | PIN [ ] ┐ │
03 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
04 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ ┐ │
-05 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│E│─────────────────────────────────────────────┐ │
+05 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│E│──────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│E│ │ │
-07 (C): │ └──────────────────────────────────────┘E│───────────────────────────────── SCROLL: 0/1 ┐ │
+07 (C): │ └──────────────────────────────────────┘E│─────────────────────── SCROLL: 0/1 | PIN [ ] ┐ │
08 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-09 (C): │ └──────────────────────────────────────┘─────────────────────────────────── SCROLL: 0/1 ┐ │
+09 (C): │ └──────────────────────────────────────┘───────────────────────── SCROLL: 0/1 | PIN [ ] ┐ │
10 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
11 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
12 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_right.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_right.snap
index 67d7cfa4..1336cda6 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_right.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_right.snap
@@ -1,18 +1,18 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 967
+assertion_line: 1459
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
-02 (C): │ ┌ Pane #5 ─────────────── SCROLL: 0/1 ┐ │
+02 (C): │ ┌ Pane #5 ───── SCROLL: 0/1 | PIN [ ] ┐ │
03 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-04 (C): │ │E┌ Pane #6 ─────────────── SCROLL: 0/1 ┐ │
-05 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│─────────────────────────────────────────────┐ │
+04 (C): │ │E┌ Pane #6 ───── SCROLL: 0/1 | PIN [ ] ┐ │
+05 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│──────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │ │
-07 (C): │ └─│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│───────────────────────────────── SCROLL: 0/1 ┐ │
+07 (C): │ └─│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│─────────────────────── SCROLL: 0/1 | PIN [ ] ┐ │
08 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-09 (C): │ └──────────────────────────────────────┘─────────────────────────────────── SCROLL: 0/1 ┐ │
+09 (C): │ └──────────────────────────────────────┘───────────────────────── SCROLL: 0/1 | PIN [ ] ┐ │
10 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
11 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
12 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_up.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_up.snap
index 193834e8..61c4e323 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_up.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_up.snap
@@ -1,18 +1,18 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 1022
+assertion_line: 1554
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
-02 (C): │ ┌ Pane #5 ─────────────── SCROLL: 0/1 ┐ │
+02 (C): │ ┌ Pane #5 ───── SCROLL: 0/1 | PIN [ ] ┐ │
03 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
04 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ ┐ │
-05 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│E│─────────────────────────────────────────────┐ │
+05 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│E│──────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│E│ │ │
-07 (C): │ └──────────────────────────────────────┘E│───────────────────────────────── SCROLL: 0/1 ┐ │
+07 (C): │ └──────────────────────────────────────┘E│─────────────────────── SCROLL: 0/1 | PIN [ ] ┐ │
08 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-09 (C): │ └──────────────────────────────────────┘─────────────────────────────────── SCROLL: 0/1 ┐ │
+09 (C): │ └──────────────────────────────────────┘───────────────────────── SCROLL: 0/1 | PIN [ ] ┐ │
10 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
11 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
12 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_with_mouse.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_with_mouse.snap
index 2561b5ce..b9696dc0 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_with_mouse.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_focus_with_mouse.snap
@@ -1,18 +1,18 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 1136
+assertion_line: 1748
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
-02 (C): │ ┌ Pane #5 ─────────────── SCROLL: 0/1 ┐ │
+02 (C): │ ┌ Pane #5 ───── SCROLL: 0/1 | PIN [ ] ┐ │
03 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-04 (C): │ │E┌ Pane #6 ─────────────── SCROLL: 0/1 ┐ │
-05 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│─────────────────────────────────────────────┐ │
+04 (C): │ │E┌ Pane #6 ───── SCROLL: 0/1 | PIN [ ] ┐ │
+05 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│──────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │ │
-07 (C): │ └─│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│───────────────────────────────── SCROLL: 0/1 ┐ │
+07 (C): │ └─│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│─────────────────────── SCROLL: 0/1 | PIN [ ] ┐ │
08 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-09 (C): │ └─────────────────────────────┌ Pane #4 ─────────────────────────────────── SCROLL: 0/1 ┐ │
+09 (C): │ └─────────────────────────────┌ Pane #4 ───────────────────────── SCROLL: 0/1 | PIN [ ] ┐ │
10 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
11 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
12 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_with_sixel_image.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_with_sixel_image.snap
index df091cdb..8365df05 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_with_sixel_image.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__move_floating_pane_with_sixel_image.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 1312
+assertion_line: 2647
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
@@ -10,7 +10,7 @@ expression: snapshot
04 (C): │ │
05 (C): │ │
06 (C): │ │
-07 (C): │ ┌ Pane #2 ────────────────────────────────── SCROLL: 0/17 ┐ │
+07 (C): │ ┌ Pane #2 ──────────────────────── SCROLL: 0/17 | PIN [ ] ┐ │
08 (C): │ │SixelSixelSixelSixelSixelSixelSixelSixelSixelSixelSixelSix│ │
09 (C): │ │SixelSixelSixelSixelSixelSixelSixelSixelSixelSixelSixelSix│ │
10 (C): │ │SixelSixelSixelSixelSixelSixelSixelSixelSixelSixelSixelSix│ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane.snap
index dd632a95..3220eee6 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane.snap
@@ -1,14 +1,14 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
+assertion_line: 849
expression: snapshot
-
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ Pane #2 ─────────────────────────────────────────────────┐ │
+05 (C): │ ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │
07 (C): │ │ │ │
08 (C): │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane_in_auto_layout-2.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane_in_auto_layout-2.snap
index cdef4812..1394348a 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane_in_auto_layout-2.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane_in_auto_layout-2.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 5799
+assertion_line: 8040
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
@@ -8,7 +8,7 @@ expression: snapshot
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ Pane #2 ────────────────────────────────────────────┐ ┌ Pane #3 ────────────────────────────────────────────┐ │
+05 (C): │ ┌ Pane #2 ─────────────────────────────────── PIN [ ] ┐ ┌ Pane #3 ─────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │ │ │
07 (C): │ │ │ │ │ │
08 (C): │ │ │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane_in_auto_layout-3.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane_in_auto_layout-3.snap
index b5c19c92..e84b8fc6 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane_in_auto_layout-3.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane_in_auto_layout-3.snap
@@ -1,10 +1,10 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 5799
+assertion_line: 8040
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
-01 (C): │ ┌ Pane #3 ────────────────────────────────────────────┐ ┌ Pane #2 ────────────────────────────────────────────┐ │
+01 (C): │ ┌ Pane #3 ─────────────────────────────────── PIN [ ] ┐ ┌ Pane #2 ─────────────────────────────────── PIN [ ] ┐ │
02 (C): │ │ │ │ │ │
03 (C): │ │ │ │ │ │
04 (C): │ │ │ │ │ │
@@ -14,7 +14,7 @@ expression: snapshot
08 (C): │ │ │ │ │ │
09 (C): │ │ │ │ │ │
10 (C): │ └─────────────────────────────────────────────────────┘ └─────────────────────────────────────────────────────┘ │
-11 (C): │ ┌ Pane #4 ────────────────────────────────────────────┐ │
+11 (C): │ ┌ Pane #4 ─────────────────────────────────── PIN [ ] ┐ │
12 (C): │ │ │ │
13 (C): │ │ │ │
14 (C): │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane_in_auto_layout.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane_in_auto_layout.snap
index d6c84185..675409f8 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane_in_auto_layout.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__new_floating_pane_in_auto_layout.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 5799
+assertion_line: 8040
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
@@ -13,7 +13,7 @@ expression: snapshot
07 (C): │ │
08 (C): │ │
09 (C): │ │
-10 (C): │ ┌ Pane #2 ─────────────────────────────────────────────────┐
+10 (C): │ ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐
11 (C): │ │ │
12 (C): │ │ │
13 (C): │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__rename_floating_pane.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__rename_floating_pane.snap
index cb73eb45..2e39065d 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__rename_floating_pane.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__rename_floating_pane.snap
@@ -1,5 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
+assertion_line: 2550
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
@@ -7,7 +8,7 @@ expression: snapshot
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ Renamed floating pane ───────────────────────────────────┐ │
+05 (C): │ ┌ Renamed floating pane ────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │
07 (C): │ │ │ │
08 (C): │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_down.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_down.snap
index 3a38a934..93b15968 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_down.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_down.snap
@@ -1,14 +1,14 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
+assertion_line: 1268
expression: snapshot
-
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ Pane #2 ─────────────────────────────────────────────────┐ │
+05 (C): │ ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │
07 (C): │ │ │ │
08 (C): │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_left.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_left.snap
index f5831eb8..1c186c17 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_left.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_left.snap
@@ -1,14 +1,14 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
+assertion_line: 1145
expression: snapshot
-
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ Pane #2 ──────────────────────────────────────────────────────┐ │
+05 (C): │ ┌ Pane #2 ───────────────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │
07 (C): │ │ │ │
08 (C): │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_right.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_right.snap
index 52dffcce..0b1b0f93 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_right.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_right.snap
@@ -1,14 +1,14 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
+assertion_line: 1186
expression: snapshot
-
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ Pane #2 ──────────────────────────────────────────────────────┐ │
+05 (C): │ ┌ Pane #2 ───────────────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │
07 (C): │ │ │ │
08 (C): │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_up.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_up.snap
index 6e4b9b6d..a4b82095 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_up.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_floating_pane_up.snap
@@ -1,12 +1,12 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
+assertion_line: 1227
expression: snapshot
-
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
02 (C): │ │
-03 (C): │ ┌ Pane #2 ─────────────────────────────────────────────────┐ │
+03 (C): │ ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐ │
04 (C): │ │ │ │
05 (C): │ │ │ │
06 (C): │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_tab_with_floating_panes.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_tab_with_floating_panes.snap
index da14ad29..b3e645b6 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_tab_with_floating_panes.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_tab_with_floating_panes.snap
@@ -1,13 +1,13 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 1544
+assertion_line: 2144
expression: snapshot
---
-00 (C): ┌ Pane #1 ────────────────────┌ ┌ ┌ Pane #4 ─────────────────────────────────── SCROLL: 0/1 ┐─────┐
+00 (C): ┌ Pane #1 ────────────────────┌ ┌ ┌ Pane #4 ───────────────────────── SCROLL: 0/1 | PIN [ ] ┐─────┐
01 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-02 (C): │ ┌ Pane #5 ─────────────── SCROLL: 0/1 ┐EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
+02 (C): │ ┌ Pane #5 ───── SCROLL: 0/1 | PIN [ ] ┐EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
03 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-04 (C): │ │E┌ Pane #6 ─────────────── SCROLL: 0/1 ┐EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
+04 (C): │ │E┌ Pane #6 ───── SCROLL: 0/1 | PIN [ ] ┐EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
05 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
06 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
07 (C): │ └─│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_whole_tab_while_floting_pane_is_suppressed.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_whole_tab_while_floting_pane_is_suppressed.snap
index 2a886db7..dd07c8fc 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_whole_tab_while_floting_pane_is_suppressed.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__resize_whole_tab_while_floting_pane_is_suppressed.snap
@@ -1,9 +1,9 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 2220
+assertion_line: 2921
expression: snapshot
---
-00 (C): ┌ Pane #1 ────────────────────┌ EDITING SCROLLBACK ──────────────────────────────────────┐─────────┐
+00 (C): ┌ Pane #1 ────────────────────┌ EDITING SCROLLBACK ───────────────────────────── PIN [ ] ┐─────────┐
01 (C): │ │ │ │
02 (C): │ │ │ │
03 (C): │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__search_floating_tab_highlight_fring.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__search_floating_tab_highlight_fring.snap
index fdb60046..62d22594 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__search_floating_tab_highlight_fring.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__search_floating_tab_highlight_fring.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 1721
+assertion_line: 3029
expression: snapshot
---
00 (C):
@@ -8,7 +8,7 @@ expression: snapshot
02 (C):
03 (C):
04 (C):
-05 (C): ┌ SEARCHING: fring ──────────────────────── SCROLL: 0/103 ┐
+05 (C): ┌ SEARCHING: fring ────────────── SCROLL: 0/103 | PIN [ ] ┐
06 (C): │ │
07 (C): │a mauris in aliquam sem fringilla. │
08 (C): │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__search_floating_tab_nothing_highlighted.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__search_floating_tab_nothing_highlighted.snap
index eeb3b491..0e0e7e6c 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__search_floating_tab_nothing_highlighted.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__search_floating_tab_nothing_highlighted.snap
@@ -1,5 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
+assertion_line: 3017
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
@@ -7,7 +8,7 @@ expression: snapshot
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ fish /home/thomas/Projects/zellij ─────── SCROLL: 0/103 ┐ │
+05 (C): │ ┌ fish /home/thomas/Projects/zellij ────── 0/103 | PIN [ ] ┐ │
06 (C): │ │d viverra tellus in hac habitasse. Nunc scelerisque viverr│ │
07 (C): │ │a mauris in aliquam sem fringilla. │ │
08 (C): │ │⏎ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__shrink_whole_tab_with_floating_panes_horizontally_and_vertically.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__shrink_whole_tab_with_floating_panes_horizontally_and_vertically.snap
index cfa37b74..e8a854d5 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__shrink_whole_tab_with_floating_panes_horizontally_and_vertically.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__shrink_whole_tab_with_floating_panes_horizontally_and_vertically.snap
@@ -1,13 +1,13 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 1594
+assertion_line: 2234
expression: snapshot
---
00 (C): ┌ Pane #1 ────────────────────┌ ┌ ┌ Pane #4 ── 0 ┐
01 (C): │ │ │E│EEEEEEEEEEEEEE│
-02 (C): │ ┌ Pane #5 ─────────────── SCROLL: 0/1 ┐EEEEEEE│
+02 (C): │ ┌ Pane #5 ───── SCROLL: 0/1 | PIN [ ] ┐EEEEEEE│
03 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-04 (C): │ │E┌ Pane #6 ─────────────── SCROLL: 0/1 ┐EEEEE│
+04 (C): │ │E┌ Pane #6 ───── SCROLL: 0/1 | PIN [ ] ┐EEEEE│
05 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│EEEEE│
06 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│EEEEE│
07 (C): │ └─│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│EEEEE│
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__shrink_whole_tab_with_floating_panes_horizontally_and_vertically_and_expand_back.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__shrink_whole_tab_with_floating_panes_horizontally_and_vertically_and_expand_back.snap
index a7c0f582..3c187c27 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__shrink_whole_tab_with_floating_panes_horizontally_and_vertically_and_expand_back.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__shrink_whole_tab_with_floating_panes_horizontally_and_vertically_and_expand_back.snap
@@ -1,18 +1,18 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 1648
+assertion_line: 2329
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
-02 (C): │ ┌ Pane #5 ─────────────── SCROLL: 0/1 ┐ │
+02 (C): │ ┌ Pane #5 ───── SCROLL: 0/1 | PIN [ ] ┐ │
03 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-04 (C): │ │E┌ Pane #6 ─────────────── SCROLL: 0/1 ┐ │
-05 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│─────────────────────────────────────────────┐ │
+04 (C): │ │E┌ Pane #6 ───── SCROLL: 0/1 | PIN [ ] ┐ │
+05 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│──────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │ │
-07 (C): │ └─│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│───────────────────────────────── SCROLL: 0/1 ┐ │
+07 (C): │ └─│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│─────────────────────── SCROLL: 0/1 | PIN [ ] ┐ │
08 (C): │ │EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
-09 (C): │ └──────────────────────────────────────┘─────────────────────────────────── SCROLL: 0/1 ┐ │
+09 (C): │ └──────────────────────────────────────┘───────────────────────── SCROLL: 0/1 | PIN [ ] ┐ │
10 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
11 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
12 (C): │ │ │E│EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE│ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__suppress_floating_pane.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__suppress_floating_pane.snap
index 6ac31044..1a6ae095 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__suppress_floating_pane.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__suppress_floating_pane.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 1639
+assertion_line: 2738
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
@@ -8,7 +8,7 @@ expression: snapshot
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ EDITING SCROLLBACK ──────────────────────────────────────┐ │
+05 (C): │ ┌ EDITING SCROLLBACK ───────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │
07 (C): │ │ │ │
08 (C): │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_including_command_panes_absent_from_existing_layout.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_including_command_panes_absent_from_existing_layout.snap
index fb7d9176..5dc4503b 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_including_command_panes_absent_from_existing_layout.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_including_command_panes_absent_from_existing_layout.snap
@@ -1,18 +1,18 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 6180
+assertion_line: 7697
expression: snapshot
---
-00 (C): ┌ Pane #2 ─────────────────────────────────────────────────┐────────────────────────────────────────────────────────────┐
+00 (C): ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐────────────────────────────────────────────────────────────┐
01 (C): │ │ │
02 (C): │ │ │
03 (C): │ │ │
04 (C): │ │ │
-05 (C): │ ┌ zellij:status-bar ───────────────────────────────────────┐ │
+05 (C): │ ┌ zellij:status-bar ────────────────────────────── PIN [ ] ┐ │
06 (C): │ │I am a │ │
-07 (C): │ │status bar │─┐ │
+07 (C): │ │status bar │ ┐ │
08 (C): │ │ │ │ │
-09 (C): └─────────────────────────────│ │───┐ │
+09 (C): └─────────────────────────────│ │ ] ┐ │
10 (C): │ ┌ Pane #3 ──────────│ │ │ │
11 (C): │ │ │ │ │ │
12 (C): │ │ │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_including_plugin_panes_absent_from_existing_layout.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_including_plugin_panes_absent_from_existing_layout.snap
index 2f06d931..ab242bad 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_including_plugin_panes_absent_from_existing_layout.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_including_plugin_panes_absent_from_existing_layout.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 5672
+assertion_line: 7864
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
@@ -8,11 +8,11 @@ expression: snapshot
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ Pane #2 ─────────────────────────────────────────────────┐ │
+05 (C): │ ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │
-07 (C): │ │ ┌ Pane #3 ─────────────────────────────────────────────────┐ │
+07 (C): │ │ ┌ Pane #3 ──────────────────────────────────────── PIN [ ] ┐ │
08 (C): │ │ │ │ │
-09 (C): │ │ │ ┌ Pane #4 ─────────────────────────────────────────────────┐ │
+09 (C): │ │ │ ┌ Pane #4 ──────────────────────────────────────── PIN [ ] ┐ │
10 (C): │ │ │ │ │ │
11 (C): │ │ │ │ │ │
12 (C): │ │ │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_not_including_command_panes_present_in_existing_layout.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_not_including_command_panes_present_in_existing_layout.snap
index 01d107cd..8d591ff0 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_not_including_command_panes_present_in_existing_layout.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_not_including_command_panes_present_in_existing_layout.snap
@@ -1,18 +1,18 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 6275
+assertion_line: 7793
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
-02 (C): │ ┌ command2 ────────────── SCROLL: 0/1 ┐ │
+02 (C): │ ┌ command2 ──── SCROLL: 0/1 | PIN [ ] ┐ │
03 (C): │ │ Waiting to run: command2 │ │
-04 (C): │ │ ┌ zellij:tab-bar ──────────────────────┐ │
-05 (C): │ │<│I am a tab bar ┌ zellij:status-bar ───────────────────────────────────────┐ │
+04 (C): │ │ ┌ zellij:tab-bar ───────────── PIN [ ] ┐ │
+05 (C): │ │<│I am a tab bar ┌ zellij:status-bar ────────────────────────────── PIN [ ] ┐ │
06 (C): │ │l│ │I am a │ │
-07 (C): │ └─│ │status bar │─┐ │
+07 (C): │ └─│ │status bar │ ┐ │
08 (C): │ │ │ │ │ │
-09 (C): │ └─────────────────────────│ │───┐ │
+09 (C): │ └─────────────────────────│ │ ] ┐ │
10 (C): │ │ │ │ │
11 (C): │ │ │ │ │
12 (C): │ │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_not_including_plugin_panes_present_in_existing_layout.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_not_including_plugin_panes_present_in_existing_layout.snap
index bb542c19..63deedf0 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_not_including_plugin_panes_present_in_existing_layout.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__swap_floating_layouts_not_including_plugin_panes_present_in_existing_layout.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 6432
+assertion_line: 7952
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
@@ -8,11 +8,11 @@ expression: snapshot
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ zellij:tab-bar ──────────────────────────────────────────┐ │
+05 (C): │ ┌ zellij:tab-bar ───────────────────────────────── PIN [ ] ┐ │
06 (C): │ │I am a tab bar │ │
-07 (C): │ │ ┌ Pane #2 ─────────────────────────────────────────────────┐ │
+07 (C): │ │ ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐ │
08 (C): │ │ │ │ │
-09 (C): │ │ │ ┌ zellij:status-bar ───────────────────────────────────────┐ │
+09 (C): │ │ │ ┌ zellij:status-bar ────────────────────────────── PIN [ ] ┐ │
10 (C): │ │ │ │I am a │ │
11 (C): │ │ │ │status bar │ │
12 (C): │ │ │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__tab_with_layout_that_has_floating_panes.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__tab_with_layout_that_has_floating_panes.snap
index 6816fcb8..ba51ae68 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__tab_with_layout_that_has_floating_panes.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__tab_with_layout_that_has_floating_panes.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 2560
+assertion_line: 3335
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
@@ -8,9 +8,9 @@ expression: snapshot
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ Pane #2 ─────────────────────────────────────────────────┐ │
+05 (C): │ ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │
-07 (C): │ │ ┌ Pane #3 ─────────────────────────────────────────────────┐ │
+07 (C): │ │ ┌ Pane #3 ──────────────────────────────────────── PIN [ ] ┐ │
08 (C): │ │ │ │ │
09 (C): │ │ │ │ │
10 (C): │ │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__toggle_floating_panes_on.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__toggle_floating_panes_on.snap
index dd632a95..bc92cb94 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__toggle_floating_panes_on.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__toggle_floating_panes_on.snap
@@ -1,14 +1,14 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
+assertion_line: 940
expression: snapshot
-
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
01 (C): │ │
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ Pane #2 ─────────────────────────────────────────────────┐ │
+05 (C): │ ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │
07 (C): │ │ │ │
08 (C): │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_closing_a_floating_pane_in_auto_layout_the_focus_goes_to_last_focused_pane.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_closing_a_floating_pane_in_auto_layout_the_focus_goes_to_last_focused_pane.snap
index 331e678b..bff48b73 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_closing_a_floating_pane_in_auto_layout_the_focus_goes_to_last_focused_pane.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_closing_a_floating_pane_in_auto_layout_the_focus_goes_to_last_focused_pane.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 6028
+assertion_line: 8340
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
@@ -8,9 +8,9 @@ expression: snapshot
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ Pane #3 ─────────────────────────────────────────────────┐ │
+05 (C): │ ┌ Pane #3 ──────────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │
-07 (C): │ │ │─┐ │
+07 (C): │ │ │ ┐ │
08 (C): │ │ │ │ │
09 (C): │ │ │ │ │
10 (C): │ │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_resizing_whole_tab_with_auto_layout_and_floating_panes_the_layout_is_maintained.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_resizing_whole_tab_with_auto_layout_and_floating_panes_the_layout_is_maintained.snap
index 26bcb978..c410513d 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_resizing_whole_tab_with_auto_layout_and_floating_panes_the_layout_is_maintained.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_resizing_whole_tab_with_auto_layout_and_floating_panes_the_layout_is_maintained.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 6079
+assertion_line: 8408
expression: snapshot
---
00 (C): ┌ Pane #1 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
@@ -11,11 +11,11 @@ expression: snapshot
05 (C): │ │
06 (C): │ │
07 (C): │ │
-08 (C): │ ┌ Pane #2 ────────────────────────────────────────────────────────────────┐ │
+08 (C): │ ┌ Pane #2 ─────────────────────────────────────────────────────── PIN [ ] ┐ │
09 (C): │ │ │ │
-10 (C): │ │ ┌ Pane #3 ────────────────────────────────────────────────────────────────┐ │
+10 (C): │ │ ┌ Pane #3 ─────────────────────────────────────────────────────── PIN [ ] ┐ │
11 (C): │ │ │ │ │
-12 (C): │ │ │ ┌ Pane #4 ────────────────────────────────────────────────────────────────┐ │
+12 (C): │ │ │ ┌ Pane #4 ─────────────────────────────────────────────────────── PIN [ ] ┐ │
13 (C): │ │ │ │ │ │
14 (C): │ │ │ │ │ │
15 (C): │ │ │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_swapping_floating_layouts_in_a_damaged_state_layout_and_pane_focus_are_unchanged.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_swapping_floating_layouts_in_a_damaged_state_layout_and_pane_focus_are_unchanged.snap
index 985cb317..ae98ca35 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_swapping_floating_layouts_in_a_damaged_state_layout_and_pane_focus_are_unchanged.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_swapping_floating_layouts_in_a_damaged_state_layout_and_pane_focus_are_unchanged.snap
@@ -1,16 +1,16 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 5859
+assertion_line: 8119
expression: snapshot
---
-00 (C): ┌ Pane #2 ─────────────────────────────────────────────────┐────────────────────────────────────────────────────────────┐
+00 (C): ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐────────────────────────────────────────────────────────────┐
01 (C): │ │ │
02 (C): │ │ │
03 (C): │ │ │
04 (C): │ │ │
-05 (C): │ ┌ Pane #3 ─────────────────────────────────────────────────┐ │
+05 (C): │ ┌ Pane #3 ──────────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │
-07 (C): │ │ ┌ Pane #4 ─────────────────────────────────────────────────┐ │
+07 (C): │ │ ┌ Pane #4 ──────────────────────────────────────── PIN [ ] ┐ │
08 (C): │ │ │ │ │
09 (C): └─────────────────────────────│ │ │ │
10 (C): │ │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_swapping_floating_layouts_in_an_undamaged_state_pane_focuses_on_focused_node.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_swapping_floating_layouts_in_an_undamaged_state_pane_focuses_on_focused_node.snap
index c42856cd..d72b4f8c 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_swapping_floating_layouts_in_an_undamaged_state_pane_focuses_on_focused_node.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_swapping_floating_layouts_in_an_undamaged_state_pane_focuses_on_focused_node.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 5915
+assertion_line: 8192
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
@@ -8,11 +8,11 @@ expression: snapshot
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ Pane #4 ─────────────────────────────────────────────────┐ │
+05 (C): │ ┌ Pane #4 ──────────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │
-07 (C): │ │ │─┐ │
+07 (C): │ │ │ ┐ │
08 (C): │ │ │ │ │
-09 (C): │ │ │ │─┐ │
+09 (C): │ │ │ │ ┐ │
10 (C): │ │ │ │ │ │
11 (C): │ │ │ │ │ │
12 (C): │ │ │ │ │ │
diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_swapping_floating_layouts_in_an_undamaged_state_with_no_focus_node_pane_focuses_on_deepest_node.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_swapping_floating_layouts_in_an_undamaged_state_with_no_focus_node_pane_focuses_on_deepest_node.snap
index 36c93e27..4614d7e6 100644
--- a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_swapping_floating_layouts_in_an_undamaged_state_with_no_focus_node_pane_focuses_on_deepest_node.snap
+++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__when_swapping_floating_layouts_in_an_undamaged_state_with_no_focus_node_pane_focuses_on_deepest_node.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/tab/./unit/tab_integration_tests.rs
-assertion_line: 5970
+assertion_line: 8266
expression: snapshot
---
00 (C): ┌ Pane #1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
@@ -8,11 +8,11 @@ expression: snapshot
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ Pane #4 ─────────────────────────────────────────────────┐ │
+05 (C): │ ┌ Pane #4 ──────────────────────────────────────── PIN [ ] ┐ │
06 (C): │ │ │ │
-07 (C): │ │ │─┐ │
+07 (C): │ │ │ ┐ │
08 (C): │ │ │ │ │
-09 (C): │ │ ┌ Pane #2 ─────────────────────────────────────────────────┐ │
+09 (C): │ │ ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐ │
10 (C): │ │ │ │ │
11 (C): │ │ │ │ │
12 (C): │ │ │ │ │
diff --git a/zellij-server/src/ui/pane_boundaries_frame.rs b/zellij-server/src/ui/pane_boundaries_frame.rs
index 57cff1ce..c3884fbf 100644
--- a/zellij-server/src/ui/pane_boundaries_frame.rs
+++ b/zellij-server/src/ui/pane_boundaries_frame.rs
@@ -5,6 +5,7 @@ use crate::ClientId;
use zellij_utils::data::{client_id_to_colors, PaletteColor, Style};
use zellij_utils::errors::prelude::*;
use zellij_utils::pane_size::Viewport;
+use zellij_utils::position::Position;
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
@@ -60,6 +61,7 @@ pub struct FrameParams {
pub pane_is_stacked_under: bool,
pub pane_is_stacked_over: bool,
pub should_draw_pane_frames: bool,
+ pub pane_is_floating: bool,
}
#[derive(Default, PartialEq)]
@@ -78,6 +80,8 @@ pub struct PaneFrame {
pane_is_stacked_over: bool,
pane_is_stacked_under: bool,
should_draw_pane_frames: bool,
+ is_pinned: bool,
+ is_floating: bool,
}
impl PaneFrame {
@@ -102,8 +106,14 @@ impl PaneFrame {
pane_is_stacked_over: frame_params.pane_is_stacked_over,
pane_is_stacked_under: frame_params.pane_is_stacked_under,
should_draw_pane_frames: frame_params.should_draw_pane_frames,
+ is_pinned: false,
+ is_floating: frame_params.pane_is_floating,
}
}
+ pub fn is_pinned(mut self, is_pinned: bool) -> Self {
+ self.is_pinned = is_pinned;
+ self
+ }
pub fn add_exit_status(&mut self, exit_status: Option<i32>) {
self.exit_status = match exit_status {
Some(exit_status) => Some(ExitStatus::Code(exit_status)),
@@ -149,32 +159,80 @@ impl PaneFrame {
max_length: usize,
) -> Option<(Vec<TerminalCharacter>, usize)> {
// string and length because of color
- if self.scroll_position.0 > 0 || self.scroll_position.1 > 0 {
- let prefix = " SCROLL: ";
- let full_indication =
- format!(" {}/{} ", self.scroll_position.0, self.scroll_position.1);
- let short_indication = format!(" {} ", self.scroll_position.0);
- let full_indication_len = full_indication.chars().count();
- let short_indication_len = short_indication.chars().count();
- let prefix_len = prefix.chars().count();
- if prefix_len + full_indication_len <= max_length {
- Some((
- foreground_color(&format!("{}{}", prefix, full_indication), self.color),
- prefix_len + full_indication_len,
- ))
- } else if full_indication_len <= max_length {
- Some((
- foreground_color(&full_indication, self.color),
- full_indication_len,
- ))
- } else if short_indication_len <= max_length {
- Some((
- foreground_color(&short_indication, self.color),
- short_indication_len,
- ))
+ let has_scroll = self.scroll_position.0 > 0 || self.scroll_position.1 > 0;
+ if has_scroll {
+ let pin_indication = if self.is_floating {
+ self.render_pinned_indication(max_length)
} else {
None
+ }; // no pin indication for tiled panes
+ let space_for_scroll_indication = pin_indication
+ .as_ref()
+ .map(|(_, length)| max_length.saturating_sub(*length + 1))
+ .unwrap_or(max_length);
+ let scroll_indication = self.render_scroll_indication(space_for_scroll_indication);
+ match (pin_indication, scroll_indication) {
+ (
+ Some((mut pin_indication, pin_indication_len)),
+ Some((mut scroll_indication, scroll_indication_len)),
+ ) => {
+ let mut characters: Vec<_> = scroll_indication.drain(..).collect();
+ let mut separator = foreground_color(&format!("|"), self.color);
+ characters.append(&mut separator);
+ characters.append(&mut pin_indication);
+ Some((characters, pin_indication_len + scroll_indication_len + 1))
+ },
+ (Some(pin_indication), None) => Some(pin_indication),
+ (None, Some(scroll_indication)) => Some(scroll_indication),
+ _ => None,
}
+ } else if self.is_floating {
+ self.render_pinned_indication(max_length)
+ } else {
+ None
+ }
+ }
+ fn render_scroll_indication(
+ &self,
+ max_length: usize,
+ ) -> Option<(Vec<TerminalCharacter>, usize)> {
+ let prefix = " SCROLL: ";
+ let full_indication = format!(" {}/{} ", self.scroll_position.0, self.scroll_position.1);
+ let short_indication = format!(" {} ", self.scroll_position.0);
+ let full_indication_len = full_indication.chars().count();
+ let short_indication_len = short_indication.chars().count();
+ let prefix_len = prefix.chars().count();
+ if prefix_len + full_indication_len <= max_length {
+ Some((
+ foreground_color(&format!("{}{}", prefix, full_indication), self.color),
+ prefix_len + full_indication_len,
+ ))
+ } else if full_indication_len <= max_length {
+ Some((
+ foreground_color(&full_indication, self.color),
+ full_indication_len,
+ ))
+ } else if short_indication_len <= max_length {
+ Some((
+ foreground_color(&short_indication, self.color),
+ short_indication_len,
+ ))
+ } else {
+ None
+ }
+ }
+ fn render_pinned_indication(
+ &self,
+ max_length: usize,
+ ) -> Option<(Vec<TerminalCharacter>, usize)> {
+ let is_checked = if self.is_pinned { '+' } else { ' ' };
+ let full_indication = format!(" PIN [{}] ", is_checked);
+ let full_indication_len = full_indication.chars().count();
+ if full_indication_len <= max_length {
+ Some((
+ foreground_color(&full_indication, self.color),
+ full_indication_len,
+ ))
} else {
None
}
@@ -694,6 +752,22 @@ impl PaneFrame {
};
Ok(res)
}
+ pub fn clicked_on_pinned(&mut self, position: Position) -> bool {
+ if self.is_floating {
+ // TODO: this is not entirely accurate because our relative position calculation in
+ // itself isn't - when that is fixed, we should adjust this as well
+ let checkbox_center_position = self.geom.cols.saturating_sub(5);
+ let checkbox_position_start = checkbox_center_position.saturating_sub(1);
+ let checkbox_position_end = checkbox_center_position + 1;
+ if position.line() == -1
+ && (position.column() >= checkbox_position_start
+ && position.column() <= checkbox_position_end)
+ {
+ return true;
+ }
+ }
+ false
+ }
pub fn render(&self) -> Result<(Vec<CharacterChunk>, Option<String>)> {
let err_context = || "failed to render pane frame";
let mut character_chunks = vec![];
diff --git a/zellij-server/src/ui/pane_contents_and_ui.rs b/zellij-server/src/ui/pane_contents_and_ui.rs
index 6a4a7ab8..b2ed6383 100644
--- a/zellij-server/src/ui/pane_contents_and_ui.rs
+++ b/zellij-server/src/ui/pane_contents_and_ui.rs
@@ -140,16 +140,26 @@ impl<'a> PaneContentsAndUi<'a> {
format!("failed to render fake cursor if needed for client {client_id}")
})?;
if let Some(colors) = client_id_to_colors(*fake_cursor_client_id, self.style.colors) {
- if let Some(vte_output) = self.pane.render_fake_cursor(colors.0, colors.1) {
- self.output.add_post_vte_instruction_to_client(
- client_id,
- &format!(
- "\u{1b}[{};{}H\u{1b}[m{}",
- self.pane.y() + 1,
- self.pane.x() + 1,
- vte_output
- ),
- );
+ let cursor_is_visible = self
+ .pane
+ .cursor_coordinates()
+ .map(|(x, y)| {
+ self.output
+ .cursor_is_visible(self.pane.x() + x, self.pane.y() + y)
+ })
+ .unwrap_or(false);
+ if cursor_is_visible {
+ if let Some(vte_output) = self.pane.render_fake_cursor(colors.0, colors.1) {
+ self.output.add_post_vte_instruction_to_client(
+ client_id,
+ &format!(
+ "\u{1b}[{};{}H\u{1b}[m{}",
+ self.pane.y() + 1,
+ self.pane.x() + 1,
+ vte_output
+ ),
+ );
+ }
}
}
}
@@ -179,6 +189,7 @@ impl<'a> PaneContentsAndUi<'a> {
client_id: ClientId,
client_mode: InputMode,
session_is_mirrored: bool,
+ pane_is_floating: bool,
) -> Result<()> {
let err_context = || format!("failed to render pane frame for client {client_id}");
@@ -210,6 +221,7 @@ impl<'a> PaneContentsAndUi<'a> {
pane_is_stacked_over: self.pane_is_stacked_over,
pane_is_stacked_under: self.pane_is_stacked_under,
should_draw_pane_frames: self.should_draw_pane_frames,
+ pane_is_floating,
}
} else {
FrameParams {
@@ -222,6 +234,7 @@ impl<'a> PaneContentsAndUi<'a> {
pane_is_stacked_over: self.pane_is_stacked_over,
pane_is_stacked_under: self.pane_is_stacked_under,
should_draw_pane_frames: self.should_draw_pane_frames,
+ pane_is_floating,
}
};
diff --git a/zellij-server/src/unit/screen_tests.rs b/zellij-server/src/unit/screen_tests.rs
index c536fe31..c80a796f 100644
--- a/zellij-server/src/unit/screen_tests.rs
+++ b/zellij-server/src/unit/screen_tests.rs
@@ -1328,6 +1328,7 @@ fn open_new_floating_pane_with_custom_coordinates() {
y: Some(SplitSize::Fixed(5)),
width: Some(SplitSize::Percent(1)),
height: Some(SplitSize::Fixed(2)),
+ pinned: None,
}),
false,
Some(1),
@@ -1362,6 +1363,7 @@ fn open_new_floating_pane_with_custom_coordinates_exceeding_viewport() {
y: Some(SplitSize::Fixed(21)),
width: Some(SplitSize::Fixed(10)),
height: Some(SplitSize::Fixed(10)),
+ pinned: None,
}),
false,
Some(1),
@@ -2229,6 +2231,7 @@ pub fn send_cli_new_pane_action_with_default_parameters() {
y: None,
width: None,
height: None,
+ pinned: None,
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@@ -2272,6 +2275,7 @@ pub fn send_cli_new_pane_action_with_split_direction() {
y: None,
width: None,
height: None,
+ pinned: None,
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@@ -2315,6 +2319,7 @@ pub fn send_cli_new_pane_action_with_command_and_cwd() {
y: None,
width: None,
height: None,
+ pinned: None,
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@@ -2358,6 +2363,7 @@ pub fn send_cli_new_pane_action_with_floating_pane_and_coordinates() {
y: None,
width: Some("20%".to_owned()),
height: None,
+ pinned: None,
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@@ -2396,6 +2402,7 @@ pub fn send_cli_edit_action_with_default_parameters() {
y: None,
width: None,
height: None,
+ pinned: None,
};
send_cli_action_to_server(&session_metadata, cli_edit_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@@ -2434,6 +2441,7 @@ pub fn send_cli_edit_action_with_line_number() {
y: None,
width: None,
height: None,
+ pinned: None,
};
send_cli_action_to_server(&session_metadata, cli_edit_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@@ -2472,6 +2480,7 @@ pub fn send_cli_edit_action_with_split_direction() {
y: None,
width: None,
height: None,
+ pinned: None,
};
send_cli_action_to_server(&session_metadata, cli_edit_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_break_floating_pane_to_a_new_tab-2.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_break_floating_pane_to_a_new_tab-2.snap
index e5dd722d..c4170f54 100644
--- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_break_floating_pane_to_a_new_tab-2.snap
+++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_break_floating_pane_to_a_new_tab-2.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/./unit/screen_tests.rs
-assertion_line: 3374
+assertion_line: 3395
expression: "format!(\"{}\", snapshot)"
---
00 (C): ┌ Pane #2 ─────────────────────────────────────────────────────────────────────┐
@@ -8,7 +8,7 @@ expression: "format!(\"{}\", snapshot)"
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ floating_pane_to_eject ──────────────┐ │
+05 (C): │ ┌ floating_pane_to_eject ───── PIN [ ] ┐ │
06 (C): │ │ │ │
07 (C): │ │ │ │
08 (C): │ │ │ │
diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_break_floating_pane_to_a_new_tab-4.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_break_floating_pane_to_a_new_tab-4.snap
index e5dd722d..c4170f54 100644
--- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_break_floating_pane_to_a_new_tab-4.snap
+++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_break_floating_pane_to_a_new_tab-4.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/./unit/screen_tests.rs
-assertion_line: 3374
+assertion_line: 3395
expression: "format!(\"{}\", snapshot)"
---
00 (C): ┌ Pane #2 ─────────────────────────────────────────────────────────────────────┐
@@ -8,7 +8,7 @@ expression: "format!(\"{}\", snapshot)"
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ floating_pane_to_eject ──────────────┐ │
+05 (C): │ ┌ floating_pane_to_eject ───── PIN [ ] ┐ │
06 (C): │ │ │ │
07 (C): │ │ │ │
08 (C): │ │ │ │
diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_break_floating_pane_to_a_new_tab.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_break_floating_pane_to_a_new_tab.snap
index 8460af7b..a87d4588 100644
--- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_break_floating_pane_to_a_new_tab.snap
+++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__screen_can_break_floating_pane_to_a_new_tab.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/./unit/screen_tests.rs
-assertion_line: 2849
+assertion_line: 3395
expression: "format!(\"{}\", snapshot)"
---
00 (C): ┌ tiled_pane ──────────────────────────────────────────────────────────────────┐
@@ -8,7 +8,7 @@ expression: "format!(\"{}\", snapshot)"
02 (C): │ │
03 (C): │ │
04 (C): │ │
-05 (C): │ ┌ floating_pane_to_eject ──────────────┐ │
+05 (C): │ ┌ floating_pane_to_eject ───── PIN [ ] ┐ │
06 (C): │ │ │ │
07 (C): │ │ │ │
08 (C): │ │ │ │
diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_floating_pane_and_coordinates.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_floating_pane_and_coordinates.snap
index be12965c..06cf752b 100644
--- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_floating_pane_and_coordinates.snap
+++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_floating_pane_and_coordinates.snap
@@ -1,6 +1,6 @@
---
source: zellij-server/src/./unit/screen_tests.rs
-assertion_line: 2351
+assertion_line: 2371
expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())"
---
-[SpawnTerminal(Some(RunCommand(RunCommand { command: "htop", args: [], cwd: Some("/some/folder"), hold_on_close: true, hold_on_start: false, originating_plugin: None })), Some(true), None, Some(FloatingPaneCoordinates { x: Some(Fixed(10)), y: None, width: Some(Percent(20)), height: None }), false, ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit]
+[SpawnTerminal(Some(RunCommand(RunCommand { command: "htop", args: [], cwd: Some("/some/folder"), hold_on_close: true, hold_on_start: false, originating_plugin: None })), Some(true), None, Some(FloatingPaneCoordinates { x: Some(Fixed(10)), y: None, width: Some(Percent(20)), height: None, pinned: None }), false, ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit]
diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_floating_panes-2.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_floating_panes-2.snap
index e9727e39..0eaddd57 100644
--- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_floating_panes-2.snap
+++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_floating_panes-2.snap
@@ -1,12 +1,12 @@
---
source: zellij-server/src/./unit/screen_tests.rs
-assertion_line: 2186
+assertion_line: 2609
expression: "format!(\"{}\", snapshot)"
---
00 (C): ┌ Pane #2 ─────────────────────────────────────────────────────────────────────┐
01 (C): │ │
02 (C): │ │
-03 (C): │ ┌ Pane #1 ─────────────────────────────┐ │
+03 (C): │ ┌ Pane #1 ──────────────────── PIN [ ] ┐ │
04 (C): │ │ │ │
05 (C): │ │ │ │
06 (C): │ │ │ │
diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_floating_panes-4.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_floating_panes-4.snap
index e9727e39..0eaddd57 100644
--- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_floating_panes-4.snap
+++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_floating_panes-4.snap
@@ -1,12 +1,12 @@
---
source: zellij-server/src/./unit/screen_tests.rs
-assertion_line: 2186
+assertion_line: 2609
expression: "format!(\"{}\", snapshot)"
---
00 (C): ┌ Pane #2 ─────────────────────────────────────────────────────────────────────┐
01 (C): │ │
02 (C): │ │
-03 (C): │ ┌ Pane #1 ─────────────────────────────┐ │
+03 (C): │ ┌ Pane #1 ──────────────────── PIN [ ] ┐ │
04 (C): │ │ │ │
05 (C): │ │ │ │
06 (C): │ │ │ │
diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_pane_embed_or_float-2.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_pane_embed_or_float-2.snap
index a6119cc8..ca19a162 100644
--- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_pane_embed_or_float-2.snap
+++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_pane_embed_or_float-2.snap
@@ -1,12 +1,12 @@
---
source: zellij-server/src/./unit/screen_tests.rs
-assertion_line: 2131
+assertion_line: 2569
expression: "format!(\"{}\", snapshot)"
---
00 (C): ┌ Pane #2 ─────────────────────────────────────────────────────────────────────┐
01 (C): │ │
02 (C): │ │
-03 (C): │ ┌ Pane #1 ─────────────────────────────┐ │
+03 (C): │ ┌ Pane #1 ──────────────────── PIN [ ] ┐ │
04 (C): │ │ │ │
05 (C): │ │ │ │
06 (C): │ │ │ │