From 1006608093fbbe19103f63fc1140b122a3904500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 16 Mar 2020 12:00:25 +0100 Subject: [PATCH] alt-screen: use a custom 'saved' cursor when switching to alt screen This fixes an issue where we failed to restore the cursor correctly when exiting from the alternate screen, if the client had sent escapes to save the cursor position while inside the alternate screen. This was because we used the *same* storage for saving the cursor position through escapes, as for saving it when entering the alternate screen. Fix by using a custom variable dedicated to normal <--> alt screen switching. --- CHANGELOG.md | 1 + csi.c | 6 +++--- terminal.c | 10 +++++----- terminal.h | 2 +- vt.c | 2 +- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00fda7e8..a4e76cbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ ### Fixed * Sixel images moved or deleted on window resize. +* Cursor sometimes incorrectly restored on exit from alternate screen. ### Security diff --git a/csi.c b/csi.c index 6147f27b..189188c6 100644 --- a/csi.c +++ b/csi.c @@ -761,7 +761,7 @@ csi_dispatch(struct terminal *term, uint8_t final) break; case 'u': - term_restore_cursor(term); + term_restore_cursor(term, &term->saved_cursor); break; case 't': { @@ -1014,7 +1014,7 @@ csi_dispatch(struct terminal *term, uint8_t final) selection_cancel(term); term->grid = &term->alt; - term->saved_cursor = term->cursor; + term->alt_saved_cursor = term->cursor; term_cursor_to(term, term->cursor.point.row, term->cursor.point.col); @@ -1137,7 +1137,7 @@ csi_dispatch(struct terminal *term, uint8_t final) selection_cancel(term); term->grid = &term->normal; - term_restore_cursor(term); + term_restore_cursor(term, &term->alt_saved_cursor); tll_free(term->alt.damage); tll_free(term->alt.scroll_damage); diff --git a/terminal.c b/terminal.c index 17233690..552b8d2a 100644 --- a/terminal.c +++ b/terminal.c @@ -1120,7 +1120,7 @@ term_reset(struct terminal *term, bool hard) if (term->grid == &term->alt) { term->grid = &term->normal; - term_restore_cursor(term); + term_restore_cursor(term, &term->alt_saved_cursor); selection_cancel(term); } @@ -1645,12 +1645,12 @@ term_reset_view(struct terminal *term) } void -term_restore_cursor(struct terminal *term) +term_restore_cursor(struct terminal *term, const struct cursor *cursor) { - int row = min(term->saved_cursor.point.row, term->rows - 1); - int col = min(term->saved_cursor.point.col, term->cols - 1); + int row = min(cursor->point.row, term->rows - 1); + int col = min(cursor->point.col, term->cols - 1); term_cursor_to(term, row, col); - term->cursor.lcf = term->saved_cursor.lcf; + term->cursor.lcf = cursor->lcf; } void diff --git a/terminal.h b/terminal.h index 90379ba1..67785399 100644 --- a/terminal.h +++ b/terminal.h @@ -486,7 +486,7 @@ void term_reverse_index(struct terminal *term); void term_arm_blink_timer(struct terminal *term); -void term_restore_cursor(struct terminal *term); +void term_restore_cursor(struct terminal *term, const struct cursor *cursor); void term_visual_focus_in(struct terminal *term); void term_visual_focus_out(struct terminal *term); diff --git a/vt.c b/vt.c index 3cdd5b24..12bc1245 100644 --- a/vt.c +++ b/vt.c @@ -347,7 +347,7 @@ action_esc_dispatch(struct terminal *term, uint8_t final) break; case '8': - term_restore_cursor(term); + term_restore_cursor(term, &term->saved_cursor); term->vt.attrs = term->vt.saved_attrs; term->charsets = term->saved_charsets; break;