diff --git a/io/router/pointer.go b/io/router/pointer.go index 591a92ff..b1cf73bb 100644 --- a/io/router/pointer.go +++ b/io/router/pointer.go @@ -239,10 +239,11 @@ func (q *pointerQueue) Frame(root *op.Ops, events *handlerEvents) { for i, k2 := range p.handlers { if k2 == k { // Drop other handlers that lost their grab. - cancelHandlers(events, p.handlers[i+1:]...) - cancelHandlers(events, p.handlers[:i]...) - q.dropHandlers(events, p.handlers[i+1:]...) - q.dropHandlers(events, p.handlers[:i]...) + dropped := make([]event.Tag, 0, len(p.handlers)-1) + dropped = append(dropped, p.handlers[:i]...) + dropped = append(dropped, p.handlers[i+1:]...) + cancelHandlers(events, dropped...) + q.dropHandlers(events, dropped...) break } } diff --git a/io/router/pointer_test.go b/io/router/pointer_test.go index c0738b4a..b2b0a930 100644 --- a/io/router/pointer_test.go +++ b/io/router/pointer_test.go @@ -79,6 +79,41 @@ func TestPointerDragNegative(t *testing.T) { assertEventSequence(t, r.Events(handler), pointer.Cancel, pointer.Enter, pointer.Press, pointer.Leave, pointer.Drag) } +func TestPointerGrab(t *testing.T) { + handler1 := new(int) + handler2 := new(int) + handler3 := new(int) + var ops op.Ops + + types := pointer.Press | pointer.Release + + pointer.InputOp{Tag: handler1, Types: types, Grab: true}.Add(&ops) + pointer.InputOp{Tag: handler2, Types: types}.Add(&ops) + pointer.InputOp{Tag: handler3, Types: types}.Add(&ops) + + var r Router + r.Frame(&ops) + r.Queue( + pointer.Event{ + Type: pointer.Press, + Position: f32.Pt(50, 50), + }, + ) + assertEventSequence(t, r.Events(handler1), pointer.Cancel, pointer.Press) + assertEventSequence(t, r.Events(handler2), pointer.Cancel, pointer.Press) + assertEventSequence(t, r.Events(handler3), pointer.Cancel, pointer.Press) + r.Frame(&ops) + r.Queue( + pointer.Event{ + Type: pointer.Release, + Position: f32.Pt(50, 50), + }, + ) + assertEventSequence(t, r.Events(handler1), pointer.Release) + assertEventSequence(t, r.Events(handler2), pointer.Cancel) + assertEventSequence(t, r.Events(handler3), pointer.Cancel) +} + func TestPointerMove(t *testing.T) { handler1 := new(int) handler2 := new(int)