io/router: make transfer targets hovering easier to detect

In commit 929e4dc12, the rules to send pointer.{Enter,Leave}
events were relaxed. Unfortunately, to be able to make use
of them was not straight forward as it required the transfer
target op to use the same handle as the hover one.
This patch eases this by allowing any handle for the target
as well as not requiring the hover op to be defined on the same
clip op as the target (then requiring a PassOp though), making
it much easier to use.

Also added a test for pointer.Enter events not being generated
if the target type does not match the source one.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
This commit is contained in:
Pierre Curto
2021-12-15 19:09:36 +01:00
committed by Elias Naur
parent af63c089f6
commit 3db11cbaad
2 changed files with 70 additions and 11 deletions
+9 -9
View File
@@ -676,18 +676,18 @@ func (q *pointerQueue) deliverEnterLeaveEvents(p *pointerInfo, events *handlerEv
if p.pressed {
// Filter out non-participating handlers,
// except potential transfer targets when a transfer has been initiated.
var transferSource *pointerHandler
var hitsHaveTarget bool
if p.dataSource != nil {
transferSource = q.handlers[p.dataSource]
}
for i := len(hits) - 1; i >= 0; i-- {
tag := hits[i]
if transferSource != nil {
if _, ok := firstMimeMatch(transferSource, q.handlers[tag]); ok {
continue
transferSource := q.handlers[p.dataSource]
for _, hit := range hits {
if _, ok := firstMimeMatch(transferSource, q.handlers[hit]); ok {
hitsHaveTarget = true
break
}
}
if _, found := searchTag(p.handlers, tag); !found {
}
for i := len(hits) - 1; i >= 0; i-- {
if _, found := searchTag(p.handlers, hits[i]); !found && !hitsHaveTarget {
hits = append(hits[:i], hits[i+1:]...)
}
}
+61 -2
View File
@@ -1004,12 +1004,15 @@ func TestTransfer(t *testing.T) {
ops := new(op.Ops)
src, _ := setup(ops, "file", "file")
var hover gesture.Hover
pass := pointer.PassOp{}.Push(ops)
stack := clip.Rect(tgtArea).Push(ops)
hover.Add(ops)
stack.Pop()
pass.Pop()
var r Router
r.Frame(ops)
// Drag and drop.
// Drag.
r.Queue(
pointer.Event{
Position: f32.Pt(10, 10),
@@ -1021,11 +1024,67 @@ func TestTransfer(t *testing.T) {
},
pointer.Event{
Position: f32.Pt(40, 10),
Type: pointer.Release,
Type: pointer.Move,
},
)
assertEventPointerTypeSequence(t, r.Events(&hover), pointer.Cancel, pointer.Enter)
// Drop.
r.Queue(
pointer.Event{
Position: f32.Pt(40, 10),
Type: pointer.Release,
},
)
// Offer valid type and data.
ofr := &offer{data: "hello"}
transfer.OfferOp{
Tag: src,
Type: "file",
Data: ofr,
}.Add(ops)
r.Frame(ops)
assertEventPointerTypeSequence(t, r.Events(&hover), pointer.Leave)
})
t.Run("invalid target NO enter/leave events", func(t *testing.T) {
ops := new(op.Ops)
src, _ := setup(ops, "file", "nofile")
var hover gesture.Hover
pass := pointer.PassOp{}.Push(ops)
stack := clip.Rect(tgtArea).Push(ops)
hover.Add(ops)
stack.Pop()
pass.Pop()
var r Router
r.Frame(ops)
// Drag.
r.Queue(
pointer.Event{
Position: f32.Pt(10, 10),
Type: pointer.Press,
},
pointer.Event{
Position: f32.Pt(10, 10),
Type: pointer.Move,
},
pointer.Event{
Position: f32.Pt(40, 10),
Type: pointer.Move,
},
)
assertEventPointerTypeSequence(t, r.Events(&hover), pointer.Cancel)
// Drop.
r.Queue(
pointer.Event{
Position: f32.Pt(40, 10),
Type: pointer.Release,
},
)
// Offer valid type and data.
ofr := &offer{data: "hello"}
transfer.OfferOp{