mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-03 08:25:34 +00:00
io/router: deliver enter/leave events to transfer participants
When a drag and drop gesture is ongoing, let the potential target handlers receive enter/leave events so that they can react to them (e.g. highlight themselves when the dragged item is over them). Fixes #321. Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
This commit is contained in:
+13
-2
@@ -674,9 +674,20 @@ func (q *pointerQueue) deliverEnterLeaveEvents(p *pointerInfo, events *handlerEv
|
|||||||
} else {
|
} else {
|
||||||
hits = q.opHit(e.Position)
|
hits = q.opHit(e.Position)
|
||||||
if p.pressed {
|
if p.pressed {
|
||||||
// Filter out non-participating handlers.
|
// Filter out non-participating handlers,
|
||||||
|
// except potential transfer targets when a transfer has been initiated.
|
||||||
|
var transferSource *pointerHandler
|
||||||
|
if p.dataSource != nil {
|
||||||
|
transferSource = q.handlers[p.dataSource]
|
||||||
|
}
|
||||||
for i := len(hits) - 1; i >= 0; i-- {
|
for i := len(hits) - 1; i >= 0; i-- {
|
||||||
if _, found := searchTag(p.handlers, hits[i]); !found {
|
tag := hits[i]
|
||||||
|
if transferSource != nil {
|
||||||
|
if _, ok := firstMimeMatch(transferSource, q.handlers[tag]); ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, found := searchTag(p.handlers, tag); !found {
|
||||||
hits = append(hits[:i], hits[i+1:]...)
|
hits = append(hits[:i], hits[i+1:]...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"gioui.org/f32"
|
"gioui.org/f32"
|
||||||
|
"gioui.org/gesture"
|
||||||
"gioui.org/io/event"
|
"gioui.org/io/event"
|
||||||
"gioui.org/io/key"
|
"gioui.org/io/key"
|
||||||
"gioui.org/io/pointer"
|
"gioui.org/io/pointer"
|
||||||
@@ -998,6 +999,43 @@ func TestTransfer(t *testing.T) {
|
|||||||
t.Error("offer was not closed")
|
t.Error("offer was not closed")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("valid target enter/leave events", func(t *testing.T) {
|
||||||
|
ops := new(op.Ops)
|
||||||
|
src, _ := setup(ops, "file", "file")
|
||||||
|
var hover gesture.Hover
|
||||||
|
stack := clip.Rect(tgtArea).Push(ops)
|
||||||
|
hover.Add(ops)
|
||||||
|
stack.Pop()
|
||||||
|
var r Router
|
||||||
|
r.Frame(ops)
|
||||||
|
// Drag and drop.
|
||||||
|
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.Release,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assertEventPointerTypeSequence(t, r.Events(&hover), pointer.Cancel, pointer.Enter)
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// offer satisfies io.ReadCloser for use in data transfers.
|
// offer satisfies io.ReadCloser for use in data transfers.
|
||||||
|
|||||||
Reference in New Issue
Block a user