mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 15:45:38 +00:00
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:
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user