From 4a9d97784f24bec72350396df9f58149c7deedc7 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Fri, 24 Jul 2020 19:17:29 +0200 Subject: [PATCH] app: [Android] don't block the main thread in Window.Do Signed-off-by: Elias Naur --- app/app_android.go | 19 ++++++++++++++----- app/window.go | 24 ++++++++++++------------ 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/app/app_android.go b/app/app_android.go index 58e40d0d..e45eb3e7 100644 --- a/app/app_android.go +++ b/app/app_android.go @@ -29,16 +29,25 @@ func (w *Window) Do(f func(view uintptr)) { } success := make(chan bool) for { - driver := make(chan androidDriver, 1) + driver := make(chan androidDriver) // two-stage process: first wait for a valid driver... - w.driverDo(func() { - driver <- w.driver.(androidDriver) - }) + go func() { + alive := w.driverDo(func() { + driver <- w.driver.(androidDriver) + }) + if !alive { + driver <- nil + } + }() + d := <-driver + if d == nil { + // Window is dead. + break + } // .. then run the function on the main thread using the // driver. The driver Do method returns false if the // view was invalidated while switching to the main thread. window.RunOnMain(func() { - d := <-driver success <- d.Do(f) }) if <-success { diff --git a/app/window.go b/app/window.go index 2c9860cb..87a70cce 100644 --- a/app/window.go +++ b/app/window.go @@ -193,17 +193,17 @@ func (w *Window) Invalidate() { } // ReadClipboard initiates a read of the clipboard in the form -// of a system.ClipboardEvent. Multiple reads may be coalescedd +// of a system.ClipboardEvent. Multiple reads may be coalesced // to a single event. func (w *Window) ReadClipboard() { - w.driverDo(func() { + go w.driverDo(func() { w.driver.ReadClipboard() }) } // WriteClipboard writes a string to the clipboard. func (w *Window) WriteClipboard(s string) { - w.driverDo(func() { + go w.driverDo(func() { w.driver.WriteClipboard(s) }) } @@ -214,20 +214,20 @@ func (w *Window) WriteClipboard(s string) { // Currently, only macOS, Windows and X11 drivers implement this functionality, // all others are stubbed. func (w *Window) Close() { - w.driverDo(func() { + go w.driverDo(func() { w.driver.Close() }) } // driverDo calls f as soon as the window has a valid driver attached, -// or does nothing if the window is destroyed while waiting. -func (w *Window) driverDo(f func()) { - go func() { - select { - case w.driverFuncs <- f: - case <-w.dead: - } - }() +// or return false if the window was destroyed while waiting. +func (w *Window) driverDo(f func()) bool { + select { + case w.driverFuncs <- f: + return true + case <-w.dead: + return false + } } func (w *Window) updateAnimation() {