top: correct cursor positioning for all ^Z or ^C cases

Some more (very obscure) conditions where a suspension
or program end might embed the shell prompt within top
output have been uncovered beyond the 2 already known.

We had already covered some suspend/end contingencies:
1. the users were using the 'fields management' screen
2. the users were prompted for any line oriented input

However, there remained some situations where ^Z or ^C
could still produce a misplaced cursor + shell prompt:
3. the 'g' command while waiting for the window choice
4. the 'W' command if about to overwrite an old rcfile
5. the '=' command when exploiting the Inspect feature
6. the period during which any error message was shown

But, even when all those bases are covered there still
remains a remote possibility that such interrupts will
occur during a top repaint cycle. So rather than throw
yet more code at these self-inflicted problems perhaps
it is better if we just throw in the proverbial towel.

Thus, I'll take the only sane approach and restore the
results expected ever since top's inception and before
scrollback buffers entered the picture. Namely, with a
^Z or ^C the cursor will be placed on the final screen
row. That usually means it will immediately follow the
last output line but it may follow many blank lines if
the user interrupts top when *not* on the main screen.

Reference(s):
. expanded repositioning (for line oriented input)
commit 33104a2bcc
. introduced repositioning (for fields management)
commit 5c974ff44d
. scrollback buffers (the cursor handling changes)
commit dedaf6e1a8

Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
Jim Warner 2013-07-06 00:00:00 -05:00 committed by Jaromir Capik
parent 30e90e4269
commit 46a1356219

View File

@ -72,9 +72,8 @@ static struct termios Tty_original, // our inherited terminal definition
Tty_raw; // for unsolicited input Tty_raw; // for unsolicited input
static int Ttychanged = 0; static int Ttychanged = 0;
/* Last established cursor state/shape, and is re-position needed */ /* Last established cursor state/shape */
static const char *Cursor_state = ""; static const char *Cursor_state = "";
static int Cursor_repos;
/* Program name used in error messages and local 'rc' file name */ /* Program name used in error messages and local 'rc' file name */
static char *Myname; static char *Myname;
@ -351,7 +350,7 @@ static void at_eoj (void) {
if (Ttychanged) { if (Ttychanged) {
tcsetattr(STDIN_FILENO, TCSAFLUSH, &Tty_original); tcsetattr(STDIN_FILENO, TCSAFLUSH, &Tty_original);
if (keypad_local) putp(keypad_local); if (keypad_local) putp(keypad_local);
if (Cursor_repos) putp(tg2(0, Screen_rows)); putp(tg2(0, Screen_rows));
putp("\n"); putp("\n");
#ifdef OFF_SCROLLBK #ifdef OFF_SCROLLBK
if (exit_ca_mode) { if (exit_ca_mode) {
@ -602,7 +601,7 @@ static void sig_paused (int dont_care_sig) {
if (-1 == tcsetattr(STDIN_FILENO, TCSAFLUSH, &Tty_original)) if (-1 == tcsetattr(STDIN_FILENO, TCSAFLUSH, &Tty_original))
error_exit(fmtmk(N_fmt(FAIL_tty_set_fmt), strerror(errno))); error_exit(fmtmk(N_fmt(FAIL_tty_set_fmt), strerror(errno)));
if (keypad_local) putp(keypad_local); if (keypad_local) putp(keypad_local);
if (Cursor_repos) putp(tg2(0, Screen_rows)); putp(tg2(0, Screen_rows));
putp(Cap_curs_norm); putp(Cap_curs_norm);
#ifndef RMAN_IGNORED #ifndef RMAN_IGNORED
putp(Cap_smam); putp(Cap_smam);
@ -1081,14 +1080,12 @@ static char *ioline (const char *prompt) {
static char buf[MEDBUFSIZ]; static char buf[MEDBUFSIZ];
char *p; char *p;
Cursor_repos = 1;
show_pmt(prompt); show_pmt(prompt);
memset(buf, '\0', sizeof(buf)); memset(buf, '\0', sizeof(buf));
ioch(1, buf, sizeof(buf)-1); ioch(1, buf, sizeof(buf)-1);
if ((p = strpbrk(buf, ws))) *p = '\0'; if ((p = strpbrk(buf, ws))) *p = '\0';
// note: we DO produce a vaid 'string' // note: we DO produce a vaid 'string'
Cursor_repos = 0;
return buf; return buf;
} // end: ioline } // end: ioline
@ -1119,7 +1116,6 @@ static char *ioline (const char *prompt) {
}; };
static struct lin_s *anchor, *plin; static struct lin_s *anchor, *plin;
Cursor_repos = 1;
if (!anchor) { if (!anchor) {
anchor = alloc_c(sizeof(struct lin_s)); anchor = alloc_c(sizeof(struct lin_s));
anchor->str = alloc_s(""); // top-of-stack == empty str anchor->str = alloc_s(""); // top-of-stack == empty str
@ -1185,7 +1181,6 @@ static char *ioline (const char *prompt) {
putp(tg2(beg+pos, Msg_row)); putp(tg2(beg+pos, Msg_row));
} while (key && key != kbd_ENTER && key != kbd_ESC); } while (key && key != kbd_ENTER && key != kbd_ESC);
Cursor_repos = 0;
// weed out duplicates, including empty strings (top-of-stack)... // weed out duplicates, including empty strings (top-of-stack)...
for (i = 0, plin = anchor; ; i++) { for (i = 0, plin = anchor; ; i++) {
#ifdef RECALL_FIXED #ifdef RECALL_FIXED
@ -2126,7 +2121,6 @@ static void fields_utility (void) {
int i, key; int i, key;
FLG_t f; FLG_t f;
Cursor_repos = 1;
spewFI spewFI
signify_that: signify_that:
putp(Cap_clr_scr); putp(Cap_clr_scr);
@ -2187,7 +2181,6 @@ signify_that:
break; break;
} }
} while (key != 'q' && key != kbd_ESC); } while (key != 'q' && key != kbd_ESC);
Cursor_repos = 0;
#undef unSCRL #undef unSCRL
#undef swapEM #undef swapEM
#undef spewFI #undef spewFI