mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-05 17:35:36 +00:00
io/input: deliver all observed events before deferring the rest
Even when a command defers event delivery to the next frame, the already observed events must still be delivered in the current frame. This matters for pointer events that hit more than one event handler. Fixes: https://todo.sr.ht/~eliasnaur/gio/594 Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -1086,6 +1086,33 @@ func TestPassCursor(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPartialEvent(t *testing.T) {
|
||||||
|
var ops op.Ops
|
||||||
|
var r Router
|
||||||
|
|
||||||
|
rect := clip.Rect(image.Rect(0, 0, 100, 100))
|
||||||
|
background := rect.Push(&ops)
|
||||||
|
event.Op(&ops, 1)
|
||||||
|
background.Pop()
|
||||||
|
|
||||||
|
overlayPass := pointer.PassOp{}.Push(&ops)
|
||||||
|
overlay := rect.Push(&ops)
|
||||||
|
event.Op(&ops, 2)
|
||||||
|
overlay.Pop()
|
||||||
|
overlayPass.Pop()
|
||||||
|
assertEventSequence(t, events(&r, -1, pointer.Filter{Target: 1, Kinds: pointer.Press}))
|
||||||
|
assertEventSequence(t, events(&r, -1, pointer.Filter{Target: 2, Kinds: pointer.Press}))
|
||||||
|
r.Frame(&ops)
|
||||||
|
r.Queue(pointer.Event{
|
||||||
|
Kind: pointer.Press,
|
||||||
|
})
|
||||||
|
assertEventSequence(t, events(&r, -1, pointer.Filter{Target: 1, Kinds: pointer.Press}, key.FocusFilter{Target: 1}),
|
||||||
|
key.FocusEvent{}, pointer.Event{Kind: pointer.Press, Source: pointer.Mouse, Priority: pointer.Shared})
|
||||||
|
r.Source().Execute(key.FocusCmd{Tag: 1})
|
||||||
|
assertEventSequence(t, events(&r, -1, pointer.Filter{Target: 2, Kinds: pointer.Press}),
|
||||||
|
pointer.Event{Kind: pointer.Press, Source: pointer.Mouse, Priority: pointer.Foremost})
|
||||||
|
}
|
||||||
|
|
||||||
// offer satisfies io.ReadCloser for use in data transfers.
|
// offer satisfies io.ReadCloser for use in data transfers.
|
||||||
type offer struct {
|
type offer struct {
|
||||||
data string
|
data string
|
||||||
|
|||||||
+21
-20
@@ -274,28 +274,29 @@ func (q *Router) Event(filters ...event.Filter) (event.Event, bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !q.deferring {
|
for i := range q.changes {
|
||||||
for i := range q.changes {
|
if q.deferring && i > 0 {
|
||||||
change := &q.changes[i]
|
break
|
||||||
for j, evt := range change.events {
|
}
|
||||||
match := false
|
change := &q.changes[i]
|
||||||
switch e := evt.event.(type) {
|
for j, evt := range change.events {
|
||||||
case key.Event:
|
match := false
|
||||||
match = q.key.scratchFilter.Matches(change.state.keyState.focus, e, false)
|
switch e := evt.event.(type) {
|
||||||
default:
|
case key.Event:
|
||||||
for _, tf := range q.scratchFilters {
|
match = q.key.scratchFilter.Matches(change.state.keyState.focus, e, false)
|
||||||
if evt.tag == tf.tag && tf.filter.Matches(evt.event) {
|
default:
|
||||||
match = true
|
for _, tf := range q.scratchFilters {
|
||||||
break
|
if evt.tag == tf.tag && tf.filter.Matches(evt.event) {
|
||||||
}
|
match = true
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if match {
|
}
|
||||||
change.events = append(change.events[:j], change.events[j+1:]...)
|
if match {
|
||||||
// Fast forward state to last matched.
|
change.events = append(change.events[:j], change.events[j+1:]...)
|
||||||
q.collapseState(i)
|
// Fast forward state to last matched.
|
||||||
return evt.event, true
|
q.collapseState(i)
|
||||||
}
|
return evt.event, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user