Commit dedaf6e1 authored by jim warner's avatar jim warner Committed by Craig Small
Browse files

top: disable tty scrollback buffer to improve SIGWINCH

A scrollback buffer used in several terminal emulators
could be a real inconvenience to a user following some
resize operations. Extra keystroke(s) would frequently
be required in order to properly render top's display.

After much sleuthing we unearthed two terminfo strings
which have the effect of disabling/restoring that darn
scrollback buffer. They were well hidden under a title
of strings 'to start/end programs using cup'. In turn,
'cup' deals with a tty's cursor addressing capability.

We don't care what you call them or what they refer to
so long as they get the job done. And these really do!
Be advised, however, that there are some side effects,
several of which can even be considered as beneficial:

. enter_ca_mode/smcup/ti disables scrollback buffering
( and that's good, it's what we had always hoped for )

. exit_ca_mode/rmcup/te restores the scrollback buffer
( but also restores screen contents existing pre-top )
( which is different from former program end results )
( where that last rendered screen was left untouched )

. the above screen replacement would impact ^Z suspend
( thus we keep the scrollback buffer disabled during )
( the suspend/resume sequence so that the users will )
( have a visual clue that top is suspended not ended )

If a terminal does not support these terminfo strings,
we will revert to top's former behavior at program end
where we position the cursor at screen bottom and then
output a single newline character. This will prevent a
shell prompt from embedding within top's final screen.

This commit's approach has been tested under a variety
of emulators and window managers, many of which linked
with libvte and others that employed their own scheme.
Examples are: gnome_terminal; kde konsole; lxterminal;
terminator; terminology; urxvt; xfce4-terminal; xterm.

I do now believe that the whole SIGWINCH deal is done!

(everything is perfectly justified plus right margins)
(are completely filled, but of course it must be luck)


Signed-off-by: jim warner's avatarJim Warner <>
parent 365a5fa5
......@@ -330,12 +330,19 @@ static void at_eoj (void) {
if (Ttychanged) {
tcsetattr(STDIN_FILENO, TCSAFLUSH, &Tty_original);
if (keypad_local) putp(keypad_local);
putp(tg2(0, Screen_rows));
if (exit_ca_mode)
// this next will also replace top's most recent screen with the
// original display contents that were visible at our invocation
else {
// but if we can't, we'll simply do it as old top always used to
putp(tg2(0, Screen_rows));
Ttychanged = 0;
......@@ -564,7 +571,11 @@ static void sig_endpgm (int dont_care_sig) {
* Catches:
* note:
* we don't fiddle with with those enter/exit_ca_mode strings
* because we want to retain most of the last screen contents
* as a visual reminder this program is suspended, not ended! */
static void sig_paused (int dont_care_sig) {
// POSIX.1-2004 async-signal-safe: tcsetattr, tcdrain, raise
if (-1 == tcsetattr(STDIN_FILENO, TCSAFLUSH, &Tty_original))
......@@ -575,7 +586,10 @@ static void sig_paused (int dont_care_sig) {
// tcdrain(STDOUT_FILENO) was not reliable prior to ncurses-5.9.20121017,
// so we'll risk POSIX's wrath with good ol' fflush, lest 'Stopped' gets
// co-mingled with our most recent output...
// later, after SIGCONT...
if (-1 == tcsetattr(STDIN_FILENO, TCSAFLUSH, &Tty_raw))
......@@ -3487,6 +3501,8 @@ static void whack_terminal (void) {
// thanks anyway stdio, but we'll manage buffering at the frame level...
setbuffer(stdout, Stdout_buf, sizeof(Stdout_buf));
// this has the effect of disabling any troublesome scrollback buffer...
if (enter_ca_mode) putp(enter_ca_mode);
// and don't forget to ask iokey to initialize his tinfo_tab
} // end: whack_terminal
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment