mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
io/input/pointer: ignore grab commands for tags that don't have the pointer
Without this fix, two gestures that both issue GrabCmd on the same frame will cancel each other. With the fix, the first will win the grab, and the other ignored. References: https://todo.sr.ht/~eliasnaur/gio/647 Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -257,6 +257,17 @@ func (q *pointerQueue) grab(state pointerState, req pointer.GrabCmd) (pointerSta
|
||||
if !p.pressed || p.id != req.ID {
|
||||
continue
|
||||
}
|
||||
// Verify that the grabber is among the handlers.
|
||||
found := false
|
||||
for _, tag := range p.handlers {
|
||||
if tag == req.Tag {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
// Drop other handlers that lost their grab.
|
||||
for i := len(p.handlers) - 1; i >= 0; i-- {
|
||||
if tag := p.handlers[i]; tag != req.Tag {
|
||||
|
||||
@@ -97,6 +97,39 @@ func TestPointerDragNegative(t *testing.T) {
|
||||
assertEventPointerTypeSequence(t, events(&r, -1, f), pointer.Enter, pointer.Press, pointer.Leave, pointer.Drag)
|
||||
}
|
||||
|
||||
func TestIgnoredGrab(t *testing.T) {
|
||||
handler1 := new(int)
|
||||
handler2 := new(int)
|
||||
var ops op.Ops
|
||||
|
||||
filter := func(t event.Tag) event.Filter {
|
||||
return pointer.Filter{Target: t, Kinds: pointer.Press | pointer.Release | pointer.Cancel}
|
||||
}
|
||||
|
||||
event.Op(&ops, handler1)
|
||||
event.Op(&ops, handler2)
|
||||
var r Router
|
||||
assertEventPointerTypeSequence(t, events(&r, -1, filter(handler1)), pointer.Cancel)
|
||||
assertEventPointerTypeSequence(t, events(&r, -1, filter(handler2)), pointer.Cancel)
|
||||
r.Frame(&ops)
|
||||
r.Queue(
|
||||
pointer.Event{
|
||||
Kind: pointer.Press,
|
||||
Position: f32.Pt(50, 50),
|
||||
},
|
||||
pointer.Event{
|
||||
Kind: pointer.Release,
|
||||
Position: f32.Pt(50, 50),
|
||||
},
|
||||
)
|
||||
assertEventPointerTypeSequence(t, events(&r, 1, filter(handler1)), pointer.Press)
|
||||
assertEventPointerTypeSequence(t, events(&r, 1, filter(handler2)), pointer.Press)
|
||||
r.Source().Execute(pointer.GrabCmd{Tag: handler1})
|
||||
r.Source().Execute(pointer.GrabCmd{Tag: handler2})
|
||||
assertEventPointerTypeSequence(t, events(&r, 1, filter(handler1)), pointer.Release)
|
||||
assertEventPointerTypeSequence(t, events(&r, 1, filter(handler2)), pointer.Cancel)
|
||||
}
|
||||
|
||||
func TestPointerGrab(t *testing.T) {
|
||||
handler1 := new(int)
|
||||
handler2 := new(int)
|
||||
|
||||
Reference in New Issue
Block a user