While profiling terminal latency in st, I observed that data read from
the tty was not immediately written to the screen, but instead queued in
a rate limiting step. This results in a delay of ~17ms on my computer
between the XEvent capture by the terminal and the new character written
to the buffer when there is no system load.
This patch creates a global flag which is set when a keypress is sent
from X which forces the terminal to check for new data on the tty fd on
every return from pselect(). When new data read from the tty results in
a line being redrawn, the flag is reset.
On my computer, this results in a speedup from 17ms to 400us, which
includes the round-trip time to the shell.
---
x.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/x.c b/x.c
index e5f1737..7b3feef 100644
--- a/x.c
+++ b/x.c
@@ -220,6 +220,7 @@ static DC dc;
static XWindow xw;
static XSelection xsel;
static TermWindow win;
+static int pendingkpress = 0;
/* Font Ring Cache */
enum {
@@ -1604,6 +1605,8 @@ xdrawline(Line line, int x1, int y1, int x2)
Glyph base, new;
XftGlyphFontSpec *specs = xw.specbuf;
+ pendingkpress = 0;
+
numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1);
i = ox = 0;
for (x = x1; x < x2 && i < numspecs; x++) {
@@ -1793,6 +1796,8 @@ kpress(XEvent *ev)
Status status;
Shortcut *bp;
+ pendingkpress = 1;
+
if (IS_SET(MODE_KBDLOCK))
return;
@@ -1922,6 +1927,8 @@ run(void)
tv = &drawtimeout;
dodraw = 0;
+ if (pendingkpress)
+ dodraw = 1;
if (blinktimeout && TIMEDIFF(now, lastblink) > blinktimeout) {
tsetdirtattr(ATTR_BLINK);
win.mode ^= MODE_BLINK;
--
2.26.1