st

fork of suckless's simple terminal
Index Commits Files Refs README LICENSE
commit 95033753be32e93915ddce14ea41b8765b665771
parent b7261c84aa3af984d5a7e5f5239c4173255a215d
Author: Christoph Lohmann <20h@r-36.net>
Date:   Fri, 15 Feb 2013 19:10:22 +0100

Adding a more efficient drawing code.

Thanks Mihail Zenkov <mihail.zenkov@gmail.com> for giving the hint!

Diffstat:
Mconfig.def.h | 5++++-
Mst.c | 65++++++++++++++++++++++++++++++++++++++---------------------------
2 files changed, 42 insertions(+), 28 deletions(-)
diff --git a/config.def.h b/config.def.h
@@ -9,10 +9,13 @@ static char font[] = "Liberation Mono:pixelsize=12:antialias=false:autohint=fals
 static int borderpx = 2;
 static char shell[] = "/bin/sh";
 
-/* double-click timeout (in milliseconds) between clicks for selection */
+/* timeouts (in milliseconds) */
 static unsigned int doubleclicktimeout = 300;
 static unsigned int tripleclicktimeout = 600;
 
+/* frames per second st should at maximum draw to the screen */
+static unsigned int framespersecond = 60;
+
 /* TERM value */
 static char termname[] = "st-256color";
 
diff --git a/st.c b/st.c
@@ -3166,10 +3166,12 @@ void
 run(void) {
     XEvent ev;
     fd_set rfd;
-    int xfd = XConnectionNumber(xw.dpy), i;
-    struct timeval drawtimeout, *tv = NULL;
+    int xfd = XConnectionNumber(xw.dpy);
+    struct timeval drawtimeout, *tv = NULL, now, last;
 
-    for(i = 0;; i++) {
+    gettimeofday(&last, NULL);
+
+    for(;;) {
         FD_ZERO(&rfd);
         FD_SET(cmdfd, &rfd);
         FD_SET(xfd, &rfd);
@@ -3179,35 +3181,44 @@ run(void) {
             die("select failed: %s\n", SERRNO);
         }
 
-        /*
-         * Stop after a certain number of reads so the user does not
-         * feel like the system is stuttering.
-         */
-        if(i < 1000 && FD_ISSET(cmdfd, &rfd)) {
-            ttyread();
+        gettimeofday(&now, NULL);
+        /* usecs until (next) frame */
+        drawtimeout.tv_sec = 0;
+        drawtimeout.tv_usec = \
+            ((1000/framespersecond) - TIMEDIFF(now, last)) * 1000;
 
-            /*
-             * Just wait a bit so it isn't disturbing the
-             * user and the system is able to write something.
-             */
-            drawtimeout.tv_sec = 0;
-            drawtimeout.tv_usec = 5;
-            tv = &drawtimeout;
-            continue;
+        /* Let us draw a frame. */
+        if(drawtimeout.tv_usec <= 0) {
+            draw();
+            XFlush(xw.dpy);
+
+            last = now;
+            tv = NULL;
         }
-        i = 0;
-        tv = NULL;
 
-        while(XPending(xw.dpy)) {
-            XNextEvent(xw.dpy, &ev);
-            if(XFilterEvent(&ev, None))
-                continue;
-            if(handler[ev.type])
-                (handler[ev.type])(&ev);
+        if(FD_ISSET(cmdfd, &rfd))
+            ttyread();
+
+        if(FD_ISSET(xfd, &rfd)) {
+            while(XPending(xw.dpy)) {
+                XNextEvent(xw.dpy, &ev);
+                if(XFilterEvent(&ev, None))
+                    continue;
+                if(handler[ev.type])
+                    (handler[ev.type])(&ev);
+            }
+
+            if(drawtimeout.tv_usec <= 0) {
+                draw();
+                XFlush(xw.dpy);
+            }
         }
 
-        draw();
-        XFlush(xw.dpy);
+        /* There is still some time to wait until next frame. */
+        if(drawtimeout.tv_usec > 0) {
+            tv = &drawtimeout;
+            continue;
+        }
     }
 }