Reputation: 592
I am trying to handle a resize signal (SIGWINCH)
void Server::resizeSignalHandler(int a)
{
signal(SIGWINCH, SIG_IGN);
endwin();
initscr();
refresh();
clear();
int x,y;
getmaxyx(stdscr, y, x);
wmove(upScreen, 0, 0);
wmove(downScreen, y/2, 0);
wresize(upScreen, y/2, x);
wresize(downScreen, y/2, x);
wclear(upScreen);
wclear(downScreen);
waddstr(upScreen, "test1");
waddstr(downScreen, "test2");
wrefresh(upScreen);
wrefresh(downScreen);
refresh();
signal(SIGWINCH, Server::resizeSignalHandler);
}
Server::Server()
{
//ncurses screen initialization
initscr();
if (!upScreen) {
upScreen = newwin(0, 0, 1, 1);
}
if (!downScreen) {
downScreen = newwin(0, 0, 1, 1);
}
//adjusting screen when user resize terminal
signal(SIGWINCH, Server::resizeSignalHandler);
//configuring screens
Server::resizeSignalHandler(0);
waddstr(Server::upScreen, "lalfasdfsafd as");
waddstr(downScreen, "supreme!");
wrefresh(Server::upScreen);
wrefresh(downScreen);
}
When I was debugging this code, in resizeSignalHandler var x,y were always the same (size didn't change). I also tried determine size with ioctl, but nothing's changed.
I figured out that many people before me had this problem http://www.mail-archive.com/[email protected]/msg11253.html Sometimes, they solved that (changing /etc/profile ;O (sic!)), but sometimes not. Is there any alternative to mac os x terminal, maybe ncurses is dedicated for xterm and similar.
Upvotes: 4
Views: 2799
Reputation: 938
getmaxyx(...)
gives wrong (not updated) terminal sizes because of custom SIGWINCH
signal handler.
You can use ioctl(fileno(stdout), TIOCGWINSZ, struct winsize*)
to get updated terminal parameters. But this won't update data returned by getmaxyx(...)
.
To update getmaxyx(...)
data, you should call resize_term(size.ws_row, size.ws_col)
So the signal handler code should look like:
void on_terminal_resize(int n) {
struct winsize size;
if (ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) {
resize_term(size.ws_row, size.ws_col);
}
// Your code goes here...
signal(SIGWINCH, on_terminal_resize);
}
Upvotes: 1
Reputation: 903
That’s because the values you get with getmaxyx
are updated themselves by a signal handler listening to SIGWINCH
. You need to save the pointer to the old signal with something like:
old_callback = signal(SIGWINCH, Server::resizeSignalHandler);
and then call it in resizeSignalHandler
:
old_callback(a);
Upvotes: 1
Reputation: 14538
I don't have a mac machine, and cant test this. But I suppose the pseudo terminal bash is running on updates $LINES and $COLUMNS but these updates are not passed to the pseudo terminal your program is assigned to. This is because you say the WINCH signal is caught, but those params are not updated. A workaround is to execute "/usr/X11/bin/resize"
/ "/usr/bin/resize"
in the signal handler. Probably that would properly update $LINES and $COLUMNS.
Upvotes: -1
Reputation: 57784
I'm not sure, but I think you have to call ioctl(1, TIOCGWINSZ, struct winsize*)
to get the updated terminal parameters. See man tty_ioctl
.
Upvotes: 0