diff --git a/config.c b/config.c index dacd2b28..d4aa60d4 100644 --- a/config.c +++ b/config.c @@ -584,6 +584,51 @@ parse_section_mouse_bindings( return false; } +static bool +parse_section_tweak( + const char *key, const char *value, struct config *conf, + const char *path, unsigned lineno) +{ + if (strcmp(key, "delayed-render-lower") == 0) { + unsigned long ns; + if (!str_to_ulong(value, 10, &ns)) { + LOG_ERR("%s:%d: expected an integer: %s", path, lineno, value); + return false; + } + + if (ns > 16666666) { + LOG_ERR("%s:%d: timeout must not exceed 16ms", path, lineno); + return false; + } + + conf->tweak.delayed_render_lower_ns = ns; + LOG_WARN("tweak: delayed-render-lower=%lu", ns); + } + + else if (strcmp(key, "delayed-render-upper") == 0) { + unsigned long ns; + if (!str_to_ulong(value, 10, &ns)) { + LOG_ERR("%s:%d: expected an integer: %s", path, lineno, value); + return false; + } + + if (ns > 16666666) { + LOG_ERR("%s:%d: timeout must not exceed 16ms", path, lineno); + return false; + } + + conf->tweak.delayed_render_upper_ns = ns; + LOG_WARN("tweak: delayed-render-upper=%lu", ns); + } + + else { + LOG_ERR("%s:%u: invalid key: %s", path, lineno, key); + return false; + } + + return true; +} + static bool parse_config_file(FILE *f, struct config *conf, const char *path) { @@ -594,6 +639,7 @@ parse_config_file(FILE *f, struct config *conf, const char *path) SECTION_CSD, SECTION_KEY_BINDINGS, SECTION_MOUSE_BINDINGS, + SECTION_TWEAK, SECTION_COUNT, } section = SECTION_MAIN; @@ -612,6 +658,7 @@ parse_config_file(FILE *f, struct config *conf, const char *path) [SECTION_CSD] = {&parse_section_csd, "csd"}, [SECTION_KEY_BINDINGS] = {&parse_section_key_bindings, "key-bindings"}, [SECTION_MOUSE_BINDINGS] = {&parse_section_mouse_bindings, "mouse-bindings"}, + [SECTION_TWEAK] = {&parse_section_tweak, "tweak"}, }; static_assert(ALEN(section_info) == SECTION_COUNT, "section info array size mismatch"); @@ -823,6 +870,11 @@ config_load(struct config *conf, const char *conf_path) .server_socket_path = get_server_socket_path(), .presentation_timings = false, .hold_at_exit = false, + + .tweak = { + .delayed_render_lower_ns = 500000, /* 0.5ms */ + .delayed_render_upper_ns = 16666666 / 2, /* half a frame period (60Hz) */ + }, }; char *default_path = NULL; diff --git a/config.h b/config.h index bf205305..5d6ec0f0 100644 --- a/config.h +++ b/config.h @@ -73,6 +73,11 @@ struct config { char *server_socket_path; bool presentation_timings; bool hold_at_exit; + + struct { + uint64_t delayed_render_lower_ns; + uint64_t delayed_render_upper_ns; + } tweak; }; bool config_load(struct config *conf, const char *path); diff --git a/terminal.c b/terminal.c index 244ef83d..b39bb8d9 100644 --- a/terminal.c +++ b/terminal.c @@ -145,11 +145,6 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data) return false; } -#if 0 - if (!pollin) - return true; -#endif - /* Prevent blinking while typing */ term_cursor_blink_restart(term); @@ -220,9 +215,15 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data) last = now; #endif + uint64_t lower_ns = term->conf->tweak.delayed_render_lower_ns; + uint64_t upper_ns = term->conf->tweak.delayed_render_upper_ns; + assert(lower_ns < 1000000000); + assert(upper_ns < 1000000000); + assert(upper_ns > lower_ns); + timerfd_settime( term->delayed_render_timer.lower_fd, 0, - &(struct itimerspec){.it_value = {.tv_nsec = 500000}}, + &(struct itimerspec){.it_value = {.tv_nsec = lower_ns}}, NULL); /* Second timeout - only reset when we render. Set to one @@ -230,7 +231,7 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data) if (!term->delayed_render_timer.is_armed) { timerfd_settime( term->delayed_render_timer.upper_fd, 0, - &(struct itimerspec){.it_value = {.tv_nsec = 16666666 / 2}}, + &(struct itimerspec){.it_value = {.tv_nsec = upper_ns}}, NULL); term->delayed_render_timer.is_armed = true; }