Skip to content

Ignore private CSI ? u instead of treating it as cursor restore to match upstream st to fix cursor moved to top of terminal upon lazygit exit. #374

Description

@Obazzi

Bug

When lazygit exits, the cursor is moved back to the top of the terminal and the screen is not cleared. As a result, the shell prompt appears over the previous shell prompt at the top of the terminal. Previously, lazygit behaved like vim: it used the alternate screen and, on exit, returned me exactly to the shell screen state from before launching it with the cursor in the right position (last position). This bug does not happen in stock st or my highly patched new st build I'm working on.

To Reproduce

  1. Open st.
  2. Spam enter to add lines of text.
  3. Run lazygit.
  4. Quit lazygit with q.
  5. Observe the terminal after lazygit exits. Press enter to make it obvious.

Fix

Only handle non-private CSI u as cursor restore. Treat private CSI ? u as unknown, matching upstream st.

diff --git a/st.c b/st.c
index 7256475..ace700d 100644
--- a/st.c
+++ b/st.c
@@ -1880,7 +1880,11 @@ csihandle(void)
 		tcursor(CURSOR_SAVE);
 		break;
 	case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */
-		tcursor(CURSOR_LOAD);
+		if (csiescseq.priv) {
+			goto unknown;
+		} else {
+			tcursor(CURSOR_LOAD);
+		}
 		break;
 	case ' ':
 		switch (csiescseq.mode[1]) {

Why

Newer terminal applications/libraries such as recent version of lazygit/tcell emit ESC[?u as a terminal capability/key protocol probe. CSI ? u is currently handled by the same branch as normal CSI u:

case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */
    tcursor(CURSOR_LOAD);
    break;

This means a private CSI query/probe is incorrectly treated as cursor restore. Stock current upstream st guards against private CSI u. Without it, ESC[?u incorrectly triggered tcursor(CURSOR_LOAD); witch caused the cursor to go to the top of the terminal upon exit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions