From 77186d16e8f1cf0e1035cbc34a5436c7a5533cf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 10 Jan 2021 15:17:19 +0100 Subject: [PATCH 01/15] =?UTF-8?q?wayland:=20pack=20booleans=20in=20the=20?= =?UTF-8?q?=E2=80=9Cpending=E2=80=9D=20configure=20struct?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wayland.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/wayland.h b/wayland.h index 5ebc8a7e..cd8320c3 100644 --- a/wayland.h +++ b/wayland.h @@ -378,15 +378,15 @@ struct wl_window { bool is_tiled_right; bool is_tiled; /* At least one of is_tiled_{top,bottom,left,right} is true */ struct { - bool is_activated; - bool is_fullscreen; - bool is_maximized; - bool is_tiled_top; - bool is_tiled_bottom; - bool is_tiled_left; - bool is_tiled_right; int width; int height; + uint8_t is_activated:1; + uint8_t is_fullscreen:1; + uint8_t is_maximized:1; + uint8_t is_tiled_top:1; + uint8_t is_tiled_bottom:1; + uint8_t is_tiled_left:1; + uint8_t is_tiled_right:1; } configure; }; From 4ebd58e38888939d221d5616debc2e72dcfb4516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 10 Jan 2021 15:40:11 +0100 Subject: [PATCH 02/15] wayland: track is-resizing state --- wayland.c | 9 ++++----- wayland.h | 2 ++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/wayland.c b/wayland.c index 7985a90c..cc648244 100644 --- a/wayland.c +++ b/wayland.c @@ -535,6 +535,7 @@ xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, bool is_activated = false; bool is_fullscreen = false; bool is_maximized = false; + bool is_resizing = false; bool is_tiled_top = false; bool is_tiled_bottom = false; bool is_tiled_left = false; @@ -566,11 +567,7 @@ xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, case XDG_TOPLEVEL_STATE_TILED_RIGHT: is_tiled_right = true; break; case XDG_TOPLEVEL_STATE_TILED_TOP: is_tiled_top = true; break; case XDG_TOPLEVEL_STATE_TILED_BOTTOM: is_tiled_bottom = true; break; - - case XDG_TOPLEVEL_STATE_RESIZING: - /* Ignored */ - /* TODO: throttle? */ - break; + case XDG_TOPLEVEL_STATE_RESIZING: is_resizing = true; break; } #if defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG @@ -614,6 +611,7 @@ xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, win->configure.is_activated = is_activated; win->configure.is_fullscreen = is_fullscreen; win->configure.is_maximized = is_maximized; + win->configure.is_resizing = is_resizing; win->configure.is_tiled_top = is_tiled_top; win->configure.is_tiled_bottom = is_tiled_bottom; win->configure.is_tiled_left = is_tiled_left; @@ -648,6 +646,7 @@ xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, bool wasnt_configured = !win->is_configured; win->is_configured = true; win->is_maximized = win->configure.is_maximized; + win->is_resizing = win->configure.is_resizing; win->is_tiled_top = win->configure.is_tiled_top; win->is_tiled_bottom = win->configure.is_tiled_bottom; win->is_tiled_left = win->configure.is_tiled_left; diff --git a/wayland.h b/wayland.h index cd8320c3..8546d856 100644 --- a/wayland.h +++ b/wayland.h @@ -372,6 +372,7 @@ struct wl_window { bool is_configured; bool is_fullscreen; bool is_maximized; + bool is_resizing; bool is_tiled_top; bool is_tiled_bottom; bool is_tiled_left; @@ -383,6 +384,7 @@ struct wl_window { uint8_t is_activated:1; uint8_t is_fullscreen:1; uint8_t is_maximized:1; + uint8_t is_resizing:1; uint8_t is_tiled_top:1; uint8_t is_tiled_bottom:1; uint8_t is_tiled_left:1; From 3948145d66892d7055f47ace9ed6474344b5c119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 10 Jan 2021 15:40:33 +0100 Subject: [PATCH 03/15] =?UTF-8?q?render:=20don=E2=80=99t=20center=20conten?= =?UTF-8?q?t=20while=20we=E2=80=99re=20being=20resized?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Doing so causes the content to jump around while interactively resizing the window. --- render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/render.c b/render.c index e45140e5..8ad5ee0c 100644 --- a/render.c +++ b/render.c @@ -2671,7 +2671,7 @@ maybe_resize(struct terminal *term, int width, int height, bool force) const int total_x_pad = term->width - grid_width; const int total_y_pad = term->height - grid_height; - if (term->conf->center) { + if (term->conf->center && !term->window->is_resizing) { term->margins.left = total_x_pad / 2; term->margins.top = total_y_pad / 2; } else { From 773b61eb79fec9966d5ccd01dccf35b02ff7a7b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 10 Jan 2021 15:41:01 +0100 Subject: [PATCH 04/15] wayland: force a resize on the final configure event after an interactive resize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is needed to apply content centering after an interactive resize, as otherwise we’d just ignore the last configure event since the only difference between that event and the next to last event is that the is-resizing bit has been cleared. I.e. the window size is identical to what we already have, and our resize code would thus ignore the event. --- wayland.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/wayland.c b/wayland.c index cc648244..4e8a8ca8 100644 --- a/wayland.c +++ b/wayland.c @@ -644,6 +644,8 @@ xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, struct terminal *term = win->term; bool wasnt_configured = !win->is_configured; + bool was_resizing = win->is_resizing; + win->is_configured = true; win->is_maximized = win->configure.is_maximized; win->is_resizing = win->configure.is_resizing; @@ -675,8 +677,9 @@ xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, term->window->frame_callback = NULL; } - bool resized = render_resize( - term, win->configure.width, win->configure.height); + bool resized = was_resizing && !win->is_resizing + ? render_resize_force(term, win->configure.width, win->configure.height) + : render_resize(term, win->configure.width, win->configure.height); if (win->configure.is_activated) term_visual_focus_in(term); From 6876ab6bc21fab00ba8b6d97e26bcb2ed567bd18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 11 Jan 2021 18:45:12 +0100 Subject: [PATCH 05/15] =?UTF-8?q?wayland:=20pending=20=E2=80=98configure?= =?UTF-8?q?=E2=80=99=20flags:=20use=20=E2=80=99bool=E2=80=99=20in=20bit-fi?= =?UTF-8?q?elds?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wayland.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/wayland.h b/wayland.h index 8546d856..d77e776b 100644 --- a/wayland.h +++ b/wayland.h @@ -381,14 +381,14 @@ struct wl_window { struct { int width; int height; - uint8_t is_activated:1; - uint8_t is_fullscreen:1; - uint8_t is_maximized:1; - uint8_t is_resizing:1; - uint8_t is_tiled_top:1; - uint8_t is_tiled_bottom:1; - uint8_t is_tiled_left:1; - uint8_t is_tiled_right:1; + bool is_activated:1; + bool is_fullscreen:1; + bool is_maximized:1; + bool is_resizing:1; + bool is_tiled_top:1; + bool is_tiled_bottom:1; + bool is_tiled_left:1; + bool is_tiled_right:1; } configure; }; From 9a1df7bb036cffbef206a3f2dbe46559b6f15d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 17 Jan 2021 16:12:54 +0100 Subject: [PATCH 06/15] render: delay TIOCSWINSZ while doing an interactive resize Instead of disabling content centering, delay the TIOCSWINSZ (a.k.a delay sending the new dimensions to the client) by a small amount while doing an interactive resize. Non-interactive resizes are still immediate. For now, force a resize when the user stops the interactive resize. This ensures the client application receives the new dimensions immediately. It still works without the last, forced, resize, but there typically be a small delay until the client application receives the final dimensions. Closes #301 Closes #283 --- config.c | 14 ++++++++ config.h | 1 + render.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++------- wayland.c | 17 +++++++++ wayland.h | 2 ++ 5 files changed, 126 insertions(+), 12 deletions(-) diff --git a/config.c b/config.c index 81b329cf..7c6b6148 100644 --- a/config.c +++ b/config.c @@ -1745,6 +1745,19 @@ parse_section_tweak( conf->tweak.box_drawing_base_thickness); } + else if (strcmp(key, "resize-delay-ms") == 0) { + unsigned long ms; + if (!str_to_ulong(value, 10, &ms)) { + LOG_AND_NOTIFY_ERR( + "%s:%d: [tweak]: resize-delay-ms: expected an integer, got '%s'", + path, lineno, value); + return false; + } + + conf->tweak.resize_delay_ms = ms; + LOG_WARN("tweak: resize-delay-ms=%hu", conf->tweak.resize_delay_ms); + } + else { LOG_AND_NOTIFY_ERR("%s:%u: [tweak]: %s: invalid key", path, lineno, key); return false; @@ -2166,6 +2179,7 @@ config_load(struct config *conf, const char *conf_path, .render_timer_log = false, .damage_whole_window = false, .box_drawing_base_thickness = 0.04, + .resize_delay_ms = 100, }, .notifications = tll_init(), diff --git a/config.h b/config.h index 1c349f2a..6dadb1a4 100644 --- a/config.h +++ b/config.h @@ -203,6 +203,7 @@ struct config { uint64_t delayed_render_upper_ns; off_t max_shm_pool_size; float box_drawing_base_thickness; + uint16_t resize_delay_ms; } tweak; user_notifications_t notifications; diff --git a/render.c b/render.c index 8ad5ee0c..04986426 100644 --- a/render.c +++ b/render.c @@ -1,10 +1,12 @@ #include "render.h" #include +#include #include #include #include +#include #include #if __has_include() #include @@ -2545,6 +2547,92 @@ frame_callback(void *data, struct wl_callback *wl_callback, uint32_t callback_da grid_render(term); } +static void +tiocswinsz(struct terminal *term) +{ + if (term->ptmx >= 0) { + if (ioctl(term->ptmx, (unsigned int)TIOCSWINSZ, + &(struct winsize){ + .ws_row = term->rows, + .ws_col = term->cols, + .ws_xpixel = term->cols * term->cell_width, + .ws_ypixel = term->rows * term->cell_height}) < 0) + { + LOG_ERRNO("TIOCSWINSZ"); + } + } +} + +static bool +fdm_tiocswinsz(struct fdm *fdm, int fd, int events, void *data) +{ + struct terminal *term = data; + + if (events & EPOLLIN) { + tiocswinsz(term); + LOG_WARN("DELAYED"); + } + + fdm_del(fdm, fd); + term->window->resize_timeout_fd = -1; + return true; +} + +static void +send_dimensions_to_client(struct terminal *term) +{ + struct wl_window *win = term->window; + + if (!win->is_resizing || term->conf->tweak.resize_delay_ms == 0) { + /* Send new dimensions to client immediately */ + tiocswinsz(term); + LOG_ERR("IMMEDIATELY"); + + /* And make sure to reset and deallocate a lingering timer */ + if (win->resize_timeout_fd >= 0) { + fdm_del(term->fdm, win->resize_timeout_fd); + win->resize_timeout_fd = -1; + } + } else { + /* Send new dimensions to client “in a while” */ + assert(win->is_resizing && term->conf->tweak.resize_delay_ms > 0); + + int fd = win->resize_timeout_fd; + uint16_t delay_ms = term->conf->tweak.resize_delay_ms; + bool successfully_scheduled = false; + + if (fd < 0) { + /* Lazy create timer fd */ + fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); + if (fd < 0) + LOG_ERRNO("failed to create TIOCSWINSZ timer"); + else if (!fdm_add(term->fdm, fd, EPOLLIN, &fdm_tiocswinsz, term)) { + close(fd); + fd = -1; + } + + win->resize_timeout_fd = fd; + } + + if (fd >= 0) { + /* Reset tiemout */ + const struct itimerspec timeout = { + .it_value = {.tv_sec = 0, .tv_nsec = delay_ms * 1000000}, + }; + + if (timerfd_settime(fd, 0, &timeout, NULL) < 0) { + LOG_ERRNO("failed to arm TIOCSWINSZ timer"); + fdm_del(term->fdm, fd); + win->resize_timeout_fd = -1; + } else + successfully_scheduled = true; + } + + if (!successfully_scheduled) + tiocswinsz(term); + } +} + /* Move to terminal.c? */ static bool maybe_resize(struct terminal *term, int width, int height, bool force) @@ -2671,7 +2759,7 @@ maybe_resize(struct terminal *term, int width, int height, bool force) const int total_x_pad = term->width - grid_width; const int total_y_pad = term->height - grid_height; - if (term->conf->center && !term->window->is_resizing) { + if (term->conf->center) { term->margins.left = total_x_pad / 2; term->margins.top = total_y_pad / 2; } else { @@ -2723,17 +2811,6 @@ maybe_resize(struct terminal *term, int width, int height, bool force) term->width, term->height, term->cols, term->rows, term->margins.left, term->margins.right, term->margins.top, term->margins.bottom); - /* Signal TIOCSWINSZ */ - if (term->ptmx >= 0 && ioctl(term->ptmx, (unsigned int)TIOCSWINSZ, - &(struct winsize){ - .ws_row = term->rows, - .ws_col = term->cols, - .ws_xpixel = term->cols * term->cell_width, - .ws_ypixel = term->rows * term->cell_height}) == -1) - { - LOG_ERRNO("TIOCSWINSZ"); - } - if (term->scroll_region.start >= term->rows) term->scroll_region.start = 0; @@ -2743,6 +2820,9 @@ maybe_resize(struct terminal *term, int width, int height, bool force) term->render.last_cursor.row = NULL; damage_view: + /* Signal TIOCSWINSZ */ + send_dimensions_to_client(term); + if (!term->window->is_maximized && !term->window->is_fullscreen && !term->window->is_tiled) diff --git a/wayland.c b/wayland.c index 4e8a8ca8..ec113552 100644 --- a/wayland.c +++ b/wayland.c @@ -677,9 +677,22 @@ xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, term->window->frame_callback = NULL; } +#if 1 + /* + * TODO: decide if we should to the last “forced” call when ending + * an interactive resize. + * + * Without it, the last TIOCSWINSZ sent to the client will be a + * scheduled one. I.e. there will be a small delay after the user + * has *stopped* resizing, and the client application receives the + * final size. + */ bool resized = was_resizing && !win->is_resizing ? render_resize_force(term, win->configure.width, win->configure.height) : render_resize(term, win->configure.width, win->configure.height); +#else + bool resized = render_resize(term, win->configure.width, win->configure.height); +#endif if (win->configure.is_activated) term_visual_focus_in(term); @@ -1278,6 +1291,7 @@ wayl_win_init(struct terminal *term) win->term = term; win->use_csd = CSD_UNKNOWN; win->csd.move_timeout_fd = -1; + win->resize_timeout_fd = -1; win->surface = wl_compositor_create_surface(wayl->compositor); if (win->surface == NULL) { @@ -1430,6 +1444,9 @@ wayl_win_destroy(struct wl_window *win) wl_surface_destroy(win->surface); wayl_roundtrip(win->term->wl); + + if (win->resize_timeout_fd >= 0) + fdm_del(win->term->wl->fdm, win->resize_timeout_fd); free(win); } diff --git a/wayland.h b/wayland.h index d77e776b..b849249e 100644 --- a/wayland.h +++ b/wayland.h @@ -390,6 +390,8 @@ struct wl_window { bool is_tiled_left:1; bool is_tiled_right:1; } configure; + + int resize_timeout_fd; }; struct config; From c82cb8bcc7ca78b90afc28d19fe60a5d29344d13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 17 Jan 2021 16:38:24 +0100 Subject: [PATCH 07/15] render: codespell: tiemout -> timeout --- render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/render.c b/render.c index 04986426..1cd8d364 100644 --- a/render.c +++ b/render.c @@ -2615,7 +2615,7 @@ send_dimensions_to_client(struct terminal *term) } if (fd >= 0) { - /* Reset tiemout */ + /* Reset timeout */ const struct itimerspec timeout = { .it_value = {.tv_sec = 0, .tv_nsec = delay_ms * 1000000}, }; From 2dc774fb17fa558fe9faf1a23cb186b2940f42f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 17 Jan 2021 16:41:22 +0100 Subject: [PATCH 08/15] render: remove debug logging --- render.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/render.c b/render.c index 1cd8d364..254057dc 100644 --- a/render.c +++ b/render.c @@ -2568,10 +2568,8 @@ fdm_tiocswinsz(struct fdm *fdm, int fd, int events, void *data) { struct terminal *term = data; - if (events & EPOLLIN) { + if (events & EPOLLIN) tiocswinsz(term); - LOG_WARN("DELAYED"); - } fdm_del(fdm, fd); term->window->resize_timeout_fd = -1; @@ -2586,7 +2584,6 @@ send_dimensions_to_client(struct terminal *term) if (!win->is_resizing || term->conf->tweak.resize_delay_ms == 0) { /* Send new dimensions to client immediately */ tiocswinsz(term); - LOG_ERR("IMMEDIATELY"); /* And make sure to reset and deallocate a lingering timer */ if (win->resize_timeout_fd >= 0) { From b4f1f72585df8fbc583b9cb7f168a971cffc5e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 18 Jan 2021 09:50:23 +0100 Subject: [PATCH 09/15] =?UTF-8?q?render:=20don=E2=80=99t=20center=20conten?= =?UTF-8?q?t=20while=20doing=20an=20interactive=20resize?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- render.c | 2 +- wayland.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/render.c b/render.c index 254057dc..1f79ad98 100644 --- a/render.c +++ b/render.c @@ -2756,7 +2756,7 @@ maybe_resize(struct terminal *term, int width, int height, bool force) const int total_x_pad = term->width - grid_width; const int total_y_pad = term->height - grid_height; - if (term->conf->center) { + if (term->conf->center && (!term->window->is_resizing)) { term->margins.left = total_x_pad / 2; term->margins.top = total_y_pad / 2; } else { diff --git a/wayland.c b/wayland.c index ec113552..d3c560b7 100644 --- a/wayland.c +++ b/wayland.c @@ -686,6 +686,9 @@ xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, * scheduled one. I.e. there will be a small delay after the user * has *stopped* resizing, and the client application receives the * final size. + * + * Note: if we also disable content centering while resizing, then + * the last, forced, resize *is* necessary. */ bool resized = was_resizing && !win->is_resizing ? render_resize_force(term, win->configure.width, win->configure.height) From a2b3ab6d9e6c63891efb3f21ca8a964dfd404fd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 18 Jan 2021 09:52:11 +0100 Subject: [PATCH 10/15] render: remove unneeded parantheses --- render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/render.c b/render.c index 1f79ad98..18d1beff 100644 --- a/render.c +++ b/render.c @@ -2756,7 +2756,7 @@ maybe_resize(struct terminal *term, int width, int height, bool force) const int total_x_pad = term->width - grid_width; const int total_y_pad = term->height - grid_height; - if (term->conf->center && (!term->window->is_resizing)) { + if (term->conf->center && !term->window->is_resizing) { term->margins.left = total_x_pad / 2; term->margins.top = total_y_pad / 2; } else { From af0fbdfd07b5e482bbdefd547733da3140b9c8f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 20 Jan 2021 18:10:24 +0100 Subject: [PATCH 11/15] changelog: tiocswinsz is now delayed by 100ms while doing an interactive resize --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd01e737..519133fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,11 @@ * The scrollback search box no longer accepts non-printable characters. * Non-formatting C0 control characters, `BS`, `HT` and `DEL` are now stripped from pasted text. +* While doing an interactive resize of a foot window, foot now + requires 100ms of idle time (where the window size does not change) + before sending the new dimensions to the client application. The + timing can be tweaked, or completely disabled, by setting + `tweak.resize-delay-ms` (https://codeberg.org/dnkl/foot/issues/301). ### Deprecated From 22a659881bbc61337e1476e8fe76d70a36095c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 20 Jan 2021 18:15:39 +0100 Subject: [PATCH 12/15] doc: foot.ini: resize-delay-ms --- doc/foot.ini.5.scd | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index 180ac7c2..aa5571df 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -677,6 +677,23 @@ any of these options. larger font (and thus larger cells) result in thicker lines. Default: _0.04_. +*resize-delay-ms* + + Time, in milliseconds, of "idle time" "before foot sends the new + window dimensions to the client application while doing an + interactive resize of a foot window. Idle time in this context is + a period of time where the window size is not changing. + + In other words, while you fiddle with window size, foot does not + send the updated dimensions to the client. Only when you pause the + fiddling for *relay-size-ms* milliseconds is the client updated. + + Emphasis is on _while_ here; as soon as the interactive resize + ends (i.e. when you let go of the window border), the final + dimensions is sent to the client, without any delays. + + Default: _100_. + *delayed-render-lower*, *delayed-render-upper* These two values control the timeouts (in nanoseconds) that are used to mitigate screen flicker caused by clients writing large, From d1a0892131c4ce3a6b259bb0b2b6597bc5da5e97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 20 Jan 2021 18:27:34 +0100 Subject: [PATCH 13/15] doc: foot.ini: explicitly say that 0 disables the delay --- doc/foot.ini.5.scd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index aa5571df..e1bf7622 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -678,7 +678,6 @@ any of these options. lines. Default: _0.04_. *resize-delay-ms* - Time, in milliseconds, of "idle time" "before foot sends the new window dimensions to the client application while doing an interactive resize of a foot window. Idle time in this context is @@ -692,6 +691,8 @@ any of these options. ends (i.e. when you let go of the window border), the final dimensions is sent to the client, without any delays. + Setting it to 0 disables the delay completely. + Default: _100_. *delayed-render-lower*, *delayed-render-upper* From 7cba42c5cea7b2872b1b304d5e4c180d1f8d7803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 20 Jan 2021 18:36:04 +0100 Subject: [PATCH 14/15] doc: foot.ini: resize-delay-ms: language tweaks --- doc/foot.ini.5.scd | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index e1bf7622..876b0211 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -683,9 +683,10 @@ any of these options. interactive resize of a foot window. Idle time in this context is a period of time where the window size is not changing. - In other words, while you fiddle with window size, foot does not - send the updated dimensions to the client. Only when you pause the - fiddling for *relay-size-ms* milliseconds is the client updated. + In other words, while you are fiddling with the window size, foot + does not send the updated dimensions to the client. Only when you + pause the fiddling for *relay-size-ms* milliseconds is the client + updated. Emphasis is on _while_ here; as soon as the interactive resize ends (i.e. when you let go of the window border), the final From 3a7588bc99a3bdc02302666c52439c73b08f1d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 21 Jan 2021 15:14:43 +0100 Subject: [PATCH 15/15] config: promote tweak.resize-delay-ms to a real, supported option --- CHANGELOG.md | 2 +- config.c | 28 ++++++++++++++-------------- config.h | 2 +- doc/foot.ini.5.scd | 38 +++++++++++++++++++------------------- foot.ini | 1 + render.c | 6 +++--- 6 files changed, 39 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 519133fa..9c517f3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,7 +67,7 @@ requires 100ms of idle time (where the window size does not change) before sending the new dimensions to the client application. The timing can be tweaked, or completely disabled, by setting - `tweak.resize-delay-ms` (https://codeberg.org/dnkl/foot/issues/301). + `resize-delay-ms` (https://codeberg.org/dnkl/foot/issues/301). ### Deprecated diff --git a/config.c b/config.c index 7c6b6148..e2d9e2cb 100644 --- a/config.c +++ b/config.c @@ -523,6 +523,19 @@ parse_section_main(const char *key, const char *value, struct config *conf, conf->center = center; } + else if (strcmp(key, "resize-delay-ms") == 0) { + unsigned long ms; + if (!str_to_ulong(value, 10, &ms)) { + LOG_AND_NOTIFY_ERR( + "%s:%d: [default]: resize-delay-ms: " + "expected an integer, got '%s'", + path, lineno, value); + return false; + } + + conf->resize_delay_ms = ms; + } + else if (strcmp(key, "bold-text-in-bright") == 0) conf->bold_in_bright = str_to_bool(value); @@ -1745,19 +1758,6 @@ parse_section_tweak( conf->tweak.box_drawing_base_thickness); } - else if (strcmp(key, "resize-delay-ms") == 0) { - unsigned long ms; - if (!str_to_ulong(value, 10, &ms)) { - LOG_AND_NOTIFY_ERR( - "%s:%d: [tweak]: resize-delay-ms: expected an integer, got '%s'", - path, lineno, value); - return false; - } - - conf->tweak.resize_delay_ms = ms; - LOG_WARN("tweak: resize-delay-ms=%hu", conf->tweak.resize_delay_ms); - } - else { LOG_AND_NOTIFY_ERR("%s:%u: [tweak]: %s: invalid key", path, lineno, key); return false; @@ -2093,6 +2093,7 @@ config_load(struct config *conf, const char *conf_path, }, .pad_x = 2, .pad_y = 2, + .resize_delay_ms = 100, .bold_in_bright = false, .bell_action = BELL_ACTION_NONE, .startup_mode = STARTUP_WINDOWED, @@ -2179,7 +2180,6 @@ config_load(struct config *conf, const char *conf_path, .render_timer_log = false, .damage_whole_window = false, .box_drawing_base_thickness = 0.04, - .resize_delay_ms = 100, }, .notifications = tll_init(), diff --git a/config.h b/config.h index 6dadb1a4..56273053 100644 --- a/config.h +++ b/config.h @@ -77,6 +77,7 @@ struct config { unsigned pad_x; unsigned pad_y; bool center; + uint16_t resize_delay_ms; bool bold_in_bright; enum { @@ -203,7 +204,6 @@ struct config { uint64_t delayed_render_upper_ns; off_t max_shm_pool_size; float box_drawing_base_thickness; - uint16_t resize_delay_ms; } tweak; user_notifications_t notifications; diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index 876b0211..8684850b 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -131,6 +131,25 @@ in this order: Default: _2x2_. +*resize-delay-ms* + Time, in milliseconds, of "idle time" "before foot sends the new + window dimensions to the client application while doing an + interactive resize of a foot window. Idle time in this context is + a period of time where the window size is not changing. + + In other words, while you are fiddling with the window size, foot + does not send the updated dimensions to the client. Only when you + pause the fiddling for *relay-size-ms* milliseconds is the client + updated. + + Emphasis is on _while_ here; as soon as the interactive resize + ends (i.e. when you let go of the window border), the final + dimensions is sent to the client, without any delays. + + Setting it to 0 disables the delay completely. + + Default: _100_. + *initial-window-size-pixels* Initial window width and height in _pixels_ (subject to output scaling), on the form _WIDTHxHEIGHT_. The height _includes_ the @@ -677,25 +696,6 @@ any of these options. larger font (and thus larger cells) result in thicker lines. Default: _0.04_. -*resize-delay-ms* - Time, in milliseconds, of "idle time" "before foot sends the new - window dimensions to the client application while doing an - interactive resize of a foot window. Idle time in this context is - a period of time where the window size is not changing. - - In other words, while you are fiddling with the window size, foot - does not send the updated dimensions to the client. Only when you - pause the fiddling for *relay-size-ms* milliseconds is the client - updated. - - Emphasis is on _while_ here; as soon as the interactive resize - ends (i.e. when you let go of the window border), the final - dimensions is sent to the client, without any delays. - - Setting it to 0 disables the delay completely. - - Default: _100_. - *delayed-render-lower*, *delayed-render-upper* These two values control the timeouts (in nanoseconds) that are used to mitigate screen flicker caused by clients writing large, diff --git a/foot.ini b/foot.ini index 19a82061..a9c0108f 100644 --- a/foot.ini +++ b/foot.ini @@ -18,6 +18,7 @@ # initial-window-size-chars= # initial-window-mode=windowed # pad=2x2 # optionally append 'center' +# resize-delay-ms=100 # bold-text-in-bright=no # bell=none diff --git a/render.c b/render.c index 18d1beff..6d7a54fa 100644 --- a/render.c +++ b/render.c @@ -2581,7 +2581,7 @@ send_dimensions_to_client(struct terminal *term) { struct wl_window *win = term->window; - if (!win->is_resizing || term->conf->tweak.resize_delay_ms == 0) { + if (!win->is_resizing || term->conf->resize_delay_ms == 0) { /* Send new dimensions to client immediately */ tiocswinsz(term); @@ -2592,10 +2592,10 @@ send_dimensions_to_client(struct terminal *term) } } else { /* Send new dimensions to client “in a while” */ - assert(win->is_resizing && term->conf->tweak.resize_delay_ms > 0); + assert(win->is_resizing && term->conf->resize_delay_ms > 0); int fd = win->resize_timeout_fd; - uint16_t delay_ms = term->conf->tweak.resize_delay_ms; + uint16_t delay_ms = term->conf->resize_delay_ms; bool successfully_scheduled = false; if (fd < 0) {