1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Fix cursor save/restore with [?1047 alt-screen sequences.

A long time ago, in commit 09f86ce7e, I introduced a separate copy of
the saved cursor position (used by the ESC 7 / ESC 8 sequences) for
the main and alternate screens. The idea was to fix mishandling of an
input sequence of the form

  ESC 7        (save cursor)
  ESC [?47h    (switch to alternate screen)
  ...
  ESC 7 ESC 8  (save and restore cursor, while in alternate screen)
  ...
  ESC [?47l    (switch back from alternate screen)
  ESC 8        (restore cursor, expecting it to match the _first_ ESC 7)

in which, before the fix, the second ESC 7 would overwrite the
position saved by the first one. So the final ESC 8 would restore the
cursor position to wherever it happened to have been saved in the
alternate screen, instead of where it was saved before switching _to_
the alternate screen.

I've recently noticed that the same bug still happens if you use the
alternative escape sequences ESC[?1047h and ESC[?1047l to switch to
the alternate screen, instead of ESC[?47h and ESC[?47l. This is
because that version of the escape sequence sets the internal flag
'keep_cur_pos' in the call to swap_screen, whose job is to arrange
that the actual cursor position doesn't change at the instant of the
switch. But the code that swaps the _saved_ cursor position in and out
is also conditioned on keep_cur_pos, so the 1047 variant of the
screen-swap sequence was bypassing that too, and behaving as if there
was just a single saved cursor position inside and outside the
alternate screen.

I don't know why I did it that way in 2006. It could have been
deliberate for some reason, or it could just have been mindless copy
and paste from the existing cursor-related swap code. But checking
with xterm now, it definitely seems to be wrong: the 1047 screen swap
preserves the _actual_ cursor position across the swap, but still has
independent _saved_ cursor positions in the two screens. So now PuTTY
does the same.

(cherry picked from commit 421a8ca5d9)
This commit is contained in:
Simon Tatham 2019-12-24 10:52:38 +00:00
parent 3d44cef8ea
commit b77bcae021

View File

@ -2089,35 +2089,35 @@ static void swap_screen(Terminal *term, int which,
term->alt_sco_acs = t;
tp = term->savecurs;
if (!reset && !keep_cur_pos)
if (!reset)
term->savecurs = term->alt_savecurs;
term->alt_savecurs = tp;
t = term->save_cset;
if (!reset && !keep_cur_pos)
if (!reset)
term->save_cset = term->alt_save_cset;
term->alt_save_cset = t;
t = term->save_csattr;
if (!reset && !keep_cur_pos)
if (!reset)
term->save_csattr = term->alt_save_csattr;
term->alt_save_csattr = t;
t = term->save_attr;
if (!reset && !keep_cur_pos)
if (!reset)
term->save_attr = term->alt_save_attr;
term->alt_save_attr = t;
ttc = term->save_truecolour;
if (!reset && !keep_cur_pos)
if (!reset)
term->save_truecolour = term->alt_save_truecolour;
term->alt_save_truecolour = ttc;
bt = term->save_utf;
if (!reset && !keep_cur_pos)
if (!reset)
term->save_utf = term->alt_save_utf;
term->alt_save_utf = bt;
bt = term->save_wnext;
if (!reset && !keep_cur_pos)
if (!reset)
term->save_wnext = term->alt_save_wnext;
term->alt_save_wnext = bt;
t = term->save_sco_acs;
if (!reset && !keep_cur_pos)
if (!reset)
term->save_sco_acs = term->alt_save_sco_acs;
term->alt_save_sco_acs = t;
}