forked from joejulian/gio
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:
@@ -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:]...)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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{
|
||||
|
||||
Reference in New Issue
Block a user