Skip to content

Commit

Permalink
fix: maintain cursor visibility across altscreen state switch
Browse files Browse the repository at this point in the history
Based on charmbracelet#462 and charmbracelet#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 charmbracelet#190.
  • Loading branch information
muesli committed Oct 23, 2022
1 parent 918d357 commit 0f1ce7f
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
4 changes: 2 additions & 2 deletions screen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
23 changes: 23 additions & 0 deletions standard_renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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()
}

Expand All @@ -313,20 +325,31 @@ 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()
}

func (r *standardRenderer) showCursor() {
r.mtx.Lock()
defer r.mtx.Unlock()

r.cursorHidden = false
r.out.ShowCursor()
}

func (r *standardRenderer) hideCursor() {
r.mtx.Lock()
defer r.mtx.Unlock()

r.cursorHidden = true
r.out.HideCursor()
}

Expand Down

0 comments on commit 0f1ce7f

Please sign in to comment.