app: [API] replace events channel with an iterator interface

The goroutine started by Window.run runs concurrently with the user
goroutine receiving from Window.Events, leading to races such as #543.
This change replaces the Window.run goroutine and the Window.Events
channel with an iterator API driven by the user goroutine directly.

Fixes: https://todo.sr.ht/~eliasnaur/gio/543
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2023-10-12 16:01:07 -05:00
parent 7550d85447
commit 37717d0df9
2 changed files with 59 additions and 34 deletions
+6 -5
View File
@@ -12,16 +12,16 @@ Create a new Window by calling NewWindow. On mobile platforms or when Gio
is embedded in another project, NewWindow merely connects with a previously
created window.
A Window is run by receiving events from its Events channel. The most
important event is FrameEvent that prompts an update of the window
contents and state.
A Window is run by calling NextEvent in a loop. The most important event is
FrameEvent that prompts an update of the window contents.
For example:
import "gioui.org/unit"
w := app.NewWindow()
for e := range w.Events() {
for {
e := w.NextEvent()
if e, ok := e.(system.FrameEvent); ok {
ops.Reset()
// Add operations to ops.
@@ -50,7 +50,8 @@ For example, to display a blank but otherwise functional window:
func main() {
go func() {
w := app.NewWindow()
for range w.Events() {
for {
w.NextEvent()
}
}()
app.Main()