KEY_RESIZE不残培()时的xterm被调整回

问题描述 投票:1回答:1

我使用Python 3.7的Debian Linux的9箱与标准的readline和诅咒模块。在xterm里面下面的代码应该输出“真”时运行,并在xterm被调整:

import readline
import os
import curses

terminal_resized = False

def main(stdscr):
    global terminal_resized
    ch = stdscr.getch()
    if ch == curses.KEY_RESIZE:
        terminal_resized = True

os.unsetenv('LINES')
os.unsetenv('COLUMNS')

curses.wrapper(main)
print(terminal_resized)

但是,输出是“假”,表明该呼叫参考getch()没有返回KEY_RESIZE。事实上,它返回-1代替。

需要注意的是代码的工作,如果我不导入的ReadLine模块预期。

在谷歌搜索到这个问题的解决方案,我遇到了一个职位自2016年表明有导入这两种readline的诅咒和模块时是一个矛盾。基本上,readline的模块设置“LINES”和“列”的环境变量和该干扰的ncurses的内置SIGWINCH信号处理程序,其是什么是最终要的getch负责()当终端被调整大小返回KEY_RESIZE。这就是为什么我有这些调用unsetenv()在那里的原因。

然而,这些unsetenv()调用显然在2019年没有效果的确,当我尝试导入的ReadLine我看不出有什么参考输出“行”或“列”后,打印出所有的环境变量。我把这些调用unsetenv()在那里呢,不过,看它是否会做任何有用的东西。

有谁知道怎么去诅咒的getch()方法,就像它应该在的ReadLine模块也是进口在Python 3.7返回KEY_RESIZE?

python python-3.x readline curses
1个回答
1
投票

在快速检查与strace的,我能看到的东西重置SIGWINCH处理回的ncurses后SIG_DFL(无动作)将其处理程序SIGWINCH。 readline的符号表中有这些相关的入口点:

_rl_block_sigwinch
_rl_redisplay_after_sigwinch
_rl_release_sigwinch
_rl_sigwinch_resize_terminal
rl_catch_sigwinch

一行readline笔记文档

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

然而,阅读libpython3.5源,看来开发商没有考虑到这一点:

/* Helper to initialize GNU readline properly. */

static void
setup_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似乎与你所看到的问题(副手,它看起来像没有解决旧之一是引入了一个新的问题)。如果信号处理程序添加一行readline没有环比的一个在ncurses的,那么后者的不再使用的ncurses不能返回KEY_RESIZE。此外,如果readline的第一设置其处理程序,ncurses的将不设置其处理程序。

后者似乎是这样的:在import readline调用模块初始化它建立了一个信号处理程序。 Ncurses的信号时,Python的诅咒包装程序调用initscr处理程序进行初始化。这不是在做PyInit__curses(呼吁import curses功能),因为这将清除屏幕。另外,将ncurses的初始化它的信号处理程序,如果newterm作为(这不会清除屏幕),但是Python没有做到这一点。

您可以解决此通过加载的ncurses(或ncursesw!)后newterm库并调用endwin,这样做的import语句之前。这似乎是一个大量的工作。我建议你打开一个bug报告。

以供参考:

© www.soinside.com 2019 - 2024. All rights reserved.