mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
io/input: support direct pointer leave events
Allow platform backends to send pointer.Leave directly. The router delivers it to entered handlers so hover state is cleared normally. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+3
-1
@@ -760,6 +760,8 @@ func (q *pointerQueue) Push(handlers map[event.Tag]*handler, state pointerState,
|
|||||||
if p.pressed {
|
if p.pressed {
|
||||||
p, evts = q.deliverDragEvent(handlers, p, evts)
|
p, evts = q.deliverDragEvent(handlers, p, evts)
|
||||||
}
|
}
|
||||||
|
case pointer.Leave:
|
||||||
|
p, evts, state.cursor, _ = q.deliverEnterLeaveEvents(handlers, state.cursor, p, evts, e)
|
||||||
case pointer.Release:
|
case pointer.Release:
|
||||||
evts = q.deliverEvent(handlers, p, evts, e)
|
evts = q.deliverEvent(handlers, p, evts, e)
|
||||||
p.pressed = false
|
p.pressed = false
|
||||||
@@ -823,7 +825,7 @@ func (q *pointerQueue) deliverEvent(handlers map[event.Tag]*handler, p pointerIn
|
|||||||
func (q *pointerQueue) deliverEnterLeaveEvents(handlers map[event.Tag]*handler, cursor pointer.Cursor, p pointerInfo, evts []taggedEvent, e pointer.Event) (pointerInfo, []taggedEvent, pointer.Cursor, bool) {
|
func (q *pointerQueue) deliverEnterLeaveEvents(handlers map[event.Tag]*handler, cursor pointer.Cursor, p pointerInfo, evts []taggedEvent, e pointer.Event) (pointerInfo, []taggedEvent, pointer.Cursor, bool) {
|
||||||
changed := false
|
changed := false
|
||||||
var hits []event.Tag
|
var hits []event.Tag
|
||||||
if e.Source != pointer.Mouse && !p.pressed && e.Kind != pointer.Press {
|
if e.Kind == pointer.Leave || e.Source != pointer.Mouse && !p.pressed && e.Kind != pointer.Press {
|
||||||
// Consider non-mouse pointers leaving when they're released.
|
// Consider non-mouse pointers leaving when they're released.
|
||||||
} else {
|
} else {
|
||||||
var transSrc *pointerFilter
|
var transSrc *pointerFilter
|
||||||
|
|||||||
@@ -255,6 +255,45 @@ func TestPointerMove(t *testing.T) {
|
|||||||
assertEventPointerTypeSequence(t, events(&r, -1, filter(handler2)), pointer.Enter, pointer.Move, pointer.Leave, pointer.Cancel)
|
assertEventPointerTypeSequence(t, events(&r, -1, filter(handler2)), pointer.Enter, pointer.Move, pointer.Leave, pointer.Cancel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPointerLeave(t *testing.T) {
|
||||||
|
handler := new(int)
|
||||||
|
var ops op.Ops
|
||||||
|
|
||||||
|
filter := pointer.Filter{
|
||||||
|
Target: handler,
|
||||||
|
Kinds: pointer.Move | pointer.Enter | pointer.Leave | pointer.Cancel,
|
||||||
|
}
|
||||||
|
defer clip.Rect(image.Rect(0, 0, 100, 100)).Push(&ops).Pop()
|
||||||
|
event.Op(&ops, handler)
|
||||||
|
|
||||||
|
var r Router
|
||||||
|
events(&r, -1, filter)
|
||||||
|
r.Frame(&ops)
|
||||||
|
r.Queue(
|
||||||
|
pointer.Event{
|
||||||
|
Kind: pointer.Move,
|
||||||
|
Source: pointer.Mouse,
|
||||||
|
PointerID: 1,
|
||||||
|
Position: f32.Pt(50, 50),
|
||||||
|
},
|
||||||
|
pointer.Event{
|
||||||
|
Kind: pointer.Leave,
|
||||||
|
Source: pointer.Mouse,
|
||||||
|
PointerID: 1,
|
||||||
|
Position: f32.Pt(50, 50),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assertEventPointerTypeSequence(t, events(&r, -1, filter), pointer.Enter, pointer.Move, pointer.Leave)
|
||||||
|
|
||||||
|
r.Queue(pointer.Event{
|
||||||
|
Kind: pointer.Move,
|
||||||
|
Source: pointer.Mouse,
|
||||||
|
PointerID: 1,
|
||||||
|
Position: f32.Pt(50, 50),
|
||||||
|
})
|
||||||
|
assertEventPointerTypeSequence(t, events(&r, -1, filter), pointer.Enter, pointer.Move)
|
||||||
|
}
|
||||||
|
|
||||||
func TestPointerTypes(t *testing.T) {
|
func TestPointerTypes(t *testing.T) {
|
||||||
handler := new(int)
|
handler := new(int)
|
||||||
var ops op.Ops
|
var ops op.Ops
|
||||||
|
|||||||
Reference in New Issue
Block a user