From 33a87ac61c387c39a2b53f1d25dfae5ff9a8986a Mon Sep 17 00:00:00 2001 From: Gordon Klaus Date: Wed, 3 Jun 2020 11:09:19 +0200 Subject: [PATCH] io/router: deliver scroll events only to the foremost scroll handler Signed-off-by: Gordon Klaus --- io/pointer/doc.go | 2 ++ io/router/pointer.go | 5 +++++ io/router/pointer_test.go | 43 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/io/pointer/doc.go b/io/pointer/doc.go index abc0ef1b..efb0a4b4 100644 --- a/io/pointer/doc.go +++ b/io/pointer/doc.go @@ -23,6 +23,8 @@ Leave, or Scroll): Types: pointer.Press | pointer.Move | pointer.Release, }.Add(ops) +Scroll events are only delivered to the foremost scroll handler. + Cancel events are always delivered. Areas diff --git a/io/router/pointer.go b/io/router/pointer.go index 1bd16040..8e27015c 100644 --- a/io/router/pointer.go +++ b/io/router/pointer.go @@ -267,6 +267,11 @@ func (q *pointerQueue) deliverEvent(p *pointerInfo, events *handlerEvents, e poi e.Position = h.transform.Invert().Transform(e.Position) addPointerEvent(events, k, e, h.types) + + // Only deliver scroll events to the foremost handler. + if e.Type == pointer.Scroll && e.Type&h.types != 0 { + return + } } } diff --git a/io/router/pointer_test.go b/io/router/pointer_test.go index 9f9bee86..9fce1686 100644 --- a/io/router/pointer_test.go +++ b/io/router/pointer_test.go @@ -125,6 +125,49 @@ func TestPointerTypes(t *testing.T) { assertEventSequence(t, r.Events(handler), pointer.Cancel, pointer.Press, pointer.Release) } +func TestPointerScroll(t *testing.T) { + handler1 := new(int) + handler2 := new(int) + var ops op.Ops + + pointer.Rect(image.Rect(0, 0, 100, 100)).Add(&ops) + pointer.InputOp{Tag: handler1, Types: pointer.Scroll}.Add(&ops) + + pointer.Rect(image.Rect(0, 0, 100, 50)).Add(&ops) + pointer.InputOp{Tag: handler2, Types: pointer.Scroll}.Add(&ops) + + var r Router + r.Frame(&ops) + r.Add( + // Hit handler 2. + pointer.Event{ + Type: pointer.Scroll, + Position: f32.Point{ + X: 50, + Y: 25, + }, + }, + // Hit handler 1. + pointer.Event{ + Type: pointer.Scroll, + Position: f32.Point{ + X: 50, + Y: 75, + }, + }, + // Hit no handlers. + pointer.Event{ + Type: pointer.Scroll, + Position: f32.Point{ + X: 50, + Y: 125, + }, + }, + ) + assertEventSequence(t, r.Events(handler1), pointer.Cancel, pointer.Scroll) + assertEventSequence(t, r.Events(handler2), pointer.Cancel, pointer.Scroll) +} + func TestPointerEnterLeave(t *testing.T) { handler1 := new(int) handler2 := new(int)