aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2026-01-27 10:18:31 +0100
committerGitHub <noreply@github.com>2026-01-27 10:18:31 +0100
commitf0a8f4659c825ca8fb34fa6f89ecab414b6c6d3f (patch)
treeefccf839dfa4bbd36a9713082a7d604a3e5ba874
parentfeat(assets): add svg logo (#4196) (diff)
downloadsl0ppij-f0a8f4659c825ca8fb34fa6f89ecab414b6c6d3f.tar.gz
sl0ppij-f0a8f4659c825ca8fb34fa6f89ecab414b6c6d3f.tar.xz
sl0ppij-f0a8f4659c825ca8fb34fa6f89ecab414b6c6d3f.zip
fix: properly occlude cursor in floating pane when pinned pane covers it (#4644)
* fix: properly occlude cursor in floating pane when pinned pane covers it * add pr
-rw-r--r--CHANGELOG.md1
-rw-r--r--zellij-server/src/output/mod.rs18
-rw-r--r--zellij-server/src/output/unit/output_tests.rs134
-rw-r--r--zellij-server/src/panes/floating_panes/mod.rs3
-rw-r--r--zellij-server/src/tab/mod.rs13
-rw-r--r--zellij-server/src/tab/unit/tab_integration_tests.rs156
-rw-r--r--zellij-server/src/tab/unit/tab_tests.rs187
-rw-r--r--zellij-server/src/ui/pane_contents_and_ui.rs7
8 files changed, 505 insertions, 14 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3497f3b8..b0211c8c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -34,6 +34,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
* fix: allow disabling automatic OSC8 hyperlink formatting (https://github.com/zellij-org/zellij/pull/4624)
* fix: properly set cwd for new sessions started from the `session-manager` (https://github.com/zellij-org/zellij/pull/4625)
* fix: get `zellij run --session <X>` to work even when the specified session has no connected users (https://github.com/zellij-org/zellij/pull/4626)
+* fix: properly occlude cursor in floating panes when (partially) covered by another pinned pane (https://github.com/zellij-org/zellij/pull/4644)
* fix: resolve short layout names as files if possible (https://github.com/zellij-org/zellij/pull/4640)
diff --git a/zellij-server/src/output/mod.rs b/zellij-server/src/output/mod.rs
index 180514ae..5ca283a7 100644
--- a/zellij-server/src/output/mod.rs
+++ b/zellij-server/src/output/mod.rs
@@ -595,11 +595,16 @@ 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(&mut self, cursor_x: usize, cursor_y: usize) -> bool {
+ pub fn cursor_is_visible(
+ &mut self,
+ cursor_x: usize,
+ cursor_y: usize,
+ z_index: Option<usize>,
+ ) -> bool {
self.cursor_coordinates = Some((cursor_x, cursor_y));
self.floating_panes_stack
.as_ref()
- .map(|s| s.cursor_is_visible(cursor_x, cursor_y))
+ .map(|s| s.cursor_is_visible(cursor_x, cursor_y, z_index))
.unwrap_or(true)
}
pub fn add_pane_contents(
@@ -910,8 +915,13 @@ 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
+ pub fn cursor_is_visible(
+ &self,
+ cursor_x: usize,
+ cursor_y: usize,
+ z_index: Option<usize>,
+ ) -> bool {
+ let z_index = z_index.map(|z| z + 1).unwrap_or(0); // +1 because we only check panes above the active pane
let panes_to_check = self.layers.iter().skip(z_index);
for pane_geom in panes_to_check {
let pane_top_edge = pane_geom.y;
diff --git a/zellij-server/src/output/unit/output_tests.rs b/zellij-server/src/output/unit/output_tests.rs
index 4a25748d..bb0bb664 100644
--- a/zellij-server/src/output/unit/output_tests.rs
+++ b/zellij-server/src/output/unit/output_tests.rs
@@ -508,7 +508,7 @@ fn test_serialize_with_size_hides_cursor_when_cropped() {
let max_size = Some(Size { rows: 10, cols: 20 });
// Set cursor outside max_size
- output.cursor_is_visible(25, 5);
+ output.cursor_is_visible(25, 5, None);
let chunk = create_character_chunk_from_str("Test", 0, 0);
output
@@ -796,18 +796,146 @@ fn test_cursor_is_visible_with_floating_panes() {
// Cursor inside pane bounds
assert!(
- !stack.cursor_is_visible(7, 7),
+ !stack.cursor_is_visible(7, 7, None),
"Cursor should not be visible when covered by pane"
);
// Cursor outside pane bounds
assert!(
- stack.cursor_is_visible(20, 20),
+ stack.cursor_is_visible(20, 20, None),
"Cursor should be visible when not covered by pane"
);
}
#[test]
+fn test_cursor_visibility_with_z_index_bottom_layer() {
+ // Two overlapping panes: bottom at (5,5) and top at (5,5)
+ let bottom_pane = create_pane_geom(5, 5, 10, 10);
+ let top_pane = create_pane_geom(5, 5, 10, 10);
+
+ let stack = FloatingPanesStack {
+ layers: vec![bottom_pane, top_pane],
+ };
+
+ // Cursor at position (7,7) in the bottom layer (z-index 0)
+ // Should be hidden because there's a pane above it (z-index 1) at the same position
+ assert!(
+ !stack.cursor_is_visible(7, 7, Some(0)),
+ "Cursor in bottom layer should be hidden by pane above it"
+ );
+}
+
+#[test]
+fn test_cursor_visibility_with_z_index_top_layer() {
+ // Two overlapping panes: bottom at (5,5) and top at (5,5)
+ let bottom_pane = create_pane_geom(5, 5, 10, 10);
+ let top_pane = create_pane_geom(5, 5, 10, 10);
+
+ let stack = FloatingPanesStack {
+ layers: vec![bottom_pane, top_pane],
+ };
+
+ // Cursor at position (7,7) in the top layer (z-index 1)
+ // Should be visible even though there's a pane below it at the same position
+ assert!(
+ stack.cursor_is_visible(7, 7, Some(1)),
+ "Cursor in top layer should be visible (not affected by panes below)"
+ );
+}
+
+#[test]
+fn test_cursor_visibility_with_multiple_layers() {
+ // Three panes stacked vertically with different layers
+ // Layer 0 (bottom): pane at (5,5)
+ // Layer 1 (middle): pane at (10,10)
+ // Layer 2 (top): pane at (5,5) - overlaps with layer 0
+ let layer0_pane = create_pane_geom(5, 5, 10, 10);
+ let layer1_pane = create_pane_geom(10, 10, 10, 10);
+ let layer2_pane = create_pane_geom(5, 5, 10, 10);
+
+ let stack = FloatingPanesStack {
+ layers: vec![layer0_pane, layer1_pane, layer2_pane],
+ };
+
+ // Cursor at (7,7) in layer 0 - should be hidden by layer 2
+ assert!(
+ !stack.cursor_is_visible(7, 7, Some(0)),
+ "Cursor in layer 0 should be hidden by layer 2 above it"
+ );
+
+ // Cursor at (16,16) in layer 1 - should be visible (layer 2 doesn't cover this position)
+ // Layer 1 is at (10,10) size 10x10, so covers (10,10) to (19,19)
+ // Layer 2 is at (5,5) size 10x10, so covers (5,5) to (14,14)
+ // Position (16,16) is inside layer 1 but outside layer 2
+ assert!(
+ stack.cursor_is_visible(16, 16, Some(1)),
+ "Cursor in layer 1 should be visible when not covered by layers above"
+ );
+
+ // Cursor at (7,7) in layer 2 - should be visible (no layers above)
+ assert!(
+ stack.cursor_is_visible(7, 7, Some(2)),
+ "Cursor in top layer should always be visible"
+ );
+}
+
+#[test]
+fn test_cursor_visibility_pinned_pane_over_floating() {
+ // Simulates a floating pane (z-index 0) with a pinned pane (z-index 1) on top
+ // Both panes overlap at the same position
+ let floating_pane = create_pane_geom(10, 10, 20, 20);
+ let mut pinned_pane = create_pane_geom(10, 10, 20, 20);
+ pinned_pane.is_pinned = true;
+
+ let stack = FloatingPanesStack {
+ layers: vec![floating_pane, pinned_pane],
+ };
+
+ // Cursor in the floating pane (z-index 0) at position covered by pinned pane
+ assert!(
+ !stack.cursor_is_visible(15, 15, Some(0)),
+ "Cursor in floating pane should be hidden when covered by pinned pane above"
+ );
+
+ // Cursor in the pinned pane (z-index 1) at the same position
+ assert!(
+ stack.cursor_is_visible(15, 15, Some(1)),
+ "Cursor in pinned pane should be visible"
+ );
+}
+
+#[test]
+fn test_cursor_visibility_partial_overlap() {
+ // Two panes with partial overlap
+ // Layer 0: pane at (0, 0) size 10x10
+ // Layer 1: pane at (5, 5) size 10x10 (overlaps bottom-right of layer 0)
+ let layer0_pane = create_pane_geom(0, 0, 10, 10);
+ let layer1_pane = create_pane_geom(5, 5, 10, 10);
+
+ let stack = FloatingPanesStack {
+ layers: vec![layer0_pane, layer1_pane],
+ };
+
+ // Cursor at (2,2) in layer 0 - not covered by layer 1, should be visible
+ assert!(
+ stack.cursor_is_visible(2, 2, Some(0)),
+ "Cursor in non-overlapping area should be visible"
+ );
+
+ // Cursor at (7,7) in layer 0 - covered by layer 1, should be hidden
+ assert!(
+ !stack.cursor_is_visible(7, 7, Some(0)),
+ "Cursor in overlapping area should be hidden by pane above"
+ );
+
+ // Cursor at (7,7) in layer 1 - should be visible (top layer)
+ assert!(
+ stack.cursor_is_visible(7, 7, Some(1)),
+ "Cursor in top layer should be visible in overlapping area"
+ );
+}
+
+#[test]
fn test_output_buffer_update_line() {
let mut buffer = OutputBuffer::default();
buffer.clear(); // Clear the initial "update all lines" state
diff --git a/zellij-server/src/panes/floating_panes/mod.rs b/zellij-server/src/panes/floating_panes/mod.rs
index 0303399f..d28e0574 100644
--- a/zellij-server/src/panes/floating_panes/mod.rs
+++ b/zellij-server/src/panes/floating_panes/mod.rs
@@ -230,6 +230,9 @@ impl FloatingPanes {
pub fn active_pane_id(&self, client_id: ClientId) -> Option<PaneId> {
self.active_panes.get(&client_id).copied()
}
+ pub fn get_pane_z_index(&self, pane_id: PaneId) -> Option<usize> {
+ self.z_indices.iter().position(|id| id == &pane_id)
+ }
pub fn active_pane_id_or_focused_pane_id(&self, client_id: Option<ClientId>) -> Option<PaneId> {
// returns the focused pane of any client_id - should be safe because the way things are
// set up at the time of writing, all clients are focused on the same floating pane due to
diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs
index ab794853..02c26362 100644
--- a/zellij-server/src/tab/mod.rs
+++ b/zellij-server/src/tab/mod.rs
@@ -3057,11 +3057,14 @@ impl Tab {
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) {
+ let active_pane_z_index = self
+ .get_active_pane_id(client_id)
+ .and_then(|pane_id| self.floating_panes.get_pane_z_index(pane_id));
+ if output.cursor_is_visible(
+ cursor_position_x,
+ cursor_position_y,
+ active_pane_z_index,
+ ) {
Some((cursor_position_x, cursor_position_y))
} else {
None
diff --git a/zellij-server/src/tab/unit/tab_integration_tests.rs b/zellij-server/src/tab/unit/tab_integration_tests.rs
index 627af6af..8b109def 100644
--- a/zellij-server/src/tab/unit/tab_integration_tests.rs
+++ b/zellij-server/src/tab/unit/tab_integration_tests.rs
@@ -10050,3 +10050,159 @@ fn borderless_pinned_floating_pane() {
);
assert_snapshot!(snapshot);
}
+
+#[test]
+fn cursor_hidden_when_floating_pane_is_under_pinned_pane() {
+ // Test that cursor is correctly hidden when focused on a floating pane that's under a pinned pane
+ let size = Size {
+ cols: 121,
+ rows: 20,
+ };
+ let client_id = 1;
+ let mut tab = create_new_tab(size, ModeInfo::default());
+ let mut output = Output::default();
+
+ // Create first floating pane (will be underneath)
+ let bottom_pane_coordinates = FloatingPaneCoordinates {
+ x: Some(PercentOrFixed::Fixed(10)),
+ y: Some(PercentOrFixed::Fixed(5)),
+ width: Some(PercentOrFixed::Fixed(40)),
+ height: Some(PercentOrFixed::Fixed(10)),
+ pinned: Some(false),
+ borderless: Some(false),
+ };
+
+ tab.new_floating_pane(
+ PaneId::Terminal(2),
+ None,
+ None,
+ false,
+ true,
+ Some(bottom_pane_coordinates),
+ None,
+ )
+ .unwrap();
+
+ // Create overlapping pinned pane on top
+ let top_pane_coordinates = FloatingPaneCoordinates {
+ x: Some(PercentOrFixed::Fixed(15)),
+ y: Some(PercentOrFixed::Fixed(6)),
+ width: Some(PercentOrFixed::Fixed(30)),
+ height: Some(PercentOrFixed::Fixed(8)),
+ pinned: Some(true),
+ borderless: Some(false),
+ };
+
+ tab.new_floating_pane(
+ PaneId::Terminal(3),
+ None,
+ None,
+ false,
+ true,
+ Some(top_pane_coordinates),
+ None,
+ )
+ .unwrap();
+
+ // Add some text to both panes so we can see them
+ tab.handle_pty_bytes(2, Vec::from("Bottom floating pane".as_bytes()))
+ .unwrap();
+ tab.handle_pty_bytes(3, Vec::from("Top pinned pane".as_bytes()))
+ .unwrap();
+
+ // Explicitly focus the bottom floating pane (PaneId::Terminal(2))
+ // Use move_focus_left to switch from pane 3 to pane 2
+ tab.move_focus_left(client_id).unwrap();
+
+ // Render
+ tab.render(&mut output, None).unwrap();
+ let (_snapshot, cursor_coordinates) = take_snapshot_and_cursor_position(
+ output.serialize().unwrap().get(&client_id).unwrap(),
+ size.rows,
+ size.cols,
+ Palette::default(),
+ );
+
+ // The cursor should be hidden because the focused pane (2) is under the pinned pane (3)
+ // and the cursor position falls within the overlapping area
+ assert_eq!(
+ cursor_coordinates, None,
+ "Cursor should be hidden when focused floating pane is under a pinned pane that covers it"
+ );
+}
+
+#[test]
+fn cursor_visible_when_pinned_pane_is_focused() {
+ // Test that cursor is visible when focused on a pinned pane that's on top
+ let size = Size {
+ cols: 121,
+ rows: 20,
+ };
+ let client_id = 1;
+ let mut tab = create_new_tab(size, ModeInfo::default());
+ let mut output = Output::default();
+
+ // Create first floating pane (will be underneath)
+ let bottom_pane_coordinates = FloatingPaneCoordinates {
+ x: Some(PercentOrFixed::Fixed(10)),
+ y: Some(PercentOrFixed::Fixed(5)),
+ width: Some(PercentOrFixed::Fixed(40)),
+ height: Some(PercentOrFixed::Fixed(10)),
+ pinned: Some(false),
+ borderless: Some(false),
+ };
+
+ tab.new_floating_pane(
+ PaneId::Terminal(2),
+ None,
+ None,
+ false,
+ true,
+ Some(bottom_pane_coordinates),
+ None,
+ )
+ .unwrap();
+
+ // Create overlapping pinned pane on top
+ let top_pane_coordinates = FloatingPaneCoordinates {
+ x: Some(PercentOrFixed::Fixed(15)),
+ y: Some(PercentOrFixed::Fixed(6)),
+ width: Some(PercentOrFixed::Fixed(30)),
+ height: Some(PercentOrFixed::Fixed(8)),
+ pinned: Some(true),
+ borderless: Some(false),
+ };
+
+ tab.new_floating_pane(
+ PaneId::Terminal(3),
+ None,
+ None,
+ false,
+ true,
+ Some(top_pane_coordinates),
+ None,
+ )
+ .unwrap();
+
+ // Add some text to both panes
+ tab.handle_pty_bytes(2, Vec::from("Bottom floating pane".as_bytes()))
+ .unwrap();
+ tab.handle_pty_bytes(3, Vec::from("Top pinned pane".as_bytes()))
+ .unwrap();
+
+ // The pinned pane should be focused by default (last created)
+ // Render
+ tab.render(&mut output, None).unwrap();
+ let (_snapshot, cursor_coordinates) = take_snapshot_and_cursor_position(
+ output.serialize().unwrap().get(&client_id).unwrap(),
+ size.rows,
+ size.cols,
+ Palette::default(),
+ );
+
+ // The cursor should be visible because the focused pane is the pinned pane on top
+ assert!(
+ cursor_coordinates.is_some(),
+ "Cursor should be visible when focused on pinned pane that's on top"
+ );
+}
diff --git a/zellij-server/src/tab/unit/tab_tests.rs b/zellij-server/src/tab/unit/tab_tests.rs
index fec63764..eea12a55 100644
--- a/zellij-server/src/tab/unit/tab_tests.rs
+++ b/zellij-server/src/tab/unit/tab_tests.rs
@@ -15066,3 +15066,190 @@ fn correctly_resize_frameless_panes_on_pane_close() {
let content_size = (pane.get_content_columns(), pane.get_content_rows());
assert_eq!(content_size, (cols, rows));
}
+
+#[test]
+fn floating_pane_z_index_is_tracked() {
+ let size = Size {
+ cols: 121,
+ rows: 20,
+ };
+ let stacked_resize = false;
+ let mut tab = create_new_tab(size, stacked_resize);
+ let _client_id = 1;
+
+ // Create first floating pane (should_float = true means it will be a floating pane)
+ tab.new_floating_pane(PaneId::Terminal(2), None, None, false, true, None, None)
+ .unwrap();
+
+ // Create second floating pane
+ tab.new_floating_pane(PaneId::Terminal(3), None, None, false, true, None, None)
+ .unwrap();
+
+ // Verify z-indices exist and are different
+ let z_index_pane2 = tab.floating_panes.get_pane_z_index(PaneId::Terminal(2));
+ let z_index_pane3 = tab.floating_panes.get_pane_z_index(PaneId::Terminal(3));
+
+ assert!(
+ z_index_pane2.is_some(),
+ "First floating pane should have a z-index"
+ );
+ assert!(
+ z_index_pane3.is_some(),
+ "Second floating pane should have a z-index"
+ );
+ assert_ne!(
+ z_index_pane2, z_index_pane3,
+ "Different panes should have different z-indices"
+ );
+}
+
+#[test]
+fn pinned_floating_pane_has_higher_z_index() {
+ let size = Size {
+ cols: 121,
+ rows: 20,
+ };
+ let stacked_resize = false;
+ let mut tab = create_new_tab(size, stacked_resize);
+ let _client_id = 1;
+
+ // Create first floating pane (will be unpinned)
+ tab.new_floating_pane(PaneId::Terminal(2), None, None, false, true, None, None)
+ .unwrap();
+
+ // Create second floating pane and pin it
+ tab.new_floating_pane(PaneId::Terminal(3), None, None, false, true, None, None)
+ .unwrap();
+ tab.set_floating_pane_pinned(PaneId::Terminal(3), true);
+
+ // Get z-indices
+ let z_index_unpinned = tab
+ .floating_panes
+ .get_pane_z_index(PaneId::Terminal(2))
+ .expect("Unpinned pane should have z-index");
+ let z_index_pinned = tab
+ .floating_panes
+ .get_pane_z_index(PaneId::Terminal(3))
+ .expect("Pinned pane should have z-index");
+
+ assert!(
+ z_index_pinned > z_index_unpinned,
+ "Pinned pane should have higher z-index than unpinned pane (pinned: {}, unpinned: {})",
+ z_index_pinned,
+ z_index_unpinned
+ );
+}
+
+#[test]
+fn pinned_pane_z_index_higher_than_regular_floating_panes() {
+ let size = Size {
+ cols: 121,
+ rows: 20,
+ };
+ let stacked_resize = false;
+ let mut tab = create_new_tab(size, stacked_resize);
+ let _client_id = 1;
+
+ // Create first floating pane
+ tab.new_floating_pane(PaneId::Terminal(2), None, None, false, true, None, None)
+ .unwrap();
+
+ // Create second floating pane
+ tab.new_floating_pane(PaneId::Terminal(3), None, None, false, true, None, None)
+ .unwrap();
+
+ // Pin the second pane so it's on top
+ tab.set_floating_pane_pinned(PaneId::Terminal(3), true);
+
+ // Verify that get_pane_z_index returns correct values for both panes
+ let z_index_bottom = tab.floating_panes.get_pane_z_index(PaneId::Terminal(2));
+ let z_index_top = tab.floating_panes.get_pane_z_index(PaneId::Terminal(3));
+
+ assert!(
+ z_index_bottom.is_some(),
+ "Regular floating pane should have z-index"
+ );
+ assert!(
+ z_index_top.is_some(),
+ "Pinned floating pane should have z-index"
+ );
+ assert!(
+ z_index_top.unwrap() > z_index_bottom.unwrap(),
+ "Pinned pane should have higher z-index than regular floating pane (pinned: {}, regular: {})",
+ z_index_top.unwrap(),
+ z_index_bottom.unwrap()
+ );
+}
+
+#[test]
+fn active_pane_z_index_retrieved_for_cursor_visibility() {
+ let size = Size {
+ cols: 121,
+ rows: 20,
+ };
+ let stacked_resize = false;
+ let mut tab = create_new_tab(size, stacked_resize);
+ let client_id = 1;
+
+ // Start with tiled panes - active pane should not have z-index
+ let active_pane_id_tiled = tab.get_active_pane_id(client_id).unwrap();
+ let z_index_tiled = tab.floating_panes.get_pane_z_index(active_pane_id_tiled);
+ assert!(
+ z_index_tiled.is_none(),
+ "Tiled pane should not have z-index in floating panes"
+ );
+
+ // Create a floating pane
+ tab.new_floating_pane(PaneId::Terminal(2), None, None, false, true, None, None)
+ .unwrap();
+
+ // Active pane should now have a z-index
+ let active_pane_id_floating = tab.get_active_pane_id(client_id).unwrap();
+ let z_index_floating = tab.floating_panes.get_pane_z_index(active_pane_id_floating);
+ assert!(
+ z_index_floating.is_some(),
+ "Active floating pane should have a z-index"
+ );
+}
+
+#[test]
+fn get_pane_z_index_returns_none_for_nonexistent_pane() {
+ let size = Size {
+ cols: 121,
+ rows: 20,
+ };
+ let stacked_resize = false;
+ let mut tab = create_new_tab(size, stacked_resize);
+ let _client_id = 1;
+
+ // Create two floating panes
+ tab.new_floating_pane(PaneId::Terminal(2), None, None, false, true, None, None)
+ .unwrap();
+ tab.new_floating_pane(PaneId::Terminal(3), None, None, false, true, None, None)
+ .unwrap();
+
+ // Query for a pane that doesn't exist
+ let z_index_nonexistent = tab.floating_panes.get_pane_z_index(PaneId::Terminal(999));
+
+ assert!(
+ z_index_nonexistent.is_none(),
+ "Non-existent pane should return None for z-index"
+ );
+
+ // Query for existing panes
+ let z_index_2 = tab.floating_panes.get_pane_z_index(PaneId::Terminal(2));
+ let z_index_3 = tab.floating_panes.get_pane_z_index(PaneId::Terminal(3));
+
+ assert!(
+ z_index_2.is_some(),
+ "Existing floating pane 2 should return Some for z-index"
+ );
+ assert!(
+ z_index_3.is_some(),
+ "Existing floating pane 3 should return Some for z-index"
+ );
+ assert_ne!(
+ z_index_2, z_index_3,
+ "Different floating panes should have different z-indices"
+ );
+}
diff --git a/zellij-server/src/ui/pane_contents_and_ui.rs b/zellij-server/src/ui/pane_contents_and_ui.rs
index 326dd96f..6e4f8c74 100644
--- a/zellij-server/src/ui/pane_contents_and_ui.rs
+++ b/zellij-server/src/ui/pane_contents_and_ui.rs
@@ -161,8 +161,11 @@ impl<'a> PaneContentsAndUi<'a> {
.pane
.cursor_coordinates(Some(*fake_cursor_client_id))
.map(|(x, y)| {
- self.output
- .cursor_is_visible(self.pane.x() + x, self.pane.y() + y)
+ self.output.cursor_is_visible(
+ self.pane.x() + x,
+ self.pane.y() + y,
+ self.z_index,
+ )
})
.unwrap_or(false);
if cursor_is_visible {