diff --git a/options.go b/options.go index 6ede540..3aad18c 100644 --- a/options.go +++ b/options.go @@ -38,6 +38,14 @@ func WithInputTTY() ProgramOption { } } +// WithoutSignalHandler disables the signal handler that Bubble Tea sets up for +// Programs. This is useful if you want to handle signals yourself. +func WithoutSignalHandler() ProgramOption { + return func(p *Program) { + p.startupOptions |= withoutSignalHandler + } +} + // WithoutCatchPanics disables the panic catching that Bubble Tea does by // default. If panic catching is disabled the terminal will be in a fairly // unusable state after a panic because Bubble Tea will not perform its usual diff --git a/options_test.go b/options_test.go index 6648ddd..ba44410 100644 --- a/options_test.go +++ b/options_test.go @@ -62,6 +62,10 @@ func TestOptions(t *testing.T) { exercise(t, WithANSICompressor(), withANSICompressor) }) + t.Run("without signal handler", func(t *testing.T) { + exercise(t, WithoutSignalHandler(), withoutSignalHandler) + }) + t.Run("mouse cell motion", func(t *testing.T) { p := NewProgram(nil, WithMouseAllMotion(), WithMouseCellMotion()) if !p.startupOptions.has(withMouseCellMotion) { diff --git a/tea.go b/tea.go index 52bd09b..82afda5 100644 --- a/tea.go +++ b/tea.go @@ -71,6 +71,7 @@ const ( withInputTTY withCustomInput withANSICompressor + withoutSignalHandler ) // Program is a terminal user interface. @@ -375,7 +376,12 @@ func (p *Program) StartReturningModel() (Model, error) { } // Handle signals. - sigintLoopDone := p.handleSignals() + sigintLoopDone := make(chan struct{}) + if !p.startupOptions.has(withoutSignalHandler) { + sigintLoopDone = p.handleSignals() + } else { + close(sigintLoopDone) + } if p.CatchPanics { defer func() {