diff --git a/io/router/key_test.go b/io/router/key_test.go index d9d4b39d..825c3639 100644 --- a/io/router/key_test.go +++ b/io/router/key_test.go @@ -345,6 +345,20 @@ func TestKeyRouting(t *testing.T) { 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 a4072f16..d51ebf02 100644 --- a/io/router/router.go +++ b/io/router/router.go @@ -141,37 +141,7 @@ func (q *Router) Queue(events ...event.Event) bool { case pointer.Event: q.pointer.queue.Push(e, &q.handlers) case key.Event: - f := q.key.queue.focus - if f == nil { - break - } - kq := &q.key.queue - if kq.Accepts(f, e) { - q.handlers.Add(f, e) - break - } - a := kq.AreaFor(f) - 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 - if n.ktag == nil { - continue - } - if n.ktag != nil && kq.Accepts(n.ktag, e) { - q.handlers.Add(n.ktag, e) - break - } - } + q.queueKeyEvent(e) case key.EditEvent, key.FocusEvent, key.SnippetEvent, key.SelectionEvent: if f := q.key.queue.focus; f != nil { q.handlers.Add(f, e) @@ -183,6 +153,40 @@ func (q *Router) Queue(events ...event.Event) bool { return q.handlers.HadEvents() } +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) + } + 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 + if n.ktag == nil { + continue + } + if n.ktag != nil && kq.Accepts(n.ktag, e) { + q.handlers.Add(n.ktag, e) + break + } + } +} + func (q *Router) MoveFocus(dir FocusDirection) bool { return q.key.queue.MoveFocus(dir, &q.handlers) }