forked from Mirrors/bubbletea
fix: stop renderer before launching a child process.
Stops the renderer before starting a child process, which prevents the repaint race condition that writes to non-altscreen.
This commit is contained in:
parent
90c9124b0a
commit
402d2b4e2b
|
@ -58,6 +58,7 @@ func newRenderer(out *termenv.Output, useANSICompressor bool) renderer {
|
|||
r := &standardRenderer{
|
||||
out: out,
|
||||
mtx: &sync.Mutex{},
|
||||
done: make(chan struct{}),
|
||||
framerate: defaultFramerate,
|
||||
useANSICompressor: useANSICompressor,
|
||||
queuedMessageLines: []string{},
|
||||
|
@ -72,12 +73,15 @@ func newRenderer(out *termenv.Output, useANSICompressor bool) renderer {
|
|||
func (r *standardRenderer) start() {
|
||||
if r.ticker == nil {
|
||||
r.ticker = time.NewTicker(r.framerate)
|
||||
} else {
|
||||
// If the ticker already exists, it has been stopped and we need to
|
||||
// reset it.
|
||||
r.ticker.Reset(r.framerate)
|
||||
}
|
||||
|
||||
// Since the renderer can be restarted after a stop, we need to reset
|
||||
// the done channel and its corresponding sync.Once.
|
||||
r.once = sync.Once{}
|
||||
r.done = make(chan struct{})
|
||||
|
||||
go r.listen()
|
||||
}
|
||||
|
@ -92,7 +96,7 @@ func (r *standardRenderer) stop() {
|
|||
|
||||
r.out.ClearLine()
|
||||
r.once.Do(func() {
|
||||
close(r.done)
|
||||
r.done <- struct{}{}
|
||||
})
|
||||
|
||||
if r.useANSICompressor {
|
||||
|
@ -109,7 +113,7 @@ func (r *standardRenderer) kill() {
|
|||
|
||||
r.out.ClearLine()
|
||||
r.once.Do(func() {
|
||||
close(r.done)
|
||||
r.done <- struct{}{}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -117,14 +121,12 @@ func (r *standardRenderer) kill() {
|
|||
func (r *standardRenderer) listen() {
|
||||
for {
|
||||
select {
|
||||
case <-r.ticker.C:
|
||||
if r.ticker != nil {
|
||||
r.flush()
|
||||
}
|
||||
case <-r.done:
|
||||
r.ticker.Stop()
|
||||
r.ticker = nil
|
||||
return
|
||||
|
||||
case <-r.ticker.C:
|
||||
r.flush()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
7
tea.go
7
tea.go
|
@ -567,6 +567,10 @@ func (p *Program) ReleaseTerminal() error {
|
|||
p.cancelReader.Cancel()
|
||||
p.waitForReadLoop()
|
||||
|
||||
if p.renderer != nil {
|
||||
p.renderer.stop()
|
||||
}
|
||||
|
||||
p.altScreenWasActive = p.renderer.altScreen()
|
||||
return p.restoreTerminalState()
|
||||
}
|
||||
|
@ -590,6 +594,9 @@ func (p *Program) RestoreTerminal() error {
|
|||
// entering alt screen already causes a repaint.
|
||||
go p.Send(repaintMsg{})
|
||||
}
|
||||
if p.renderer != nil {
|
||||
p.renderer.start()
|
||||
}
|
||||
|
||||
// If the output is a terminal, it may have been resized while another
|
||||
// process was at the foreground, in which case we may not have received
|
||||
|
|
Loading…
Reference in New Issue