Search code examples
ctimeoutncursesgetch

Redraw delay when using getch() with timeout() set


I have ncurses program where I need instant response to user input and term resize and 1 sec delay between redraws.

  • By using sleep(1) I got instant redraw on startup and term resize but 1 sec delay on user input.
  • By using timeout(1 * 1000) and getch() I get instant response for input but 1 sec redraw delay on startup and resize.

Here is example program to demonstrate the problem:

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <ncurses.h>

static sig_atomic_t resize;

void sighandler(int sig) {
    if (sig == SIGWINCH)
        resize = 1;
}

int main(int argc, char *argv[]) {
    double delay = 1.0;
    char key = ERR;
    WINDOW *testwin;

    if (argc > 1)
        delay = strtod(argv[1], NULL);

    signal(SIGWINCH, sighandler);
    initscr();
    timeout(delay * 1000);
    testwin = newwin(LINES, COLS, 0, 0);

    while (key != 'q') {
        if (key != ERR)
            resize = 1;

        if (resize) {
            endwin();
            refresh();
            clear();

            werase(testwin);
            wresize(testwin, LINES, COLS);
            resize = 0;
        }

        box(testwin, 0, 0);
        wnoutrefresh(testwin);
        doupdate();

        key = getch();
    }

    delwin(testwin);
    endwin();
    return EXIT_SUCCESS;
}

Solution

  • I managed to solve the resize delay by removing clear();

    #include <stdlib.h>
    #include <stdio.h>
    #include <signal.h>
    #include <ncurses.h>
    
    static sig_atomic_t resize;
    
    void sighandler(int sig) {
        if (sig == SIGWINCH)
            resize = 1;
    }
    
    int main(int argc, char *argv[]) {
        double delay = 1.0;
        char key = ERR;
        WINDOW *testwin;
    
        if (argc > 1)
            delay = strtod(argv[1], NULL);
    
        signal(SIGWINCH, sighandler);
        initscr();
        timeout(delay * 1000);
        testwin = newwin(LINES, COLS, 0, 0);
    
        while (key != 'q') {
            key = getch();
    
            if (key != ERR)
                resize = 1;
    
            if (resize) {
                endwin();
                refresh();
    
                werase(testwin);
                wresize(testwin, LINES, COLS);
                resize = 0;
            }
    
            box(testwin, 0, 0);
            wnoutrefresh(testwin);
            doupdate();
        }
    
        delwin(testwin);
        endwin();
        return EXIT_SUCCESS;
    }