diff --git a/options.go b/options.go index d1c0403..b9e8104 100644 --- a/options.go +++ b/options.go @@ -3,6 +3,7 @@ package tea import ( "context" "io" + "sync/atomic" "github.com/muesli/termenv" ) @@ -76,7 +77,7 @@ func WithoutCatchPanics() ProgramOption { // This is mainly useful for testing. func WithoutSignals() ProgramOption { return func(p *Program) { - p.ignoreSignals = true + atomic.StoreUint32(&p.ignoreSignals, 1) } } diff --git a/options_test.go b/options_test.go index fdbc5b2..74e75fe 100644 --- a/options_test.go +++ b/options_test.go @@ -2,6 +2,7 @@ package tea import ( "bytes" + "sync/atomic" "testing" ) @@ -37,7 +38,7 @@ func TestOptions(t *testing.T) { t.Run("without signals", func(t *testing.T) { p := NewProgram(nil, WithoutSignals()) - if !p.ignoreSignals { + if atomic.LoadUint32(&p.ignoreSignals) == 0 { t.Errorf("ignore signals should have been set") } }) diff --git a/tea.go b/tea.go index 34fb883..74e83e3 100644 --- a/tea.go +++ b/tea.go @@ -18,6 +18,7 @@ import ( "os/signal" "runtime/debug" "sync" + "sync/atomic" "syscall" "github.com/containerd/console" @@ -153,7 +154,7 @@ type Program struct { // was the altscreen active before releasing the terminal? altScreenWasActive bool - ignoreSignals bool + ignoreSignals uint32 // Stores the original reference to stdin for cases where input is not a // TTY on windows and we've automatically opened CONIN$ to receive input. @@ -238,7 +239,7 @@ func (p *Program) handleSignals() chan struct{} { return case <-sig: - if !p.ignoreSignals { + if atomic.LoadUint32(&p.ignoreSignals) == 0 { p.msgs <- QuitMsg{} return } @@ -632,7 +633,7 @@ func (p *Program) shutdown(kill bool) { // ReleaseTerminal restores the original terminal state and cancels the input // reader. You can return control to the Program with RestoreTerminal. func (p *Program) ReleaseTerminal() error { - p.ignoreSignals = true + atomic.StoreUint32(&p.ignoreSignals, 1) p.cancelReader.Cancel() p.waitForReadLoop() @@ -648,7 +649,7 @@ func (p *Program) ReleaseTerminal() error { // terminal to the former state when the program was running, and repaints. // Use it to reinitialize a Program after running ReleaseTerminal. func (p *Program) RestoreTerminal() error { - p.ignoreSignals = false + atomic.StoreUint32(&p.ignoreSignals, 0) if err := p.initTerminal(); err != nil { return err