Restore the terminal if one of gocui's goroutines panics

A panic in the goroutine that polls the terminal for events leaves the
terminal in raw mode and on the alternate screen. The panic is then
hard to read, and the terminal needs a reset afterwards.

Guard this goroutine the same way as the worker goroutines. Guard the
goroutines that send a resize event too; they are unlikely to panic,
but this way all of gocui's goroutines are guarded, and a check for
unguarded goroutines doesn't need any exceptions.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan HallerandClaude Opus 5.5 committed 2026-10-14 20:28:53 +02:00
1 parent d8972194d5
commit 6042e1c28b
1 file changed
+4 -4
+4 -4
View File
@@ -1106,7 +1106,7 @@ func (g *Gui) SetManager(managers ...Manager) {
g.keybindings = nil
g.tabClickBindings = nil
go func() { g.gEvents <- GocuiEvent{Type: eventResize} }()
go safe(func() { g.gEvents <- GocuiEvent{Type: eventResize} })
}
// SetManagerFunc sets the given manager function. It deletes all views and
@@ -1120,7 +1120,7 @@ func (g *Gui) SetManagerFunc(manager func(*Gui) error) {
func (g *Gui) MainLoop() error {
defer close(g.loopExited)
go func() {
go safe(func() {
for {
select {
case <-g.stop:
@@ -1129,7 +1129,7 @@ func (g *Gui) MainLoop() error {
g.gEvents <- g.pollEvent()
}
}
}()
})
Screen.EnableFocus()
Screen.EnablePaste()
@@ -2187,7 +2187,7 @@ func (g *Gui) Resume() error {
// Schedule a redraw of the whole screen. Nothing else guarantees one:
// flushes are skipped while suspended, and after re-engaging the screen
// the terminal shows nothing until we draw again.
go func() { g.gEvents <- GocuiEvent{Type: eventResize} }()
go safe(func() { g.gEvents <- GocuiEvent{Type: eventResize} })
return nil
}