From cc63a3aeb7320d8859fee009a970fbed7d1d3187 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sat, 23 Jan 2021 12:00:50 +0100 Subject: [PATCH] io/router: don't send pointer.Cancel events to disappearing handlers As a follow-up to gioui.org/commit/24f69bf4, this change makes it so that merely adding a pointer.InputOp doesn't trigger redraws when the pointer is hovered over its area. Signed-off-by: Elias Naur --- io/router/pointer.go | 16 ++++++++++++---- io/router/pointer_test.go | 9 ++++++--- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/io/router/pointer.go b/io/router/pointer.go index 77165429..69b475e3 100644 --- a/io/router/pointer.go +++ b/io/router/pointer.go @@ -205,7 +205,7 @@ func (q *pointerQueue) hit(areaIdx int, p f32.Point) bool { return true } -func (q *pointerQueue) init() { +func (q *pointerQueue) reset() { if q.handlers == nil { q.handlers = make(map[event.Tag]*pointerHandler) } @@ -213,7 +213,7 @@ func (q *pointerQueue) init() { } func (q *pointerQueue) Frame(root *op.Ops, events *handlerEvents) { - q.init() + q.reset() for _, h := range q.handlers { // Reset handler. h.active = false @@ -238,6 +238,8 @@ func (q *pointerQueue) Frame(root *op.Ops, events *handlerEvents) { for i, k2 := range p.handlers { if k2 == k { // Drop other handlers that lost their grab. + cancelHandlers(events, p.handlers[i+1:]...) + cancelHandlers(events, p.handlers[:i]...) q.dropHandlers(events, p.handlers[i+1:]...) q.dropHandlers(events, p.handlers[:i]...) break @@ -248,9 +250,14 @@ func (q *pointerQueue) Frame(root *op.Ops, events *handlerEvents) { } } -func (q *pointerQueue) dropHandlers(events *handlerEvents, tags ...event.Tag) { +func cancelHandlers(events *handlerEvents, tags ...event.Tag) { for _, k := range tags { events.Add(k, pointer.Event{Type: pointer.Cancel}) + } +} + +func (q *pointerQueue) dropHandlers(events *handlerEvents, tags ...event.Tag) { + for _, k := range tags { for i := range q.pointers { p := &q.pointers[i] for i := len(p.handlers) - 1; i >= 0; i-- { @@ -268,10 +275,11 @@ func (q *pointerQueue) dropHandlers(events *handlerEvents, tags ...event.Tag) { } func (q *pointerQueue) Push(e pointer.Event, events *handlerEvents) { - q.init() + q.reset() if e.Type == pointer.Cancel { q.pointers = q.pointers[:0] for k := range q.handlers { + cancelHandlers(events, k) q.dropHandlers(events, k) } return diff --git a/io/router/pointer_test.go b/io/router/pointer_test.go index 5d61a7d4..7161e82a 100644 --- a/io/router/pointer_test.go +++ b/io/router/pointer_test.go @@ -89,9 +89,12 @@ func TestPointerMove(t *testing.T) { Type: pointer.Move, Position: f32.Pt(100, 50), }, + pointer.Event{ + Type: pointer.Cancel, + }, ) - assertEventSequence(t, r.Events(handler1), pointer.Cancel, pointer.Enter, pointer.Move, pointer.Move, pointer.Leave) - assertEventSequence(t, r.Events(handler2), pointer.Cancel, pointer.Enter, pointer.Move, pointer.Leave) + assertEventSequence(t, r.Events(handler1), pointer.Cancel, pointer.Enter, pointer.Move, pointer.Move, pointer.Leave, pointer.Cancel) + assertEventSequence(t, r.Events(handler2), pointer.Cancel, pointer.Enter, pointer.Move, pointer.Leave, pointer.Cancel) } func TestPointerTypes(t *testing.T) { @@ -396,7 +399,7 @@ func TestPointerActiveInputDisappears(t *testing.T) { Position: f32.Pt(25, 25), }, ) - assertEventSequence(t, r.Events(handler1), pointer.Cancel) + assertEventSequence(t, r.Events(handler1)) } func TestMultitouch(t *testing.T) {