I have a small ncurses-based program which performs basic chemical calculations. Its main function is like this:
int main() {
initscr();
cbreak();
nonl();
noecho();
/* draws borderlines from position 0 to (COLS - 1)
for purely decorative purposes at the top and bottom
of the screen */
draw_GUI();
keypress_loop();
endwin();
};
The keypress_loop()
function waits for user to press a key and then prints the key's symbol on the screen if the key is letter or digit and makes a beep if the key is neither letter nor digit. If user presses F2 the function returns and the program ends.
void keypress_loop()
{
int key;
while ((key = wgetch(stdscr)) != KEY_F(2))
process_key(key);
}
So far everything works as intended. But then I add a signal handler for SIGWINCH to make sure that borderlines are redrawn correctly after resizing the terminal emulator's window. Before initscr()
in the main()
function I insert:
signal(SIGWINCH, handle_resizing);
And handle_resizing
() looks like this:
static void
handle_resizing(int signo) {
endwin();
initscr();
cbreak();
nonl();
noecho();
draw_GUI();
}
This SIGWINCH-handling function redraws the borderlines as intended. But the problem is that, when user presses a key after resizing, the program ignores this key. And only after user presses a key three or more times the program starts recognizing the key and then everything works OK! How can I make the program to immediately recognize key presses after resizing?
The handle_resizing
function calls functions which are unsafe to use in a signal handler. The resizeterm
manual page has a section discussing this. Your program should use the KEY_RESIZE
return value from getch
.