mirror of
https://github.com/zellij-org/zellij.git
synced 2024-11-23 08:57:14 +03:00
Enable should_render
(fix pane render) (#318)
* fix pane render when switch/resize tab * render when reflow_lines * back to always render because widechar issue * fix clippy * force_render when current grid contains widechar * bug fix * pane_contains -> panes_contain * fix conflict * fix(terminal): bring back should_render Co-authored-by: Aram Drevekenin <aram@poor.dev>
This commit is contained in:
parent
b5d38e95c8
commit
454ad0ed19
@ -198,6 +198,9 @@ impl Grid {
|
|||||||
clear_viewport_before_rendering: false,
|
clear_viewport_before_rendering: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn contains_widechar(&self) -> bool {
|
||||||
|
self.viewport.iter().any(|c| c.contains_widechar())
|
||||||
|
}
|
||||||
pub fn advance_to_next_tabstop(&mut self, styles: CharacterStyles) {
|
pub fn advance_to_next_tabstop(&mut self, styles: CharacterStyles) {
|
||||||
let columns_until_next_tabstop = TABSTOP_WIDTH - (self.cursor.x % TABSTOP_WIDTH);
|
let columns_until_next_tabstop = TABSTOP_WIDTH - (self.cursor.x % TABSTOP_WIDTH);
|
||||||
let columns_until_screen_end = (self.width - self.cursor.x).saturating_sub(1);
|
let columns_until_screen_end = (self.width - self.cursor.x).saturating_sub(1);
|
||||||
@ -1223,6 +1226,9 @@ impl Row {
|
|||||||
self.is_canonical = true;
|
self.is_canonical = true;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
pub fn contains_widechar(&self) -> bool {
|
||||||
|
self.columns.iter().any(|c| c.is_widechar())
|
||||||
|
}
|
||||||
pub fn add_character_at(&mut self, terminal_character: TerminalCharacter, x: usize) {
|
pub fn add_character_at(&mut self, terminal_character: TerminalCharacter, x: usize) {
|
||||||
match self.columns.len().cmp(&x) {
|
match self.columns.len().cmp(&x) {
|
||||||
Ordering::Equal => self.columns.push(terminal_character),
|
Ordering::Equal => self.columns.push(terminal_character),
|
||||||
|
@ -96,6 +96,9 @@ impl Pane for PluginPane {
|
|||||||
fn position_and_size_override(&self) -> Option<PositionAndSize> {
|
fn position_and_size_override(&self) -> Option<PositionAndSize> {
|
||||||
self.position_and_size_override
|
self.position_and_size_override
|
||||||
}
|
}
|
||||||
|
fn contains_widechar(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
fn should_render(&self) -> bool {
|
fn should_render(&self) -> bool {
|
||||||
self.should_render
|
self.should_render
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use unicode_width::UnicodeWidthChar;
|
||||||
|
|
||||||
use crate::utils::logging::debug_log_to_file;
|
use crate::utils::logging::debug_log_to_file;
|
||||||
use ::std::fmt::{self, Debug, Display, Formatter};
|
use ::std::fmt::{self, Debug, Display, Formatter};
|
||||||
|
|
||||||
@ -634,3 +636,13 @@ impl ::std::fmt::Debug for TerminalCharacter {
|
|||||||
write!(f, "{}", self.character)
|
write!(f, "{}", self.character)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TerminalCharacter {
|
||||||
|
pub fn width(&self) -> usize {
|
||||||
|
self.character.width().unwrap_or(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_widechar(&self) -> bool {
|
||||||
|
self.width() > 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -87,6 +87,7 @@ impl Pane for TerminalPane {
|
|||||||
for byte in bytes.iter() {
|
for byte in bytes.iter() {
|
||||||
self.vte_parser.advance(&mut self.grid, *byte);
|
self.vte_parser.advance(&mut self.grid, *byte);
|
||||||
}
|
}
|
||||||
|
self.set_should_render(true);
|
||||||
}
|
}
|
||||||
fn cursor_coordinates(&self) -> Option<(usize, usize)> {
|
fn cursor_coordinates(&self) -> Option<(usize, usize)> {
|
||||||
// (x, y)
|
// (x, y)
|
||||||
@ -138,6 +139,9 @@ impl Pane for TerminalPane {
|
|||||||
fn position_and_size_override(&self) -> Option<PositionAndSize> {
|
fn position_and_size_override(&self) -> Option<PositionAndSize> {
|
||||||
self.position_and_size_override
|
self.position_and_size_override
|
||||||
}
|
}
|
||||||
|
fn contains_widechar(&self) -> bool {
|
||||||
|
self.grid.contains_widechar()
|
||||||
|
}
|
||||||
fn should_render(&self) -> bool {
|
fn should_render(&self) -> bool {
|
||||||
self.grid.should_render
|
self.grid.should_render
|
||||||
}
|
}
|
||||||
@ -166,14 +170,7 @@ impl Pane for TerminalPane {
|
|||||||
self.max_width
|
self.max_width
|
||||||
}
|
}
|
||||||
fn render(&mut self) -> Option<String> {
|
fn render(&mut self) -> Option<String> {
|
||||||
// FIXME:
|
if self.should_render() {
|
||||||
// the below conditional is commented out because it causes several bugs:
|
|
||||||
// 1. When panes are resized or tabs are switched the previous contents of the screen stick
|
|
||||||
// around
|
|
||||||
// 2. When there are wide characters in a pane, since we don't yet handle them properly,
|
|
||||||
// the spill over to the pane to the right
|
|
||||||
// if self.should_render || cfg!(test) {
|
|
||||||
if true {
|
|
||||||
let mut vte_output = String::new();
|
let mut vte_output = String::new();
|
||||||
let buffer_lines = &self.read_buffer_as_lines();
|
let buffer_lines = &self.read_buffer_as_lines();
|
||||||
let display_cols = self.get_columns();
|
let display_cols = self.get_columns();
|
||||||
@ -215,7 +212,7 @@ impl Pane for TerminalPane {
|
|||||||
}
|
}
|
||||||
character_styles.clear();
|
character_styles.clear();
|
||||||
}
|
}
|
||||||
self.grid.should_render = false;
|
self.set_should_render(false);
|
||||||
Some(vte_output)
|
Some(vte_output)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -274,15 +271,15 @@ impl Pane for TerminalPane {
|
|||||||
}
|
}
|
||||||
fn scroll_up(&mut self, count: usize) {
|
fn scroll_up(&mut self, count: usize) {
|
||||||
self.grid.move_viewport_up(count);
|
self.grid.move_viewport_up(count);
|
||||||
self.grid.should_render = true;
|
self.set_should_render(true);
|
||||||
}
|
}
|
||||||
fn scroll_down(&mut self, count: usize) {
|
fn scroll_down(&mut self, count: usize) {
|
||||||
self.grid.move_viewport_down(count);
|
self.grid.move_viewport_down(count);
|
||||||
self.grid.should_render = true;
|
self.set_should_render(true);
|
||||||
}
|
}
|
||||||
fn clear_scroll(&mut self) {
|
fn clear_scroll(&mut self) {
|
||||||
self.grid.reset_viewport();
|
self.grid.reset_viewport();
|
||||||
self.grid.should_render = true;
|
self.set_should_render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn active_at(&self) -> Instant {
|
fn active_at(&self) -> Instant {
|
||||||
@ -337,6 +334,7 @@ impl TerminalPane {
|
|||||||
let rows = self.get_rows();
|
let rows = self.get_rows();
|
||||||
let columns = self.get_columns();
|
let columns = self.get_columns();
|
||||||
self.grid.change_size(rows, columns);
|
self.grid.change_size(rows, columns);
|
||||||
|
self.set_should_render(true);
|
||||||
}
|
}
|
||||||
pub fn read_buffer_as_lines(&self) -> Vec<Vec<TerminalCharacter>> {
|
pub fn read_buffer_as_lines(&self) -> Vec<Vec<TerminalCharacter>> {
|
||||||
self.grid.as_character_lines()
|
self.grid.as_character_lines()
|
||||||
|
@ -102,6 +102,9 @@ pub trait Pane {
|
|||||||
fn position_and_size_override(&self) -> Option<PositionAndSize>;
|
fn position_and_size_override(&self) -> Option<PositionAndSize>;
|
||||||
fn should_render(&self) -> bool;
|
fn should_render(&self) -> bool;
|
||||||
fn set_should_render(&mut self, should_render: bool);
|
fn set_should_render(&mut self, should_render: bool);
|
||||||
|
// FIXME: this method is used to trigger a force render to hide widechar problem
|
||||||
|
// it should be removed when we can handle widechars
|
||||||
|
fn contains_widechar(&self) -> bool;
|
||||||
fn selectable(&self) -> bool;
|
fn selectable(&self) -> bool;
|
||||||
fn set_selectable(&mut self, selectable: bool);
|
fn set_selectable(&mut self, selectable: bool);
|
||||||
fn set_invisible_borders(&mut self, invisible_borders: bool);
|
fn set_invisible_borders(&mut self, invisible_borders: bool);
|
||||||
@ -694,18 +697,31 @@ impl Tab {
|
|||||||
pub fn toggle_fullscreen_is_active(&mut self) {
|
pub fn toggle_fullscreen_is_active(&mut self) {
|
||||||
self.fullscreen_is_active = !self.fullscreen_is_active;
|
self.fullscreen_is_active = !self.fullscreen_is_active;
|
||||||
}
|
}
|
||||||
|
pub fn set_force_render(&mut self) {
|
||||||
|
for pane in self.panes.values_mut() {
|
||||||
|
pane.set_should_render(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn is_sync_panes_active(&self) -> bool {
|
pub fn is_sync_panes_active(&self) -> bool {
|
||||||
self.synchronize_is_active
|
self.synchronize_is_active
|
||||||
}
|
}
|
||||||
pub fn toggle_sync_panes_is_active(&mut self) {
|
pub fn toggle_sync_panes_is_active(&mut self) {
|
||||||
self.synchronize_is_active = !self.synchronize_is_active;
|
self.synchronize_is_active = !self.synchronize_is_active;
|
||||||
}
|
}
|
||||||
|
pub fn panes_contain_widechar(&self) -> bool {
|
||||||
|
self.panes.iter().any(|(_, p)| p.contains_widechar())
|
||||||
|
}
|
||||||
pub fn render(&mut self) {
|
pub fn render(&mut self) {
|
||||||
if self.active_terminal.is_none() {
|
if self.active_terminal.is_none() {
|
||||||
// we might not have an active terminal if we closed the last pane
|
// we might not have an active terminal if we closed the last pane
|
||||||
// in that case, we should not render as the app is exiting
|
// in that case, we should not render as the app is exiting
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// if any pane contain widechar, all pane in the same row will messup. We should render them every time
|
||||||
|
// FIXME: remove this when we can handle widechars correctly
|
||||||
|
if self.panes_contain_widechar() {
|
||||||
|
self.set_force_render()
|
||||||
|
}
|
||||||
let mut stdout = self.os_api.get_stdout_writer();
|
let mut stdout = self.os_api.get_stdout_writer();
|
||||||
let mut boundaries = Boundaries::new(
|
let mut boundaries = Boundaries::new(
|
||||||
self.full_screen_ws.columns as u16,
|
self.full_screen_ws.columns as u16,
|
||||||
|
@ -151,8 +151,9 @@ impl Screen {
|
|||||||
let active_tab_pos = self.get_active_tab().unwrap().position;
|
let active_tab_pos = self.get_active_tab().unwrap().position;
|
||||||
let new_tab_pos = (active_tab_pos + 1) % self.tabs.len();
|
let new_tab_pos = (active_tab_pos + 1) % self.tabs.len();
|
||||||
|
|
||||||
for tab in self.tabs.values() {
|
for tab in self.tabs.values_mut() {
|
||||||
if tab.position == new_tab_pos {
|
if tab.position == new_tab_pos {
|
||||||
|
tab.set_force_render();
|
||||||
self.active_tab_index = Some(tab.index);
|
self.active_tab_index = Some(tab.index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -169,8 +170,9 @@ impl Screen {
|
|||||||
} else {
|
} else {
|
||||||
active_tab_pos - 1
|
active_tab_pos - 1
|
||||||
};
|
};
|
||||||
for tab in self.tabs.values() {
|
for tab in self.tabs.values_mut() {
|
||||||
if tab.position == new_tab_pos {
|
if tab.position == new_tab_pos {
|
||||||
|
tab.set_force_render();
|
||||||
self.active_tab_index = Some(tab.index);
|
self.active_tab_index = Some(tab.index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -181,9 +183,10 @@ impl Screen {
|
|||||||
|
|
||||||
pub fn go_to_tab(&mut self, mut tab_index: usize) {
|
pub fn go_to_tab(&mut self, mut tab_index: usize) {
|
||||||
tab_index -= 1;
|
tab_index -= 1;
|
||||||
let active_tab = self.get_active_tab().unwrap();
|
let active_tab_index = self.get_active_tab().unwrap().index;
|
||||||
if let Some(t) = self.tabs.values().find(|t| t.position == tab_index) {
|
if let Some(t) = self.tabs.values_mut().find(|t| t.position == tab_index) {
|
||||||
if t.index != active_tab.index {
|
if t.index != active_tab_index {
|
||||||
|
t.set_force_render();
|
||||||
self.active_tab_index = Some(t.index);
|
self.active_tab_index = Some(t.index);
|
||||||
self.update_tabs();
|
self.update_tabs();
|
||||||
self.render();
|
self.render();
|
||||||
@ -227,6 +230,7 @@ impl Screen {
|
|||||||
for (_, tab) in self.tabs.iter_mut() {
|
for (_, tab) in self.tabs.iter_mut() {
|
||||||
tab.resize_whole_tab(new_screen_size);
|
tab.resize_whole_tab(new_screen_size);
|
||||||
}
|
}
|
||||||
|
let _ = self.get_active_tab_mut().map(|t| t.set_force_render());
|
||||||
self.render();
|
self.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user