From 55daf9d49df4a0e0774b27acd33735abf80f80dd Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Thu, 31 Jul 2014 04:45:02 +0200 Subject: [PATCH] Make the resize work, using an ugly workaround MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems efficient (more than the curses.endwin(); stdscr.refresh() stuf, which is slow and really really ugly) and it doesn't break my lovely main loop, so it’s all good (except that it uses shutil…) --- src/core/core.py | 24 +++++++++++++++++++++++- src/poezio.py | 2 ++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/core/core.py b/src/core/core.py index c2996b5d..446cc9f0 100644 --- a/src/core/core.py +++ b/src/core/core.py @@ -11,6 +11,7 @@ log = logging.getLogger(__name__) import asyncio import collections +import shutil import curses import os import pipes @@ -482,6 +483,27 @@ class Core(object): pass sys.__excepthook__(typ, value, trace) + def sigwinch_handler(self): + """A work-around for ncurses resize stuff, which sucks. Normally, ncurses + catches SIGWINCH itself. In its signal handler, it updates the + windows structures (for example the size, etc) and it + ungetch(KEY_RESIZE). That way, the next time we call getch() we know + that a resize occured and we can act on it. BUT poezio doesn’t call + getch() until it knows it will return something. The problem is we + can’t know that, because stdin is not affected by this KEY_RESIZE + value (it is only inserted in a ncurses internal fifo that we can’t + access). + + The (ugly) solution is to handle SIGWINCH ourself, trigger the + change of the internal windows sizes stored in ncurses module, using + sizes that we get using shutil, ungetch the KEY_RESIZE value and + then call getch to handle the resize on poezio’s side properly. + """ + size = shutil.get_terminal_size() + curses.resizeterm(size.lines, size.columns) + curses.ungetch(curses.KEY_RESIZE) + self.on_input_readable() + def on_input_readable(self): """ main loop waiting for the user to press a key @@ -562,8 +584,8 @@ class Core(object): self.do_command(replace_line_breaks(char), False) else: self.do_command(''.join(char_list), True) - self.doupdate() self.xmpp.plugin['xep_0012'].begin_idle(jid=self.xmpp.boundjid) + self.doupdate() def save_config(self): """ diff --git a/src/poezio.py b/src/poezio.py index 96445db2..68acae10 100644 --- a/src/poezio.py +++ b/src/poezio.py @@ -61,7 +61,9 @@ def main(): # the asyncio logger will not follow our configuration and won't write # the tracebacks in the correct file, etc import asyncio + asyncio.get_event_loop().add_reader(sys.stdin, cocore.on_input_readable) + asyncio.get_event_loop().add_signal_handler(signal.SIGWINCH, cocore.sigwinch_handler) cocore.xmpp.start() asyncio.get_event_loop().run_forever() # We reach this point only when loop.stop() is called