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()