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:
parent
93a9b5a7fe
commit
5608e9477b
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user