diff --git a/app/os.go b/app/os.go index fdf76c90..c6968954 100644 --- a/app/os.go +++ b/app/os.go @@ -163,7 +163,7 @@ type driver interface { // Configure the window. Configure([]Option) // SetCursor updates the current cursor to name. - SetCursor(name pointer.CursorName) + SetCursor(cursor pointer.Cursor) // Raise the window at the top. Raise() // Close the window. diff --git a/app/os_android.go b/app/os_android.go index 41055cb3..6200133e 100644 --- a/app/os_android.go +++ b/app/os_android.go @@ -1338,9 +1338,9 @@ func (w *window) Perform(system.Action) {} func (w *window) Raise() {} -func (w *window) SetCursor(name pointer.CursorName) { +func (w *window) SetCursor(cursor pointer.Cursor) { runInJVM(javaVM(), func(env *C.JNIEnv) { - setCursor(env, w.view, name) + setCursor(env, w.view, cursor) }) } @@ -1379,8 +1379,8 @@ var androidCursor = [...]uint16{ pointer.CursorNorthWestSouthEastResize: 1017, // TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW } -func setCursor(env *C.JNIEnv, view C.jobject, name pointer.CursorName) { - curID := androidCursor[name] +func setCursor(env *C.JNIEnv, view C.jobject, cursor pointer.Cursor) { + curID := androidCursor[cursor] callVoidMethod(env, view, gioView.setCursor, jvalue(curID)) } diff --git a/app/os_darwin.go b/app/os_darwin.go index 4bba8138..c89d4dcf 100644 --- a/app/os_darwin.go +++ b/app/os_darwin.go @@ -243,7 +243,7 @@ var macosCursorID = [...]byte{ // windowSetCursor updates the cursor from the current one to a new one // and returns the new one. -func windowSetCursor(from, to pointer.CursorName) pointer.CursorName { +func windowSetCursor(from, to pointer.Cursor) pointer.Cursor { if from == to { return to } diff --git a/app/os_ios.go b/app/os_ios.go index f2583809..df45aa9a 100644 --- a/app/os_ios.go +++ b/app/os_ios.go @@ -97,7 +97,7 @@ type window struct { displayLink *displayLink visible bool - cursor pointer.CursorName + cursor pointer.Cursor config Config pointerMap []C.CFTypeRef @@ -301,8 +301,8 @@ func (w *window) SetAnimating(anim bool) { } } -func (w *window) SetCursor(name pointer.CursorName) { - w.cursor = windowSetCursor(w.cursor, name) +func (w *window) SetCursor(cursor pointer.Cursor) { + w.cursor = windowSetCursor(w.cursor, cursor) } func (w *window) onKeyCommand(name string) { diff --git a/app/os_js.go b/app/os_js.go index 49595357..7eb64d56 100644 --- a/app/os_js.go +++ b/app/os_js.go @@ -574,9 +574,9 @@ var webCursor = [...]string{ pointer.CursorNorthWestSouthEastResize: "nwse-resize", } -func (w *window) SetCursor(name pointer.CursorName) { +func (w *window) SetCursor(cursor pointer.Cursor) { style := w.cnv.Get("style") - style.Set("cursor", webCursor[name]) + style.Set("cursor", webCursor[cursor]) } func (w *window) Wakeup() { diff --git a/app/os_macos.go b/app/os_macos.go index ed1dd77b..83a29497 100644 --- a/app/os_macos.go +++ b/app/os_macos.go @@ -205,7 +205,7 @@ type window struct { w *callbacks stage system.Stage displayLink *displayLink - cursor pointer.CursorName + cursor pointer.Cursor scale float32 config Config @@ -368,8 +368,8 @@ func (w *window) setTitle(prev, cnf Config) { func (w *window) Perform(system.Action) {} -func (w *window) SetCursor(name pointer.CursorName) { - w.cursor = windowSetCursor(w.cursor, name) +func (w *window) SetCursor(cursor pointer.Cursor) { + w.cursor = windowSetCursor(w.cursor, cursor) } func (w *window) EditorStateChanged(old, new editorState) { diff --git a/app/os_unix.go b/app/os_unix.go index b6a19a77..4ec413bb 100644 --- a/app/os_unix.go +++ b/app/os_unix.go @@ -69,7 +69,7 @@ func newWindow(window *callbacks, options []Option) error { return errors.New("app: no window driver available") } -// xCursor contains mapping from pointer.CursorName to XCursor. +// xCursor contains mapping from pointer.Cursor to XCursor. var xCursor = [...]string{ pointer.CursorDefault: "left_ptr", pointer.CursorNone: "", diff --git a/app/os_wayland.go b/app/os_wayland.go index 2e300771..3dcf4609 100644 --- a/app/os_wayland.go +++ b/app/os_wayland.go @@ -1086,17 +1086,17 @@ func (w *window) Raise() { // https://wayland.app/protocols/xdg-shell#xdg_toplevel:request:set_minimized } -func (w *window) SetCursor(name pointer.CursorName) { +func (w *window) SetCursor(cursor pointer.Cursor) { ptr := w.disp.seat.pointer if ptr == nil { return } - if name == pointer.CursorNone { + if cursor == pointer.CursorNone { C.wl_pointer_set_cursor(ptr, w.serial, nil, 0, 0) return } - xcursor := xCursor[name] + xcursor := xCursor[cursor] cname := C.CString(xcursor) defer C.free(unsafe.Pointer(cname)) c := C.wl_cursor_theme_get_cursor(w.cursor.theme, cname) diff --git a/app/os_windows.go b/app/os_windows.go index f6a9332a..47624846 100644 --- a/app/os_windows.go +++ b/app/os_windows.go @@ -704,8 +704,8 @@ func (w *window) writeClipboard(s string) error { return nil } -func (w *window) SetCursor(name pointer.CursorName) { - c, err := loadCursor(name) +func (w *window) SetCursor(cursor pointer.Cursor) { + c, err := loadCursor(cursor) if err != nil { c = resources.cursor } @@ -715,7 +715,7 @@ func (w *window) SetCursor(name pointer.CursorName) { } } -// windowsCursor contains mapping from CursorName to an IDC. +// windowsCursor contains mapping from pointer.Cursor to an IDC. var windowsCursor = [...]uint16{ pointer.CursorDefault: windows.IDC_ARROW, pointer.CursorNone: 0, @@ -745,14 +745,14 @@ var windowsCursor = [...]uint16{ pointer.CursorNorthWestSouthEastResize: windows.IDC_SIZENWSE, } -func loadCursor(name pointer.CursorName) (syscall.Handle, error) { - switch name { +func loadCursor(cursor pointer.Cursor) (syscall.Handle, error) { + switch cursor { case pointer.CursorDefault: return resources.cursor, nil case pointer.CursorNone: return 0, nil default: - return windows.LoadCursor(windowsCursor[name]) + return windows.LoadCursor(windowsCursor[cursor]) } } diff --git a/app/os_x11.go b/app/os_x11.go index 21b923a1..8d84343b 100644 --- a/app/os_x11.go +++ b/app/os_x11.go @@ -107,7 +107,7 @@ type x11Window struct { clipboard struct { content []byte } - cursor pointer.CursorName + cursor pointer.Cursor config Config wakeups chan struct{} @@ -295,22 +295,22 @@ func (w *x11Window) Raise() { C.XMapRaised(w.display(), w.xw) } -func (w *x11Window) SetCursor(name pointer.CursorName) { - if name == pointer.CursorNone { - w.cursor = name +func (w *x11Window) SetCursor(cursor pointer.Cursor) { + if cursor == pointer.CursorNone { + w.cursor = cursor C.XFixesHideCursor(w.x, w.xw) return } - xcursor := xCursor[name] + xcursor := xCursor[cursor] cname := C.CString(xcursor) defer C.free(unsafe.Pointer(cname)) c := C.XcursorLibraryLoadCursor(w.x, cname) if c == 0 { - name = pointer.CursorDefault + cursor = pointer.CursorDefault } - w.cursor = name - // If c if null (i.e. name was not found), + w.cursor = cursor + // If c if null (i.e. cursor was not found), // XDefineCursor will use the default cursor. C.XDefineCursor(w.x, w.xw, c) } diff --git a/app/window.go b/app/window.go index b7c29400..29e59349 100644 --- a/app/window.go +++ b/app/window.go @@ -69,7 +69,7 @@ type Window struct { delayedDraw *time.Timer queue queue - cursor pointer.CursorName + cursor pointer.Cursor decorations struct { op.Ops Config @@ -334,13 +334,6 @@ func (w *Window) WriteClipboard(s string) { }) } -// SetCursorName changes the current window cursor to name. -func (w *Window) SetCursorName(name pointer.CursorName) { - w.driverDefer(func(d driver) { - d.SetCursor(name) - }) -} - // Run f in the same thread as the native window event loop, and wait for f to // return or the window to close. Run is guaranteed not to deadlock if it is // invoked during the handling of a ViewEvent, system.FrameEvent, diff --git a/io/pointer/pointer.go b/io/pointer/pointer.go index f67427ae..60e36b4d 100644 --- a/io/pointer/pointer.go +++ b/io/pointer/pointer.go @@ -54,11 +54,6 @@ type PassStack struct { macroID int } -// CursorNameOp sets the cursor for the current area. -type CursorNameOp struct { - Name CursorName -} - // InputOp declares an input handler ready for pointer // events. type InputOp struct { @@ -90,13 +85,14 @@ type Source uint8 // Buttons is a set of mouse buttons type Buttons uint8 -// CursorName is the name of a cursor. -type CursorName byte +// Cursor denotes a pre-defined cursor shape. Its Add method adds an +// operation that sets the cursor shape for the current clip area. +type Cursor byte // The cursors correspond to CSS pointer naming. const ( // CursorDefault is the default cursor. - CursorDefault CursorName = iota + CursorDefault Cursor = iota // CursorNone hides the cursor. To show it again, use any other cursor. CursorNone // CursorText is for selecting and inserting text. @@ -247,10 +243,10 @@ func (p PassStack) Pop() { data[0] = byte(ops.TypePopPass) } -func (op CursorNameOp) Add(o *op.Ops) { +func (op Cursor) Add(o *op.Ops) { data := ops.Write(&o.Internal, ops.TypeCursorLen) data[0] = byte(ops.TypeCursor) - data[1] = byte(op.Name) + data[1] = byte(op) } // Add panics if the scroll range does not contain zero. @@ -360,7 +356,7 @@ func (b Buttons) String() string { return strings.Join(strs, "|") } -func (c CursorName) String() string { +func (c Cursor) String() string { switch c { case CursorDefault: return "Default" diff --git a/io/router/pointer.go b/io/router/pointer.go index 19e7cd1c..30065dd3 100644 --- a/io/router/pointer.go +++ b/io/router/pointer.go @@ -18,7 +18,7 @@ type pointerQueue struct { hitTree []hitNode areas []areaNode cursors []cursorNode - cursor pointer.CursorName + cursor pointer.Cursor handlers map[event.Tag]*pointerHandler pointers []pointerInfo transfers []io.ReadCloser // pending data transfers @@ -45,8 +45,8 @@ type hitNode struct { } type cursorNode struct { - name pointer.CursorName - area int + cursor pointer.Cursor + area int } type pointerInfo struct { @@ -306,10 +306,10 @@ func (c *pointerCollector) semanticDisabled(disabled bool) { area.semantic.content.disabled = disabled } -func (c *pointerCollector) cursor(name pointer.CursorName) { +func (c *pointerCollector) cursor(cursor pointer.Cursor) { c.q.cursors = append(c.q.cursors, cursorNode{ - name: name, - area: len(c.q.areas) - 1, + cursor: cursor, + area: len(c.q.areas) - 1, }) } @@ -725,7 +725,7 @@ func (q *pointerQueue) deliverEnterLeaveEvents(p *pointerInfo, events *handlerEv h := q.handlers[k] for i := len(q.cursors) - 1; i >= 0; i-- { if c := q.cursors[i]; c.area == h.area { - q.cursor = c.name + q.cursor = c.cursor break } } diff --git a/io/router/pointer_test.go b/io/router/pointer_test.go index be4b29ab..808fd25f 100644 --- a/io/router/pointer_test.go +++ b/io/router/pointer_test.go @@ -572,7 +572,7 @@ func TestMultitouch(t *testing.T) { assertEventPointerTypeSequence(t, r.Events(h2), pointer.Cancel, pointer.Enter, pointer.Press, pointer.Release) } -func TestCursorNameOp(t *testing.T) { +func TestCursor(t *testing.T) { ops := new(op.Ops) var r Router var h, h2 int @@ -582,7 +582,7 @@ func TestCursorNameOp(t *testing.T) { defer clip.Rect(image.Rectangle{Max: image.Pt(100, 100)}).Push(ops).Pop() // The cursor is checked and changed upon cursor movement. pointer.InputOp{Tag: &h}.Add(ops) - pointer.CursorNameOp{Name: pointer.CursorPointer}.Add(ops) + pointer.CursorPointer.Add(ops) if widget2 != nil { widget2() } @@ -605,7 +605,7 @@ func TestCursorNameOp(t *testing.T) { for _, tc := range []struct { label string event interface{} - want pointer.CursorName + want pointer.Cursor }{ {label: "move inside", event: _at(50, 50), @@ -638,7 +638,7 @@ func TestCursorNameOp(t *testing.T) { event: func() []event.Event { widget2 = func() { pointer.InputOp{Tag: &h2}.Add(ops) - pointer.CursorNameOp{Name: pointer.CursorCrosshair}.Add(ops) + pointer.CursorCrosshair.Add(ops) } return []event.Event{ _at(50, 50), diff --git a/io/router/router.go b/io/router/router.go index 7e789743..e303d85c 100644 --- a/io/router/router.go +++ b/io/router/router.go @@ -193,7 +193,7 @@ func (q *Router) ReadClipboard() bool { } // Cursor returns the last cursor set. -func (q *Router) Cursor() pointer.CursorName { +func (q *Router) Cursor() pointer.Cursor { return q.pointer.queue.cursor } @@ -298,7 +298,7 @@ func (q *Router) collect() { } pc.inputOp(op, &q.handlers) case ops.TypeCursor: - name := pointer.CursorName(encOp.Data[1]) + name := pointer.Cursor(encOp.Data[1]) pc.cursor(name) case ops.TypeSource: op := transfer.SourceOp{ diff --git a/io/system/decoration.go b/io/system/decoration.go index f61be6d9..40a61ba8 100644 --- a/io/system/decoration.go +++ b/io/system/decoration.go @@ -49,10 +49,10 @@ const ( ActionResizeSouthEast ) -// CursorName returns the cursor for the action. +// Cursor returns the cursor for the action. // It must be a single action otherwise the default // cursor is returned. -func (a Action) CursorName() pointer.CursorName { +func (a Action) Cursor() pointer.Cursor { switch a { case ActionResizeNorthWest: return pointer.CursorNorthWestResize diff --git a/widget/decorations.go b/widget/decorations.go index 39e033e8..2a6efd96 100644 --- a/widget/decorations.go +++ b/widget/decorations.go @@ -93,7 +93,7 @@ func (d *Decorations) LayoutResize(gtx layout.Context, actions system.Action) { } st := clip.Rect(data.Rectangle).Push(gtx.Ops) if rsz.Hover.Hovered(gtx) { - pointer.CursorNameOp{Name: action.CursorName()}.Add(gtx.Ops) + action.Cursor().Add(gtx.Ops) } rsz.Drag.Add(gtx.Ops) pass := pointer.PassOp{}.Push(gtx.Ops) diff --git a/widget/editor.go b/widget/editor.go index 2e212561..7e7c8f85 100644 --- a/widget/editor.go +++ b/widget/editor.go @@ -626,7 +626,7 @@ func (e *Editor) layout(gtx layout.Context, content layout.Widget) layout.Dimens } e.requestFocus = false defer clip.Rect(image.Rectangle{Max: e.viewSize}).Push(gtx.Ops).Pop() - pointer.CursorNameOp{Name: pointer.CursorText}.Add(gtx.Ops) + pointer.CursorText.Add(gtx.Ops) var scrollRange image.Rectangle if e.SingleLine {