From 5f6fa252099ebdd4eb3f08cc4674aff2ca9a2c97 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Fri, 8 Jan 2021 10:36:12 +0100 Subject: [PATCH] app/internal/window: [wasm] have at most one animation callback in flight Track whether requestAnimationCallback has been called when SetAnimating changes the animated state of the window. Multiple callbacks result in wasteful redraws. Without this change, my browser becomes unresponsive when Window.Invalidate is called every frame. Calling Invalidate every frame is a misuse (InvalidateOp should be used for animation), but it's nice to have reasonable behaviour. This change might also fix the issues described in https://github.com/gioui/gio/pull/7. Signed-off-by: Elias Naur --- app/internal/window/os_js.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/internal/window/os_js.go b/app/internal/window/os_js.go index ca790e76..a0cd30c7 100644 --- a/app/internal/window/os_js.go +++ b/app/internal/window/os_js.go @@ -41,6 +41,9 @@ type window struct { inset f32.Point scale float32 animating bool + // animRequested tracks whether a requestAnimationFrame callback + // is pending. + animRequested bool } func NewWindow(win Callbacks, opts *Options) error { @@ -417,6 +420,7 @@ func (w *window) funcOf(f func(this js.Value, args []js.Value) interface{}) js.F func (w *window) animCallback() { w.mu.Lock() anim := w.animating + w.animRequested = anim if anim { w.requestAnimationFrame.Invoke(w.redraw) } @@ -429,10 +433,11 @@ func (w *window) animCallback() { func (w *window) SetAnimating(anim bool) { w.mu.Lock() defer w.mu.Unlock() - if anim && !w.animating { + w.animating = anim + if anim && !w.animRequested { + w.animRequested = true w.requestAnimationFrame.Invoke(w.redraw) } - w.animating = anim } func (w *window) ReadClipboard() {