ncurses 通过三种方法获取窗口大小:
- 在支持 TIOCGWINSZ 的终端中
ioctl(2)
,通过调用获取窗口尺寸initscr(3)
。
- 通过 terminfo 数据库提供的信息。许多终端类型都有固定的尺寸尺寸,行和列的适当值是从这个数据库中获得的。
- 通过获取 LINES 和 COLUMNS 环境变量的值。
好吧,bash(1)
通常在程序退出时和调用下一个之前将这些环境变量值调整为正确的值,如果这可用于bash(1)
,但如果您的程序不支持该SIGWINCH
信号(或不处理它),很可能是 ncurses库不会知道在程序运行期间窗口大小发生了变化(默认情况下,我没有看到 ncurses 检测到这一点)。即使您在支持它的系统上运行,如果您没有为该信号安装信号处理程序,ncurses 库本身也无法承受窗口尺寸的变化,因为它必须调整stdscr
内容的大小并且可以使用几个标准处理旧内容和新的可用空间。
我观察到的标准是 ncurses 本身不处理窗口更改(至少在默认情况下,您还必须考虑这与 ncurses 发生的情况相同,它没有检测到另一个进程是否已写入您的 tty,并且屏幕出现乱码)。为了处理这个问题,你必须为信号安装一个信号处理程序SIGWINCH
(当终端尺寸发生变化时,这个信号被发送到整个进程组,通常是从 pty 主机端),并使ioctl(2)
适用于 tty 设备获取新的窗口尺寸并调用适当的低级 ncurses 例程来更改新的几何形状stdsrc
和stdwin
缓冲区,因为这将需要为它们重新分配内存。这意味着您可以自由决定在终端调整大小时窗口内容会发生什么,但会让您做所有的工作来处理它。我有一个程序,它SIGWINCH
可以exec(2)
自行启动并重新启动,因此它会在initscr(3)
调用时获得新的屏幕尺寸。如果您无法自动exec(2)
执行程序,只需深入了解如何重置stdscr
尺寸以及正确更改LINS
和COLS
全局变量的文档。(如果我找到有关如何操作的文档,我将使用适当的信息编辑此答案。)
笔记
我已经运行了你的程序,它按预期工作......用星号填充第一行和最后一行。只需调用getch()
beforeendwin()
即可看到绘制的屏幕。