From b2a99fddcad3c952cc7e0dfb05021c57de072693 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Tue, 11 Jan 2022 08:59:58 +0100 Subject: [PATCH] app: run driver callbacks after event processing Running, for example, Window.Close during a FrameEvent processing doesn't end well on platforms that immediately destroys the window. This change defers callbacks to after the completing the current event. Fixes: https://todo.sr.ht/~eliasnaur/gio/340 Signed-off-by: Elias Naur --- app/window.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/window.go b/app/window.go index f32b4619..b20fbfa6 100644 --- a/app/window.go +++ b/app/window.go @@ -48,6 +48,7 @@ type Window struct { waiting bool waitEvents []event.Event + defers []func(d driver) out chan event.Event frames chan *op.Ops frameAck chan struct{} @@ -428,6 +429,10 @@ func (c *callbacks) Event(e event.Event) { c.w.waitEvents = c.w.waitEvents[:len(c.w.waitEvents)-1] c.w.processEvent(c.d, we) } + for _, f := range c.w.defers { + f(c.d) + } + c.w.defers = nil c.w.updateState(c.d) } @@ -465,7 +470,7 @@ func (w *Window) waitAck(d driver) { for { select { case f := <-w.driverFuncs: - f(d) + w.defers = append(w.defers, f) case w.out <- ackEvent: // A dummy event went through, so we know the application has processed the previous event. return @@ -500,7 +505,7 @@ func (w *Window) waitFrame(d driver) (*op.Ops, bool) { for { select { case f := <-w.driverFuncs: - f(d) + w.defers = append(w.defers, f) case frame := <-w.frames: // The client called FrameEvent.Frame. return frame, true @@ -554,8 +559,6 @@ func (w *Window) collectSemanticDiffs(diffs *[]router.SemanticID, n router.Seman func (w *Window) updateState(d driver) { for { select { - case f := <-w.driverFuncs: - f(d) case <-w.redraws: w.setNextFrame(time.Time{}) w.updateAnimation(d)