1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-23 21:32:13 +03:00

kitty img: make allowances for permanence of image attachments

An implementation detail in wezterm is that it doesn't model
image placements as a separate entity; they are all bound to
the image cells in the terminal model.

The semantics of the kitty image protocol are that placements
are "permanent" wrt. overwriting a cell with text, except for
the explicit EraseInLine/EraseInDisplay sequences that are
used for clearing.

This commit takes a pass at implementing that semantic in
the wezterm data model.

refs: #986
This commit is contained in:
Wez Furlong 2021-08-06 09:01:18 -07:00
parent aac4d36d6e
commit 6a7e6596b9
6 changed files with 36 additions and 11 deletions

View File

@ -40,7 +40,7 @@ pub struct ImageAttachParams {
pub columns: Option<usize>,
pub rows: Option<usize>,
pub image_id: u32,
pub image_id: Option<u32>,
pub placement_id: Option<u32>,
pub style: ImageAttachStyle,

View File

@ -136,7 +136,7 @@ impl TerminalState {
rows: None,
data: image_data,
style: ImageAttachStyle::Iterm,
image_id: 0,
image_id: None,
placement_id: None,
do_not_move_cursor: false,
});

View File

@ -124,7 +124,7 @@ impl TerminalState {
z_index: placement.z_index.unwrap_or(0),
columns: placement.columns.map(|x| x as usize),
rows: placement.rows.map(|x| x as usize),
image_id,
image_id: Some(image_id),
placement_id: placement.placement_id,
do_not_move_cursor: placement.do_not_move_cursor,
});

View File

@ -121,7 +121,7 @@ impl TerminalState {
data: image_data,
style: ImageAttachStyle::Sixel,
z_index: 0,
image_id: 0,
image_id: None,
placement_id: None,
do_not_move_cursor: false,
});

View File

@ -90,7 +90,7 @@ pub struct ImageCell {
display_offset_x: u32,
display_offset_y: u32,
image_id: u32,
image_id: Option<u32>,
placement_id: Option<u32>,
}
@ -100,7 +100,7 @@ impl ImageCell {
bottom_right: TextureCoordinate,
data: Arc<ImageData>,
) -> Self {
Self::with_z_index(top_left, bottom_right, data, 0, 0, 0, 0, None)
Self::with_z_index(top_left, bottom_right, data, 0, 0, 0, None, None)
}
pub fn with_z_index(
@ -110,7 +110,7 @@ impl ImageCell {
z_index: i32,
display_offset_x: u32,
display_offset_y: u32,
image_id: u32,
image_id: Option<u32>,
placement_id: Option<u32>,
) -> Self {
Self {
@ -126,7 +126,11 @@ impl ImageCell {
}
pub fn matches_placement(&self, image_id: u32, placement_id: Option<u32>) -> bool {
self.image_id == image_id && self.placement_id == placement_id
self.image_id == Some(image_id) && self.placement_id == placement_id
}
pub fn has_placement_id(&self) -> bool {
self.placement_id.is_some()
}
pub fn top_left(&self) -> TextureCoordinate {

View File

@ -405,6 +405,27 @@ impl Line {
/// Similarly, when we assign a cell, we need to blank out those
/// occluded successor cells.
pub fn set_cell(&mut self, idx: usize, cell: Cell) -> &Cell {
self.set_cell_impl(idx, cell, false)
}
pub fn set_cell_clearing_image_placements(&mut self, idx: usize, cell: Cell) -> &Cell {
self.set_cell_impl(idx, cell, true)
}
fn raw_set_cell(&mut self, idx: usize, mut cell: Cell, clear: bool) {
if !clear {
if let Some(images) = self.cells[idx].attrs().images() {
for image in images {
if image.has_placement_id() {
cell.attrs_mut().attach_image(Box::new(image));
}
}
}
}
self.cells[idx] = cell;
}
fn set_cell_impl(&mut self, idx: usize, cell: Cell, clear: bool) -> &Cell {
let width = cell.width();
// if the line isn't wide enough, pad it out with the default attributes.
@ -428,10 +449,10 @@ impl Line {
// For double-wide or wider chars, ensure that the cells that
// are overlapped by this one are blanked out.
for i in 1..=width.saturating_sub(1) {
self.cells[idx + i] = Cell::new(' ', cell.attrs().clone());
self.raw_set_cell(idx + i, Cell::new(' ', cell.attrs().clone()), clear);
}
self.cells[idx] = cell;
self.raw_set_cell(idx, cell, clear);
&self.cells[idx]
}
@ -529,7 +550,7 @@ impl Line {
pub fn fill_range(&mut self, cols: Range<usize>, cell: &Cell) {
for x in cols {
// FIXME: we can skip the look-back for second and subsequent iterations
self.set_cell(x, cell.clone());
self.set_cell_impl(x, cell.clone(), true);
}
self.prune_trailing_blanks();
}