Skip to content Skip to sidebar Skip to footer

Key_resize Not Returned From Getch() When Xterm Is Resized

I am using Python 3.7 on a Debian Linux 9 box with the standard readline and curses modules. The following code should output 'True' when run inside an xterm and the xterm is resi

Solution 1:

In a quick check with strace, I can see that something resets the SIGWINCH handler back to SIG_DFL (no action) after ncurses sets its handler for SIGWINCH. The symbol table of readline has these relevant entrypoints:

_rl_block_sigwinch
_rl_redisplay_after_sigwinch
_rl_release_sigwinch
_rl_sigwinch_resize_terminal
rl_catch_sigwinch

The documentation for readline notes

    o A new variable, rl_catch_sigwinch, is available to application
      writers to indicate to readline whether ornot it should install its
      own signal handler for SIGWINCH, which will chain to the calling
      applications's SIGWINCH handler, if one is installed;

However, reading the source for libpython3.5, it appears that the developer did not take that into account:

/* Helper to initialize GNU readline properly. */staticvoidsetup_readline(readlinestate *mod_state){
...
    rl_readline_name = "python";
    /* Force rebind of TAB to insert-tab */rl_bind_key('\t', rl_insert);
    /* Bind both ESC-TAB and ESC-ESC to the completion function */rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap);
    rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap);
#ifdef HAVE_RL_RESIZE_TERMINAL/* Set up signal handler for window resize */
    sigwinch_ohandler = PyOS_setsig(SIGWINCH, readline_sigwinch_handler);
#endif

This change in 2016 appears to be related to the problem you're seeing (offhand, it looks like a new problem was introduced without solving the old one). If the signal-handler added for readline doesn't chain over to the one in ncurses, then the latter's no longer used and ncurses cannot return KEY_RESIZE. Also—if readline sets up its handler first, ncurses won't set up its handler.

The latter seems to be the case: the import readline calls the module initialization which sets up a signal handler. The ncurses signal handler is initialized when the Python curses wrapper calls initscr. That's not done in PyInit__curses (the function called on import curses) because that would clear the screen. Alternatively, ncurses would initialize its signal handler if newterm was called (which would not clear the screen), but Python doesn't do that.

You could work around this by loading the ncurses (or ncursesw!) library and calling newterm followed by endwin, doing that before the import statements. That seems like a lot of work. I'd recommend opening a bug report.

For reference:

Post a Comment for "Key_resize Not Returned From Getch() When Xterm Is Resized"