commit 753aca3e5175d7732b05d31c11bf980314647dd7
parent 1d24bd36fea2c5e98a04559815295a52e3cd3379
Author: TripleK2004 <kowkeerthankumar@gmail.com>
Date: Wed, 9 Jun 2021 20:24:21 +0530
patched appsync
Diffstat:
6 files changed, 83 insertions(+), 9 deletions(-)
diff --git 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...
<br>
diff --git a/config.def.h b/config.def.h
@@ -52,6 +52,12 @@ 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
@@ -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;
/*
@@ -52,6 +52,12 @@ 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
@@ -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 <time.h>
+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
@@ -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
@@ -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)) {