multi-cursor: refactor: add function for dirtying/damaging all multi-cursors

This commit is contained in:
Daniel Eklöf 2025-08-31 10:25:17 +02:00
parent 4f89c461b1
commit 265c93c4c4
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 32 additions and 47 deletions

View file

@ -3417,28 +3417,6 @@ 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
@ -3464,6 +3442,7 @@ grid_render(struct terminal *term)
/* Dirty old and current cursor cell, to ensure they're repainted */
dirty_old_cursor(term);
dirty_cursor(term);
term_damage_all_multi_cursors(term);
if (term->render.last_buf == NULL ||
term->render.last_buf->width != buf->width ||
@ -3703,31 +3682,13 @@ 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;
}
}
}
/*
* 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)
*/
term_damage_all_multi_cursors(term);
render_overlay(term);
render_ime_preedit(term, buf);

View file

@ -2567,6 +2567,29 @@ term_damage_cursor(struct terminal *term)
term->grid->cur_row->dirty = true;
}
void
term_damage_all_multi_cursors(struct terminal *term)
{
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 (const pixman_box32_t *box = boxes; box < &boxes[rect_count]; box++) {
for (int r = box->y1; r < box->y2; r++) {
struct row *row = grid_row(term->grid, r);
xassert(row != NULL);
row->dirty = true;
for (struct cell *c = &row->cells[box->x1]; c < &row->cells[box->x2]; c++)
c->attrs.clean = false;
}
}
}
void
term_damage_margins(struct terminal *term)
{

View file

@ -1021,6 +1021,7 @@ void term_theme_switch_to_2(struct terminal *term);
void term_theme_toggle(struct terminal *term);
void term_remove_all_multi_cursors(struct terminal *term);
void term_damage_all_multi_cursors(struct terminal *term);
static inline void term_reset_grapheme_state(struct terminal *term)
{