From 2381c5ad70b2d64042422177bc227d8e2a085201 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sat, 23 Apr 2022 15:36:45 +0200 Subject: [PATCH] io/router,widget: give every key.InputOp a chance to process events If the currently focused handler don't want the key event, try every other handler, from top to bottom. This change requires widgets to only react when focused. Fixes: https://todo.sr.ht/~eliasnaur/gio/406 Signed-off-by: Elias Naur --- io/router/key_test.go | 18 +----------------- io/router/router.go | 19 +++---------------- widget/button.go | 2 +- widget/enum.go | 2 +- 4 files changed, 6 insertions(+), 35 deletions(-) diff --git a/io/router/key_test.go b/io/router/key_test.go index 825c3639..4bab0f1c 100644 --- a/io/router/key_test.go +++ b/io/router/key_test.go @@ -333,32 +333,16 @@ func TestKeyRouting(t *testing.T) { key.InputOp{Tag: &handlers[2], Keys: "A"}.Add(ops) cl1.Pop() - key.FocusOp{Tag: &handlers[2]}.Add(ops) - r.Frame(ops) A, B := key.Event{Name: "A"}, key.Event{Name: "B"} r.Queue(A, B) - assertKeyEvent(t, r.Events(&handlers[2]), true, A) + assertKeyEvent(t, r.Events(&handlers[2]), false, A) assertKeyEvent(t, r.Events(&handlers[1]), false, B) assertKeyEvent(t, r.Events(&handlers[0]), false) } -func TestTopLevelInputOp(t *testing.T) { - h := new(int) - ops := new(op.Ops) - r := new(Router) - - key.InputOp{Tag: h, Keys: "A"}.Add(ops) - r.Frame(ops) - - A := key.Event{Name: "A"} - r.Queue(A) - - assertKeyEvent(t, r.Events(h), false, A) -} - func assertKeyEvent(t *testing.T, events []event.Event, expected bool, expectedInputs ...event.Event) { t.Helper() var evtFocus int diff --git a/io/router/router.go b/io/router/router.go index c7b5a7b7..f3a901fc 100644 --- a/io/router/router.go +++ b/io/router/router.go @@ -182,25 +182,12 @@ func rangeNorm(r key.Range) key.Range { func (q *Router) queueKeyEvent(e key.Event) { kq := &q.key.queue - f := q.key.queue.focus - a := 0 // Root area - if f != nil { - if kq.Accepts(f, e) { - q.handlers.Add(f, e) - return - } - a = kq.AreaFor(f) + if f := q.key.queue.focus; f != nil && kq.Accepts(f, e) { + q.handlers.Add(f, e) + return } pq := &q.pointer.queue idx := len(pq.hitTree) - 1 - // Locate first potential receiver. - for idx != -1 { - n := &pq.hitTree[idx] - if n.area == a { - break - } - idx-- - } for idx != -1 { n := &pq.hitTree[idx] idx = n.next diff --git a/widget/button.go b/widget/button.go index 0980b137..db456f53 100644 --- a/widget/button.go +++ b/widget/button.go @@ -166,7 +166,7 @@ func (b *Clickable) update(gtx layout.Context) { case key.FocusEvent: b.focused = e.Focus case key.Event: - if e.State != key.Release { + if !b.focused || e.State != key.Release { break } if e.Name != key.NameReturn && e.Name != key.NameSpace { diff --git a/widget/enum.go b/widget/enum.go index 2a1343e8..d1dba87e 100644 --- a/widget/enum.go +++ b/widget/enum.go @@ -98,7 +98,7 @@ func (e *Enum) Layout(gtx layout.Context, k string, content layout.Widget) layou e.focused = false } case key.Event: - if ev.State != key.Release { + if !e.focused || ev.State != key.Release { break } if ev.Name != key.NameEnter && ev.Name != key.NameSpace {