From 685e39bd9bd9c589ff779d71ea24f30ed7257f93 Mon Sep 17 00:00:00 2001 From: har7an <99636919+har7an@users.noreply.github.com> Date: Tue, 13 Dec 2022 09:49:41 +0000 Subject: [PATCH] Hotfix: Resize with plugin panes (#2019) * server/panes/tiled/grid: Fix area calculation for debug assertions. Now also considers fixed-size panes correctly. * server/panes/tiled/grid: Refactor function to make it more readable and remove some implicitly handled "special" cases. * server/panes/tiled/grid: Handle plugins panes like any other pane type and only check whether they are fixed-size panes, too. * changelog: Add PR #2019 --- CHANGELOG.md | 2 + .../src/panes/tiled_panes/tiled_pane_grid.rs | 62 +++++++------------ 2 files changed, 26 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81d1d88bb..ac73d1794 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## [Unreleased] +* hotfix: fix panics when resizing with flexible plugin panes in layout (https://github.com/zellij-org/zellij/pull/2019) + ## [0.34.3] - 2022-12-09 * (BREAKING CHANGE) performance: change plugin data flow to improve render speed (https://github.com/zellij-org/zellij/pull/1934) diff --git a/zellij-server/src/panes/tiled_panes/tiled_pane_grid.rs b/zellij-server/src/panes/tiled_panes/tiled_pane_grid.rs index fc53defc1..fdb2f74ad 100644 --- a/zellij-server/src/panes/tiled_panes/tiled_pane_grid.rs +++ b/zellij-server/src/panes/tiled_panes/tiled_pane_grid.rs @@ -4,7 +4,7 @@ use crate::tab::{MIN_TERMINAL_HEIGHT, MIN_TERMINAL_WIDTH}; use crate::{panes::PaneId, tab::Pane}; use std::cmp::Reverse; use std::collections::{HashMap, HashSet}; -use zellij_utils::data::{Direction, ResizeStrategy}; +use zellij_utils::data::{Direction, Resize, ResizeStrategy}; use zellij_utils::{ errors::prelude::*, input::layout::SplitDirection, @@ -57,15 +57,11 @@ impl<'a> TiledPaneGrid<'a> { let mut summed_area: f64 = 0.0; for pane in self.panes.clone().borrow().values() { - if let PaneId::Terminal(_id) = pane.pid() { - let geom = pane.current_geom(); - summed_area += match (geom.rows.as_percent(), geom.cols.as_percent()) { - (Some(rows), Some(cols)) => rows * cols, - _ => continue, - }; - } else { - continue; - } + let geom = pane.current_geom(); + summed_area += match (geom.rows.as_percent(), geom.cols.as_percent()) { + (Some(rows), Some(cols)) => rows * cols, + _ => continue, + }; } summed_area / (100.0 * 100.0) @@ -103,23 +99,19 @@ impl<'a> TiledPaneGrid<'a> { ) -> Result { let err_context = || format!("failed to determine if pane {pane_id:?} can {strategy}"); - let pane_ids = if let Some(direction) = strategy.direction { - let mut vec = self + if let Some(direction) = strategy.direction { + let mut pane_ids = self .pane_ids_directly_next_to(pane_id, &direction) .with_context(err_context)?; - vec.retain(|id| self.pane_is_flexible(direction.into(), id).unwrap_or(false)); - vec - } else { - return Ok(true); - }; + pane_ids.retain(|id| self.pane_is_flexible(direction.into(), id).unwrap_or(false)); - use zellij_utils::data::Resize::Decrease as Dec; - use zellij_utils::data::Resize::Increase as Inc; + if pane_ids.is_empty() { + return Ok(false); + } - if !pane_ids.is_empty() { - if strategy.direction_horizontal() { + if direction.is_horizontal() { match strategy.resize { - Inc => { + Resize::Increase => { for id in pane_ids { if !self .can_reduce_pane_width(&id, change_by.0 as f64) @@ -130,13 +122,13 @@ impl<'a> TiledPaneGrid<'a> { } Ok(true) }, - Dec => self + Resize::Decrease => self .can_reduce_pane_width(pane_id, change_by.0 as f64) .with_context(err_context), } - } else if strategy.direction_vertical() { + } else { match strategy.resize { - Inc => { + Resize::Increase => { for id in pane_ids { if !self .can_reduce_pane_height(&id, change_by.1 as f64) @@ -147,15 +139,14 @@ impl<'a> TiledPaneGrid<'a> { } Ok(true) }, - Dec => self + Resize::Decrease => self .can_reduce_pane_height(pane_id, change_by.1 as f64) .with_context(err_context), } - } else { - unimplemented!(); } } else { - Ok(false) + // Undirected resize, this is checked elsewhere + Ok(true) } } @@ -181,10 +172,10 @@ impl<'a> TiledPaneGrid<'a> { .direction .and_then(|direction| { // Only invert if there are no neighbor IDs in the given direction - self.pane_ids_directly_next_to(pane_id, &direction) - .unwrap_or_default() - .is_empty() - .then_some(true) + let mut neighbors = self.pane_ids_directly_next_to(pane_id, &direction) + .unwrap_or_default(); + neighbors.retain(|pane_id| self.pane_is_flexible(direction.into(), pane_id).unwrap_or(false)); + neighbors.is_empty().then_some(true) }) .unwrap_or(false) { @@ -518,11 +509,6 @@ impl<'a> TiledPaneGrid<'a> { .with_context(err_context)?; for (&pid, terminal) in panes.iter() { - // We cannot resize plugin panes, so we do not even bother trying. - if let PaneId::Plugin(_) = pid { - continue; - } - if match direction { Direction::Left => (terminal.x() + terminal.cols()) == terminal_to_check.x(), Direction::Down => {