forked from joejulian/gio
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:
@@ -225,6 +225,9 @@ func (s *Scroll) Scroll(cfg unit.Converter, q event.Queue, t time.Time, axis Axi
|
||||
s.dragging = false
|
||||
s.grab = false
|
||||
case pointer.Scroll:
|
||||
if e.Priority < pointer.Foremost {
|
||||
continue
|
||||
}
|
||||
switch s.axis {
|
||||
case Horizontal:
|
||||
s.scroll += e.Scroll.X
|
||||
|
||||
@@ -113,6 +113,9 @@ const (
|
||||
// Shared priority is for handlers that
|
||||
// are part of a matching set larger than 1.
|
||||
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
|
||||
)
|
||||
@@ -199,6 +202,8 @@ func (p Priority) String() string {
|
||||
switch p {
|
||||
case Shared:
|
||||
return "Shared"
|
||||
case Foremost:
|
||||
return "Foremost"
|
||||
case Grabbed:
|
||||
return "Grabbed"
|
||||
default:
|
||||
|
||||
+16
-13
@@ -262,29 +262,34 @@ func (q *pointerQueue) Push(e pointer.Event, events *handlerEvents) {
|
||||
}
|
||||
|
||||
func (q *pointerQueue) deliverEvent(p *pointerInfo, events *handlerEvents, e pointer.Event) {
|
||||
foremost := true
|
||||
for _, k := range p.handlers {
|
||||
h := q.handlers[k]
|
||||
e := e
|
||||
if p.pressed && len(p.handlers) == 1 {
|
||||
e.Priority = pointer.Grabbed
|
||||
} else if foremost {
|
||||
e.Priority = pointer.Foremost
|
||||
}
|
||||
|
||||
e.Position = h.transform.Invert().Transform(e.Position)
|
||||
|
||||
addPointerEvent(events, k, e, h.types)
|
||||
|
||||
// Only deliver scroll events to the foremost handler.
|
||||
if e.Type == pointer.Scroll && e.Type&h.types != 0 {
|
||||
return
|
||||
if e.Type&h.types == e.Type {
|
||||
foremost = false
|
||||
events.Add(k, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (q *pointerQueue) deliverEnterLeaveEvents(p *pointerInfo, events *handlerEvents, e pointer.Event) {
|
||||
foremost := true
|
||||
for _, k := range p.handlers {
|
||||
h := q.handlers[k]
|
||||
e := e
|
||||
if p.pressed && len(p.handlers) == 1 {
|
||||
e.Priority = pointer.Grabbed
|
||||
} else if foremost {
|
||||
e.Priority = pointer.Foremost
|
||||
}
|
||||
|
||||
// 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:
|
||||
p.entered = append(p.entered[:entered], p.entered[entered+1:]...)
|
||||
e.Type = pointer.Leave
|
||||
addPointerEvent(events, k, e, h.types)
|
||||
case hit && entered == -1:
|
||||
p.entered = append(p.entered, k)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ func TestPointerTypes(t *testing.T) {
|
||||
assertEventSequence(t, r.Events(handler), pointer.Cancel, pointer.Press, pointer.Release)
|
||||
}
|
||||
|
||||
func TestPointerScroll(t *testing.T) {
|
||||
func TestPointerPriority(t *testing.T) {
|
||||
handler1 := new(int)
|
||||
handler2 := new(int)
|
||||
var ops op.Ops
|
||||
@@ -139,7 +139,7 @@ func TestPointerScroll(t *testing.T) {
|
||||
var r Router
|
||||
r.Frame(&ops)
|
||||
r.Add(
|
||||
// Hit handler 2.
|
||||
// Hit both handlers.
|
||||
pointer.Event{
|
||||
Type: pointer.Scroll,
|
||||
Position: f32.Point{
|
||||
@@ -164,8 +164,12 @@ func TestPointerScroll(t *testing.T) {
|
||||
},
|
||||
},
|
||||
)
|
||||
assertEventSequence(t, r.Events(handler1), pointer.Cancel, pointer.Scroll)
|
||||
assertEventSequence(t, r.Events(handler2), pointer.Cancel, pointer.Scroll)
|
||||
hev1 := r.Events(handler1)
|
||||
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) {
|
||||
@@ -463,7 +467,7 @@ func pointerTypes(events []event.Event) []pointer.Type {
|
||||
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.
|
||||
func assertEventSequence(t *testing.T, events []event.Event, expected ...pointer.Type) {
|
||||
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) {
|
||||
// Set this to the number of overlapping handlers that you want to
|
||||
// evaluate performance for. Typical values for the example applications
|
||||
|
||||
Reference in New Issue
Block a user