summaryrefslogtreecommitdiff
path: root/st.c
diff options
context:
space:
mode:
authorzachir <zachir@librem.one>2023-02-20 03:57:35 -0600
committerzachir <zachir@librem.one>2023-02-20 03:57:35 -0600
commit32a99f67c4aebeceac8cd58edc63d9c59f1a3220 (patch)
treeb7691f980c3a53d1e153535c60bc24606e7b237d /st.c
parentc4aeb32df95c2ad8adfacae4b0627c65f9a9e929 (diff)
add appsync patch
Diffstat (limited to 'st.c')
-rw-r--r--st.c50
1 files changed, 47 insertions, 3 deletions
diff --git a/st.c b/st.c
index a90bf3f..e323dbf 100644
--- a/st.c
+++ b/st.c
@@ -279,6 +279,33 @@ static const uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
static const Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
static const 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)
{
@@ -894,6 +921,9 @@ ttynew(const char *line, char *cmd, const char *out, char **args)
return cmdfd;
}
+static int twrite_aborted = 0;
+int ttyread_pending() { return twrite_aborted; }
+
size_t
ttyread(void)
{
@@ -902,7 +932,7 @@ ttyread(void)
int ret, written;
/* append read bytes to unprocessed bytes */
- ret = read(cmdfd, buf+buflen, LEN(buf)-buflen);
+ ret = twrite_aborted ? 1 : read(cmdfd, buf+buflen, LEN(buf)-buflen);
switch (ret) {
case 0:
@@ -910,7 +940,7 @@ ttyread(void)
case -1:
die("couldn't read from shell: %s\n", strerror(errno));
default:
- buflen += ret;
+ buflen += twrite_aborted ? 0 : ret;
written = twrite(buf, buflen, 0);
buflen -= written;
/* keep any incomplete UTF-8 byte sequence for the next call */
@@ -1076,7 +1106,8 @@ tsetdirtattr(int attr)
void
tfulldirt(void)
{
- for (int i = 0; i < term.row; i++)
+ tsync_end();
+ for (int i = 0; i < term.row; i++)
term.dirty[i] = 1;
}
@@ -2232,6 +2263,12 @@ strhandle(void)
xsettitle(strescseq.args[0], 0);
return;
case 'P': /* DCS -- Device Control String */
+ /* https://gitlab.com/gnachman/iterm2/-/wikis/synchronized-updates-spec */
+ if (strstr(strescseq.buf, "=1s") == strescseq.buf)
+ tsync_begin(); /* BSU */
+ else if (strstr(strescseq.buf, "=2s") == strescseq.buf)
+ tsync_end(); /* ESU */
+ return;
case '_': /* APC -- Application Program Command */
case '^': /* PM -- Privacy Message */
return;
@@ -2772,6 +2809,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)) {
/* process a complete utf8 char */
@@ -2782,6 +2822,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;