bug-ncurses
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Resizing properly without calling endwin()?


From: Ignacy Gawedzki
Subject: Resizing properly without calling endwin()?
Date: Sat, 9 Feb 2008 15:05:55 +0100
User-agent: Mutt/1.5.15+20070412 (2007-04-11)

Hi all,

I've been fighting with ncurses to get it handle resizing properly, for a few
hours and haven't found yet any more robust solution than to call
endwin() and refresh().

The thing is I need my own signal handler for SIGWINCH because I don't want to
rely on calling getch() (or wget_wch(), since I'm using wide characters) to
detect a terminal resize.

At first I simply applied the common solution, which is calling endwin() and
refresh() after a resize and redrawing all my stuff from scratch.  Although
this is a pretty solid way of dealing with resizes, with TERM=xterm it has the
ugly effect of showing glimpses of the terminal as it is *before* ncurses
initializes it.  This is because endwin() restores the previous terminal
state.

I tried to avoid doing that by calling resize_term() myself (using the values
returned by TIOCGWINSZ) and calling clear() and refresh().  Unfortunately,
when the terminal is resized very often (i.e. when the window manager is set
to show the updated window at every intermediate dimensions), sometimes the
screen is not redrawn properly.  This is very difficult to reproduce in a
deterministic way, so that looking at the trace logs is futile.

My program generally blocks the SIGWINCH signal, except when waiting in a call
to ppoll(), so that SIGWINCH deliveries happen exclusively during that call,
which gets interrupted and returns EINTR.  The handler itself only modifies a
global boolean variable to mark the event and the screen redrawing is
performed asynchronously.

My explanation so far is the following: if the terminal is resized slowly
enough to allow a complete redraw between each resize, then everything is fine
(this happens most of the time); but if the terminal is resized *during* a
redraw, although the signal itself is delivered at a later point and another
redraw is performed, the ncurses internal buffer that's supposed to reflect
the physical state of the screen is not doing so anymore and the subsequent
calls to refresh() or wrefresh() don't update the screen properly.

So my question is the following: how can I tell ncurses that its internal
buffer representing the physical screen is not reliable anymore and that it
has to erase the whole screen and start drawing again from scratch, just as it
does in the initial call to clear() but *without* restoring the previous state
(so as to avoid showing the previous screen content) as it is done by a call
to endwin() and refresh()?

Thanks.

Ignacy

-- 
Save the whales. Feed the hungry. Free the mallocs. 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]