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.
This commit is contained in:
Daniel Eklöf 2025-08-31 09:23:34 +02:00
parent cc02902db0
commit 4907c5d08a
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F

View file

@ -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