term: enabling application synchronized updates clear pending grid refresh

This fixes issues with de-synchronized frames being rendered; we may
have scheduled a redraw earlier, that hasn’t yet triggered (probably
because we’re waiting for a frame callback), when we enable
application synchronized updates.

This means we risk rendering a partially updated state when the frame
callback finally arrives, if the application hasn’t yet ended its
synchronized update.
This commit is contained in:
Daniel Eklöf 2020-12-14 19:05:03 +01:00
parent 602dbdb9f6
commit 6c8b034aff
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 15 additions and 10 deletions

View file

@ -131,6 +131,8 @@ means foot can be PGO:d in e.g. sandboxed build scripts. See
dragging the cursor outside the grid.
* Parsing of the sub-parameter versions of indexed SGR color escapes
(e.g. `\E[38:5...m`)
* Frames occasionally being rendered while application synchronized
updates is in effect.
### Security

View file

@ -224,8 +224,6 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data)
cursor_blink_rearm_timer(term);
}
term->render.app_sync_updates.flipped = false;
uint8_t buf[24 * 1024];
ssize_t count = sizeof(buf);
@ -246,9 +244,7 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data)
vt_from_slave(term, buf, count);
}
if (!term->render.app_sync_updates.enabled &&
!term->render.app_sync_updates.flipped)
{
if (!term->render.app_sync_updates.enabled) {
/*
* We likely need to re-render. But, we don't want to do it
* immediately. Often, a single client update is done through
@ -325,6 +321,7 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data)
} else
return term_shutdown(term);
}
return true;
}
@ -2546,9 +2543,6 @@ term_spawn_new(const struct terminal *term)
void
term_enable_app_sync_updates(struct terminal *term)
{
if (!term->render.app_sync_updates.enabled)
term->render.app_sync_updates.flipped = true;
term->render.app_sync_updates.enabled = true;
if (timerfd_settime(
@ -2558,6 +2552,17 @@ term_enable_app_sync_updates(struct terminal *term)
LOG_ERR("failed to arm timer for application synchronized updates");
}
/* Disable pending refresh *iff* the grid is the *only* thing
* scheduled to be re-rendered */
if (!term->render.refresh.csd && !term->render.refresh.search &&
!term->render.refresh.title &&
!term->render.pending.csd && !term->render.pending.search &&
!term->render.pending.title)
{
term->render.refresh.grid = false;
term->render.pending.grid = false;
}
/* Disarm delayed rendering timers */
timerfd_settime(
term->delayed_render_timer.lower_fd, 0,
@ -2575,7 +2580,6 @@ term_disable_app_sync_updates(struct terminal *term)
return;
term->render.app_sync_updates.enabled = false;
term->render.app_sync_updates.flipped = true;
render_refresh(term);
/* Reset timers */

View file

@ -410,7 +410,6 @@ struct terminal {
struct {
bool enabled;
int timer_fd;
bool flipped;
} app_sync_updates;
/* Render threads + synchronization primitives */