From 1100e03c1eb2d030b80fc6a806c89911d3e42c07 Mon Sep 17 00:00:00 2001 From: pierre Date: Wed, 27 Jan 2021 19:56:47 +0100 Subject: [PATCH] io/router: support cursor changes on Frame events Add support to Router so that the cursor can be changed with CursorNameOp without any mouse movement. Enter and Leave events are also delivered as areas change. Signed-off-by: pierre --- app/window.go | 13 +++++++++---- io/router/pointer.go | 8 ++++++++ io/router/pointer_test.go | 31 ++++++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/app/window.go b/app/window.go index 5bf7c09e..7c1f143e 100644 --- a/app/window.go +++ b/app/window.go @@ -409,6 +409,7 @@ func (w *Window) run(opts *window.Options) { w.destroy(err) return } + w.updateCursor() case *system.CommandEvent: w.out <- e w.waitAck() @@ -424,10 +425,7 @@ func (w *Window) run(opts *window.Options) { w.setNextFrame(time.Time{}) w.updateAnimation() } - if c := w.queue.q.Cursor(); c != w.cursor { - w.cursor = c - w.SetCursorName(c) - } + w.updateCursor() w.out <- e } w.ack <- struct{}{} @@ -435,6 +433,13 @@ func (w *Window) run(opts *window.Options) { } } +func (w *Window) updateCursor() { + if c := w.queue.q.Cursor(); c != w.cursor { + w.cursor = c + w.SetCursorName(c) + } +} + func (q *queue) Events(k event.Tag) []event.Event { return q.q.Events(k) } diff --git a/io/router/pointer.go b/io/router/pointer.go index 149ade76..e34d53ad 100644 --- a/io/router/pointer.go +++ b/io/router/pointer.go @@ -47,6 +47,9 @@ type pointerInfo struct { id pointer.ID pressed bool handlers []event.Tag + // last tracks the last pointer event received, + // used while processing frame events. + last pointer.Event // entered tracks the tags that contain the pointer. entered []event.Tag @@ -247,6 +250,10 @@ func (q *pointerQueue) Frame(root *op.Ops, events *handlerEvents) { } } } + for i := range q.pointers { + p := &q.pointers[i] + q.deliverEnterLeaveEvents(p, events, p.last) + } } func cancelHandlers(events *handlerEvents, tags ...event.Tag) { @@ -295,6 +302,7 @@ func (q *pointerQueue) Push(e pointer.Event, events *handlerEvents) { pidx = len(q.pointers) - 1 } p := &q.pointers[pidx] + p.last = e if e.Type == pointer.Move && p.pressed { e.Type = pointer.Drag diff --git a/io/router/pointer_test.go b/io/router/pointer_test.go index b5309cbd..e457f8e7 100644 --- a/io/router/pointer_test.go +++ b/io/router/pointer_test.go @@ -443,7 +443,7 @@ func TestMultitouch(t *testing.T) { func TestCursorNameOp(t *testing.T) { ops := new(op.Ops) var r Router - var h int + var h, h2 int var widget2 func() widget := func() { // This is the area where the cursor is changed to CursorPointer. @@ -502,6 +502,35 @@ func TestCursorNameOp(t *testing.T) { }, want: pointer.CursorDefault, }, + {label: "add new input on top while inside", + event: func() []event.Event { + widget2 = func() { + pointer.InputOp{Tag: &h2}.Add(ops) + pointer.CursorNameOp{Name: pointer.CursorCrossHair}.Add(ops) + } + return []event.Event{ + _at(50, 50), + key.Event{ + Name: "A", + State: key.Press, + }, + } + }, + want: pointer.CursorCrossHair, + }, + {label: "remove input on top while inside", + event: func() []event.Event { + widget2 = nil + return []event.Event{ + _at(50, 50), + key.Event{ + Name: "A", + State: key.Press, + }, + } + }, + want: pointer.CursorPointer, + }, } { t.Run(tc.label, func(t *testing.T) { ops.Reset()