Aha! At long last I've managed to reproduce the intermittent problem

I've been having with the cursor sometimes restoring to the wrong
place when screen(1) terminates. The offending sequence of escape
sequences goes ESC 7 (save cursor), ESC [?47h (switch to alternate
screen), ESC 7 (save cursor _again_), do some stuff, ESC 8 (restore
cursor), run screen session for a bit, ESC [?47l (return to main
screen), ESC 8 (restore cursor). The final ESC 8 is expected to
restore the cursor to where it was saved by the initial ESC 7.

Translation: the ESC 7 saved cursor state is part of the state we
must swap out when switching to the alternate screen. In other
words, we need to track _four_ cursor positions: active and saved,
on each of main and alternate screen. Previously we were tracking
only three.

[originally from svn r6788]
This commit is contained in:
Simon Tatham 2006-08-15 12:45:21 +00:00
Родитель 33b7caa590
Коммит 09f86ce7ec
1 изменённых файлов: 35 добавлений и 5 удалений

Просмотреть файл

@ -1184,6 +1184,7 @@ static void power_on(Terminal *term, int clear)
{
term->alt_x = term->alt_y = 0;
term->savecurs.x = term->savecurs.y = 0;
term->alt_savecurs.x = term->alt_savecurs.y = 0;
term->alt_t = term->marg_t = 0;
if (term->rows != -1)
term->alt_b = term->marg_b = term->rows - 1;
@ -1196,13 +1197,16 @@ static void power_on(Terminal *term, int clear)
}
term->alt_om = term->dec_om = term->cfg.dec_om;
term->alt_ins = term->insert = FALSE;
term->alt_wnext = term->wrapnext = term->save_wnext = FALSE;
term->alt_wnext = term->wrapnext =
term->save_wnext = term->alt_save_wnext = FALSE;
term->alt_wrap = term->wrap = term->cfg.wrap_mode;
term->alt_cset = term->cset = term->save_cset = 0;
term->alt_utf = term->utf = term->save_utf = 0;
term->alt_cset = term->cset = term->save_cset = term->alt_save_cset = 0;
term->alt_utf = term->utf = term->save_utf = term->alt_save_utf = 0;
term->utf_state = 0;
term->alt_sco_acs = term->sco_acs = term->save_sco_acs = 0;
term->cset_attr[0] = term->cset_attr[1] = term->save_csattr = CSET_ASCII;
term->alt_sco_acs = term->sco_acs =
term->save_sco_acs = term->alt_save_sco_acs = 0;
term->cset_attr[0] = term->cset_attr[1] =
term->save_csattr = term->alt_save_csattr = CSET_ASCII;
term->rvideo = 0;
term->in_vbell = FALSE;
term->cursor_on = 1;
@ -1747,6 +1751,7 @@ static int find_last_nonempty_line(Terminal * term, tree234 * screen)
static void swap_screen(Terminal *term, int which, int reset, int keep_cur_pos)
{
int t;
pos tp;
tree234 *ttr;
if (!which)
@ -1794,6 +1799,31 @@ static void swap_screen(Terminal *term, int which, int reset, int keep_cur_pos)
t = term->sco_acs;
if (!reset) term->sco_acs = term->alt_sco_acs;
term->alt_sco_acs = t;
tp = term->savecurs;
if (!reset && !keep_cur_pos)
term->savecurs = term->alt_savecurs;
term->alt_savecurs = tp;
t = term->save_cset;
if (!reset && !keep_cur_pos)
term->save_cset = term->alt_save_cset;
term->alt_save_cset = t;
t = term->save_csattr;
if (!reset && !keep_cur_pos)
term->save_csattr = term->alt_save_csattr;
term->alt_save_csattr = t;
t = term->save_utf;
if (!reset && !keep_cur_pos)
term->save_utf = term->alt_save_utf;
term->alt_save_utf = t;
t = term->save_wnext;
if (!reset && !keep_cur_pos)
term->save_wnext = term->alt_save_wnext;
term->alt_save_wnext = t;
t = term->save_sco_acs;
if (!reset && !keep_cur_pos)
term->save_sco_acs = term->alt_save_sco_acs;
term->alt_save_sco_acs = t;
}
if (reset && term->screen) {