fix(borders): properly handle in-viewport borderless panes (#697)

* fix(borders): properly handle in-viewport borderless panes

* style(fmt): make clippy happy

* fix(borders): properly handle panes outside the viewport on startup

* style(fmt): not this time, clippy

* docs(changelog): document change
This commit is contained in:
Aram Drevekenin 2021-09-06 20:26:30 +02:00 committed by GitHub
parent 86fdd2400e
commit 203a42c616
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 12 deletions

View file

@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
* Fix bug when in some cases closing a tab would not clear the previous pane's contents (https://github.com/zellij-org/zellij/pull/684) * Fix bug when in some cases closing a tab would not clear the previous pane's contents (https://github.com/zellij-org/zellij/pull/684)
* Fix bug where tabs would sometimes be created with the wrong index in their name (https://github.com/zellij-org/zellij/pull/686) * Fix bug where tabs would sometimes be created with the wrong index in their name (https://github.com/zellij-org/zellij/pull/686)
* Fix bug where wide chars would mess up pane titles (https://github.com/zellij-org/zellij/pull/698) * Fix bug where wide chars would mess up pane titles (https://github.com/zellij-org/zellij/pull/698)
* Fix various borderless-frame in viewport bugs (https://github.com/zellij-org/zellij/pull/697)
## [0.16.0] - 2021-08-31 ## [0.16.0] - 2021-08-31
* Plugins don't crash zellij anymore on receiving mouse events (https://github.com/zellij-org/zellij/pull/620) * Plugins don't crash zellij anymore on receiving mouse events (https://github.com/zellij-org/zellij/pull/620)

View file

@ -253,7 +253,9 @@ impl Pane for TerminalPane {
color: self.frame_color, color: self.frame_color,
}; };
if &frame != last_frame { if &frame != last_frame {
vte_output.push_str(&frame.render()); if !self.borderless {
vte_output.push_str(&frame.render());
}
self.frame = Some(frame); self.frame = Some(frame);
} }
} }

View file

@ -684,22 +684,35 @@ impl Tab {
} }
pub fn set_pane_frames(&mut self, draw_pane_frames: bool) { pub fn set_pane_frames(&mut self, draw_pane_frames: bool) {
self.draw_pane_frames = draw_pane_frames; self.draw_pane_frames = draw_pane_frames;
self.should_clear_display_before_rendering = true;
let viewport = self.viewport;
for (pane_id, pane) in self.panes.iter_mut() { for (pane_id, pane) in self.panes.iter_mut() {
pane.set_frame(draw_pane_frames); if !pane.borderless() {
if draw_pane_frames { pane.set_frame(draw_pane_frames);
}
#[allow(clippy::if_same_then_else)]
if draw_pane_frames & !pane.borderless() {
// there's definitely a frame around this pane, offset its contents
pane.set_content_offset(Offset::frame(1)); pane.set_content_offset(Offset::frame(1));
} else if draw_pane_frames && pane.borderless() {
// there's no frame around this pane, and the tab isn't handling the boundaries
// between panes (they each draw their own frames as they please)
// this one doesn't - do not offset its content
pane.set_content_offset(Offset::default());
} else if !is_inside_viewport(&viewport, pane) {
// this pane is outside the viewport and has no border - it should not have an offset
pane.set_content_offset(Offset::default());
} else { } else {
// no draw_pane_frames and this pane should have a separation to other panes
// according to its position in the viewport (eg. no separation if its at the
// viewport bottom) - offset its content accordingly
let position_and_size = pane.current_geom(); let position_and_size = pane.current_geom();
let (pane_columns_offset, pane_rows_offset) = let (pane_columns_offset, pane_rows_offset) =
pane_content_offset(&position_and_size, &self.viewport); pane_content_offset(&position_and_size, &self.viewport);
pane.set_content_offset(Offset::shift(pane_rows_offset, pane_columns_offset)); pane.set_content_offset(Offset::shift(pane_rows_offset, pane_columns_offset));
} }
// FIXME: this should also override the above logic
if pane.borderless() {
pane.set_content_offset(Offset::default());
}
// FIXME: This, and all other `set_terminal_size_using_fd` calls, would be best in // FIXME: This, and all other `set_terminal_size_using_fd` calls, would be best in
// `TerminalPane::reflow_lines` // `TerminalPane::reflow_lines`
if let PaneId::Terminal(pid) = pane_id { if let PaneId::Terminal(pid) = pane_id {
@ -2345,10 +2358,9 @@ impl Tab {
.unwrap(); .unwrap();
} }
fn is_inside_viewport(&self, pane_id: &PaneId) -> bool { fn is_inside_viewport(&self, pane_id: &PaneId) -> bool {
let pane_position_and_size = self.panes.get(pane_id).unwrap().current_geom(); // this is mostly separated to an outside function in order to allow us to pass a clone to
pane_position_and_size.y >= self.viewport.y // it sometimes when we need to get around the borrow checker
&& pane_position_and_size.y + pane_position_and_size.rows.as_usize() is_inside_viewport(&self.viewport, self.panes.get(pane_id).unwrap())
<= self.viewport.y + self.viewport.rows
} }
fn offset_viewport(&mut self, position_and_size: &Viewport) { fn offset_viewport(&mut self, position_and_size: &Viewport) {
if position_and_size.x == self.viewport.x if position_and_size.x == self.viewport.x
@ -2378,6 +2390,14 @@ impl Tab {
} }
} }
#[allow(clippy::borrowed_box)]
fn is_inside_viewport(viewport: &Viewport, pane: &Box<dyn Pane>) -> bool {
let pane_position_and_size = pane.current_geom();
pane_position_and_size.y >= viewport.y
&& pane_position_and_size.y + pane_position_and_size.rows.as_usize()
<= viewport.y + viewport.rows
}
#[cfg(test)] #[cfg(test)]
#[path = "./unit/tab_tests.rs"] #[path = "./unit/tab_tests.rs"]
mod tab_tests; mod tab_tests;