Search code examples
ncursescurses

Does refresh() need to be called at least once, when using windows in ncurses?


I've been testing ncurses, I tried doing a simple code using windows, by reading the code from the tutorials it seemed to me like calling wrefresh() was enough if changes were made just to one window. So I tried the following code, but it doesn't work, does anyone know why?

#include <ncurses.h>

int main (void) {
    int ch;

    initscr();
    raw();
    keypad(stdscr, TRUE);
    noecho();

    WINDOW *my_window = newwin(10, 20, 3, 4);
    box(my_window, 0, 0);
    wrefresh(my_window);

    while ((ch=getch()) != 'q');
    endwin();
    return 0;
}

If I add an extra call to refresh() before wrefresh() everything works fine.

#include <ncurses.h>

int main (void) {
    int ch;

    initscr();
    raw();
    keypad(stdscr, TRUE);
    noecho();

    WINDOW *my_window = newwin(10, 20, 3, 4);
    box(my_window, 0, 0);
    refresh();
    wrefresh(my_window);

    while ((ch=getch()) != 'q');
    endwin();
    return 0;
}

I've tried several things, for instance calling refresh() after wrefresh() doesn't work either, using only refresh() also does not work. Also example 7 in this guide shows after calling refresh() once, it is enough to just call wrefresh() in the while loop.

Is it always mandatory to make a call to refresh() at least once after initscr()? the documentation does not seem to mention this.


Solution

  • Calling getch is the same as wgetch(stdscr). When you call wgetch, it refreshes the window that it uses as a parameter. If you are trying to refresh a different window (such as my_window), then you should use that window as the parameter.

    In your example, there is nothing interesting that is written to stdscr. So you can omit the plain refresh() call.

    With those changes, the program is

    #include <ncurses.h>
    
    int main (void) {
        int ch;
    
        initscr();
        raw();
        keypad(stdscr, TRUE);
        noecho();
    
        WINDOW *my_window = newwin(10, 20, 3, 4);
        box(my_window, 0, 0);
    
        while ((ch=wgetch(my_window)) != 'q');
        endwin();
        return 0;
    }
    

    For a more interesting demo, you could write into the window. That is best done with a subwindow, so that it can be scrolled, e.g.,

    #include <ncurses.h>
    
    int main (void) {
        WINDOW *my_window;
        WINDOW *my_scroller;
        int ch;
    
        initscr();
        raw();
        keypad(stdscr, TRUE);
        noecho();
    
        if ((my_window = newwin(10, 20, 3, 4)) != 0) {
            box(my_window, 0, 0);
            wrefresh(my_window);
            if ((my_scroller = derwin(my_window, 8, 18, 1, 1)) != 0) {
                scrollok(my_scroller, TRUE);
                while ((ch=wgetch(my_scroller)) != 'q') {
                    wprintw(my_scroller, "%#x - %s\n", ch, keyname(ch));
                }
            }
        }
        endwin();
        return 0;
    }