summaryrefslogtreecommitdiffstats
path: root/zellij-server/src/panes/tiled_panes/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'zellij-server/src/panes/tiled_panes/mod.rs')
-rw-r--r--zellij-server/src/panes/tiled_panes/mod.rs364
1 files changed, 325 insertions, 39 deletions
diff --git a/zellij-server/src/panes/tiled_panes/mod.rs b/zellij-server/src/panes/tiled_panes/mod.rs
index cad53e3f1..bd6470c90 100644
--- a/zellij-server/src/panes/tiled_panes/mod.rs
+++ b/zellij-server/src/panes/tiled_panes/mod.rs
@@ -1,4 +1,5 @@
mod pane_resizer;
+mod stacked_panes;
mod tiled_pane_grid;
use crate::resize_pty;
@@ -15,6 +16,7 @@ use crate::{
ui::pane_contents_and_ui::PaneContentsAndUi,
ClientId,
};
+use stacked_panes::StackedPanes;
use zellij_utils::{
data::{ModeInfo, ResizeStrategy, Style},
errors::prelude::*,
@@ -249,6 +251,10 @@ impl TiledPanes {
self.set_pane_frames(self.draw_pane_frames);
}
+ pub fn reapply_pane_frames(&mut self) {
+ // same as set_pane_frames except it reapplies the current situation
+ self.set_pane_frames(self.draw_pane_frames);
+ }
pub fn set_pane_frames(&mut self, draw_pane_frames: bool) {
self.draw_pane_frames = draw_pane_frames;
let viewport = *self.viewport.borrow();
@@ -276,7 +282,12 @@ impl TiledPanes {
let position_and_size = pane.current_geom();
let (pane_columns_offset, pane_rows_offset) =
pane_content_offset(&position_and_size, &viewport);
- pane.set_content_offset(Offset::shift(pane_rows_offset, pane_columns_offset));
+ if !draw_pane_frames && pane.current_geom().is_stacked {
+ // stacked panes should always leave 1 top row for a title
+ pane.set_content_offset(Offset::shift_right_and_top(pane_columns_offset, 1));
+ } else {
+ pane.set_content_offset(Offset::shift(pane_rows_offset, pane_columns_offset));
+ }
}
resize_pty!(pane, self.os_api, self.senders).unwrap();
@@ -287,7 +298,9 @@ impl TiledPanes {
if let Some(active_pane_id) = &self.active_panes.get(&client_id) {
if let Some(active_pane) = self.panes.get_mut(active_pane_id) {
let full_pane_size = active_pane.position_and_size();
- if full_pane_size.rows.as_usize() < MIN_TERMINAL_HEIGHT * 2 {
+ if full_pane_size.rows.as_usize() < MIN_TERMINAL_HEIGHT * 2
+ || full_pane_size.is_stacked
+ {
return false;
} else {
return split(SplitDirection::Horizontal, &full_pane_size).is_some();
@@ -300,7 +313,9 @@ impl TiledPanes {
if let Some(active_pane_id) = &self.active_panes.get(&client_id) {
if let Some(active_pane) = self.panes.get_mut(active_pane_id) {
let full_pane_size = active_pane.position_and_size();
- if full_pane_size.cols.as_usize() < MIN_TERMINAL_WIDTH * 2 {
+ if full_pane_size.cols.as_usize() < MIN_TERMINAL_WIDTH * 2
+ || full_pane_size.is_stacked
+ {
return false;
}
return split(SplitDirection::Vertical, &full_pane_size).is_some();
@@ -312,7 +327,7 @@ impl TiledPanes {
let active_pane_id = &self.active_panes.get(&client_id).unwrap();
let active_pane = self.panes.get(active_pane_id).unwrap();
let full_pane_size = active_pane.position_and_size();
- if full_pane_size.rows.is_fixed() {
+ if full_pane_size.rows.is_fixed() || full_pane_size.is_stacked {
return false;
}
if split(SplitDirection::Horizontal, &full_pane_size).is_some() {
@@ -343,7 +358,7 @@ impl TiledPanes {
let active_pane_id = &self.active_panes.get(&client_id).unwrap();
let active_pane = self.panes.get(active_pane_id).unwrap();
let full_pane_size = active_pane.position_and_size();
- if full_pane_size.cols.is_fixed() {
+ if full_pane_size.cols.is_fixed() || full_pane_size.is_stacked {
return false;
}
if split(SplitDirection::Vertical, &full_pane_size).is_some() {
@@ -370,7 +385,83 @@ impl TiledPanes {
self.relayout(SplitDirection::Horizontal);
}
}
+ pub fn focus_pane_for_all_clients(&mut self, pane_id: PaneId) {
+ let connected_clients: Vec<ClientId> =
+ self.connected_clients.borrow().iter().copied().collect();
+ for client_id in connected_clients {
+ if self
+ .panes
+ .get(&pane_id)
+ .map(|p| p.current_geom().is_stacked)
+ .unwrap_or(false)
+ {
+ let _ = StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide)
+ .focus_pane(&pane_id);
+ }
+ self.active_panes
+ .insert(client_id, pane_id, &mut self.panes);
+ self.set_pane_active_at(pane_id);
+ }
+ self.set_force_render();
+ self.reapply_pane_frames();
+ }
+ pub fn reapply_pane_focus(&mut self) {
+ let connected_clients: Vec<ClientId> =
+ self.connected_clients.borrow().iter().copied().collect();
+ for client_id in connected_clients {
+ match &self.active_panes.get(&client_id).copied() {
+ Some(pane_id) => {
+ if self
+ .panes
+ .get(&pane_id)
+ .map(|p| p.current_geom().is_stacked)
+ .unwrap_or(false)
+ {
+ let _ =
+ StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide)
+ .focus_pane(&pane_id);
+ }
+ self.active_panes
+ .insert(client_id, *pane_id, &mut self.panes);
+ self.set_pane_active_at(*pane_id);
+ },
+ None => {
+ if let Some(first_pane_id) = self.first_selectable_pane_id() {
+ let pane_id = first_pane_id; // TODO: combine with above
+ if self
+ .panes
+ .get(&pane_id)
+ .map(|p| p.current_geom().is_stacked)
+ .unwrap_or(false)
+ {
+ let _ = StackedPanes::new_from_btreemap(
+ &mut self.panes,
+ &self.panes_to_hide,
+ )
+ .focus_pane(&pane_id);
+ }
+ self.active_panes
+ .insert(client_id, pane_id, &mut self.panes);
+ self.set_pane_active_at(pane_id);
+ }
+ },
+ }
+ }
+ self.set_force_render();
+ self.reapply_pane_frames();
+ }
pub fn focus_pane(&mut self, pane_id: PaneId, client_id: ClientId) {
+ if self
+ .panes
+ .get(&pane_id)
+ .map(|p| p.current_geom().is_stacked)
+ .unwrap_or(false)
+ {
+ let _ = StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide)
+ .focus_pane(&pane_id);
+ self.reapply_pane_frames();
+ }
+
self.active_panes
.insert(client_id, pane_id, &mut self.panes);
if self.session_is_mirrored {
@@ -384,6 +475,34 @@ impl TiledPanes {
}
self.reset_boundaries();
}
+ pub fn focus_pane_at_position(&mut self, position_and_size: PaneGeom, client_id: ClientId) {
+ if let Some(pane_id) = self
+ .panes
+ .iter()
+ .find(|(_pid, pane)| pane.position_and_size() == position_and_size)
+ .map(|(pid, _p)| *pid)
+ {
+ if let Some(currently_active_pane_id) = self.active_panes.get(&client_id) {
+ let prev_geom = {
+ if let Some(currently_focused_pane) =
+ self.panes.get_mut(currently_active_pane_id)
+ {
+ let prev_geom = currently_focused_pane.position_and_size();
+ currently_focused_pane.set_geom(position_and_size);
+ Some(prev_geom)
+ } else {
+ None
+ }
+ };
+ if let Some(prev_geom) = prev_geom {
+ if let Some(previous_pane) = self.panes.get_mut(&pane_id) {
+ previous_pane.set_geom(prev_geom);
+ self.reset_boundaries();
+ }
+ }
+ }
+ }
+ }
pub fn focus_pane_if_client_not_focused(&mut self, pane_id: PaneId, client_id: ClientId) {
if self.active_panes.get(&client_id).is_none() {
self.focus_pane(pane_id, client_id)
@@ -448,8 +567,20 @@ impl TiledPanes {
.map(|(client_id, pane_id)| (*client_id, *pane_id))
.collect()
};
+ let (stacked_pane_ids_under_flexible_pane, stacked_pane_ids_over_flexible_pane) = {
+ // TODO: do not recalculate this every time on render
+ StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide)
+ .stacked_pane_ids_under_and_over_flexible_panes()
+ .unwrap() // TODO: no unwrap
+ };
for (kind, pane) in self.panes.iter_mut() {
if !self.panes_to_hide.contains(&pane.pid()) {
+ let pane_is_stacked_under =
+ stacked_pane_ids_under_flexible_pane.contains(&pane.pid());
+ let pane_is_stacked_over =
+ stacked_pane_ids_over_flexible_pane.contains(&pane.pid());
+ let should_draw_pane_frames = self.draw_pane_frames;
+ let pane_is_stacked = pane.current_geom().is_stacked;
let mut pane_contents_and_ui = PaneContentsAndUi::new(
pane,
output,
@@ -457,6 +588,9 @@ impl TiledPanes {
&active_panes,
multiple_users_exist_in_session,
None,
+ pane_is_stacked_under,
+ pane_is_stacked_over,
+ should_draw_pane_frames,
);
for client_id in &connected_clients {
let client_mode = self
@@ -476,6 +610,22 @@ impl TiledPanes {
pane_contents_and_ui
.render_pane_frame(*client_id, client_mode, self.session_is_mirrored)
.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)
+ .with_context(err_context)?;
+ // we also need to render its boundaries as normal
+ let boundaries = client_id_to_boundaries
+ .entry(*client_id)
+ .or_insert_with(|| Boundaries::new(*self.viewport.borrow()));
+ pane_contents_and_ui.render_pane_boundaries(
+ *client_id,
+ client_mode,
+ boundaries,
+ self.session_is_mirrored,
+ );
} else {
let boundaries = client_id_to_boundaries
.entry(*client_id)
@@ -542,6 +692,8 @@ impl TiledPanes {
Err(e) => match e.downcast_ref::<ZellijError>() {
Some(ZellijError::PaneSizeUnchanged) => {}, // ignore unchanged layout
_ => {
+ // display area still changed, even if we had an error
+ display_area.cols = cols;
Err::<(), _>(anyError::msg(e))
.context("failed to resize tab horizontally")
.non_fatal();
@@ -557,6 +709,8 @@ impl TiledPanes {
Err(e) => match e.downcast_ref::<ZellijError>() {
Some(ZellijError::PaneSizeUnchanged) => {}, // ignore unchanged layout
_ => {
+ // display area still changed, even if we had an error
+ display_area.rows = rows;
Err::<(), _>(anyError::msg(e))
.context("failed to resize tab vertically")
.non_fatal();
@@ -629,13 +783,26 @@ impl TiledPanes {
let connected_clients: Vec<ClientId> =
{ self.connected_clients.borrow().iter().copied().collect() };
let active_pane_id = self.get_active_pane_id(client_id).unwrap();
- let pane_grid = TiledPaneGrid::new(
- &mut self.panes,
- &self.panes_to_hide,
- *self.display_area.borrow(),
- *self.viewport.borrow(),
- );
- let next_active_pane_id = pane_grid.next_selectable_pane_id(&active_pane_id);
+ let next_active_pane_id = {
+ let pane_grid = TiledPaneGrid::new(
+ &mut self.panes,
+ &self.panes_to_hide,
+ *self.display_area.borrow(),
+ *self.viewport.borrow(),
+ );
+ pane_grid.next_selectable_pane_id(&active_pane_id)
+ };
+ if self
+ .panes
+ .get(&next_active_pane_id)
+ .map(|p| p.current_geom().is_stacked)
+ .unwrap_or(false)
+ {
+ let _ = StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide)
+ .focus_pane(&next_active_pane_id);
+ self.reapply_pane_frames();
+ }
+
for client_id in connected_clients {
self.active_panes
.insert(client_id, next_active_pane_id, &mut self.panes);
@@ -647,13 +814,26 @@ impl TiledPanes {
let connected_clients: Vec<ClientId> =
{ self.connected_clients.borrow().iter().copied().collect() };
let active_pane_id = self.get_active_pane_id(client_id).unwrap();
- let pane_grid = TiledPaneGrid::new(
- &mut self.panes,
- &self.panes_to_hide,
- *self.display_area.borrow(),
- *self.viewport.borrow(),
- );
- let next_active_pane_id = pane_grid.previous_selectable_pane_id(&active_pane_id);
+ let next_active_pane_id = {
+ let pane_grid = TiledPaneGrid::new(
+ &mut self.panes,
+ &self.panes_to_hide,
+ *self.display_area.borrow(),
+ *self.viewport.borrow(),
+ );
+ pane_grid.previous_selectable_pane_id(&active_pane_id)
+ };
+
+ if self
+ .panes
+ .get(&next_active_pane_id)
+ .map(|p| p.current_geom().is_stacked)
+ .unwrap_or(false)
+ {
+ let _ = StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide)
+ .focus_pane(&next_active_pane_id);
+ self.reapply_pane_frames();
+ }
for client_id in connected_clients {
self.active_panes
.insert(client_id, next_active_pane_id, &mut self.panes);
@@ -716,13 +896,15 @@ impl TiledPanes {
pub fn move_focus_down(&mut self, client_id: ClientId) -> bool {
match self.get_active_pane_id(client_id) {
Some(active_pane_id) => {
- let pane_grid = TiledPaneGrid::new(
+ let mut pane_grid = TiledPaneGrid::new(
&mut self.panes,
&self.panes_to_hide,
*self.display_area.borrow(),
*self.viewport.borrow(),
);
- let next_index = pane_grid.next_selectable_pane_id_below(&active_pane_id);
+ let next_index = pane_grid
+ .next_selectable_pane_id_below(&active_pane_id)
+ .or_else(|| pane_grid.progress_stack_down_if_in_stack(&active_pane_id));
match next_index {
Some(p) => {
// render previously active pane so that its frame does not remain actively
@@ -732,12 +914,16 @@ impl TiledPanes {
.get_mut(self.active_panes.get(&client_id).unwrap())
.unwrap();
+ let previously_active_pane_is_stacked =
+ previously_active_pane.current_geom().is_stacked;
previously_active_pane.set_should_render(true);
// we render the full viewport to remove any ui elements that might have been
// there before (eg. another user's cursor)
previously_active_pane.render_full_viewport();
let next_active_pane = self.panes.get_mut(&p).unwrap();
+ let next_active_pane_is_stacked =
+ next_active_pane.current_geom().is_stacked;
next_active_pane.set_should_render(true);
// we render the full viewport to remove any ui elements that might have been
// there before (eg. another user's cursor)
@@ -745,6 +931,13 @@ impl TiledPanes {
self.focus_pane(p, client_id);
self.set_pane_active_at(p);
+ if previously_active_pane_is_stacked || next_active_pane_is_stacked {
+ // we do this because a stack pane focus change also changes its
+ // geometry and we need to let the pty know about this (like in a
+ // normal size change)
+ self.focus_pane_for_all_clients(p); // TODO: for all client *in stack*
+ self.reapply_pane_frames();
+ }
true
},
@@ -757,13 +950,15 @@ impl TiledPanes {
pub fn move_focus_up(&mut self, client_id: ClientId) -> bool {
match self.get_active_pane_id(client_id) {
Some(active_pane_id) => {
- let pane_grid = TiledPaneGrid::new(
+ let mut pane_grid = TiledPaneGrid::new(
&mut self.panes,
&self.panes_to_hide,
*self.display_area.borrow(),
*self.viewport.borrow(),
);
- let next_index = pane_grid.next_selectable_pane_id_above(&active_pane_id);
+ let next_index = pane_grid
+ .next_selectable_pane_id_above(&active_pane_id)
+ .or_else(|| pane_grid.progress_stack_up_if_in_stack(&active_pane_id));
match next_index {
Some(p) => {
// render previously active pane so that its frame does not remain actively
@@ -773,12 +968,16 @@ impl TiledPanes {
.get_mut(self.active_panes.get(&client_id).unwrap())
.unwrap();
+ let previously_active_pane_is_stacked =
+ previously_active_pane.current_geom().is_stacked;
previously_active_pane.set_should_render(true);
// we render the full viewport to remove any ui elements that might have been
// there before (eg. another user's cursor)
previously_active_pane.render_full_viewport();
let next_active_pane = self.panes.get_mut(&p).unwrap();
+ let next_active_pane_is_stacked =
+ next_active_pane.current_geom().is_stacked;
next_active_pane.set_should_render(true);
// we render the full viewport to remove any ui elements that might have been
// there before (eg. another user's cursor)
@@ -786,6 +985,13 @@ impl TiledPanes {
self.focus_pane(p, client_id);
self.set_pane_active_at(p);
+ if previously_active_pane_is_stacked || next_active_pane_is_stacked {
+ // we do this because a stack pane focus change also changes its
+ // geometry and we need to let the pty know about this (like in a
+ // normal size change)
+ self.focus_pane_for_all_clients(p); // TODO: for all client *in stack*
+ self.reapply_pane_frames();
+ }
true
},
@@ -836,15 +1042,66 @@ impl TiledPanes {
None => false,
}
}
- pub fn move_active_pane(&mut self, client_id: ClientId) {
+ pub fn switch_active_pane_with(&mut self, pane_id: PaneId) {
+ if let Some(active_pane_id) = self.first_active_pane_id() {
+ if let PaneId::Plugin(_) = active_pane_id {
+ // we do not implicitly change the location of plugin panes
+ // TODO: we might want to make this configurable through a layout property or a
+ // plugin API
+ return;
+ }
+ let current_position = self.panes.get(&active_pane_id).unwrap();
+ let prev_geom = current_position.position_and_size();
+ let prev_geom_override = current_position.geom_override();
+
+ let new_position = self.panes.get_mut(&pane_id).unwrap();
+ let next_geom = new_position.position_and_size();
+ let next_geom_override = new_position.geom_override();
+ new_position.set_geom(prev_geom);
+ if let Some(geom) = prev_geom_override {
+ new_position.set_geom_override(geom);
+ }
+ resize_pty!(new_position, self.os_api, self.senders).unwrap();
+ new_position.set_should_render(true);
+
+ let current_position = self.panes.get_mut(&active_pane_id).unwrap();
+ current_position.set_geom(next_geom);
+ if let Some(geom) = next_geom_override {
+ current_position.set_geom_override(geom);
+ }
+ resize_pty!(current_position, self.os_api, self.senders).unwrap();
+ current_position.set_should_render(true);
+ self.focus_pane_for_all_clients(active_pane_id);
+ self.set_pane_frames(self.draw_pane_frames);
+ }
+ }
+ pub fn move_active_pane(&mut self, search_backwards: bool, client_id: ClientId) {
let active_pane_id = self.get_active_pane_id(client_id).unwrap();
- let pane_grid = TiledPaneGrid::new(
- &mut self.panes,
- &self.panes_to_hide,
- *self.display_area.borrow(),
- *self.viewport.borrow(),
- );
- let new_position_id = pane_grid.next_selectable_pane_id(&active_pane_id);
+
+ let new_position_id = {
+ let pane_grid = TiledPaneGrid::new(
+ &mut self.panes,
+ &self.panes_to_hide,
+ *self.display_area.borrow(),
+ *self.viewport.borrow(),
+ );
+ if search_backwards {
+ pane_grid.previous_selectable_pane_id(&active_pane_id)
+ } else {
+ pane_grid.next_selectable_pane_id(&active_pane_id)
+ }
+ };
+ if self
+ .panes
+ .get(&new_position_id)
+ .map(|p| p.current_geom().is_stacked)
+ .unwrap_or(false)
+ {
+ let _ = StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide)
+ .focus_pane(&new_position_id);
+ self.reapply_pane_frames();
+ }
+
let current_position = self.panes.get(&active_pane_id).unwrap();
let prev_geom = current_position.position_and_size();
let prev_geom_override = current_position.geom_override();
@@ -870,13 +1127,15 @@ impl TiledPanes {
}
pub fn move_active_pane_down(&mut self, client_id: ClientId) {
if let Some(active_pane_id) = self.get_active_pane_id(client_id) {
- let pane_grid = TiledPaneGrid::new(
+ let mut pane_grid = TiledPaneGrid::new(
&mut self.panes,
&self.panes_to_hide,
*self.display_area.borrow(),
*self.viewport.borrow(),
);
- let next_index = pane_grid.next_selectable_pane_id_below(&active_pane_id);
+ let next_index = pane_grid
+ .next_selectable_pane_id_below(&active_pane_id)
+ .or_else(|| pane_grid.progress_stack_down_if_in_stack(&active_pane_id));
if let Some(p) = next_index {
let active_pane_id = self.active_panes.get(&client_id).unwrap();
let current_position = self.panes.get(active_pane_id).unwrap();
@@ -978,13 +1237,15 @@ impl TiledPanes {
}
pub fn move_active_pane_up(&mut self, client_id: ClientId) {
if let Some(active_pane_id) = self.get_active_pane_id(client_id) {
- let pane_grid = TiledPaneGrid::new(
+ let mut pane_grid = TiledPaneGrid::new(
&mut self.panes,
&self.panes_to_hide,
*self.display_area.borrow(),
*self.viewport.borrow(),
);
- let next_index = pane_grid.next_selectable_pane_id_above(&active_pane_id);
+ let next_index = pane_grid
+ .next_selectable_pane_id_above(&active_pane_id)
+ .or_else(|| pane_grid.progress_stack_up_if_in_stack(&active_pane_id));
if let Some(p) = next_index {
let active_pane_id = self.active_panes.get(&client_id).unwrap();
let current_position = self.panes.get(active_pane_id).unwrap();
@@ -1033,11 +1294,21 @@ impl TiledPanes {
.map(|(pane_id, _pane)| **pane_id);
match next_active_pane_id {
- Some(next_active_pane) => {
+ Some(next_active_pane_id) => {
+ if self
+ .panes
+ .get(&next_active_pane_id)
+ .map(|p| p.current_geom().is_stacked)
+ .unwrap_or(false)
+ {
+ let _ = StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide)
+ .focus_pane(&next_active_pane_id);
+ self.reapply_pane_frames();
+ }
for (client_id, active_pane_id) in active_panes {
if active_pane_id == pane_id {
self.active_panes
- .insert(client_id, next_active_pane, &mut self.panes);
+ .insert(client_id, next_active_pane_id, &mut self.panes);
}
}
},
@@ -1160,13 +1431,13 @@ impl TiledPanes {
viewport_pane.set_geom_override(viewport_pane.position_and_size());
}
let viewport = { *self.viewport.borrow() };
- let active_terminal = self.get_pane_mut(active_pane_id).unwrap();
+ let active_pane = self.get_pane_mut(active_pane_id).unwrap();
let full_screen_geom = PaneGeom {
x: viewport.x,
y: viewport.y,
..Default::default()
};
- active_terminal.set_geom_override(full_screen_geom);
+ active_pane.set_geom_override(full_screen_geom);
}
let connected_client_list: Vec<ClientId> =
{ self.connected_clients.borrow().iter().copied().collect() };
@@ -1196,6 +1467,9 @@ impl TiledPanes {
pub fn panes_to_hide_count(&self) -> usize {
self.panes_to_hide.len()
}
+ pub fn visible_panes_count(&self) -> usize {
+ self.panes.len().saturating_sub(self.panes_to_hide.len())
+ }
pub fn add_to_hidden_panels(&mut self, pid: PaneId) {
self.panes_to_hide.insert(pid);
}
@@ -1208,6 +1482,18 @@ impl TiledPanes {
pub fn focus_all_panes(&mut self) {
self.active_panes.focus_all_panes(&mut self.panes);
}
+ pub fn drain(&mut self) -> BTreeMap<PaneId, Box<dyn Pane>> {
+ match self.panes.iter().next().map(|(pid, _p)| *pid) {
+ Some(first_pid) => self.panes.split_off(&first_pid),
+ None => BTreeMap::new(),
+ }
+ }
+ pub fn active_panes(&self) -> ActivePanes {
+ self.active_panes.clone()
+ }
+ pub fn set_active_panes(&mut self, active_panes: ActivePanes) {
+ self.active_panes = active_panes;
+ }
fn move_clients_between_panes(&mut self, from_pane_id: PaneId, to_pane_id: PaneId) {
let clients_in_pane: Vec<ClientId> = self
.active_panes