From 265c93c4c4199fa131476fdbd9eacb9d2fcf51c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 31 Aug 2025 10:25:17 +0200 Subject: [PATCH] multi-cursor: refactor: add function for dirtying/damaging all multi-cursors --- render.c | 55 ++++++++---------------------------------------------- terminal.c | 23 +++++++++++++++++++++++ terminal.h | 1 + 3 files changed, 32 insertions(+), 47 deletions(-) diff --git a/render.c b/render.c index 41ea2ad6..9660f85a 100644 --- a/render.c +++ b/render.c @@ -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); diff --git a/terminal.c b/terminal.c index fe21cfd2..e8a25061 100644 --- a/terminal.c +++ b/terminal.c @@ -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) { diff --git a/terminal.h b/terminal.h index 0f202193..86f8226f 100644 --- a/terminal.h +++ b/terminal.h @@ -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) {