ncurses的 - 调整毛刺 [英] ncurses - resizing glitch

查看:158
本文介绍了ncurses的 - 调整毛刺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了的ncurses 程序,我试图让它正确地调整大小的终端响应。虽然我可以在我的程序正确读取终端的尺寸,的ncurses 似乎并不正确处理新的层面。这里有一个(有些冗长)示例程序:

I'm writing an ncurses program and am trying to make it respond correctly to terminal resizing. While I can read the terminal dimensions correctly in my program, ncurses doesn't seem to deal with new dimensions correctly. Here's a (somewhat lengthy) sample program:

#include <ncurses.h>
#include <string.h>
#include <signal.h>
#include <sys/ioctl.h>

void handle_winch(int sig){

    struct winsize w;
    ioctl(0, TIOCGWINSZ, &w);
    COLS = w.ws_col;
    LINES = w.ws_row;

    wresize(stdscr, LINES, COLS);
    clear();

    mvprintw(0, 0, "COLS = %d, LINES = %d", COLS, LINES);
    for (int i = 0; i < COLS; i++)
        mvaddch(1, i, '*');

    refresh();
}

int main(int argc, char *argv[]){

    initscr();

    struct sigaction sa;
    memset(&sa, 0, sizeof(struct sigaction));
    sa.sa_handler = handle_winch;
    sigaction(SIGWINCH, &sa, NULL);

    while(getch() != 27) {}

    endwin();
    return 0;
}

如果你运行它,你可以看到,终端尺寸正确检索。但第二行,这是应该吸取 * -characters在屏幕上,不能正常工作。尝试调整窗口水平使其变大, * 取值不会得到更大。

If you run it, you can see that the terminal dimensions are correctly retrieved. But the second line, which is supposed to draw *-characters across the screen, doesn't work. Try resizing the window horizontally to make it larger, the line of *s will not get larger.

这里有什么问题吗?我知道,人们可以暂时离开诅咒模式,但我preFER一个清晰的解决方案。谢谢!

What's the problem here? I'm aware that one can temporarily leave curses mode, but I'd prefer a cleaner solution. Thanks!

推荐答案

不要设置 COLS LINES 。这些由ncurses的管理。此外,让ncurses的大小调整适当后重新初始化。这意味着,不叫wresize()。只需调用endwin()代替。确保使用其他的ncurses函数之前endwin()调用后直接调用refresh()。

Do not set COLS and LINES. These are managed by ncurses. Also, let ncurses reinitialize properly after a resize. That means, don't call wresize(). Just call endwin() instead. Make sure to call refresh() directly after an endwin() call before using other ncurses functions.

您还没有在所有需要的ioctl()。 ncurses的需要自动检测新尺寸的照顾。

You also don't need the ioctl() at all. ncurses takes care of detecting the new size automatically.

所以,你需要的是pretty多少只是一个endwin()调用:

So what you need is pretty much just an endwin() call:

void handle_winch(int sig)
{
    endwin();
    // Needs to be called after an endwin() so ncurses will initialize
    // itself with the new terminal dimensions.
    refresh();
    clear();

    mvprintw(0, 0, "COLS = %d, LINES = %d", COLS, LINES);
    for (int i = 0; i < COLS; i++)
        mvaddch(1, i, '*');
    refresh();
}

此外,一些ncurses的版本被配置为提供自己SIGWINCH处理程序。这些版本返回KEY_RESIZE作为一个按键输入时,调整大小时,。如果你要利用这一点,你就不需要一个信号处理程序都没有。相反,所有你需要的是:

Furthermore, some ncurses versions are configured to supply their own SIGWINCH handler. Those versions return KEY_RESIZE as a key input when a resize occurs. If you were to make use of that, you wouldn't need a signal handler at all. Instead, all you need is:

#include <ncurses.h>
#include <string.h>

int main()
{

    initscr();

    int key;
    while ((key = getch()) != 27) {
        if (key == KEY_RESIZE) {
            clear();
            mvprintw(0, 0, "COLS = %d, LINES = %d", COLS, LINES);
            for (int i = 0; i < COLS; i++)
                mvaddch(1, i, '*');
            refresh();
        }
    }

    endwin();
    return 0;
}

不幸的是,你不能依赖于安装正与KEY_RESIZE配置的所有ncurses的,所以信号处理程序是最便携的解决方案。

Unfortunately, you can't rely on all ncurses installation being configured with KEY_RESIZE, so the signal handler is the most portable solution.

这篇关于ncurses的 - 调整毛刺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆