diff options
-rwxr-xr-x | tcvt.py | 66 |
1 files changed, 50 insertions, 16 deletions
@@ -315,13 +315,14 @@ class Terminal: self.lastchar = ord(b' ') self.columns = columns self.reverse = reverse + self.need_refresh = None def switchmode(self): if isinstance(self.screen, Columns): self.screen = Simple(self.realscreen) else: self.screen = Columns(self.realscreen, self.columns) - self.screen.refresh() + self.request_refresh() def resized(self): # The refresh call causes curses to notice the new dimensions. @@ -332,15 +333,32 @@ class Terminal: reverse=self.reverse) except BadWidth: self.screen = Simple(self.realscreen) + self.request_refresh() def resizepty(self, ptyfd): ym, xm = self.screen.getmaxyx() fcntl.ioctl(ptyfd, termios.TIOCSWINSZ, struct.pack("HHHH", ym, xm, 0, 0)) + def refresh_needed(self): + return self.need_refresh is not None + + def request_refresh(self): + if self.need_refresh is None: + self.need_refresh = time.time() + + def refresh(self, minwait=0): + if self.need_refresh is None: + return + if minwait > 0 and self.need_refresh + minwait > time.time(): + return + self.screen.refresh() + self.need_refresh = None + def addch(self, char): self.lastchar = char self.screen.addch(char) + self.request_refresh() def __enter__(self): self.realscreen = curses.initscr() @@ -371,27 +389,32 @@ class Terminal: def do_cr(self): self.screen.relmove(0, -9999) + self.request_refresh() def do_cub(self, n): self.screen.relmove(0, -n) + self.request_refresh() def do_cub1(self): self.do_cub(1) def do_cud(self, n): self.screen.relmove(n, 0) + self.request_refresh() def do_cud1(self): self.do_cud(1) def do_cuf(self, n): self.screen.relmove(0, n) + self.request_refresh() def do_cuf1(self): self.do_cuf(1) def do_cuu(self, n): self.screen.relmove(-n, 0) + self.request_refresh() def do_cuu1(self): self.do_cuu(1) @@ -399,6 +422,7 @@ class Terminal: def do_dch(self, n): for _ in range(n): self.screen.delch() + self.request_refresh() def do_dch1(self): self.do_dch(1) @@ -406,6 +430,7 @@ class Terminal: def do_dl(self, n): for _ in range(n): self.screen.deleteln() + self.request_refresh() def do_dl1(self): self.do_dl(1) @@ -413,39 +438,49 @@ class Terminal: def do_ech(self, n): for _ in range(n): self.screen.addch(ord(b' ')) + self.request_refresh() def do_ed(self): self.screen.clrtobot() + self.request_refresh() def do_el(self): self.screen.clrtoeol() + self.request_refresh() def do_el1(self): y, x = self.screen.getyx() - self.screen.move(y, 0) - for _ in range(x): - self.screen.addch(ord(b' ')) + if x > 0: + self.screen.move(y, 0) + for _ in range(x): + self.screen.addch(ord(b' ')) + self.request_refresh() def do_home(self): self.screen.move(0, 0) + self.request_refresh() def do_hpa(self, n): y, _ = self.screen.getyx() self.screen.move(y, n) + self.request_refresh() def do_ht(self): y, x = self.screen.getyx() _, xm = self.screen.getmaxyx() x = min(x + 8 - x % 8, xm - 1) self.screen.move(y, x) + self.request_refresh() def do_ich(self, n): for _ in range(n): self.screen.insch(ord(b' ')) + self.request_refresh() def do_il(self, n): for _ in range(n): self.screen.insertln() + self.request_refresh() def do_il1(self): self.do_il(1) @@ -458,6 +493,7 @@ class Terminal: self.screen.move(y, 0) else: self.screen.move(y+1, 0) + self.request_refresh() def do_invis(self): self.screen.attron(curses.A_INVIS) @@ -468,6 +504,7 @@ class Terminal: def do_vpa(self, n): _, x = self.screen.getyx() self.screen.move(n, x) + self.request_refresh() def feed_reset(self): if self.graphics_font: @@ -595,14 +632,17 @@ class Terminal: if len(parts) != 2: raise ValueError("feed esc [ %r H" % parts) self.screen.move(*map((-1).__add__, map(int, parts))) + self.request_refresh() elif prev == bytearray(b'2') and char == ord(b'J'): self.screen.move(0, 0) self.screen.clrtobot() + self.request_refresh() elif char == ord(b'd') and prev.isdigit(): self.do_vpa(int(prev) - 1) elif char == ord(b'b') and prev.isdigit(): for _ in range(int(prev)): self.screen.addch(self.lastchar) + self.request_refresh() elif char == ord(b'G') and prev.isdigit(): self.do_hpa(int(prev) - 1) elif char == ord(b'K') and prev == b'1': @@ -705,11 +745,10 @@ def main(): with process as masterfd: with Terminal(acsc, options.columns, reverse=options.reverse) as t: t.resizepty(masterfd) - refreshpending = None while True: + timeout = 0 if t.refresh_needed() else None try: - res, _, _ = select.select([0, masterfd], [], [], - refreshpending and 0) + res = select.select([0, masterfd], [], [], timeout)[0] except select.error as err: if err.args[0] == errno.EINTR: t.resized() @@ -731,6 +770,7 @@ def main(): else: if "TCVT_DEVEL" in os.environ: raise ValueError("getch returned %d" % key) + t.refresh(0.1) elif masterfd in res: try: data = os.read(masterfd, 1024) @@ -746,15 +786,9 @@ def main(): t.feed(char) except ValueError: t.feed_reset() - if refreshpending is None: - refreshpending = time.time() + 0.1 - elif refreshpending is not None: - t.screen.refresh() - refreshpending = None - if refreshpending is not None and \ - refreshpending < time.time(): - t.screen.refresh() - refreshpending = None + t.refresh(0.1) + else: + t.refresh() except ExecutionError as err: print(str(err)) sys.exit(255) |