1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-28 07:55:03 +03:00

termwiz: make seqno a required param for Line

Previously, we would implicitly set it to the special SEQ_ZERO
value, but since that value always flags the row as changed,
it causes some over-invalidation issues downstream in wezterm.

This commit makes that parameter required, so that the code that
is creating a new Line always passes down the seqno from that event.

refs: #1472
This commit is contained in:
Wez Furlong 2021-12-29 08:28:08 -07:00
parent 93a9b5a7fe
commit 5608e9477b
11 changed files with 66 additions and 64 deletions

View File

@ -153,7 +153,7 @@ impl LogicalLine {
let num_phys = self.physical_lines.len();
for (idx, phys) in self.physical_lines.iter_mut().enumerate() {
let len = phys.cells().len();
let remainder = line.split_off(len);
let remainder = line.split_off(len, SEQ_ZERO);
*phys = line;
line = remainder;
let wrapped = idx == num_phys - 1;
@ -493,7 +493,7 @@ mod test {
.collect::<Vec<String>>();
let n_chunks = chunks.len();
for (idx, chunk) in chunks.into_iter().enumerate() {
let mut line = Line::from_text(&chunk, &Default::default());
let mut line = Line::from_text(&chunk, &Default::default(), SEQ_ZERO);
if idx < n_chunks - 1 {
line.set_last_cell_was_wrapped(true, SEQ_ZERO);
}
@ -860,10 +860,10 @@ mod test {
let attr = Default::default();
let logical = LogicalLine {
physical_lines: vec![
Line::from_text("hello", &attr),
Line::from_text("yo", &attr),
Line::from_text("hello", &attr, SEQ_ZERO),
Line::from_text("yo", &attr, SEQ_ZERO),
],
logical: Line::from_text("helloyo", &attr),
logical: Line::from_text("helloyo", &attr, SEQ_ZERO),
first_row: 0,
};

View File

@ -56,6 +56,7 @@ impl Screen {
physical_cols: usize,
config: &Arc<dyn TerminalConfiguration>,
allow_scrollback: bool,
seqno: SequenceNo,
) -> Screen {
let physical_rows = physical_rows.max(1);
let physical_cols = physical_cols.max(1);
@ -63,7 +64,7 @@ impl Screen {
let mut lines =
VecDeque::with_capacity(physical_rows + scrollback_size(config, allow_scrollback));
for _ in 0..physical_rows {
lines.push_back(Line::with_width(physical_cols));
lines.push_back(Line::with_width(physical_cols, seqno));
}
Screen {
@ -215,7 +216,8 @@ impl Screen {
// lines than the viewport size, or we resized taller,
// pad us back out to the viewport size
while self.lines.len() < physical_rows {
self.lines.push_back(Line::with_width(self.physical_cols));
self.lines
.push_back(Line::with_width(self.physical_cols, seqno));
}
let new_cursor_y;
@ -236,7 +238,8 @@ impl Screen {
physical_rows.saturating_sub(new_cursor_y as usize);
let actual_num_rows_after_cursor = self.lines.len().saturating_sub(cursor_y);
for _ in actual_num_rows_after_cursor..required_num_rows_after_cursor {
self.lines.push_back(Line::with_width(self.physical_cols));
self.lines
.push_back(Line::with_width(self.physical_cols, seqno));
}
} else {
// Compute the new cursor location; this is logically the inverse

View File

@ -162,9 +162,10 @@ impl ScreenOrAlt {
physical_rows: usize,
physical_cols: usize,
config: &Arc<dyn TerminalConfiguration>,
seqno: SequenceNo,
) -> Self {
let screen = Screen::new(physical_rows, physical_cols, config, true);
let alt_screen = Screen::new(physical_rows, physical_cols, config, false);
let screen = Screen::new(physical_rows, physical_cols, config, true, seqno);
let alt_screen = Screen::new(physical_rows, physical_cols, config, false, seqno);
Self {
screen,
@ -428,7 +429,8 @@ impl TerminalState {
writer: Box<dyn std::io::Write + Send>,
) -> TerminalState {
let writer = Box::new(ThreadedWriter::new(writer));
let screen = ScreenOrAlt::new(size.physical_rows, size.physical_cols, &config);
let seqno = 1;
let screen = ScreenOrAlt::new(size.physical_rows, size.physical_cols, &config, seqno);
let color_map = default_color_map();
@ -487,7 +489,7 @@ impl TerminalState {
image_cache: lru::LruCache::new(16),
user_vars: HashMap::new(),
kitty_img: Default::default(),
seqno: 0,
seqno,
unicode_version,
unicode_version_stack: vec![],
suppress_initial_title_change: false,

View File

@ -13,7 +13,7 @@ fn test_789() {
let black = CellAttributes::default()
.set_background(AnsiColor::Black)
.clone();
let mut line = Line::from_text("foo", &black);
let mut line = Line::from_text("foo", &black, SEQ_ZERO);
line.resize(8, 0);
for x in 3..8 {
line.set_cell(x, Cell::blank_with_attrs(black.clone()), 0);

View File

@ -403,7 +403,7 @@ fn test_semantic() {
let mut input = CellAttributes::default();
input.set_semantic_type(SemanticType::Input);
let mut prompt_line = Line::from_text("> ls -l ", &output);
let mut prompt_line = Line::from_text("> ls -l ", &output, SEQ_ZERO);
for i in 0..2 {
prompt_line.cells_mut()[i]
.attrs_mut()
@ -456,11 +456,11 @@ fn test_semantic() {
line!(),
&term.screen().visible_lines(),
&[
Line::from_text("hello ", &output),
Line::from_text("there ", &output),
Line::from_text("three ", &output),
Line::from_text("hello ", &output, SEQ_ZERO),
Line::from_text("there ", &output, SEQ_ZERO),
Line::from_text("three ", &output, SEQ_ZERO),
prompt_line,
Line::from_text("some file ", &output),
Line::from_text("some file ", &output, SEQ_ZERO),
],
Compare::TEXT | Compare::ATTRS,
);
@ -1050,7 +1050,7 @@ fn test_hyperlinks() {
line!(),
&term.screen().visible_lines(),
&[
Line::from_text("hello", &linked),
Line::from_text("hello", &linked, SEQ_ZERO),
" ".into(),
" ".into(),
],
@ -1068,8 +1068,8 @@ fn test_hyperlinks() {
line!(),
&term.screen().visible_lines(),
&[
Line::from_text_with_wrapped_last_col("hello", &linked),
Line::from_text("hey!!", &linked),
Line::from_text_with_wrapped_last_col("hello", &linked, SEQ_ZERO),
Line::from_text("hey!!", &linked, SEQ_ZERO),
" ".into(),
],
Compare::TEXT | Compare::ATTRS,
@ -1084,7 +1084,7 @@ fn test_hyperlinks() {
term.soft_reset();
term.print("00t");
let mut partial_line = Line::from_text("wo00t", &CellAttributes::default());
let mut partial_line = Line::from_text("wo00t", &CellAttributes::default(), SEQ_ZERO);
partial_line.set_cell(
0,
Cell::new(
@ -1111,8 +1111,8 @@ fn test_hyperlinks() {
line!(),
&term.screen().visible_lines(),
&[
Line::from_text_with_wrapped_last_col("hello", &linked),
Line::from_text_with_wrapped_last_col("hey!!", &linked),
Line::from_text_with_wrapped_last_col("hello", &linked, SEQ_ZERO),
Line::from_text_with_wrapped_last_col("hey!!", &linked, SEQ_ZERO),
partial_line,
],
Compare::TEXT | Compare::ATTRS,

View File

@ -67,27 +67,19 @@ impl Line {
Self { bits, cells, seqno }
}
pub fn from_cells(cells: Vec<Cell>) -> Self {
pub fn from_cells(cells: Vec<Cell>, seqno: SequenceNo) -> Self {
let bits = LineBits::NONE;
Self {
bits,
cells,
seqno: SEQ_ZERO,
}
Self { bits, cells, seqno }
}
pub fn with_width(width: usize) -> Self {
pub fn with_width(width: usize, seqno: SequenceNo) -> Self {
let mut cells = Vec::with_capacity(width);
cells.resize_with(width, Cell::blank);
let bits = LineBits::NONE;
Self {
bits,
cells,
seqno: SEQ_ZERO,
}
Self { bits, cells, seqno }
}
pub fn from_text(s: &str, attrs: &CellAttributes) -> Line {
pub fn from_text(s: &str, attrs: &CellAttributes, seqno: SequenceNo) -> Line {
let mut cells = Vec::new();
for sub in s.graphemes(true) {
@ -102,12 +94,16 @@ impl Line {
Line {
cells,
bits: LineBits::NONE,
seqno: SEQ_ZERO,
seqno,
}
}
pub fn from_text_with_wrapped_last_col(s: &str, attrs: &CellAttributes) -> Line {
let mut line = Self::from_text(s, attrs);
pub fn from_text_with_wrapped_last_col(
s: &str,
attrs: &CellAttributes,
seqno: SequenceNo,
) -> Line {
let mut line = Self::from_text(s, attrs, seqno);
line.cells
.last_mut()
.map(|cell| cell.attrs_mut().set_wrapped(true));
@ -366,12 +362,12 @@ impl Line {
s
}
pub fn split_off(&mut self, idx: usize) -> Self {
pub fn split_off(&mut self, idx: usize, seqno: SequenceNo) -> Self {
let cells = self.cells.split_off(idx);
Self {
bits: self.bits,
cells,
seqno: SEQ_ZERO,
seqno,
}
}
@ -756,7 +752,7 @@ impl Line {
impl<'a> From<&'a str> for Line {
fn from(s: &str) -> Line {
Line::from_text(s, &CellAttributes::default())
Line::from_text(s, &CellAttributes::default(), SEQ_ZERO)
}
}

View File

@ -228,13 +228,6 @@ impl Surface {
/// If the cursor position would be outside the bounds of the newly resized
/// screen, it will be moved to be within the new bounds.
pub fn resize(&mut self, width: usize, height: usize) {
self.lines.resize(height, Line::with_width(width));
for line in &mut self.lines {
line.resize(width, self.seqno);
}
self.width = width;
self.height = height;
// We need to invalidate the change stream prior to this
// event, so we nominally generate an entry for the resize
// here. Since rendering a resize doesn't make sense, we
@ -248,6 +241,14 @@ impl Surface {
self.changes.clear();
}
self.lines
.resize(height, Line::with_width(width, self.seqno));
for line in &mut self.lines {
line.resize(width, self.seqno);
}
self.width = width;
self.height = height;
// Ensure that the cursor position is well-defined
self.xpos = compute_position_change(self.xpos, &Position::Relative(0), self.width);
self.ypos = compute_position_change(self.ypos, &Position::Relative(0), self.height);
@ -378,13 +379,13 @@ impl Surface {
fn scroll_screen_up(&mut self) {
self.lines.remove(0);
self.lines.push(Line::with_width(self.width));
self.lines.push(Line::with_width(self.width, self.seqno));
}
fn scroll_region_up(&mut self, start: usize, size: usize, count: usize) {
// Replace the first lines with empty lines
for index in start..start + min(count, size) {
self.lines[index] = Line::with_width(self.width);
self.lines[index] = Line::with_width(self.width, self.seqno);
}
// Rotate the remaining lines up the surface.
if 0 < count && count < size {
@ -395,7 +396,7 @@ impl Surface {
fn scroll_region_down(&mut self, start: usize, size: usize, count: usize) {
// Replace the last lines with empty lines
for index in start + size - min(count, size)..start + size {
self.lines[index] = Line::with_width(self.width);
self.lines[index] = Line::with_width(self.width, self.seqno);
}
// Rotate the remaining lines down the surface.
if 0 < count && count < size {

View File

@ -250,7 +250,7 @@ impl RenderableInner {
.set_underline(Underline::Double)
.clone();
let text_line = Line::from_text(text, &attrs);
let text_line = Line::from_text(text, &attrs, SEQ_ZERO);
if row == 0 {
for cell in text_line.cells() {
@ -634,7 +634,7 @@ impl RenderableState {
LineEntry::DirtyAndFetching(line, then)
}
Some(LineEntry::Fetching(then)) => {
result.push(Line::with_width(inner.dimensions.cols));
result.push(Line::with_width(inner.dimensions.cols, SEQ_ZERO));
LineEntry::Fetching(then)
}
Some(LineEntry::Stale(line)) => {
@ -643,7 +643,7 @@ impl RenderableState {
LineEntry::DirtyAndFetching(line, now)
}
None => {
result.push(Line::with_width(inner.dimensions.cols));
result.push(Line::with_width(inner.dimensions.cols, SEQ_ZERO));
to_fetch.add(idx);
LineEntry::Fetching(now)
}

View File

@ -15,7 +15,7 @@ use std::rc::Rc;
use std::sync::Arc;
use structopt::StructOpt;
use termwiz::cell::CellAttributes;
use termwiz::surface::Line;
use termwiz::surface::{Line, SEQ_ZERO};
use wezterm_client::domain::{ClientDomain, ClientDomainConfig};
use wezterm_gui_subcommands::*;
use wezterm_ssh::*;
@ -487,7 +487,7 @@ pub fn run_ls_fonts(config: config::ConfigHandle, cmd: &LsFontsCommand) -> anyho
)?;
if let Some(text) = &cmd.text {
let line = Line::from_text(text, &CellAttributes::default());
let line = Line::from_text(text, &CellAttributes::default(), SEQ_ZERO);
let cell_clusters = line.cluster();
for cluster in cell_clusters {
let style = font_config.match_style(&config, &cluster.attrs);

View File

@ -257,7 +257,7 @@ mod test {
use k9::assert_equal as assert_eq;
use std::rc::Rc;
use termwiz::cell::CellAttributes;
use termwiz::surface::Line;
use termwiz::surface::{Line, SEQ_ZERO};
use wezterm_font::FontConfiguration;
use wezterm_font::LoadedFont;
@ -272,7 +272,7 @@ mod test {
T: Texture2d,
T: std::fmt::Debug,
{
let line = Line::from_text(text, &CellAttributes::default());
let line = Line::from_text(text, &CellAttributes::default(), SEQ_ZERO);
eprintln!("{:?}", line);
let cell_clusters = line.cluster();
assert_eq!(cell_clusters.len(), 1);
@ -391,7 +391,7 @@ mod test {
);
let style = TextStyle::default();
let font = fonts.resolve_font(&style).unwrap();
let line = Line::from_text(&text, &CellAttributes::default());
let line = Line::from_text(&text, &CellAttributes::default(), SEQ_ZERO);
let cell_clusters = line.cluster();
let cluster = &cell_clusters[0];

View File

@ -159,7 +159,7 @@ fn is_tab_hover(mouse_x: Option<usize>, x: usize, tab_title_len: usize) -> bool
impl TabBarState {
pub fn default() -> Self {
Self {
line: Line::with_width(1),
line: Line::with_width(1, SEQ_ZERO),
items: vec![],
}
}
@ -248,7 +248,7 @@ impl TabBarState {
}
.min(config.tab_max_width);
let mut line = Line::with_width(0);
let mut line = Line::with_width(0, SEQ_ZERO);
let mut x = 0;
let mut items = vec![];
@ -472,5 +472,5 @@ fn parse_status_text(text: &str, default_cell: CellAttributes) -> Line {
}
});
flush_print(&mut print_buffer, &mut cells, &pen);
Line::from_cells(cells)
Line::from_cells(cells, SEQ_ZERO)
}