diff --git a/CHANGELOG.md b/CHANGELOG.md index b21f466c..f45af785 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * fix: out of bounds mouse release events (https://github.com/zellij-org/zellij/pull/4300) * fix: account for emoji/widechars when double/triple-clicking to mark words (https://github.com/zellij-org/zellij/pull/4302) * fix: allow pasting and emojis in tab/pane names and pasting in search (https://github.com/zellij-org/zellij/pull/4303) +* fix: stack pane ordering when stacking multiple panes (https://github.com/zellij-org/zellij/pull/4308) ## [0.42.2] - 2025-04-15 * refactor(terminal): track scroll_region as tuple rather than Option (https://github.com/zellij-org/zellij/pull/4082) diff --git a/default-plugins/multiple-select/src/main.rs b/default-plugins/multiple-select/src/main.rs index 8017bb69..bd6a8a58 100644 --- a/default-plugins/multiple-select/src/main.rs +++ b/default-plugins/multiple-select/src/main.rs @@ -186,20 +186,29 @@ impl App { fn update_grouped_panes(&mut self, pane_manifest: &PaneManifest, own_client_id: ClientId) { self.grouped_panes.clear(); let mut count = 0; + let mut panes_with_index = Vec::new(); for (_tab_index, pane_infos) in &pane_manifest.panes { for pane_info in pane_infos { - if pane_info.index_in_pane_group.get(&own_client_id).is_some() { + if let Some(index_in_pane_group) = pane_info.index_in_pane_group.get(&own_client_id) + { let pane_id = if pane_info.is_plugin { PaneId::Plugin(pane_info.id) } else { PaneId::Terminal(pane_info.id) }; - self.grouped_panes.push(pane_id); + panes_with_index.push((*index_in_pane_group, pane_id)); count += 1; } } } + + panes_with_index.sort_by_key(|(index, _)| *index); + + for (_, pane_id) in panes_with_index { + self.grouped_panes.push(pane_id); + } + if count == 0 { self.close_self(); } diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs index e0125915..9e00a5f2 100644 --- a/zellij-server/src/screen.rs +++ b/zellij-server/src/screen.rs @@ -2768,13 +2768,14 @@ impl Screen { } } pub fn stack_panes(&mut self, mut pane_ids_to_stack: Vec) -> Option { - // if successful, returns the pane id of the root pane + // if successful, returns the pane id of the last pane in the stack if pane_ids_to_stack.is_empty() { log::error!("Got an empty list of pane_ids to stack"); return None; } let stack_size = pane_ids_to_stack.len(); let root_pane_id = pane_ids_to_stack.remove(0); + let last_pane_id = pane_ids_to_stack.last(); let Some(root_tab_id) = self .tabs .iter() @@ -2824,7 +2825,7 @@ impl Screen { self.tabs .get_mut(&root_tab_id) .map(|t| t.stack_panes(root_pane_id, panes_to_stack)); - return Some(root_pane_id); + return last_pane_id.copied(); } pub fn change_floating_panes_coordinates( &mut self, @@ -5470,8 +5471,8 @@ pub(crate) fn screen_thread_main( screen.set_floating_pane_pinned(pane_id, should_be_pinned); }, ScreenInstruction::StackPanes(pane_ids_to_stack, client_id) => { - if let Some(root_pane_id) = screen.stack_panes(pane_ids_to_stack) { - let _ = screen.focus_pane_with_id(root_pane_id, false, client_id); + if let Some(last_pane_id) = screen.stack_panes(pane_ids_to_stack) { + let _ = screen.focus_pane_with_id(last_pane_id, false, client_id); let _ = screen.unblock_input(); let _ = screen.render(None); let pane_group = screen.get_client_pane_group(&client_id); diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs index e8c61a69..b6eadc14 100644 --- a/zellij-server/src/tab/mod.rs +++ b/zellij-server/src/tab/mod.rs @@ -5278,24 +5278,9 @@ impl Tab { } self.swap_layouts.set_is_tiled_damaged(); // TODO: verify we can do all the below first if self.pane_is_stacked(root_pane_id) { - if let Some(lowest_pane_id_in_stack) = self - .tiled_panes - .pane_ids_in_stack_of_pane_id(&root_pane_id) - .last() - { - // we get lowest_pane_id_in_stack so that we can extract the pane below and re-add - // it to its own stack - this has the effect of making it the last pane in the - // stack so that the rest of the panes will later be added below it - which makes - // sense from the perspective of the user - if let Some(pane) = self.extract_pane(root_pane_id, true) { - self.tiled_panes - .add_pane_to_stack(&lowest_pane_id_in_stack, pane); - } - } for pane in panes_to_stack.drain(..) { self.tiled_panes.add_pane_to_stack(&root_pane_id, pane); } - self.tiled_panes.expand_pane_in_stack(root_pane_id); } else { // + 1 for the root pane let mut stack_geoms = self diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_stack_panes_action-2.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_stack_panes_action-2.snap index 042e0d34..fefe190e 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_stack_panes_action-2.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_stack_panes_action-2.snap @@ -3,12 +3,12 @@ source: zellij-server/src/./unit/screen_tests.rs expression: "format!(\"{}\", snapshot)" --- 00 (C): ┌ Pane #1 ─────┐┌ Pane #2 ─────────────────────────────────────┐┌ Pane #5 ─────┐ -01 (C): │ ││ ││ │ -02 (C): │ ││ ││ │ +01 (C): │ │┌ Pane #3 ─────────────────────────────────────┐│ │ +02 (C): │ │┌ Pane #4 ─────────────────────────────────────┐│ │ 03 (C): │ ││ ││ │ 04 (C): │ ││ ││ │ 05 (C): │ ││ ││ │ 06 (C): │ ││ ││ │ -07 (C): │ │└──────────────────────────────────────────────┘│ │ -08 (C): │ │└ Pane #3 ─────────────────────────────────────┘│ │ -09 (C): └──────────────┘└ Pane #4 ─────────────────────────────────────┘└──────────────┘ +07 (C): │ ││ ││ │ +08 (C): │ ││ ││ │ +09 (C): └──────────────┘└──────────────────────────────────────────────┘└──────────────┘