Custom rendering applications need to be prepared to handle empty view events,
as an empty view event is sent during window shutdown. However, the current
implementation requires applications to write a platform-specific helper
function for each supported platform in order to check whether a received
view event is empty. This commit provides a safe, convenient, cross-platform
method that applications can use to detect this special view event and respond
to it.
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
---
app/app.go | 4 ++++
app/os_android.go | 3 +++
app/os_ios.go | 3 +++
app/os_js.go | 3 +++
app/os_macos.go | 3 +++
app/os_unix.go | 6 ++++++
app/os_windows.go | 3 +++
app/window.go | 3 +--
8 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/app/app.go b/app/app.go
index ef4a0fe2..a9bb0614 100644
--- a/app/app.go
+++ b/app/app.go
@@ -61,6 +61,10 @@ type FrameEvent struct {
type ViewEvent interface {
implementsViewEvent()
ImplementsEvent()
+ // Valid will return true when the ViewEvent does contains valid handles.
+ // If a window receives an invalid ViewEvent, it should deinitialize any
+ // state referring to handles from a previous ViewEvent.
+ Valid() bool
}
// Insets is the space taken up by
diff --git a/app/os_android.go b/app/os_android.go
index a18bd083..3255d5f9 100644
--- a/app/os_android.go
+++ b/app/os_android.go
@@ -1495,3 +1495,6 @@ func Java_org_gioui_Gio_scheduleMainFuncs(env *C.JNIEnv, cls C.jclass) {
func (AndroidViewEvent) implementsViewEvent() {}
func (AndroidViewEvent) ImplementsEvent() {}
+func (a AndroidViewEvent) Valid() bool {
+ return a != (AndroidViewEvent{})
+}
diff --git a/app/os_ios.go b/app/os_ios.go
index 53a22eaf..2a281cb8 100644
--- a/app/os_ios.go
+++ b/app/os_ios.go
@@ -441,3 +441,6 @@ func gio_runMain() {
func (UIKitViewEvent) implementsViewEvent() {}
func (UIKitViewEvent) ImplementsEvent() {}
+func (u UIKitViewEvent) Valid() bool {
+ return u != (UIKitViewEvent{})
+}
diff --git a/app/os_js.go b/app/os_js.go
index 79e02783..66042917 100644
--- a/app/os_js.go
+++ b/app/os_js.go
@@ -822,3 +822,6 @@ func translateKey(k string) (key.Name, bool) {
func (JSViewEvent) implementsViewEvent() {}
func (JSViewEvent) ImplementsEvent() {}
+func (j JSViewEvent) Valid() bool {
+ return !(j.Element.IsNull() || j.Element.IsUndefined())
+}
diff --git a/app/os_macos.go b/app/os_macos.go
index 1da5083f..3b2dbbfd 100644
--- a/app/os_macos.go
+++ b/app/os_macos.go
@@ -1068,3 +1068,6 @@ func convertMods(mods C.NSUInteger) key.Modifiers {
func (AppKitViewEvent) implementsViewEvent() {}
func (AppKitViewEvent) ImplementsEvent() {}
+func (a AppKitViewEvent) Valid() bool {
+ return a != (AppKitViewEvent{})
+}
diff --git a/app/os_unix.go b/app/os_unix.go
index 933b8ff5..28181b8f 100644
--- a/app/os_unix.go
+++ b/app/os_unix.go
@@ -21,6 +21,9 @@ type X11ViewEvent struct {
func (X11ViewEvent) implementsViewEvent() {}
func (X11ViewEvent) ImplementsEvent() {}
+func (x X11ViewEvent) Valid() bool {
+ return x != (X11ViewEvent{})
+}
type WaylandViewEvent struct {
// Display is the *wl_display returned by wl_display_connect.
@@ -31,6 +34,9 @@ type WaylandViewEvent struct {
func (WaylandViewEvent) implementsViewEvent() {}
func (WaylandViewEvent) ImplementsEvent() {}
+func (w WaylandViewEvent) Valid() bool {
+ return w != (WaylandViewEvent{})
+}
func osMain() {
select {}
diff --git a/app/os_windows.go b/app/os_windows.go
index 888391b7..7c950a5a 100644
--- a/app/os_windows.go
+++ b/app/os_windows.go
@@ -981,3 +981,6 @@ func configForDPI(dpi int) unit.Metric {
func (Win32ViewEvent) implementsViewEvent() {}
func (Win32ViewEvent) ImplementsEvent() {}
+func (w Win32ViewEvent) Valid() bool {
+ return w != (Win32ViewEvent{})
+}
diff --git a/app/window.go b/app/window.go
index f8aee3ea..bf85099a 100644
--- a/app/window.go
+++ b/app/window.go
@@ -7,7 +7,6 @@ import (
"fmt"
"image"
"image/color"
- "reflect"
"runtime"
"sync"
"time"
@@ -643,7 +642,7 @@ func (w *Window) processEvent(e event.Event) bool {
}
w.coalesced.destroy = &e2
case ViewEvent:
- if reflect.ValueOf(e2).IsZero() && w.gpu != nil {
+ if !e2.Valid() && w.gpu != nil {
w.ctx.Lock()
w.gpu.Release()
w.gpu = nil
--
2.45.2