summaryrefslogtreecommitdiffstats
path: root/zellij-server/src/panes
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2022-12-14 22:26:48 +0100
committerGitHub <noreply@github.com>2022-12-14 22:26:48 +0100
commitc3115a428ed5c990cc5ead5629dabb624ae90453 (patch)
treefe1a3c0f344b6d1056789861d6d28ca5196f838d /zellij-server/src/panes
parent177cd20beaf7a89d54b295f1aab498b7ab2c04c1 (diff)
fix(panes): show visual error when unable to split panes vertically/horizontally (#2025)
* fix(panes): show visual error when failing to split pane vertically/horizontally * fix: lockfile
Diffstat (limited to 'zellij-server/src/panes')
-rw-r--r--zellij-server/src/panes/plugin_pane.rs26
-rw-r--r--zellij-server/src/panes/terminal_pane.rs26
-rw-r--r--zellij-server/src/panes/tiled_panes/mod.rs39
3 files changed, 87 insertions, 4 deletions
diff --git a/zellij-server/src/panes/plugin_pane.rs b/zellij-server/src/panes/plugin_pane.rs
index a530b20b2..3a0ec9c83 100644
--- a/zellij-server/src/panes/plugin_pane.rs
+++ b/zellij-server/src/panes/plugin_pane.rs
@@ -64,6 +64,7 @@ pub(crate) struct PluginPane {
prev_pane_name: String,
frame: HashMap<ClientId, PaneFrame>,
borderless: bool,
+ pane_frame_color_override: Option<(PaletteColor, Option<String>)>,
}
impl PluginPane {
@@ -102,6 +103,7 @@ impl PluginPane {
vte_parsers: HashMap::new(),
grids: HashMap::new(),
style,
+ pane_frame_color_override: None,
}
}
}
@@ -244,7 +246,13 @@ impl Pane for PluginPane {
}
if let Some(grid) = self.grids.get(&client_id) {
let err_context = || format!("failed to render frame for client {client_id}");
- let pane_title = if self.pane_name.is_empty()
+ let pane_title = if let Some(text_color_override) = self
+ .pane_frame_color_override
+ .as_ref()
+ .and_then(|(_color, text)| text.as_ref())
+ {
+ text_color_override.into()
+ } else if self.pane_name.is_empty()
&& input_mode == InputMode::RenamePane
&& frame_params.is_main_client
{
@@ -257,12 +265,15 @@ impl Pane for PluginPane {
self.pane_name.clone()
};
- let frame = PaneFrame::new(
+ let mut frame = PaneFrame::new(
self.current_geom().into(),
grid.scrollback_position_and_length(),
pane_title,
frame_params,
);
+ if let Some((frame_color_override, _text)) = self.pane_frame_color_override.as_ref() {
+ frame.override_color(*frame_color_override);
+ }
let res = match self.frame.get(&client_id) {
// TODO: use and_then or something?
@@ -469,6 +480,17 @@ impl Pane for PluginPane {
)]))
.unwrap();
}
+ fn add_red_pane_frame_color_override(&mut self, error_text: Option<String>) {
+ self.pane_frame_color_override = Some((self.style.colors.red, error_text));
+ }
+ fn clear_pane_frame_color_override(&mut self) {
+ self.pane_frame_color_override = None;
+ }
+ fn frame_color_override(&self) -> Option<PaletteColor> {
+ self.pane_frame_color_override
+ .as_ref()
+ .map(|(color, _text)| *color)
+ }
}
impl PluginPane {
diff --git a/zellij-server/src/panes/terminal_pane.rs b/zellij-server/src/panes/terminal_pane.rs
index b5c51c659..4d5ed840c 100644
--- a/zellij-server/src/panes/terminal_pane.rs
+++ b/zellij-server/src/panes/terminal_pane.rs
@@ -109,7 +109,8 @@ pub struct TerminalPane {
is_held: Option<(Option<i32>, IsFirstRun, RunCommand)>, // a "held" pane means that its command has either exited and the pane is waiting for a
// possible user instruction to be re-run, or that the command has not yet been run
banner: Option<String>, // a banner to be rendered inside this TerminalPane, used for panes
- // held on startup and can possibly be used to display some errors
+ // held on startup and can possibly be used to display some errors
+ pane_frame_color_override: Option<(PaletteColor, Option<String>)>,
}
impl Pane for TerminalPane {
@@ -301,7 +302,13 @@ impl Pane for TerminalPane {
) -> Result<Option<(Vec<CharacterChunk>, Option<String>)>> {
let err_context = || format!("failed to render frame for client {client_id}");
// TODO: remove the cursor stuff from here
- let pane_title = if self.pane_name.is_empty()
+ let pane_title = if let Some(text_color_override) = self
+ .pane_frame_color_override
+ .as_ref()
+ .and_then(|(_color, text)| text.as_ref())
+ {
+ text_color_override.into()
+ } else if self.pane_name.is_empty()
&& input_mode == InputMode::RenamePane
&& frame_params.is_main_client
{
@@ -353,6 +360,9 @@ impl Pane for TerminalPane {
frame.add_exit_status(exit_status.as_ref().copied());
}
}
+ if let Some((frame_color_override, _text)) = self.pane_frame_color_override.as_ref() {
+ frame.override_color(*frame_color_override);
+ }
let res = match self.frame.get(&client_id) {
// TODO: use and_then or something?
@@ -669,6 +679,17 @@ impl Pane for TerminalPane {
}
self.set_should_render(true);
}
+ fn add_red_pane_frame_color_override(&mut self, error_text: Option<String>) {
+ self.pane_frame_color_override = Some((self.style.colors.red, error_text));
+ }
+ fn clear_pane_frame_color_override(&mut self) {
+ self.pane_frame_color_override = None;
+ }
+ fn frame_color_override(&self) -> Option<PaletteColor> {
+ self.pane_frame_color_override
+ .as_ref()
+ .map(|(color, _text)| *color)
+ }
}
impl TerminalPane {
@@ -717,6 +738,7 @@ impl TerminalPane {
search_term: String::new(),
is_held: None,
banner: None,
+ pane_frame_color_override: None,
}
}
pub fn get_x(&self) -> usize {
diff --git a/zellij-server/src/panes/tiled_panes/mod.rs b/zellij-server/src/panes/tiled_panes/mod.rs
index b5caa5916..ee752ea15 100644
--- a/zellij-server/src/panes/tiled_panes/mod.rs
+++ b/zellij-server/src/panes/tiled_panes/mod.rs
@@ -205,6 +205,19 @@ impl TiledPanes {
})
.collect()
}
+ pub fn borderless_pane_geoms(&self) -> Vec<Viewport> {
+ self.panes
+ .values()
+ .filter_map(|p| {
+ let geom = p.position_and_size();
+ if p.borderless() {
+ Some(geom.into())
+ } else {
+ None
+ }
+ })
+ .collect()
+ }
pub fn first_selectable_pane_id(&self) -> Option<PaneId> {
self.panes
.iter()
@@ -295,6 +308,19 @@ impl TiledPanes {
}
false
}
+ pub fn can_split_active_pane_horizontally(&self, client_id: ClientId) -> bool {
+ 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() {
+ return false;
+ }
+ if split(SplitDirection::Horizontal, &full_pane_size).is_some() {
+ true
+ } else {
+ false
+ }
+ }
pub fn split_pane_horizontally(
&mut self,
pid: PaneId,
@@ -313,6 +339,19 @@ impl TiledPanes {
self.relayout(SplitDirection::Vertical);
}
}
+ pub fn can_split_active_pane_vertically(&self, client_id: ClientId) -> bool {
+ 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() {
+ return false;
+ }
+ if split(SplitDirection::Vertical, &full_pane_size).is_some() {
+ true
+ } else {
+ false
+ }
+ }
pub fn split_pane_vertically(
&mut self,
pid: PaneId,