无法用ncurses确定终端大小

时间:2012-04-18 07:38:50

标签: c++ macos ncurses

我正在尝试处理调整大小信号(SIGWINCH)

void Server::resizeSignalHandler(int a)
{
signal(SIGWINCH, SIG_IGN);

endwin();
initscr();
refresh();
clear();

int x,y;
getmaxyx(stdscr, y, x);

wmove(upScreen, 0, 0);
wmove(downScreen, y/2, 0);
wresize(upScreen, y/2, x);
wresize(downScreen, y/2, x);
wclear(upScreen);
wclear(downScreen);
waddstr(upScreen, "test1");
waddstr(downScreen, "test2");
wrefresh(upScreen);
wrefresh(downScreen);
refresh();

signal(SIGWINCH, Server::resizeSignalHandler);

}
Server::Server()
{
//ncurses screen initialization
initscr();

if (!upScreen) {
    upScreen = newwin(0, 0, 1, 1);
}
if (!downScreen) {
    downScreen = newwin(0, 0, 1, 1);
}
//adjusting screen when user resize terminal
signal(SIGWINCH, Server::resizeSignalHandler);

//configuring screens
Server::resizeSignalHandler(0);

waddstr(Server::upScreen, "lalfasdfsafd as");
waddstr(downScreen, "supreme!");
wrefresh(Server::upScreen);
wrefresh(downScreen);
}

当我调试此代码时,在resizeSignalHandler var x中,y总是相同的(大小没有改变)。我也尝试用ioctl确定大小,但没有任何改变。

我发现在我之前有很多人遇到过这个问题 http://www.mail-archive.com/arch@archlinux.org/msg11253.html 有时候,他们解决了这个问题(改变/ etc / profile; O(原文!)),但有时却没有。 有没有替代mac os x终端,也许ncurses专用于xterm和类似。

4 个答案:

答案 0 :(得分:1)

这是因为getmaxyx获得的值由一个听SIGWINCH的信号处理程序自行更新。您需要将指针保存到旧信号,例如:

old_callback = signal(SIGWINCH, Server::resizeSignalHandler);

然后在resizeSignalHandler中调用它:

old_callback(a);

答案 1 :(得分:1)

由于自定义getmaxyx(...)信号处理程序,

SIGWINCH提供了错误的(未更新的)终端大小。

您可以使用ioctl(fileno(stdout), TIOCGWINSZ, struct winsize*)获取更新的终端参数。但这不会更新getmaxyt(...)返回的数据。

要更新getmaxyx(...)数据,您应致电resize_term(size.ws_row, size.ws_col)

因此信号处理程序代码应如下所示:

void on_terminal_resize(int n) {
    struct winsize size;

    if (ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) {
        resize_term(size.ws_row, size.ws_col);
    }
    // Your code goes here...
    signal(SIGWINCH, on_terminal_resize);
}

答案 2 :(得分:0)

我不确定,但我认为您必须致电ioctl(1, TIOCGWINSZ, struct winsize*)以获取更新的终端参数。请参阅man tty_ioctl

答案 3 :(得分:-1)

我没有mac机器,也无法测试。但我想伪终端bash正在更新$ LINES和$ COLUMNS上运行,但这些更新不会传递给程序所分配的伪终端。这是因为您说WINCH信号被捕获,但这些参数不会更新。解决方法是在信号处理程序中执行"/usr/X11/bin/resize" / "/usr/bin/resize"。可能会正确更新$ LINES和$ COLUMNS。