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 }