From 4907c5d08a56a4c37d85e83b65723b678c853fe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 31 Aug 2025 09:23:34 +0200 Subject: [PATCH] render: multi-cursor: dirty all multi-cursors before rendering In most cases, this isn't necessary, since the cursors don't move (and when the application adds/deletes multi-cursors, we dirty the grid _then_). However, when we scroll the viewport, we're basically memmov:ing grid contents without re-rendering, this can cause multi-cursors to be "overwritten", and thus we need to explicitly re-render them. Note: there's still an issue where scrolling content *with* a multi-cursor doesn't correctly erase the scrolled multi-cursor. --- render.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/render.c b/render.c index 5af3d44b..7ceb99a1 100644 --- a/render.c +++ b/render.c @@ -3417,6 +3417,28 @@ dirty_cursor(struct terminal *term) struct cell *cell = &row->cells[cursor->col]; cell->attrs.clean = 0; row->dirty = true; + + + /* TODO: move to separate function */ + if (likely(term->multi_cursor.shapes == NULL)) + return; + + 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; + } + } } static void