app: add cross-platform empty view event detection

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>
This commit is contained in:
Chris Waldon
2024-06-27 13:56:28 -04:00
committed by Elias Naur
parent c900d58fb3
commit 4a1b4c2642
8 changed files with 26 additions and 2 deletions
+4
View File
@@ -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
+3
View File
@@ -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{})
}
+3
View File
@@ -441,3 +441,6 @@ func gio_runMain() {
func (UIKitViewEvent) implementsViewEvent() {}
func (UIKitViewEvent) ImplementsEvent() {}
func (u UIKitViewEvent) Valid() bool {
return u != (UIKitViewEvent{})
}
+3
View File
@@ -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())
}
+3
View File
@@ -1074,3 +1074,6 @@ func convertMods(mods C.NSUInteger) key.Modifiers {
func (AppKitViewEvent) implementsViewEvent() {}
func (AppKitViewEvent) ImplementsEvent() {}
func (a AppKitViewEvent) Valid() bool {
return a != (AppKitViewEvent{})
}
+6
View File
@@ -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 {}
+3
View File
@@ -981,3 +981,6 @@ func configForDPI(dpi int) unit.Metric {
func (Win32ViewEvent) implementsViewEvent() {}
func (Win32ViewEvent) ImplementsEvent() {}
func (w Win32ViewEvent) Valid() bool {
return w != (Win32ViewEvent{})
}
+1 -2
View File
@@ -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