config: add cursor.blink-rate option

The default is 500ms, which corresponds to the old, hardcoded default.

Closes #1707
This commit is contained in:
Daniel Eklöf 2024-05-20 09:03:29 +02:00
parent bc193c7be5
commit c4f1380943
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
7 changed files with 37 additions and 11 deletions

View file

@ -54,6 +54,13 @@
## Unreleased ## Unreleased
### Added ### Added
* `cursor.blink-rate` option, allowing you to configure the rate the
cursor blinks with (when `cursor.blink=yes`) ([#1707][1707]);
[1707]: https://codeberg.org/dnkl/foot/issues/1707
### Changed ### Changed
* All `XTGETTCAP` capabilities are now in the `tigetstr()` format: * All `XTGETTCAP` capabilities are now in the `tigetstr()` format:

View file

@ -1395,7 +1395,10 @@ parse_section_cursor(struct context *ctx)
} }
else if (streq(key, "blink")) else if (streq(key, "blink"))
return value_to_bool(ctx, &conf->cursor.blink); return value_to_bool(ctx, &conf->cursor.blink.enabled);
else if (streq(key, "blink-rate"))
return value_to_uint32(ctx, 10, &conf->cursor.blink.rate_ms);
else if (streq(key, "color")) { else if (streq(key, "color")) {
if (!value_to_two_colors( if (!value_to_two_colors(
@ -3102,7 +3105,10 @@ config_load(struct config *conf, const char *conf_path,
.cursor = { .cursor = {
.style = CURSOR_BLOCK, .style = CURSOR_BLOCK,
.unfocused_style = CURSOR_UNFOCUSED_HOLLOW, .unfocused_style = CURSOR_UNFOCUSED_HOLLOW,
.blink = false, .blink = {
.enabled = false,
.rate_ms = 500,
},
.color = { .color = {
.text = 0, .text = 0,
.cursor = 0, .cursor = 0,

View file

@ -262,7 +262,10 @@ struct config {
struct { struct {
enum cursor_style style; enum cursor_style style;
enum cursor_unfocused_style unfocused_style; enum cursor_unfocused_style unfocused_style;
bool blink; struct {
bool enabled;
uint32_t rate_ms;
} blink;
struct { struct {
uint32_t text; uint32_t text;
uint32_t cursor; uint32_t cursor;

2
csi.c
View file

@ -1665,7 +1665,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
switch (param) { switch (param) {
case 0: /* blinking block, but we use it to reset to configured default */ case 0: /* blinking block, but we use it to reset to configured default */
term->cursor_style = term->conf->cursor.style; term->cursor_style = term->conf->cursor.style;
term->cursor_blink.deccsusr = term->conf->cursor.blink; term->cursor_blink.deccsusr = term->conf->cursor.blink.enabled;
term_cursor_blink_update(term); term_cursor_blink_update(term);
break; break;

View file

@ -511,7 +511,12 @@ applications can change these at runtime.
*blink* *blink*
Boolean. Enables blinking cursor. Note that this can be overridden Boolean. Enables blinking cursor. Note that this can be overridden
by applications. Default: _no_. by applications. Related option: *blink-rate*. Default: _no_.
*blink-rate*
The rate at which the cursor blink, when cursor blinking has been
enabled. Expressed in milliseconds between each blink. Default:
_500_.
*color* *color*
Two space separated RRGGBB values (i.e. plain old 6-digit hex Two space separated RRGGBB values (i.e. plain old 6-digit hex

View file

@ -1229,7 +1229,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
.cursor_style = conf->cursor.style, .cursor_style = conf->cursor.style,
.cursor_blink = { .cursor_blink = {
.decset = false, .decset = false,
.deccsusr = conf->cursor.blink, .deccsusr = conf->cursor.blink.enabled,
.state = CURSOR_BLINK_ON, .state = CURSOR_BLINK_ON,
.fd = -1, .fd = -1,
}, },
@ -2046,7 +2046,7 @@ term_reset(struct terminal *term, bool hard)
term->alt.saved_cursor = (struct cursor){.point = {0, 0}}; term->alt.saved_cursor = (struct cursor){.point = {0, 0}};
term->cursor_style = term->conf->cursor.style; term->cursor_style = term->conf->cursor.style;
term->cursor_blink.decset = false; term->cursor_blink.decset = false;
term->cursor_blink.deccsusr = term->conf->cursor.blink; term->cursor_blink.deccsusr = term->conf->cursor.blink.enabled;
term_cursor_blink_update(term); term_cursor_blink_update(term);
term->cursor_color.text = term->conf->cursor.color.text; term->cursor_color.text = term->conf->cursor.color.text;
term->cursor_color.cursor = term->conf->cursor.color.cursor; term->cursor_color.cursor = term->conf->cursor.color.cursor;
@ -2746,9 +2746,13 @@ cursor_blink_rearm_timer(struct terminal *term)
term->cursor_blink.fd = fd; term->cursor_blink.fd = fd;
} }
static const struct itimerspec timer = { const int rate_ms = term->conf->cursor.blink.rate_ms;
.it_value = {.tv_sec = 0, .tv_nsec = 500000000}, const long secs = rate_ms / 1000;
.it_interval = {.tv_sec = 0, .tv_nsec = 500000000}, const long nsecs = (rate_ms % 1000) * 1000000;
const struct itimerspec timer = {
.it_value = {.tv_sec = secs, .tv_nsec = nsecs},
.it_interval = {.tv_sec = secs, .tv_nsec = nsecs},
}; };
if (timerfd_settime(term->cursor_blink.fd, 0, &timer, NULL) < 0) { if (timerfd_settime(term->cursor_blink.fd, 0, &timer, NULL) < 0) {

View file

@ -641,7 +641,8 @@ test_section_cursor(void)
(const char *[]){"unchanged", "hollow", "none"}, (const char *[]){"unchanged", "hollow", "none"},
(int []){CURSOR_UNFOCUSED_UNCHANGED, CURSOR_UNFOCUSED_HOLLOW, CURSOR_UNFOCUSED_NONE}, (int []){CURSOR_UNFOCUSED_UNCHANGED, CURSOR_UNFOCUSED_HOLLOW, CURSOR_UNFOCUSED_NONE},
(int *)&conf.cursor.unfocused_style); (int *)&conf.cursor.unfocused_style);
test_boolean(&ctx, &parse_section_cursor, "blink", &conf.cursor.blink); test_boolean(&ctx, &parse_section_cursor, "blink", &conf.cursor.blink.enabled);
test_uint32(&ctx, &parse_section_cursor, "blink-rate", &conf.cursor.blink.rate_ms);
test_pt_or_px(&ctx, &parse_section_cursor, "beam-thickness", test_pt_or_px(&ctx, &parse_section_cursor, "beam-thickness",
&conf.cursor.beam_thickness); &conf.cursor.beam_thickness);
test_pt_or_px(&ctx, &parse_section_cursor, "underline-thickness", test_pt_or_px(&ctx, &parse_section_cursor, "underline-thickness",