Skip to content

Commit

Permalink
fix(borders): properly handle in-viewport borderless panes (#697)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
imsnif committed Sep 6, 2021
1 parent 86fdd24 commit 203a42c
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 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 various borderless-frame in viewport bugs (https://github.com/zellij-org/zellij/pull/697)

## [0.16.0] - 2021-08-31
* Plugins don't crash zellij anymore on receiving mouse events (https://github.com/zellij-org/zellij/pull/620)
Expand Down
4 changes: 3 additions & 1 deletion zellij-server/src/panes/terminal_pane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,9 @@ impl Pane for TerminalPane {
color: self.frame_color,
};
if &frame != last_frame {
vte_output.push_str(&frame.render());
if !self.borderless {
vte_output.push_str(&frame.render());
}
self.frame = Some(frame);
}
}
Expand Down
42 changes: 31 additions & 11 deletions zellij-server/src/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -684,22 +684,35 @@ impl Tab {
}
pub fn set_pane_frames(&mut self, draw_pane_frames: bool) {
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() {
pane.set_frame(draw_pane_frames);
if draw_pane_frames {
if !pane.borderless() {
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));
} 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 {
// 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 (pane_columns_offset, pane_rows_offset) =
pane_content_offset(&position_and_size, &self.viewport);
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
// `TerminalPane::reflow_lines`
if let PaneId::Terminal(pid) = pane_id {
Expand Down Expand Up @@ -2345,10 +2358,9 @@ impl Tab {
.unwrap();
}
fn is_inside_viewport(&self, pane_id: &PaneId) -> bool {
let pane_position_and_size = self.panes.get(pane_id).unwrap().current_geom();
pane_position_and_size.y >= self.viewport.y
&& pane_position_and_size.y + pane_position_and_size.rows.as_usize()
<= self.viewport.y + self.viewport.rows
// this is mostly separated to an outside function in order to allow us to pass a clone to
// it sometimes when we need to get around the borrow checker
is_inside_viewport(&self.viewport, self.panes.get(pane_id).unwrap())
}
fn offset_viewport(&mut self, position_and_size: &Viewport) {
if position_and_size.x == self.viewport.x
Expand Down Expand Up @@ -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)]
#[path = "./unit/tab_tests.rs"]
mod tab_tests;

0 comments on commit 203a42c

Please sign in to comment.