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 <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2022-04-14 18:51:39 +02:00
parent 9c59612e08
commit bec0283e54
2 changed files with 21 additions and 12 deletions
+4
View File
@@ -282,6 +282,10 @@ func TestFocusScroll(t *testing.T) {
Types: pointer.Scroll, Types: pointer.Scroll,
ScrollBounds: image.Rect(-100, -100, 100, 100), ScrollBounds: image.Rect(-100, -100, 100, 100),
}.Add(ops) }.Add(ops)
// Test that h is scrolled even if behind another handler.
pointer.InputOp{
Tag: new(int),
}.Add(ops)
cl.Pop() cl.Pop()
parent.Pop() parent.Pop()
r.Frame(ops) r.Frame(ops)
+17 -12
View File
@@ -600,17 +600,26 @@ func (q *pointerQueue) pointerOf(e pointer.Event) int {
// Deliver is like Push, but delivers an event to a particular area. // Deliver is like Push, but delivers an event to a particular area.
func (q *pointerQueue) Deliver(areaIdx int, e pointer.Event, events *handlerEvents) { func (q *pointerQueue) Deliver(areaIdx int, e pointer.Event, events *handlerEvents) {
var sx, sy = e.Scroll.X, e.Scroll.Y var sx, sy = e.Scroll.X, e.Scroll.Y
for areaIdx != -1 { idx := len(q.hitTree) - 1
a := &q.areas[areaIdx] // Locate first potential receiver.
areaIdx = a.parent for idx != -1 {
if !a.semantic.valid { 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 continue
} }
cnt := a.semantic.content h := q.handlers[n.tag]
if cnt.tag == nil { if e.Type&h.types == 0 {
continue continue
} }
h := q.handlers[cnt.tag] e := e
if e.Type == pointer.Scroll { if e.Type == pointer.Scroll {
if sx == 0 && sy == 0 { if sx == 0 && sy == 0 {
break 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) 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) 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) e.Position = q.invTransform(h.area, e.Position)
events.Add(cnt.tag, e) events.Add(n.tag, e)
if e.Type != pointer.Scroll { if e.Type != pointer.Scroll {
break break
} }