fixes #682 views/app uses deprecated PostEventWait

This commit is contained in:
Garrett D'Amore 2024-02-15 22:01:05 -08:00
parent c3711de418
commit cc24c71d4b
1 changed files with 25 additions and 38 deletions

View File

@ -1,4 +1,4 @@
// Copyright 2018 The Tcell Authors // Copyright 2024 The Tcell Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License. // you may not use file except in compliance with the License.
@ -28,6 +28,9 @@ type Application struct {
err error err error
wg sync.WaitGroup wg sync.WaitGroup
paste bool paste bool
stopQ chan struct{}
eventQ chan tcell.Event
stopOnce sync.Once
} }
// SetRootWidget sets the primary (root, main) Widget to be displayed. // SetRootWidget sets the primary (root, main) Widget to be displayed.
@ -56,30 +59,23 @@ func (app *Application) initialize() error {
// Quit causes the application to shutdown gracefully. It does not wait // Quit causes the application to shutdown gracefully. It does not wait
// for the application to exit, but returns immediately. // for the application to exit, but returns immediately.
func (app *Application) Quit() { func (app *Application) Quit() {
ev := &eventAppQuit{} app.stopOnce.Do(func() { close(app.stopQ) })
ev.SetEventNow()
if scr := app.screen; scr != nil {
go func() { scr.PostEventWait(ev) }()
}
} }
// Refresh causes the application forcibly redraw everything. Use this // Refresh causes the application forcibly redraw everything. Use this
// to clear up screen corruption, etc. // to clear up screen corruption, etc.
func (app *Application) Refresh() { func (app *Application) Refresh() {
ev := &eventAppRefresh{}
ev.SetEventNow()
if scr := app.screen; scr != nil { if scr := app.screen; scr != nil {
go func() { scr.PostEventWait(ev) }() scr.Sync()
} }
} }
// Update asks the application to draw any screen updates that have not // Update asks the application to draw any screen updates that have not
// been drawn yet. // been drawn yet. It is not necessary to call this from inside an
// event handler, as a draw will be done implicitly after handling events.
func (app *Application) Update() { func (app *Application) Update() {
ev := &eventAppUpdate{}
ev.SetEventNow()
if scr := app.screen; scr != nil { if scr := app.screen; scr != nil {
go func() { scr.PostEventWait(ev) }() scr.Show()
} }
} }
@ -140,6 +136,10 @@ func (app *Application) run() {
screen.Clear() screen.Clear()
widget.SetView(screen) widget.SetView(screen)
app.eventQ = make(chan tcell.Event, 16)
app.stopQ = make(chan struct{})
go screen.ChannelEvents(app.eventQ, app.stopQ)
loop: loop:
for { for {
if widget = app.widget; widget == nil { if widget = app.widget; widget == nil {
@ -148,14 +148,13 @@ loop:
widget.Draw() widget.Draw()
screen.Show() screen.Show()
ev := screen.PollEvent() ev := <-app.eventQ
switch nev := ev.(type) { // ev := screen.PollEvent()
case *eventAppQuit: if ev == nil {
screen.Fini()
break loop break loop
case *eventAppUpdate: }
screen.Show() switch nev := ev.(type) {
case *eventAppRefresh:
screen.Sync()
case *eventAppFunc: case *eventAppFunc:
nev.fn() nev.fn()
case *tcell.EventResize: case *tcell.EventResize:
@ -188,18 +187,6 @@ func (app *Application) Run() error {
return app.Wait() return app.Wait()
} }
type eventAppUpdate struct {
tcell.EventTime
}
type eventAppQuit struct {
tcell.EventTime
}
type eventAppRefresh struct {
tcell.EventTime
}
type eventAppFunc struct { type eventAppFunc struct {
tcell.EventTime tcell.EventTime
fn func() fn func()