Search code examples
c++ncurses

ncurses WINDOW* disappears after console resize


So, let's say we have a

WINDOW *main_win=newwin(50, 80, 1, 0); // 50 rows, 80 columns
WINDOW *status_win=newwin(3, 100, 51, 0); // Status bar
WINDOW *interaction_bar=newwin(1, 200, 0, 0);

I have a function that prints strings onto it (mvwaddstr) and it works as planned. But after resizing the terminal to particularly <50 columns and resize it back to >53 columns, the status_win just magically disappears. wclear and wrefresh doesn't render anything onto it.

I've tested something like

delwin(main_win);
delwin(status_win);
delwin(interaciton_bar);
main_win=newwin(50, 80, 1, 0);
status_win=newwin(3, 100, 51, 0);
interaction_bar=newwin(1, 200, 0, 0);

Surprisingly, the status_win gets rendered back. But there's a problem.

I use int ch = wgetch(main_win); to get my keyboard input. Somehow it can read keys like 'w', 'a', 's', 'd', but when it comes to keys like KEY_LEFT and KEY_RIGHT, my console just starts to jitter and seems like it isn't being processed.


Solution

  • Regarding the disappearing window (likely reduced to 1x1, which is not "magically disappears"). ncurses will attempt to keep a window which has the same width (or height) as stdscr preserve that relationship when resizing, as mentioned in the manual page:

    When resizing windows, resize_term recursively adjusts subwindows, keeping them within the updated parent window's limits. If a top-level window happens to extend to the screen's limits, then on resizing the window, resize_term will keep the window extending to the corresponding limit, regardless of whether the screen has shrunk or grown.

    Regarding "starts to jitter", if your window did not enable keypad (as in the given fragment of code), then the cursor keys will be seen as a sequence of characters rather than as a single code:

    The keypad option enables the keypad of the user's terminal. If enabled (bf is TRUE), the user can press a function key (such as an arrow key) and wgetch(3x) returns a single value representing the function key, as in KEY_LEFT. If disabled (bf is FALSE), curses does not treat function keys specially and the program has to interpret the escape sequences itself. If the keypad in the terminal can be turned on (made to transmit) and off (made to work locally), turning on this option causes the terminal keypad to be turned on when wgetch(3x) is called. The default value for keypad is FALSE.