From 4f89c461b15543cebdd3cc1d5112894a5986418f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 31 Aug 2025 09:29:27 +0200 Subject: [PATCH] render: dirty all multi-cursor cells *after* rendering a frame This ensures they're re-rendered the next frame, and fixes an issue were multi-cursors weren't erased when scrolled. That is, they scrolled with the content, *and* was re-drawn at the correct (fixed) location they were scrolled away from. Since multi-cursors shouldn't scroll with the content, they need to be erased when the content is scrolled. --- render.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/render.c b/render.c index 7ceb99a1..41ea2ad6 100644 --- a/render.c +++ b/render.c @@ -3703,6 +3703,32 @@ grid_render(struct terminal *term) pixman_region32_fini(&damage); + if (unlikely(term->multi_cursor.shapes != NULL)) { + /* + * WIP: dirty all multi-cursors again, to ensure they're + * re-rendered the next frame. This is needed to properly + * _erase_ multi-cursors that have been scrolled (the cursors + * don't scroll with the content, but stay fixed) + */ + + int rect_count = 0; + const pixman_box32_t *boxes = pixman_region32_rectangles(&term->multi_cursor.active, &rect_count); + + for (int i = 0; i < rect_count; i++) { + const pixman_box32_t *box = &boxes[i]; + + for (int r = box->y1; r < box->y2; r++) { + struct row *row = grid_row(term->grid, r); + xassert(row != NULL); + + row->dirty = true; + + for (int c = box->x1; c < box->x2; c++) + row->cells[c].attrs.clean = false; + } + } + } + render_overlay(term); render_ime_preedit(term, buf); render_scrollback_position(term);