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 <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2022-04-23 15:36:45 +02:00
parent 0273203743
commit 2381c5ad70
4 changed files with 6 additions and 35 deletions
+1 -17
View File
@@ -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
+3 -16
View File
@@ -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
+1 -1
View File
@@ -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 {
+1 -1
View File
@@ -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 {