From 9c705b26ee2cefe8e9710c6dc8dbbd1ac5a5c53f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 2 Jan 2021 22:24:49 +0100 Subject: [PATCH] render: mark cell overflowed into as dirty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When tweak.allow-overflowing-double-width-glyphs=yes, then certain glyphs are allowed to overflow into the neighbouring cell. However, if the cell “owning” the double-width glyph is erased (_only_ that cell), then the cell overflowed into is not redrawn, causing part of the double-width glyph to remain on screen. To avoid checking for these glyphs when printing to the terminal (i.e at parse time), simply mark both cells as dirty when we render the overflowing glyph. Yes, this means that the cells will always be re-rendered. We count on them only making up a small portion of the screen. --- CHANGELOG.md | 3 +++ render.c | 11 ++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3ba4654..8cb6fe1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,9 @@ descriptor is closed. * Crash on compositors not implementing the _text input_ interface (https://codeberg.org/dnkl/foot/issues/259). +* Erased, overflowing glyphs (when + `tweak.allow-overflowing-double-width-glyphs=yes` - the default) not + properly erasing the cell overflowed **into**. ### Security diff --git a/render.c b/render.c index f66e277e..2951c466 100644 --- a/render.c +++ b/render.c @@ -481,7 +481,16 @@ render_cell(struct terminal *term, pixman_image_t *pix, col < term->cols - 1 && (row->cells[col + 1].wc == 0 || row->cells[col + 1].wc == L' ')) { - cell_cols = min(2, cols_left); + cell_cols = 2; + + /* + * Ensure the cell we’re overflowing into gets re-rendered, to + * ensure it is erased if *this* cell is erased. Note that we + * do *not* mark the row as dirty - we don’t need to re-render + * the cell if nothing else on the row has changed. + */ + row->cells[col].attrs.clean = 0; + row->cells[col + 1].attrs.clean = 0; } pixman_region32_t clip;