io/pointer,io/router,gesture: add pointer.Foremost priority

Replace the pointer.Scroll special case with a new priority that
indicates the foremost handler, checked in gesture.Scroll.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2020-06-05 10:46:19 +02:00
parent 2accb88381
commit 65d4707e3e
4 changed files with 47 additions and 18 deletions
+3
View File
@@ -225,6 +225,9 @@ func (s *Scroll) Scroll(cfg unit.Converter, q event.Queue, t time.Time, axis Axi
s.dragging = false s.dragging = false
s.grab = false s.grab = false
case pointer.Scroll: case pointer.Scroll:
if e.Priority < pointer.Foremost {
continue
}
switch s.axis { switch s.axis {
case Horizontal: case Horizontal:
s.scroll += e.Scroll.X s.scroll += e.Scroll.X
+5
View File
@@ -113,6 +113,9 @@ const (
// Shared priority is for handlers that // Shared priority is for handlers that
// are part of a matching set larger than 1. // are part of a matching set larger than 1.
Shared Priority = iota Shared Priority = iota
// Foremost priority is like Shared, but the
// handler is the foremost of the matching set.
Foremost
// Grabbed is used for matching sets of size 1. // Grabbed is used for matching sets of size 1.
Grabbed Grabbed
) )
@@ -199,6 +202,8 @@ func (p Priority) String() string {
switch p { switch p {
case Shared: case Shared:
return "Shared" return "Shared"
case Foremost:
return "Foremost"
case Grabbed: case Grabbed:
return "Grabbed" return "Grabbed"
default: default:
+16 -13
View File
@@ -262,29 +262,34 @@ func (q *pointerQueue) Push(e pointer.Event, events *handlerEvents) {
} }
func (q *pointerQueue) deliverEvent(p *pointerInfo, events *handlerEvents, e pointer.Event) { func (q *pointerQueue) deliverEvent(p *pointerInfo, events *handlerEvents, e pointer.Event) {
foremost := true
for _, k := range p.handlers { for _, k := range p.handlers {
h := q.handlers[k] h := q.handlers[k]
e := e e := e
if p.pressed && len(p.handlers) == 1 { if p.pressed && len(p.handlers) == 1 {
e.Priority = pointer.Grabbed e.Priority = pointer.Grabbed
} else if foremost {
e.Priority = pointer.Foremost
} }
e.Position = h.transform.Invert().Transform(e.Position) e.Position = h.transform.Invert().Transform(e.Position)
addPointerEvent(events, k, e, h.types) if e.Type&h.types == e.Type {
foremost = false
// Only deliver scroll events to the foremost handler. events.Add(k, e)
if e.Type == pointer.Scroll && e.Type&h.types != 0 {
return
} }
} }
} }
func (q *pointerQueue) deliverEnterLeaveEvents(p *pointerInfo, events *handlerEvents, e pointer.Event) { func (q *pointerQueue) deliverEnterLeaveEvents(p *pointerInfo, events *handlerEvents, e pointer.Event) {
foremost := true
for _, k := range p.handlers { for _, k := range p.handlers {
h := q.handlers[k] h := q.handlers[k]
e := e e := e
if p.pressed && len(p.handlers) == 1 { if p.pressed && len(p.handlers) == 1 {
e.Priority = pointer.Grabbed e.Priority = pointer.Grabbed
} else if foremost {
e.Priority = pointer.Foremost
} }
// Hit-test to deliver Enter/Leave events. Consider non-mouse // Hit-test to deliver Enter/Leave events. Consider non-mouse
@@ -304,18 +309,16 @@ func (q *pointerQueue) deliverEnterLeaveEvents(p *pointerInfo, events *handlerEv
case !hit && entered != -1: case !hit && entered != -1:
p.entered = append(p.entered[:entered], p.entered[entered+1:]...) p.entered = append(p.entered[:entered], p.entered[entered+1:]...)
e.Type = pointer.Leave e.Type = pointer.Leave
addPointerEvent(events, k, e, h.types)
case hit && entered == -1: case hit && entered == -1:
p.entered = append(p.entered, k) p.entered = append(p.entered, k)
e.Type = pointer.Enter e.Type = pointer.Enter
addPointerEvent(events, k, e, h.types) default:
continue
}
if e.Type&h.types == e.Type {
foremost = false
events.Add(k, e)
} }
}
}
func addPointerEvent(events *handlerEvents, k event.Tag, e pointer.Event, types pointer.Type) {
if e.Type&types == e.Type {
events.Add(k, e)
} }
} }
+23 -5
View File
@@ -125,7 +125,7 @@ func TestPointerTypes(t *testing.T) {
assertEventSequence(t, r.Events(handler), pointer.Cancel, pointer.Press, pointer.Release) assertEventSequence(t, r.Events(handler), pointer.Cancel, pointer.Press, pointer.Release)
} }
func TestPointerScroll(t *testing.T) { func TestPointerPriority(t *testing.T) {
handler1 := new(int) handler1 := new(int)
handler2 := new(int) handler2 := new(int)
var ops op.Ops var ops op.Ops
@@ -139,7 +139,7 @@ func TestPointerScroll(t *testing.T) {
var r Router var r Router
r.Frame(&ops) r.Frame(&ops)
r.Add( r.Add(
// Hit handler 2. // Hit both handlers.
pointer.Event{ pointer.Event{
Type: pointer.Scroll, Type: pointer.Scroll,
Position: f32.Point{ Position: f32.Point{
@@ -164,8 +164,12 @@ func TestPointerScroll(t *testing.T) {
}, },
}, },
) )
assertEventSequence(t, r.Events(handler1), pointer.Cancel, pointer.Scroll) hev1 := r.Events(handler1)
assertEventSequence(t, r.Events(handler2), pointer.Cancel, pointer.Scroll) hev2 := r.Events(handler2)
assertEventSequence(t, hev1, pointer.Cancel, pointer.Scroll, pointer.Scroll)
assertEventSequence(t, hev2, pointer.Cancel, pointer.Scroll)
assertEventPriorities(t, hev1, pointer.Shared, pointer.Shared, pointer.Foremost)
assertEventPriorities(t, hev2, pointer.Shared, pointer.Foremost)
} }
func TestPointerEnterLeave(t *testing.T) { func TestPointerEnterLeave(t *testing.T) {
@@ -463,7 +467,7 @@ func pointerTypes(events []event.Event) []pointer.Type {
return types return types
} }
// assertEventSequence ensures that the provided actualEvents match the expected event types // assertEventSequence checks that the provided events match the expected pointer event types
// in the provided order. // in the provided order.
func assertEventSequence(t *testing.T, events []event.Event, expected ...pointer.Type) { func assertEventSequence(t *testing.T, events []event.Event, expected ...pointer.Type) {
t.Helper() t.Helper()
@@ -473,6 +477,20 @@ func assertEventSequence(t *testing.T, events []event.Event, expected ...pointer
} }
} }
// assertEventPriorities checks that the pointer.Event priorities of events match prios.
func assertEventPriorities(t *testing.T, events []event.Event, prios ...pointer.Priority) {
t.Helper()
var got []pointer.Priority
for _, e := range events {
if e, ok := e.(pointer.Event); ok {
got = append(got, e.Priority)
}
}
if !reflect.DeepEqual(got, prios) {
t.Errorf("expected priorities %v, got %v", prios, got)
}
}
func BenchmarkRouterAdd(b *testing.B) { func BenchmarkRouterAdd(b *testing.B) {
// Set this to the number of overlapping handlers that you want to // Set this to the number of overlapping handlers that you want to
// evaluate performance for. Typical values for the example applications // evaluate performance for. Typical values for the example applications