app: [Android] don't block the main thread in Window.Do

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2020-07-24 19:17:29 +02:00
parent e381ff40d6
commit 4a9d97784f
2 changed files with 26 additions and 17 deletions
+14 -5
View File
@@ -29,16 +29,25 @@ func (w *Window) Do(f func(view uintptr)) {
} }
success := make(chan bool) success := make(chan bool)
for { for {
driver := make(chan androidDriver, 1) driver := make(chan androidDriver)
// two-stage process: first wait for a valid driver... // two-stage process: first wait for a valid driver...
w.driverDo(func() { go func() {
driver <- w.driver.(androidDriver) 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 // .. then run the function on the main thread using the
// driver. The driver Do method returns false if the // driver. The driver Do method returns false if the
// view was invalidated while switching to the main thread. // view was invalidated while switching to the main thread.
window.RunOnMain(func() { window.RunOnMain(func() {
d := <-driver
success <- d.Do(f) success <- d.Do(f)
}) })
if <-success { if <-success {
+12 -12
View File
@@ -193,17 +193,17 @@ func (w *Window) Invalidate() {
} }
// ReadClipboard initiates a read of the clipboard in the form // 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. // to a single event.
func (w *Window) ReadClipboard() { func (w *Window) ReadClipboard() {
w.driverDo(func() { go w.driverDo(func() {
w.driver.ReadClipboard() w.driver.ReadClipboard()
}) })
} }
// WriteClipboard writes a string to the clipboard. // WriteClipboard writes a string to the clipboard.
func (w *Window) WriteClipboard(s string) { func (w *Window) WriteClipboard(s string) {
w.driverDo(func() { go w.driverDo(func() {
w.driver.WriteClipboard(s) w.driver.WriteClipboard(s)
}) })
} }
@@ -214,20 +214,20 @@ func (w *Window) WriteClipboard(s string) {
// Currently, only macOS, Windows and X11 drivers implement this functionality, // Currently, only macOS, Windows and X11 drivers implement this functionality,
// all others are stubbed. // all others are stubbed.
func (w *Window) Close() { func (w *Window) Close() {
w.driverDo(func() { go w.driverDo(func() {
w.driver.Close() w.driver.Close()
}) })
} }
// driverDo calls f as soon as the window has a valid driver attached, // driverDo calls f as soon as the window has a valid driver attached,
// or does nothing if the window is destroyed while waiting. // or return false if the window was destroyed while waiting.
func (w *Window) driverDo(f func()) { func (w *Window) driverDo(f func()) bool {
go func() { select {
select { case w.driverFuncs <- f:
case w.driverFuncs <- f: return true
case <-w.dead: case <-w.dead:
} return false
}() }
} }
func (w *Window) updateAnimation() { func (w *Window) updateAnimation() {