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 <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-01-08 10:36:12 +01:00
parent b430786f9b
commit 5f6fa25209
+7 -2
View File
@@ -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() {