mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-07 04:06:07 -05:00
main: mitigate screen flashes on slow client
If a client writes to the PTY "too slow", we often end up flashing the screen. This could for example be caused by a client first erasing a line, then we render that frame, followed by the client updating the just-erased line. When we render _that_ frame, it will be perceived as a flash. Mitigate this by trying to read client data again, after finishing processing one batch, but before rendering. To avoid hanging on client output (and never rendering anything), limit this to at most 3 iterations. This may have to be tweaked.
This commit is contained in:
parent
a0602aedb5
commit
f87d4f856a
1 changed files with 25 additions and 8 deletions
33
main.c
33
main.c
|
|
@ -8,6 +8,7 @@
|
|||
#include <locale.h>
|
||||
#include <getopt.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
//#include <termios.h>
|
||||
|
|
@ -987,6 +988,20 @@ main(int argc, char *const *argv)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Read logic requires non-blocking mode */
|
||||
{
|
||||
int fd_flags = fcntl(c.term.ptmx, F_GETFL);
|
||||
if (fd_flags == -1) {
|
||||
LOG_ERRNO("failed to set non blocking mode on PTY master");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (fcntl(c.term.ptmx, F_SETFL, fd_flags | O_NONBLOCK) == -1) {
|
||||
LOG_ERRNO("failed to set non blocking mode on PTY master");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
struct pollfd fds[] = {
|
||||
{.fd = wl_display_get_fd(c.wl.display), .events = POLLIN},
|
||||
|
|
@ -1011,16 +1026,18 @@ main(int argc, char *const *argv)
|
|||
}
|
||||
|
||||
if (fds[1].revents & POLLIN) {
|
||||
uint8_t data[8192];
|
||||
ssize_t count = read(c.term.ptmx, data, sizeof(data));
|
||||
if (count < 0) {
|
||||
LOG_ERRNO("failed to read from pseudo terminal");
|
||||
break;
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
uint8_t data[8192];
|
||||
ssize_t count = read(c.term.ptmx, data, sizeof(data));
|
||||
if (count < 0) {
|
||||
if (errno != EAGAIN)
|
||||
LOG_ERRNO("failed to read from pseudo terminal");
|
||||
break;
|
||||
}
|
||||
|
||||
vt_from_slave(&c.term, data, count);
|
||||
}
|
||||
|
||||
//LOG_DBG("%.*s", (int)count, data);
|
||||
|
||||
vt_from_slave(&c.term, data, count);
|
||||
if (!c.frame_is_scheduled)
|
||||
grid_render(&c);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue