mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-05 17:35:36 +00:00
io/input: switch internal API to return one event at a time
Make the internal changes to support fine-grained event delivery. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+33
-23
@@ -124,6 +124,8 @@ type handler struct {
|
|||||||
filter filter
|
filter filter
|
||||||
// prevFilter is the filter being built in the current frame.
|
// prevFilter is the filter being built in the current frame.
|
||||||
nextFilter filter
|
nextFilter filter
|
||||||
|
// processedFilter is the filters that have exhausted available events.
|
||||||
|
processedFilter filter
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter is the union of a set of [io/event.Filters].
|
// filter is the union of a set of [io/event.Filters].
|
||||||
@@ -185,6 +187,17 @@ func (s Source) Events(k event.Tag, filters ...event.Filter) []event.Event {
|
|||||||
|
|
||||||
func (q *Router) Events(k event.Tag, filters ...event.Filter) []event.Event {
|
func (q *Router) Events(k event.Tag, filters ...event.Filter) []event.Event {
|
||||||
var events []event.Event
|
var events []event.Event
|
||||||
|
for {
|
||||||
|
e, ok := q.nextEvent(k, filters...)
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
events = append(events, e)
|
||||||
|
}
|
||||||
|
return events
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Router) nextEvent(k event.Tag, filters ...event.Filter) (event.Event, bool) {
|
||||||
h := q.stateFor(k)
|
h := q.stateFor(k)
|
||||||
q.scratchFilter.Reset()
|
q.scratchFilter.Reset()
|
||||||
// Record handler filters and add reset events.
|
// Record handler filters and add reset events.
|
||||||
@@ -193,38 +206,34 @@ func (q *Router) Events(k event.Tag, filters ...event.Filter) []event.Event {
|
|||||||
switch f.(type) {
|
switch f.(type) {
|
||||||
case key.FocusFilter:
|
case key.FocusFilter:
|
||||||
if reset, ok := h.key.ResetEvent(); ok {
|
if reset, ok := h.key.ResetEvent(); ok {
|
||||||
events = append(events, reset)
|
return reset, true
|
||||||
}
|
}
|
||||||
case pointer.Filter:
|
case pointer.Filter:
|
||||||
if reset, ok := h.pointer.ResetEvent(); ok {
|
if reset, ok := h.pointer.ResetEvent(); ok {
|
||||||
events = append(events, reset)
|
return reset, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h.nextFilter.Merge(q.scratchFilter)
|
h.nextFilter.Merge(q.scratchFilter)
|
||||||
if q.deferring {
|
if !q.deferring {
|
||||||
return events
|
for i := range q.changes {
|
||||||
}
|
change := &q.changes[i]
|
||||||
// Accumulate events from state changes until there are no more
|
j := 0
|
||||||
// matching events.
|
for j < len(change.events) {
|
||||||
matchedIdx := 0
|
evt := change.events[j]
|
||||||
for i := range q.changes {
|
if evt.tag != k || !q.scratchFilter.Matches(evt.event) {
|
||||||
change := &q.changes[i]
|
j++
|
||||||
j := 0
|
continue
|
||||||
for j < len(change.events) {
|
}
|
||||||
evt := change.events[j]
|
change.events = append(change.events[:j], change.events[j+1:]...)
|
||||||
if evt.tag != k || !q.scratchFilter.Matches(evt.event) {
|
// Fast forward state to last matched.
|
||||||
j++
|
q.collapseState(i)
|
||||||
continue
|
return evt.event, true
|
||||||
}
|
}
|
||||||
events = append(events, evt.event)
|
|
||||||
change.events = append(change.events[:j], change.events[j+1:]...)
|
|
||||||
matchedIdx = i
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Fast forward state to last matched.
|
h.processedFilter.Merge(q.scratchFilter)
|
||||||
q.collapseState(matchedIdx)
|
return nil, false
|
||||||
return events
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// collapseState in the interval [1;idx] into q.changes[0].
|
// collapseState in the interval [1;idx] into q.changes[0].
|
||||||
@@ -269,6 +278,7 @@ func (q *Router) Frame(frame *op.Ops) {
|
|||||||
for _, h := range q.handlers {
|
for _, h := range q.handlers {
|
||||||
h.filter, h.nextFilter = h.nextFilter, h.filter
|
h.filter, h.nextFilter = h.nextFilter, h.filter
|
||||||
h.nextFilter.Reset()
|
h.nextFilter.Reset()
|
||||||
|
h.processedFilter.Reset()
|
||||||
h.pointer.Reset()
|
h.pointer.Reset()
|
||||||
h.key.Reset()
|
h.key.Reset()
|
||||||
}
|
}
|
||||||
@@ -400,7 +410,7 @@ func (q *Router) execute(c Command) {
|
|||||||
}
|
}
|
||||||
for _, e := range ch.events {
|
for _, e := range ch.events {
|
||||||
h, ok := q.handlers[e.tag]
|
h, ok := q.handlers[e.tag]
|
||||||
immediate = immediate && ok && h.old && !h.nextFilter.Matches(e.event)
|
immediate = immediate && ok && h.old && !h.processedFilter.Matches(e.event)
|
||||||
}
|
}
|
||||||
if immediate {
|
if immediate {
|
||||||
// Hold on to the remaining events for state replay.
|
// Hold on to the remaining events for state replay.
|
||||||
|
|||||||
Reference in New Issue
Block a user