From 0f1ce7f2d9c94d9972a67566347ceb14a48c320b Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 13 Oct 2022 08:16:29 +0200 Subject: [PATCH] fix: maintain cursor visibility across altscreen state switch Based on #462 and #452 by @londek, but fixes maintaining the current visibility state across altscreen state changes. This makes the behavior consistent across terminals, some of which keep separate state for altscreen and regular buffer. Fixes #190. --- screen_test.go | 4 ++-- standard_renderer.go | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/screen_test.go b/screen_test.go index 33b5169..2f305e3 100644 --- a/screen_test.go +++ b/screen_test.go @@ -19,12 +19,12 @@ func TestClearMsg(t *testing.T) { { name: "altscreen", cmds: []Cmd{EnterAltScreen, ExitAltScreen}, - expected: "\x1b[?25l\x1b[?1049h\x1b[2J\x1b[1;1H\x1b[1;1H\x1b[?1049lsuccess\r\n\x1b[0D\x1b[2K\x1b[?25h\x1b[?1002l\x1b[?1003l", + expected: "\x1b[?25l\x1b[?1049h\x1b[2J\x1b[1;1H\x1b[1;1H\x1b[?25l\x1b[?1049l\x1b[?25lsuccess\r\n\x1b[0D\x1b[2K\x1b[?25h\x1b[?1002l\x1b[?1003l", }, { name: "altscreen_autoexit", cmds: []Cmd{EnterAltScreen}, - expected: "\x1b[?25l\x1b[?1049h\x1b[2J\x1b[1;1H\x1b[1;1Hsuccess\r\n\x1b[2;0H\x1b[2K\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1049l", + expected: "\x1b[?25l\x1b[?1049h\x1b[2J\x1b[1;1H\x1b[1;1H\x1b[?25lsuccess\r\n\x1b[2;0H\x1b[2K\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1049l\x1b[?25h", }, { name: "mouse_cellmotion", diff --git a/standard_renderer.go b/standard_renderer.go index 54c0f5d..17b44e2 100644 --- a/standard_renderer.go +++ b/standard_renderer.go @@ -38,6 +38,9 @@ type standardRenderer struct { useANSICompressor bool once sync.Once + // cursor visibility state + cursorHidden bool + // essentially whether or not we're using the full size of the terminal altScreenActive bool @@ -299,6 +302,15 @@ func (r *standardRenderer) enterAltScreen() { r.out.ClearScreen() r.out.MoveCursor(1, 1) + // cmd.exe and other terminals keep separate cursor states for the AltScreen + // and the main buffer. We have to explicitly reset the cursor visibility + // whenever we enter AltScreen. + if r.cursorHidden { + r.out.HideCursor() + } else { + r.out.ShowCursor() + } + r.repaint() } @@ -313,6 +325,15 @@ func (r *standardRenderer) exitAltScreen() { r.altScreenActive = false r.out.ExitAltScreen() + // cmd.exe and other terminals keep separate cursor states for the AltScreen + // and the main buffer. We have to explicitly reset the cursor visibility + // whenever we exit AltScreen. + if r.cursorHidden { + r.out.HideCursor() + } else { + r.out.ShowCursor() + } + r.repaint() } @@ -320,6 +341,7 @@ func (r *standardRenderer) showCursor() { r.mtx.Lock() defer r.mtx.Unlock() + r.cursorHidden = false r.out.ShowCursor() } @@ -327,6 +349,7 @@ func (r *standardRenderer) hideCursor() { r.mtx.Lock() defer r.mtx.Unlock() + r.cursorHidden = true r.out.HideCursor() }