From cf9f2bbffebb2cd9b89b3e208f6e7d027a6c1fb9 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sat, 20 Apr 2024 18:16:33 +0000 Subject: [PATCH] app: [Wayland] don't send events after DestroyEvent Like a previous commit for X11, this change ensures no events are sent after DestroyEvent. Signed-off-by: Elias Naur --- app/os_wayland.go | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/app/os_wayland.go b/app/os_wayland.go index 550a4917..0689655d 100644 --- a/app/os_wayland.go +++ b/app/os_wayland.go @@ -216,6 +216,8 @@ type window struct { wakeups chan struct{} + closing bool + // invMu avoids the race between the destruction of disp and // Invalidate waking it up. invMu sync.Mutex @@ -556,7 +558,7 @@ func gio_onXdgSurfaceConfigure(data unsafe.Pointer, wmSurf *C.struct_xdg_surface //export gio_onToplevelClose func gio_onToplevelClose(data unsafe.Pointer, topLvl *C.struct_xdg_toplevel) { w := callbackLoad(data).(*window) - w.close(nil) + w.closing = true } //export gio_onToplevelConfigure @@ -1139,7 +1141,7 @@ func (w *window) Perform(actions system.Action) { walkActions(actions, func(action system.Action) { switch action { case system.ActionClose: - w.close(nil) + w.closing = true } }) } @@ -1366,6 +1368,11 @@ func gio_onFrameDone(data unsafe.Pointer, callback *C.struct_wl_callback, t C.ui func (w *window) close(err error) { w.ProcessEvent(WaylandViewEvent{}) w.ProcessEvent(DestroyEvent{Err: err}) + w.destroy() + w.invMu.Lock() + w.disp.destroy() + w.disp = nil + w.invMu.Unlock() } func (w *window) dispatch() { @@ -1374,7 +1381,7 @@ func (w *window) dispatch() { w.w.Invalidate() return } - if err := w.disp.dispatch(); err != nil { + if err := w.disp.dispatch(); err != nil || w.closing { w.close(err) return } @@ -1399,13 +1406,6 @@ func (w *window) Event() event.Event { w.dispatch() continue } - if _, destroy := evt.(DestroyEvent); destroy { - w.destroy() - w.invMu.Lock() - w.disp.destroy() - w.disp = nil - w.invMu.Unlock() - } return evt } } @@ -1515,6 +1515,10 @@ func (d *wlDisplay) wakeup() { } func (w *window) destroy() { + if w.lastFrameCallback != nil { + C.wl_callback_destroy(w.lastFrameCallback) + w.lastFrameCallback = nil + } if w.cursor.surf != nil { C.wl_surface_destroy(w.cursor.surf) }