From 753aca3e5175d7732b05d31c11bf980314647dd7 Mon Sep 17 00:00:00 2001 From: TripleK2004 Date: Wed, 9 Jun 2021 20:24:21 +0530 Subject: [PATCH] patched appsync --- README.md | 3 ++- config.def.h | 6 ++++++ config.h | 10 ++++++++-- st.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- st.info | 1 + x.c | 22 +++++++++++++++++++--- 6 files changed, 83 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 8f938b920f5b296b9b0710547ec7cc89d19ccca6..7f795d8aff6a1b2cff686f9ff73461fe3ebd6aa4 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,8 @@ This is a custom suckless st build (credits to lukesmith's build for ligatures p - newterm - anysize - anygeometry -- xresources +- xresources +- sync patch ( Better draw timing to reduce flicker/tearing and improve animation smoothness ) - live reload ( change colors/fonts on the fly ) and more...
diff --git a/config.def.h b/config.def.h index a80ec0af204ddcbeebfff346f1c21a0613e6ae0c..e500bc5b147eede95721485e75c65d7a55ca1476 100644 --- a/config.def.h +++ b/config.def.h @@ -51,6 +51,12 @@ int allowaltscreen = 1; static double minlatency = 8; static double maxlatency = 33; +/* + * Synchronized-Update timeout in ms + * https://gitlab.com/gnachman/iterm2/-/wikis/synchronized-updates-spec + */ +static uint su_timeout = 200; + /* * blinking timeout (set to 0 to disable blinking) for the terminal blinking * attribute. diff --git a/config.h b/config.h index 373ae165600baccd719a26a7213014d314c87b28..e500bc5b147eede95721485e75c65d7a55ca1476 100644 --- a/config.h +++ b/config.h @@ -5,8 +5,8 @@ * * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html */ -static char *font = "JetBrainsMono Nerd Font:style:medium :pixelsize=15:antialias=true:autohint=true"; -static char *font2[] = { "JetBrainsMono Nerd Font:style:medium :pixelsize=15:antialias=true:autohint=true" }; +static char *font = "JetBrainsMono Nerd Font :pixelsize=15:antialias=true:autohint=true"; +static char *font2[] = { "JetBrainsMono Nerd Font :pixelsize=15:antialias=true:autohint=true" }; static int borderpx = 0; /* @@ -51,6 +51,12 @@ int allowaltscreen = 1; static double minlatency = 8; static double maxlatency = 33; +/* + * Synchronized-Update timeout in ms + * https://gitlab.com/gnachman/iterm2/-/wikis/synchronized-updates-spec + */ +static uint su_timeout = 200; + /* * blinking timeout (set to 0 to disable blinking) for the terminal blinking * attribute. diff --git a/st.c b/st.c index 1ef50784eb6ade9aa4c847ca2e6e36ae133668aa..9e05ce6507c12afdfa0e3b8a401f1a4871ea6e8f 100644 --- a/st.c +++ b/st.c @@ -247,6 +247,33 @@ static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; static Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; +#include +static int su = 0; +struct timespec sutv; + +static void +tsync_begin() +{ + clock_gettime(CLOCK_MONOTONIC, &sutv); + su = 1; +} + +static void +tsync_end() +{ + su = 0; +} + +int +tinsync(uint timeout) +{ + struct timespec now; + if (su && !clock_gettime(CLOCK_MONOTONIC, &now) + && TIMEDIFF(now, sutv) >= timeout) + su = 0; + return su; +} + ssize_t xwrite(int fd, const char *s, size_t len) { @@ -835,6 +862,9 @@ ttynew(char *line, char *cmd, char *out, char **args) return cmdfd; } +static int twrite_aborted = 0; +int ttyread_pending() { return twrite_aborted; } + size_t ttyread(void) { @@ -844,10 +874,10 @@ ttyread(void) int ret; /* append read bytes to unprocessed bytes */ - if ((ret = read(cmdfd, buf+buflen, LEN(buf)-buflen)) < 0) + if ((ret = twrite_aborted ? 1 : read(cmdfd, buf+buflen, LEN(buf)-buflen)) < 0) die("couldn't read from shell: %s\n", strerror(errno)); - buflen += ret; - + + buflen += twrite_aborted ? 0 : ret; written = twrite(buf, buflen, 0); buflen -= written; /* keep any uncomplete utf8 char for the next call */ @@ -1010,6 +1040,7 @@ tsetdirtattr(int attr) void tfulldirt(void) { + tsync_end(); tsetdirt(0, term.row-1); } @@ -2008,6 +2039,12 @@ strhandle(void) return; case 'P': /* DCS -- Device Control String */ term.mode |= ESC_DCS; + /* https://gitlab.com/gnachman/iterm2/-/wikis/synchronized-updates-spec */ + if (strstr(strescseq.buf, "=1s") == strescseq.buf) + tsync_begin(), term.mode &= ~ESC_DCS; /* BSU */ + else if (strstr(strescseq.buf, "=2s") == strescseq.buf) + tsync_end(), term.mode &= ~ESC_DCS; /* ESU */ + return; case '_': /* APC -- Application Program Command */ case '^': /* PM -- Privacy Message */ return; @@ -2633,6 +2670,9 @@ twrite(const char *buf, int buflen, int show_ctrl) Rune u; int n; + int su0 = su; + twrite_aborted = 0; + for (n = 0; n < buflen; n += charsize) { if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) { /* process a complete utf8 char */ @@ -2643,6 +2683,10 @@ twrite(const char *buf, int buflen, int show_ctrl) u = buf[n] & 0xFF; charsize = 1; } + if (su0 && !su) { + twrite_aborted = 1; + break; // ESU - allow rendering before a new BSU + } if (show_ctrl && ISCONTROL(u)) { if (u & 0x80) { u &= 0x7f; diff --git a/st.info b/st.info index 78ffd3035215cdcfc03db6457bbd04e76b261999..ff3e13de6e7a733cebcd88778b9d89127e17760f 100644 --- a/st.info +++ b/st.info @@ -193,6 +193,7 @@ st| simpleterm, Ms=\E]52;%p1%s;%p2%s\007, Se=\E[2 q, Ss=\E[%p1%d q, + Sync=\EP=%p1%ds\E\\, st-256color| simpleterm with 256 colors, use=st, diff --git a/x.c b/x.c index 6c254db908b9906ee869095e45b6441ec6edc7bf..2c5eef481af735bc36debceaff3509b6e3775dfc 100644 --- a/x.c +++ b/x.c @@ -2003,6 +2003,9 @@ resize(XEvent *e) cresize(e->xconfigure.width, e->xconfigure.height); } +int tinsync(uint); +int ttyread_pending(); + void run(void) { @@ -2037,7 +2040,7 @@ run(void) FD_SET(ttyfd, &rfd); FD_SET(xfd, &rfd); - if (XPending(xw.dpy)) + if (XPending(xw.dpy) || ttyread_pending()) timeout = 0; /* existing events might not set xfd */ seltv.tv_sec = timeout / 1E3; @@ -2051,7 +2054,8 @@ run(void) } clock_gettime(CLOCK_MONOTONIC, &now); - if (FD_ISSET(ttyfd, &rfd)) + int ttyin = FD_ISSET(ttyfd, &rfd) || ttyread_pending(); + if (ttyin) ttyread(); xev = 0; @@ -2075,7 +2079,7 @@ run(void) * maximum latency intervals during `cat huge.txt`, and perfect * sync with periodic updates from animations/key-repeats/etc. */ - if (FD_ISSET(ttyfd, &rfd) || xev) { + if (ttyin || xev) { if (!drawing) { trigger = now; drawing = 1; @@ -2086,6 +2090,18 @@ run(void) continue; /* we have time, try to find idle */ } + if (tinsync(su_timeout)) { + /* + * on synchronized-update draw-suspension: don't reset + * drawing so that we draw ASAP once we can (just after + * ESU). it won't be too soon because we already can + * draw now but we skip. we set timeout > 0 to draw on + * SU-timeout even without new content. + */ + timeout = minlatency; + continue; + } + /* idle detected or maxlatency exhausted -> draw */ timeout = -1; if (blinktimeout && tattrset(ATTR_BLINK)) {