diff --git a/render.c b/render.c index 7a03778d..f8b263a0 100644 --- a/render.c +++ b/render.c @@ -169,21 +169,6 @@ coord_is_selected(const struct terminal *term, int col, int row) } } -static void -arm_blink_timer(struct terminal *term) -{ - LOG_DBG("arming blink timer"); - struct itimerspec alarm = { - .it_value = {.tv_sec = 0, .tv_nsec = 500 * 1000000}, - .it_interval = {.tv_sec = 0, .tv_nsec = 500 * 1000000}, - }; - - if (timerfd_settime(term->blink.fd, 0, &alarm, NULL) < 0) - LOG_ERRNO("failed to arm blink timer"); - else - term->blink.active = true; -} - static int render_cell(struct terminal *term, pixman_image_t *pix, struct cell *cell, int col, int row, bool has_cursor) @@ -292,10 +277,8 @@ render_cell(struct terminal *term, pixman_image_t *pix, } } - if (cell->attrs.blink && !term->blink.active) { - /* First cell we see that has blink set - arm blink timer */ - arm_blink_timer(term); - } + if (cell->attrs.blink) + term_arm_blink_timer(term); if (cell->wc == 0 || cell->attrs.conceal) return cell_cols; @@ -638,35 +621,6 @@ grid_render(struct terminal *term) } } - if (term->blink.active) { - /* Check if there are still any visible blinking cells */ - bool none_is_blinking = true; - for (int r = 0; r < term->rows; r++) { - struct row *row = grid_row_in_view(term->grid, r); - for (int col = 0; col < term->cols; col++) { - if (row->cells[col].attrs.blink) { - none_is_blinking = false; - break; - } - } - } - - /* No, disarm the blink timer */ - if (none_is_blinking) { - LOG_DBG("disarming blink timer"); - - term->blink.active = false; - term->blink.state = BLINK_ON; - - if (timerfd_settime( - term->blink.fd, 0, - &(struct itimerspec){{0}}, NULL) < 0) - { - LOG_ERRNO("failed to disarm blink timer"); - } - } - } - /* * Determine if we need to render a cursor or not. The cursor * could be hidden. Or it could have been scrolled out of view. @@ -710,7 +664,6 @@ grid_render(struct terminal *term) cell->attrs.clean = 0; term->render.last_cursor.cell = cell; - term->render.last_cursor.blink_state = term->cursor_blink.state; int cols_updated = render_cell( term, pix, cell, term->cursor.point.col, view_aligned_row, true); diff --git a/terminal.c b/terminal.c index 493dcaa2..acc526e5 100644 --- a/terminal.c +++ b/terminal.c @@ -259,6 +259,7 @@ fdm_blink(struct fdm *fdm, int fd, int events, void *data) ? BLINK_OFF : BLINK_ON; /* Scan all visible cells and mark rows with blinking cells dirty */ + bool no_blinking_cells = true; for (int r = 0; r < term->rows; r++) { struct row *row = grid_row_in_view(term->grid, r); for (int col = 0; col < term->cols; col++) { @@ -267,14 +268,43 @@ fdm_blink(struct fdm *fdm, int fd, int events, void *data) if (cell->attrs.blink) { cell->attrs.clean = 0; row->dirty = true; + no_blinking_cells = false; } } } - render_refresh(term); + if (no_blinking_cells) { + LOG_DBG("disarming blink timer"); + + term->blink.active = false; + term->blink.state = BLINK_ON; + + static const struct itimerspec disarm = {{0}}; + if (timerfd_settime(term->blink.fd, 0, &disarm, NULL) < 0) + LOG_ERRNO("failed to disarm blink timer"); + } else + render_refresh(term); return true; } +void +term_arm_blink_timer(struct terminal *term) +{ + if (term->blink.active) + return; + + LOG_DBG("arming blink timer"); + struct itimerspec alarm = { + .it_value = {.tv_sec = 0, .tv_nsec = 500 * 1000000}, + .it_interval = {.tv_sec = 0, .tv_nsec = 500 * 1000000}, + }; + + if (timerfd_settime(term->blink.fd, 0, &alarm, NULL) < 0) + LOG_ERRNO("failed to arm blink timer"); + else + term->blink.active = true; +} + static void cursor_refresh(struct terminal *term) { diff --git a/terminal.h b/terminal.h index f4fd5276..47548896 100644 --- a/terminal.h +++ b/terminal.h @@ -296,7 +296,6 @@ struct terminal { struct coord actual; /* Absolute */ struct coord in_view; /* Offset by view */ struct cell *cell; /* For easy access to content */ - int blink_state; } last_cursor; struct buffer *last_buf; /* Buffer we rendered to last time */ @@ -365,6 +364,8 @@ void term_scroll_reverse_partial( void term_linefeed(struct terminal *term); void term_reverse_index(struct terminal *term); +void term_arm_blink_timer(struct terminal *term); + void term_restore_cursor(struct terminal *term); void term_focus_in(struct terminal *term);