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,
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)
+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.
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
}