about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-09-04 11:07:08 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-09-04 11:12:03 -0700
commit1ed9af8300c037174dba4fc83fffeea9e6291ab8 (patch)
treebcfe79c4fd21f428f542d417e745595d2cc950c6
parent7e23f02f89ceebddaf55fa2c31621a18fe63ff98 (diff)
downloadmu-1ed9af8300c037174dba4fc83fffeea9e6291ab8.tar.gz
2141 - attempt to deal with slow networks
On slow networks sometimes escape sequences were being partially
consumed, causing junk to be added to the editor when you pressed arrow
keys and so on. Now we have a way to wait.

Empirically seems to work if I page-up and then scroll back up using
up-arrow. Before I'd consistently get junk even on my local machine. Now
I no longer do.

If we still see problems I'll increase the wait time and see if the
increase helps. Then we'll know more about this approach.
-rw-r--r--cannot_write_tests_for4
-rw-r--r--termbox/input.inl43
2 files changed, 31 insertions, 16 deletions
diff --git a/cannot_write_tests_for b/cannot_write_tests_for
index a77ef91b..8a678b37 100644
--- a/cannot_write_tests_for
+++ b/cannot_write_tests_for
@@ -3,3 +3,7 @@
 3. hide/show screen
 4. more touch event types
 5. sandbox isolation
+
+termbox issues are implementation-specific and not worth testing:
+  whether we clear junk from other processes
+  latency in interpreting low-level escape characters
diff --git a/termbox/input.inl b/termbox/input.inl
index 97ea1190..0088cd91 100644
--- a/termbox/input.inl
+++ b/termbox/input.inl
@@ -21,6 +21,9 @@ static bool starts_with(const char *s1, int len, const char *s2)
 // convert escape sequence to event, and return consumed bytes on success (failure == 0)
 static int parse_escape_seq(struct tb_event *event, const char *buf, int len)
 {
+  static int parse_attempts = 0;
+  static const int MAX_PARSE_ATTEMPTS = 2;
+
 //?   int x = 0;
 //?   FOO("-- %d\n", len);
 //?   for (x = 0; x < len; ++x) {
@@ -48,6 +51,7 @@ static int parse_escape_seq(struct tb_event *event, const char *buf, int len)
       event->key = TB_KEY_MOUSE_RELEASE;
       break;
     default:
+      parse_attempts = 0;
       return -6;
     }
     event->type = TB_EVENT_MOUSE; // TB_EVENT_KEY by default
@@ -56,6 +60,7 @@ static int parse_escape_seq(struct tb_event *event, const char *buf, int len)
     event->x = (uint8_t)buf[4] - 1 - 32;
     event->y = (uint8_t)buf[5] - 1 - 32;
 
+    parse_attempts = 0;
     return 6;
   }
 
@@ -66,6 +71,7 @@ static int parse_escape_seq(struct tb_event *event, const char *buf, int len)
     if (starts_with(buf, len, keys[i])) {
       event->ch = 0;
       event->key = 0xFFFF-i;
+      parse_attempts = 0;
       return strlen(keys[i]);
     }
   }
@@ -73,35 +79,48 @@ static int parse_escape_seq(struct tb_event *event, const char *buf, int len)
   if (starts_with(buf, len, "\033[200~")) {
     event->ch = 0;
     event->key = TB_KEY_START_PASTE;
+    parse_attempts = 0;
     return strlen("\033[200~");
   }
   if (starts_with(buf, len, "\033[201~")) {
     event->ch = 0;
     event->key = TB_KEY_END_PASTE;
+    parse_attempts = 0;
     return strlen("\033[201~");
   }
   if (starts_with(buf, len, "\033[1;5A")) {
     event->ch = 0;
     event->key = TB_KEY_CTRL_ARROW_UP;
+    parse_attempts = 0;
     return strlen("\033[1;5A");
   }
   if (starts_with(buf, len, "\033[1;5B")) {
     event->ch = 0;
     event->key = TB_KEY_CTRL_ARROW_DOWN;
+    parse_attempts = 0;
     return strlen("\033[1;5B");
   }
   if (starts_with(buf, len, "\033[1;5C")) {
     event->ch = 0;
     event->key = TB_KEY_CTRL_ARROW_RIGHT;
+    parse_attempts = 0;
     return strlen("\033[1;5C");
   }
   if (starts_with(buf, len, "\033[1;5D")) {
     event->ch = 0;
     event->key = TB_KEY_CTRL_ARROW_LEFT;
+    parse_attempts = 0;
     return strlen("\033[1;5D");
   }
 
-  return 0;
+  // no escape sequence recognized? wait a bit in case our buffer is incomplete
+  ++parse_attempts;
+  if (parse_attempts < MAX_PARSE_ATTEMPTS) return 0;
+  // still nothing? give up and consume just the esc
+  event->ch = 0;
+  event->key = TB_KEY_ESC;
+  parse_attempts = 0;
+  return 1;
 }
 
 static bool extract_event(struct tb_event *event, struct bytebuffer *inbuf)
@@ -118,23 +137,15 @@ static bool extract_event(struct tb_event *event, struct bytebuffer *inbuf)
 //?   }
   if (buf[0] == '\033') {
     int n = parse_escape_seq(event, buf, len);
+    if (n == 0) return false;
 //?     FOO("parsed: %u %u %u %u\n", n, (unsigned int)event->type, (unsigned int)event->key, event->ch);
-    if (n != 0) {
-      bool success = true;
-      if (n < 0) {
-        success = false;
-        n = -n;
-      }
-      bytebuffer_truncate(inbuf, n);
-      return success;
-    } else {
-//?       FOO("escape sequence\n");
-      // it's not escape sequence; assume it's esc
-      event->ch = 0;
-      event->key = TB_KEY_ESC;
-      bytebuffer_truncate(inbuf, 1);
-      return true;
+    bool success = true;
+    if (n < 0) {
+      success = false;
+      n = -n;
     }
+    bytebuffer_truncate(inbuf, n);
+    return success;
   }
 
   // if we're here, this is not an escape sequence and not an alt sequence