From b0bd3e1e7f530db8879e8cbde79de245e6101a8a Mon Sep 17 00:00:00 2001 From: Aram Drevekenin Date: Mon, 24 Aug 2026 20:14:58 +0200 Subject: [PATCH] fix: fullscreen floating pane editor (#5528) * fix: fullscreen floating pane editor * add pr --- CHANGELOG.md | 1 + zellij-server/src/panes/floating_panes/mod.rs | 10 +- zellij-server/src/tab/unit/tab_tests.rs | 113 ++++++++++++++++++ 3 files changed, 123 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba346b3fd..0a1a9d5c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * fix: some issues with notification parsing (eg. neovim notification on save) (https://github.com/zellij-org/zellij/pull/5523) * fix: kitty image size on startup and clearing with stacked unlisted full framed panes (https://github.com/zellij-org/zellij/pull/5526) * fix: focus event in remote attach (https://github.com/zellij-org/zellij/pull/5527) +* fix: editing scrollback issue with a fullscreen floating pane (https://github.com/zellij-org/zellij/pull/5528) ## [0.45.0] - 2026-08-20 * feat: allow tabs to have different sizes if clients aren't focused on the same one (https://github.com/zellij-org/zellij/pull/5133) diff --git a/zellij-server/src/panes/floating_panes/mod.rs b/zellij-server/src/panes/floating_panes/mod.rs index 45e21fac9..f14e01dbb 100644 --- a/zellij-server/src/panes/floating_panes/mod.rs +++ b/zellij-server/src/panes/floating_panes/mod.rs @@ -212,9 +212,17 @@ impl FloatingPanes { .and_then(|removed_pane| { let removed_pane_id = removed_pane.pid(); let with_pane_id = with_pane.pid(); - let removed_pane_geom = removed_pane.current_geom(); + let removed_pane_geom = removed_pane.position_and_size(); + let removed_pane_geom_override = removed_pane.geom_override(); with_pane.set_geom(removed_pane_geom); + match removed_pane_geom_override { + Some(geom_override) => with_pane.set_geom_override(geom_override), + None => with_pane.reset_size_and_position_override(), + }; self.panes.insert(with_pane_id, with_pane); + if self.fullscreen_pane_id == Some(pane_id) { + self.fullscreen_pane_id = Some(with_pane_id); + } let z_index = self .z_indices .iter() diff --git a/zellij-server/src/tab/unit/tab_tests.rs b/zellij-server/src/tab/unit/tab_tests.rs index 14be7264c..18f02da28 100644 --- a/zellij-server/src/tab/unit/tab_tests.rs +++ b/zellij-server/src/tab/unit/tab_tests.rs @@ -2429,6 +2429,119 @@ pub fn opening_scrollback_editor_on_fullscreen_pane_retargets_fullscreen() { } } +#[test] +pub fn opening_scrollback_editor_on_fullscreen_floating_pane_retargets_fullscreen() { + let client_id = 1; + let mut tab = create_tab_with_two_floating_panes(); + let viewport = *tab.viewport.borrow(); + let active_pane_id = tab + .floating_panes + .active_pane_id(client_id) + .expect("a floating pane is focused"); + let original_geom = tab + .floating_panes + .get(&active_pane_id) + .expect("focused floating pane exists") + .position_and_size(); + + tab.toggle_active_pane_fullscreen(client_id); + assert_eq!( + tab.floating_panes.fullscreen_pane_id(), + Some(active_pane_id), + "fullscreen tracks the original floating pane", + ); + + let editor_pane_id = PaneId::Terminal(99); + tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id) + .unwrap(); + assert_eq!( + tab.floating_panes.fullscreen_pane_id(), + Some(editor_pane_id), + "fullscreen now tracks the editor pane id, not the suppressed one", + ); + let editor_geom = floating_pane_geom(&tab, editor_pane_id); + assert_eq!( + editor_geom.cols.as_usize(), + viewport.cols, + "the editor pane covers the viewport cols", + ); + assert_eq!( + editor_geom.rows.as_usize(), + viewport.rows, + "the editor pane covers the viewport rows", + ); + + tab.toggle_active_pane_fullscreen(client_id); + assert!( + !tab.floating_panes.fullscreen_is_active(), + "fullscreen is cleared after the second toggle", + ); + let editor_pane = tab + .floating_panes + .get(&editor_pane_id) + .expect("editor pane is present in floating panes"); + assert!( + editor_pane.geom_override().is_none(), + "editor pane no longer carries the fullscreen geom_override", + ); + assert_eq!( + editor_pane.position_and_size(), + original_geom, + "editor pane falls back to the replaced pane's original geometry", + ); +} + +#[test] +pub fn closing_fullscreen_floating_scrollback_editor_restores_geometry() { + let client_id = 1; + let mut tab = create_tab_with_two_floating_panes(); + let active_pane_id = tab + .floating_panes + .active_pane_id(client_id) + .expect("a floating pane is focused"); + let original_geom = tab + .floating_panes + .get(&active_pane_id) + .expect("focused floating pane exists") + .position_and_size(); + + let editor_pane_id = PaneId::Terminal(99); + tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id) + .unwrap(); + tab.toggle_active_pane_fullscreen(client_id); + assert_eq!( + tab.floating_panes.fullscreen_pane_id(), + Some(editor_pane_id), + "fullscreen tracks the editor pane", + ); + + tab.close_pane(editor_pane_id, false, None); + assert_eq!( + tab.floating_panes.fullscreen_pane_id(), + Some(active_pane_id), + "fullscreen now tracks the restored suppressed pane", + ); + + tab.toggle_active_pane_fullscreen(client_id); + assert!( + !tab.floating_panes.fullscreen_is_active(), + "fullscreen is cleared after the second toggle", + ); + let restored_pane = tab + .floating_panes + .get(&active_pane_id) + .expect("restored pane is present"); + assert!( + restored_pane.geom_override().is_none(), + "restored pane no longer carries the fullscreen geom_override", + ); + assert_eq!( + restored_pane.position_and_size(), + original_geom, + "restored pane is back to its original geometry", + ); +} + #[test] fn switch_to_next_pane_fullscreen() { let size = Size {