From 6c76fa6dec3990f542c2d6309a1a5619db6427bc Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Thu, 14 Apr 2022 17:45:04 +0200 Subject: [PATCH] app,io/key,io/system: [API] replace system.CommandEvent with key.Event It's much simpler to map the Android back button to a key.Event and let the usual key filtering determine whether to block its default behaviour. Signed-off-by: Elias Naur --- app/os_android.go | 4 +--- app/os_js.go | 5 +---- app/window.go | 23 ++++++++++++++--------- io/key/key.go | 1 + io/system/system.go | 24 +++--------------------- 5 files changed, 20 insertions(+), 37 deletions(-) diff --git a/app/os_android.go b/app/os_android.go index a3fafec1..877d7af0 100644 --- a/app/os_android.go +++ b/app/os_android.go @@ -571,9 +571,7 @@ func Java_org_gioui_GioView_onFrameCallback(env *C.JNIEnv, class C.jclass, view //export Java_org_gioui_GioView_onBack func Java_org_gioui_GioView_onBack(env *C.JNIEnv, class C.jclass, view C.jlong) C.jboolean { w := cgo.Handle(view).Value().(*window) - ev := &system.CommandEvent{Type: system.CommandBack} - w.callbacks.Event(ev) - if ev.Cancel { + if w.callbacks.Event(key.Event{Name: key.NameBack}) { return C.JNI_TRUE } return C.JNI_FALSE diff --git a/app/os_js.go b/app/os_js.go index 7eb64d56..00a17ed1 100644 --- a/app/os_js.go +++ b/app/os_js.go @@ -172,12 +172,9 @@ func (w *window) addEventListeners() { return nil }) w.addEventListener(w.window, "popstate", func(this js.Value, args []js.Value) interface{} { - ev := &system.CommandEvent{Type: system.CommandBack} - w.w.Event(ev) - if ev.Cancel { + if w.w.Event(key.Event{Name: key.NameBack}) { return w.browserHistory.Call("forward") } - return w.browserHistory.Call("back") }) w.addEventListener(w.document, "visibilitychange", func(this js.Value, args []js.Value) interface{} { diff --git a/app/window.go b/app/window.go index e23837b6..f947cbea 100644 --- a/app/window.go +++ b/app/window.go @@ -416,29 +416,31 @@ func (c *callbacks) SetDriver(d driver) { c.w.wakeupFuncs <- wakeup } -func (c *callbacks) Event(e event.Event) { +func (c *callbacks) Event(e event.Event) bool { if c.d == nil { panic("event while no driver active") } c.waitEvents = append(c.waitEvents, e) if c.busy { - return + return true } c.busy = true defer func() { c.busy = false }() + var handled bool for len(c.waitEvents) > 0 { e := c.waitEvents[0] copy(c.waitEvents, c.waitEvents[1:]) c.waitEvents = c.waitEvents[:len(c.waitEvents)-1] - c.w.processEvent(c.d, e) + handled = c.w.processEvent(c.d, e) } c.w.updateState(c.d) if c.w.closing { c.w.closing = false c.d.Close() } + return handled } // SemanticRoot returns the ID of the semantic root. @@ -740,10 +742,10 @@ func (w *Window) updateState(d driver) { } } -func (w *Window) processEvent(d driver, e event.Event) { +func (w *Window) processEvent(d driver, e event.Event) bool { select { case <-w.dead: - return + return false default: } switch e2 := e.(type) { @@ -816,9 +818,6 @@ func (w *Window) processEvent(d driver, e event.Event) { } w.processFrame(d, frameStart) w.updateCursor(d) - case *system.CommandEvent: - w.out <- e - w.waitAck(d) case system.DestroyEvent: w.destroyGPU() w.out <- e2 @@ -838,10 +837,12 @@ func (w *Window) processEvent(d driver, e event.Event) { e2.Config.Size = e2.Config.Size.Sub(w.decorations.size) w.out <- e2 case event.Event: - if w.queue.q.Queue(e2) { + handled := w.queue.q.Queue(e2) + if handled { w.setNextFrame(time.Time{}) w.updateAnimation(d) } else if e, ok := e.(key.Event); ok && e.State == key.Press { + handled = true switch { case e.Name == key.NameTab && e.Modifiers == 0: w.moveFocus(router.FocusForward, d) @@ -855,10 +856,14 @@ func (w *Window) processEvent(d driver, e event.Event) { w.moveFocus(router.FocusLeft, d) case e.Name == key.NameRight && e.Modifiers == 0: w.moveFocus(router.FocusRight, d) + default: + handled = false } } w.updateCursor(d) + return handled } + return true } func (w *Window) run(options []Option) { diff --git a/io/key/key.go b/io/key/key.go index 9e7556cf..639e9296 100644 --- a/io/key/key.go +++ b/io/key/key.go @@ -223,6 +223,7 @@ const ( NameDown = "Down" NameLeft = "Left" NameRight = "Right" + NameBack = "Back" ) // Contain reports whether m contains all modifiers diff --git a/io/system/system.go b/io/system/system.go index e1458252..e8caf8e8 100644 --- a/io/system/system.go +++ b/io/system/system.go @@ -54,20 +54,9 @@ type StageEvent struct { Stage Stage } -// CommandEvent is a system event. Unlike most other events, CommandEvent is -// delivered as a pointer to allow Cancel to suppress it. -type CommandEvent struct { - Type CommandType - // Cancel suppress the default action of the command. - Cancel bool -} - // Stage of a Window. type Stage uint8 -// CommandType is the type of a CommandEvent. -type CommandType uint8 - const ( // StagePaused is the Stage for inactive Windows. // Inactive Windows don't receive FrameEvents. @@ -76,12 +65,6 @@ const ( StageRunning ) -const ( - // CommandBack is the command for a back action - // such as the Android back button. - CommandBack CommandType = iota -) - func (l Stage) String() string { switch l { case StagePaused: @@ -93,7 +76,6 @@ func (l Stage) String() string { } } -func (FrameEvent) ImplementsEvent() {} -func (StageEvent) ImplementsEvent() {} -func (*CommandEvent) ImplementsEvent() {} -func (DestroyEvent) ImplementsEvent() {} +func (FrameEvent) ImplementsEvent() {} +func (StageEvent) ImplementsEvent() {} +func (DestroyEvent) ImplementsEvent() {}