Search code examples
c++ncursescurses

ncurses non-blocking read pushes cursor to bottom of window


My game's main loop relies on a non-blocking read from getnstr. It checks whether the string to which it has read has non-zero length before proceeding with the rest of the loop (I couldn't find the convention for getting this behavior if one exists).

The problem is that it has the effect of forcing the input cursor down the bottom of the window, as if I had spammed Enter or something.

    char command[5];
    timeout(0);
    while (getnstr(command, 4) && gameActive) {
        if (strlen(command) == 0) { continue; } 
        ... 
    }

Solution

  • Agreeing that it seems surprising, but SVr4 curses (which ncurses does match in this detail) always moves to the next row after completing the (attempt to) read characters.

    You can see the corresponding code for (Open)Solaris at Illumos's Github in lines 191-207:

    /*
     * The following code is equivalent to waddch(win, '\n')
     * except that it does not do a wclrtoeol.
     */
    if (doecho) {
        SP->fl_echoit = TRUE;
        win->_curx = 0;
        if (win->_cury + 1 > win->_bmarg)
            (void) wscrl(win, 1);
        else
            win->_cury++;
    
        win->_sync = savsync;
        win->_immed = savimmed;
        win->_leave = savleave;
        (void) wrefresh(win);
    }
    

    that is, the "win->_cury++;" (or the scrolling operation).