0

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;
}
n0p
  • 3,399
  • 2
  • 29
  • 50
Ari Malinen
  • 576
  • 2
  • 6
  • 20

2 Answers2

3

I'm thinking about select and/or threads: one thread could monitor the resize while the other one will wait for user input.

You can synchronize threads with a select, which can wait on multiple file descriptors: for example you can write on a pipe when you detect an event to wake-up the main process. Cool thing is you can also set a timeout to be woken-up even if no event happened (then you can put a timeout of one second to trigger the redraw).

n0p
  • 3,399
  • 2
  • 29
  • 50
  • definitely I would go with `select`. Threads are nice, but a pain to debug. – rslemos Aug 12 '14 at 15:46
  • Agreed, but the the OP wants to wait on 2 different events that does not originally involve file descriptors: on what would he wait ? I think in this particular case, debugging won't be too annoying. – n0p Aug 13 '14 at 07:39
  • Thanks for help. I tried select also but had some issues. Now i have it working with ncurses getch() and timeout(). – Ari Malinen Aug 15 '14 at 14:09
0

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;
}
Ari Malinen
  • 576
  • 2
  • 6
  • 20