From d490cc84c0a78813403f6c2740a69ef3c8017f49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 16 Dec 2019 21:31:40 +0100 Subject: [PATCH] term: cursor blink: cursor refresh now dirties the cursor cell Normally we don't dirty the cell on cursor movement. But, since a blinking cursor isn't a cursor that has moved, our normal cursor rendering wont work. Dirty the cursor cell to force a redraw of it. --- terminal.c | 48 +++++++++++++++++++++++++++++++++++++++++++----- terminal.h | 2 ++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/terminal.c b/terminal.c index 5fe9e072..b016f2e7 100644 --- a/terminal.c +++ b/terminal.c @@ -275,6 +275,17 @@ fdm_blink(struct fdm *fdm, int fd, int events, void *data) return true; } +static void +cursor_refresh(struct terminal *term) +{ + if (term->is_shutting_down) + return; + + term->grid->cur_row->cells[term->cursor.point.col].attrs.clean = 0; + term->grid->cur_row->dirty = true; + render_refresh(term); +} + static bool fdm_cursor_blink(struct fdm *fdm, int fd, int events, void *data) { @@ -301,7 +312,7 @@ fdm_cursor_blink(struct fdm *fdm, int fd, int events, void *data) term->cursor_blink.state = term->cursor_blink.state == CURSOR_BLINK_ON ? CURSOR_BLINK_OFF : CURSOR_BLINK_ON; - render_refresh(term); + cursor_refresh(term); return true; } @@ -526,6 +537,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl, .default_cursor_style = conf->cursor.style, .cursor_style = conf->cursor.style, .cursor_blink = { + .active = false, .state = CURSOR_BLINK_ON, .fd = cursor_blink_fd, }, @@ -1127,25 +1139,51 @@ term_cursor_down(struct terminal *term, int count) term_cursor_to(term, term->cursor.point.row + move_amount, term->cursor.point.col); } -void -term_cursor_blink_enable(struct terminal *term) +static bool +cursor_blink_start_timer(struct terminal *term) { static const struct itimerspec timer = { .it_value = {.tv_sec = 0, .tv_nsec = 500000000}, .it_interval = {.tv_sec = 0, .tv_nsec = 500000000}, }; - if (timerfd_settime(term->cursor_blink.fd, 0, &timer, NULL) < 0) + if (timerfd_settime(term->cursor_blink.fd, 0, &timer, NULL) < 0) { LOG_ERRNO("failed to arm cursor blink timer"); + return false; + } + return true; +} + +static bool +cursor_blink_stop_timer(struct terminal *term) +{ + return timerfd_settime(term->cursor_blink.fd, 0, &(struct itimerspec){{0}}, NULL) == 0; +} + +void +term_cursor_blink_enable(struct terminal *term) +{ term->cursor_blink.state = CURSOR_BLINK_ON; + term->cursor_blink.active = term->wl->focused == term + ? cursor_blink_start_timer(term) : true; + cursor_refresh(term); } void term_cursor_blink_disable(struct terminal *term) { + term->cursor_blink.active = false; term->cursor_blink.state = CURSOR_BLINK_ON; - timerfd_settime(term->cursor_blink.fd, 0, &(struct itimerspec){{0}}, NULL); + cursor_blink_stop_timer(term); + //cursor_refresh(term); /* TODO: causes excessive flicker in Emacs */ +} + +void +term_cursor_blink_restart(struct terminal *term) +{ + if (term->cursor_blink.active) + term_cursor_blink_enable(term); } void diff --git a/terminal.h b/terminal.h index e29f5269..f4fd5276 100644 --- a/terminal.h +++ b/terminal.h @@ -233,6 +233,7 @@ struct terminal { enum cursor_style default_cursor_style; enum cursor_style cursor_style; struct { + bool active; enum { CURSOR_BLINK_ON, CURSOR_BLINK_OFF } state; int fd; } cursor_blink; @@ -351,6 +352,7 @@ void term_cursor_up(struct terminal *term, int count); void term_cursor_down(struct terminal *term, int count); void term_cursor_blink_enable(struct terminal *term); void term_cursor_blink_disable(struct terminal *term); +void term_cursor_blink_restart(struct terminal *term); void term_scroll(struct terminal *term, int rows); void term_scroll_reverse(struct terminal *term, int rows);