From bec0283e54f155d2a949ab6ae7eb0b074773ffdd Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Thu, 14 Apr 2022 18:51:39 +0200 Subject: [PATCH] io/router: deliver synthetic events to sibling pointer handlers Before this change, synthetic events such as scrolling caused by focus movement would use semantic information to determine potential receivers. However, there can only be one handler per area so sibling handlers would not be considered. This change makes the event delivery traverse the entire tree of handlers, including siblings. Signed-off-by: Elias Naur --- io/router/key_test.go | 4 ++++ io/router/pointer.go | 29 +++++++++++++++++------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/io/router/key_test.go b/io/router/key_test.go index 49763599..c99040df 100644 --- a/io/router/key_test.go +++ b/io/router/key_test.go @@ -282,6 +282,10 @@ func TestFocusScroll(t *testing.T) { Types: pointer.Scroll, ScrollBounds: image.Rect(-100, -100, 100, 100), }.Add(ops) + // Test that h is scrolled even if behind another handler. + pointer.InputOp{ + Tag: new(int), + }.Add(ops) cl.Pop() parent.Pop() r.Frame(ops) diff --git a/io/router/pointer.go b/io/router/pointer.go index 6c1ce31d..e5123ee4 100644 --- a/io/router/pointer.go +++ b/io/router/pointer.go @@ -600,17 +600,26 @@ func (q *pointerQueue) pointerOf(e pointer.Event) int { // Deliver is like Push, but delivers an event to a particular area. func (q *pointerQueue) Deliver(areaIdx int, e pointer.Event, events *handlerEvents) { var sx, sy = e.Scroll.X, e.Scroll.Y - for areaIdx != -1 { - a := &q.areas[areaIdx] - areaIdx = a.parent - if !a.semantic.valid { + idx := len(q.hitTree) - 1 + // Locate first potential receiver. + for idx != -1 { + n := &q.hitTree[idx] + if n.area == areaIdx { + break + } + idx-- + } + for idx != -1 { + n := &q.hitTree[idx] + idx = n.next + if n.tag == nil { continue } - cnt := a.semantic.content - if cnt.tag == nil { + h := q.handlers[n.tag] + if e.Type&h.types == 0 { continue } - h := q.handlers[cnt.tag] + e := e if e.Type == pointer.Scroll { if sx == 0 && sy == 0 { break @@ -619,12 +628,8 @@ func (q *pointerQueue) Deliver(areaIdx int, e pointer.Event, events *handlerEven sx, e.Scroll.X = setScrollEvent(sx, h.scrollRange.Min.X, h.scrollRange.Max.X) sy, e.Scroll.Y = setScrollEvent(sy, h.scrollRange.Min.Y, h.scrollRange.Max.Y) } - if e.Type&h.types == 0 { - continue - } - e := e e.Position = q.invTransform(h.area, e.Position) - events.Add(cnt.tag, e) + events.Add(n.tag, e) if e.Type != pointer.Scroll { break }