mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
app: add support for system cursors
Signed-off-by: pierre <pierre.curto@gmail.com>
This commit is contained in:
@@ -3,6 +3,8 @@ image: freebsd/11.x
|
||||
packages:
|
||||
- libX11
|
||||
- libxkbcommon
|
||||
- libXcursor
|
||||
- libXfixes
|
||||
- wayland
|
||||
- mesa-libs
|
||||
- xorg-vfbserver
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.view.Choreographer;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.PointerIcon;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.WindowInsets;
|
||||
@@ -36,7 +37,6 @@ import android.view.inputmethod.EditorInfo;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
public final class GioView extends SurfaceView implements Choreographer.FrameCallback {
|
||||
private final static Object initLock = new Object();
|
||||
private static boolean jniLoaded;
|
||||
|
||||
private final SurfaceHolder.Callback surfCallbacks;
|
||||
@@ -124,6 +124,11 @@ public final class GioView extends SurfaceView implements Choreographer.FrameCal
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setCursor(Context ctx, int id) {
|
||||
PointerIcon pointerIcon = PointerIcon.getSystemIcon(ctx, id);
|
||||
GioView.this.setPointerIcon(pointerIcon);
|
||||
}
|
||||
|
||||
private void dispatchMotionEvent(MotionEvent event) {
|
||||
for (int j = 0; j < event.getHistorySize(); j++) {
|
||||
long time = event.getHistoricalEventTime(j);
|
||||
|
||||
@@ -80,6 +80,7 @@ type window struct {
|
||||
mshowTextInput C.jmethodID
|
||||
mhideTextInput C.jmethodID
|
||||
mpostFrameCallback C.jmethodID
|
||||
msetCursor C.jmethodID
|
||||
}
|
||||
|
||||
// ViewEvent is sent whenever the Window's underlying Android view
|
||||
@@ -202,6 +203,7 @@ func Java_org_gioui_GioView_onCreateView(env *C.JNIEnv, class C.jclass, view C.j
|
||||
mshowTextInput: getMethodID(env, class, "showTextInput", "()V"),
|
||||
mhideTextInput: getMethodID(env, class, "hideTextInput", "()V"),
|
||||
mpostFrameCallback: getMethodID(env, class, "postFrameCallback", "()V"),
|
||||
msetCursor: getMethodID(env, class, "setCursor", "(Landroid/content/Context;I)V"),
|
||||
}
|
||||
wopts := <-mainWindow.out
|
||||
w.callbacks = wopts.window
|
||||
@@ -649,6 +651,32 @@ func (w *window) ReadClipboard() {
|
||||
})
|
||||
}
|
||||
|
||||
func (w *window) SetCursor(name pointer.CursorName) {
|
||||
var curID int
|
||||
switch name {
|
||||
default:
|
||||
fallthrough
|
||||
case pointer.CursorDefault:
|
||||
curID = 1000 // TYPE_ARROW
|
||||
case pointer.CursorText:
|
||||
curID = 1008 // TYPE_TEXT
|
||||
case pointer.CursorPointer:
|
||||
curID = 1002 // TYPE_HAND
|
||||
case pointer.CursorCrossHair:
|
||||
curID = 1007 // TYPE_CROSSHAIR
|
||||
case pointer.CursorColResize:
|
||||
curID = 1014 // TYPE_HORIZONTAL_DOUBLE_ARROW
|
||||
case pointer.CursorRowResize:
|
||||
curID = 1015 // TYPE_VERTICAL_DOUBLE_ARROW
|
||||
case pointer.CursorNone:
|
||||
curID = 0 // TYPE_NULL
|
||||
}
|
||||
runOnMain(func(env *C.JNIEnv) {
|
||||
callVoidMethod(env, w.view, w.msetCursor,
|
||||
jvalue(android.appCtx), jvalue(curID))
|
||||
})
|
||||
}
|
||||
|
||||
// Close the window. Not implemented for Android.
|
||||
func (w *window) Close() {}
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@ __attribute__ ((visibility ("hidden"))) void gio_releaseDisplayLink(CFTypeRef dl
|
||||
__attribute__ ((visibility ("hidden"))) int gio_startDisplayLink(CFTypeRef dl);
|
||||
__attribute__ ((visibility ("hidden"))) int gio_stopDisplayLink(CFTypeRef dl);
|
||||
__attribute__ ((visibility ("hidden"))) void gio_setDisplayLinkDisplay(CFTypeRef dl, uint64_t did);
|
||||
__attribute__ ((visibility ("hidden"))) void gio_hideCursor();
|
||||
__attribute__ ((visibility ("hidden"))) void gio_showCursor();
|
||||
__attribute__ ((visibility ("hidden"))) void gio_setCursor(NSUInteger curID);
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
@@ -22,6 +25,8 @@ import (
|
||||
"time"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
|
||||
"gioui.org/io/pointer"
|
||||
)
|
||||
|
||||
// displayLink is the state for a display link (CVDisplayLinkRef on macOS,
|
||||
@@ -169,3 +174,41 @@ func gio_onFrameCallback(dl C.CFTypeRef) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
if from == to {
|
||||
return to
|
||||
}
|
||||
var curID int
|
||||
switch to {
|
||||
default:
|
||||
to = pointer.CursorDefault
|
||||
fallthrough
|
||||
case pointer.CursorDefault:
|
||||
curID = 1
|
||||
case pointer.CursorText:
|
||||
curID = 2
|
||||
case pointer.CursorPointer:
|
||||
curID = 3
|
||||
case pointer.CursorCrossHair:
|
||||
curID = 4
|
||||
case pointer.CursorColResize:
|
||||
curID = 5
|
||||
case pointer.CursorRowResize:
|
||||
curID = 6
|
||||
case pointer.CursorNone:
|
||||
runOnMain(func() {
|
||||
C.gio_hideCursor()
|
||||
})
|
||||
return to
|
||||
}
|
||||
runOnMain(func() {
|
||||
if from == pointer.CursorNone {
|
||||
C.gio_showCursor()
|
||||
}
|
||||
C.gio_setCursor(C.NSUInteger(curID))
|
||||
})
|
||||
return to
|
||||
}
|
||||
|
||||
@@ -20,3 +20,43 @@ void gio_nsstringGetCharacters(CFTypeRef cstr, unichar *chars, NSUInteger loc, N
|
||||
NSString *str = (__bridge NSString *)cstr;
|
||||
[str getCharacters:chars range:NSMakeRange(loc, length)];
|
||||
}
|
||||
|
||||
void gio_hideCursor() {
|
||||
@autoreleasepool {
|
||||
[NSCursor hide];
|
||||
}
|
||||
}
|
||||
|
||||
void gio_showCursor() {
|
||||
@autoreleasepool {
|
||||
[NSCursor unhide];
|
||||
}
|
||||
}
|
||||
|
||||
void gio_setCursor(NSUInteger curID) {
|
||||
@autoreleasepool {
|
||||
switch (curID) {
|
||||
case 1:
|
||||
[NSCursor.arrowCursor set];
|
||||
break;
|
||||
case 2:
|
||||
[NSCursor.IBeamCursor set];
|
||||
break;
|
||||
case 3:
|
||||
[NSCursor.pointingHandCursor set];
|
||||
break;
|
||||
case 4:
|
||||
[NSCursor.crosshairCursor set];
|
||||
break;
|
||||
case 5:
|
||||
[NSCursor.resizeLeftRightCursor set];
|
||||
break;
|
||||
case 6:
|
||||
[NSCursor.resizeUpDownCursor set];
|
||||
break;
|
||||
default:
|
||||
[NSCursor.arrowCursor set];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ type window struct {
|
||||
|
||||
layer C.CFTypeRef
|
||||
visible atomic.Value
|
||||
cursor pointer.CursorName
|
||||
|
||||
pointerMap []C.CFTypeRef
|
||||
}
|
||||
@@ -249,6 +250,10 @@ func (w *window) SetAnimating(anim bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func (w *window) SetCursor(name pointer.CursorName) {
|
||||
w.cursor = windowSetCursor(w.cursor, name)
|
||||
}
|
||||
|
||||
func (w *window) onKeyCommand(name string) {
|
||||
w.w.Event(key.Event{
|
||||
Name: name,
|
||||
|
||||
@@ -426,6 +426,11 @@ func (w *window) WriteClipboard(s string) {
|
||||
w.clipboard.Call("writeText", s)
|
||||
}
|
||||
|
||||
func (w *window) SetCursor(name pointer.CursorName) {
|
||||
style := w.cnv.Get("style")
|
||||
style.Set("cursor", string(name))
|
||||
}
|
||||
|
||||
func (w *window) ShowTextInput(show bool) {
|
||||
// Run in a goroutine to avoid a deadlock if the
|
||||
// focus change result in an event.
|
||||
|
||||
@@ -58,6 +58,7 @@ type window struct {
|
||||
w Callbacks
|
||||
stage system.Stage
|
||||
displayLink *displayLink
|
||||
cursor pointer.CursorName
|
||||
|
||||
scale float32
|
||||
}
|
||||
@@ -74,7 +75,7 @@ var launched = make(chan struct{})
|
||||
// cascadeTopLeftFromPoint.
|
||||
var nextTopLeft C.NSPoint
|
||||
|
||||
// mustView is like lookoupView, except that it panics
|
||||
// mustView is like lookupView, except that it panics
|
||||
// if the view isn't mapped.
|
||||
func mustView(view C.CFTypeRef) *window {
|
||||
w, ok := lookupView(view)
|
||||
@@ -122,6 +123,10 @@ func (w *window) WriteClipboard(s string) {
|
||||
})
|
||||
}
|
||||
|
||||
func (w *window) SetCursor(name pointer.CursorName) {
|
||||
w.cursor = windowSetCursor(w.cursor, name)
|
||||
}
|
||||
|
||||
func (w *window) ShowTextInput(show bool) {}
|
||||
|
||||
func (w *window) SetAnimating(anim bool) {
|
||||
@@ -227,6 +232,7 @@ func gio_onDraw(view C.CFTypeRef) {
|
||||
func gio_onFocus(view C.CFTypeRef, focus C.BOOL) {
|
||||
w := mustView(view)
|
||||
w.w.Event(key.FocusEvent{Focus: focus == C.YES})
|
||||
w.SetCursor(w.cursor)
|
||||
}
|
||||
|
||||
//export gio_onChangeScreen
|
||||
|
||||
@@ -764,16 +764,7 @@ func gio_onPointerEnter(data unsafe.Pointer, pointer *C.struct_wl_pointer, seria
|
||||
s.serial = serial
|
||||
w := callbackLoad(unsafe.Pointer(surf)).(*window)
|
||||
s.pointerFocus = w
|
||||
// Get images[0].
|
||||
img := *w.cursor.cursor.images
|
||||
buf := C.wl_cursor_image_get_buffer(img)
|
||||
if buf == nil {
|
||||
return
|
||||
}
|
||||
C.wl_pointer_set_cursor(pointer, serial, w.cursor.surf, C.int32_t(img.hotspot_x), C.int32_t(img.hotspot_y))
|
||||
C.wl_surface_attach(w.cursor.surf, buf, 0, 0)
|
||||
C.wl_surface_damage(w.cursor.surf, 0, 0, C.int32_t(img.width), C.int32_t(img.height))
|
||||
C.wl_surface_commit(w.cursor.surf)
|
||||
w.setCursor(pointer, serial)
|
||||
w.lastPos = f32.Point{X: fromFixed(x), Y: fromFixed(y)}
|
||||
}
|
||||
|
||||
@@ -917,6 +908,50 @@ func (w *window) WriteClipboard(s string) {
|
||||
w.disp.wakeup()
|
||||
}
|
||||
|
||||
func (w *window) SetCursor(name pointer.CursorName) {
|
||||
if name == pointer.CursorNone {
|
||||
C.wl_pointer_set_cursor(w.disp.seat.pointer, w.serial, nil, 0, 0)
|
||||
return
|
||||
}
|
||||
switch name {
|
||||
default:
|
||||
fallthrough
|
||||
case pointer.CursorDefault:
|
||||
name = "left_ptr"
|
||||
case pointer.CursorText:
|
||||
name = "xterm"
|
||||
case pointer.CursorPointer:
|
||||
name = "hand1"
|
||||
case pointer.CursorCrossHair:
|
||||
name = "crosshair"
|
||||
case pointer.CursorRowResize:
|
||||
name = "top_side"
|
||||
case pointer.CursorColResize:
|
||||
name = "left_side"
|
||||
}
|
||||
cname := C.CString(string(name))
|
||||
defer C.free(unsafe.Pointer(cname))
|
||||
c := C.wl_cursor_theme_get_cursor(w.cursor.theme, cname)
|
||||
if c == nil {
|
||||
return
|
||||
}
|
||||
w.cursor.cursor = c
|
||||
w.setCursor(w.disp.seat.pointer, w.serial)
|
||||
}
|
||||
|
||||
func (w *window) setCursor(pointer *C.struct_wl_pointer, serial C.uint32_t) {
|
||||
// Get images[0].
|
||||
img := *w.cursor.cursor.images
|
||||
buf := C.wl_cursor_image_get_buffer(img)
|
||||
if buf == nil {
|
||||
return
|
||||
}
|
||||
C.wl_pointer_set_cursor(pointer, serial, w.cursor.surf, C.int32_t(img.hotspot_x), C.int32_t(img.hotspot_y))
|
||||
C.wl_surface_attach(w.cursor.surf, buf, 0, 0)
|
||||
C.wl_surface_damage(w.cursor.surf, 0, 0, C.int32_t(img.width), C.int32_t(img.height))
|
||||
C.wl_surface_commit(w.cursor.surf)
|
||||
}
|
||||
|
||||
func (w *window) resetFling() {
|
||||
w.fling.start = false
|
||||
w.fling.anim = fling.Animation{}
|
||||
|
||||
@@ -45,6 +45,7 @@ type window struct {
|
||||
height int
|
||||
stage system.Stage
|
||||
pointerBtns pointer.Buttons
|
||||
cursor syscall.Handle
|
||||
|
||||
mu sync.Mutex
|
||||
animating bool
|
||||
@@ -105,6 +106,9 @@ func NewWindow(window Callbacks, opts *Options) error {
|
||||
windows.ShowWindow(w.hwnd, windows.SW_SHOWDEFAULT)
|
||||
windows.SetForegroundWindow(w.hwnd)
|
||||
windows.SetFocus(w.hwnd)
|
||||
// Since the window class for the cursor is null,
|
||||
// set it here to show the cursor.
|
||||
w.SetCursor(pointer.CursorDefault)
|
||||
if err := w.loop(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -120,17 +124,16 @@ func initResources() error {
|
||||
return err
|
||||
}
|
||||
resources.handle = hInst
|
||||
curs, err := windows.LoadCursor(windows.IDC_ARROW)
|
||||
c, err := loadCursor(pointer.CursorDefault)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resources.cursor = curs
|
||||
resources.cursor = c
|
||||
wcls := windows.WndClassEx{
|
||||
CbSize: uint32(unsafe.Sizeof(windows.WndClassEx{})),
|
||||
Style: windows.CS_HREDRAW | windows.CS_VREDRAW | windows.CS_OWNDC,
|
||||
LpfnWndProc: syscall.NewCallback(windowProc),
|
||||
HInstance: hInst,
|
||||
HCursor: curs,
|
||||
LpszClassName: syscall.StringToUTF16Ptr("GioWindow"),
|
||||
}
|
||||
cls, err := windows.RegisterClassEx(&wcls)
|
||||
@@ -299,6 +302,8 @@ func windowProc(hwnd syscall.Handle, msg uint32, wParam, lParam uintptr) uintptr
|
||||
Y: w.minmax.maxHeight + w.deltas.height,
|
||||
}
|
||||
}
|
||||
case windows.WM_SETCURSOR:
|
||||
windows.SetCursor(w.cursor)
|
||||
}
|
||||
|
||||
return windows.DefWindowProc(hwnd, msg, wParam, lParam)
|
||||
@@ -552,6 +557,37 @@ func (w *window) writeClipboard(s string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *window) SetCursor(name pointer.CursorName) {
|
||||
c, err := loadCursor(name)
|
||||
if err != nil {
|
||||
c = resources.cursor
|
||||
}
|
||||
w.cursor = c
|
||||
}
|
||||
|
||||
func loadCursor(name pointer.CursorName) (syscall.Handle, error) {
|
||||
var curID uint16
|
||||
switch name {
|
||||
default:
|
||||
fallthrough
|
||||
case pointer.CursorDefault:
|
||||
return resources.cursor, nil
|
||||
case pointer.CursorText:
|
||||
curID = windows.IDC_IBEAM
|
||||
case pointer.CursorPointer:
|
||||
curID = windows.IDC_HAND
|
||||
case pointer.CursorCrossHair:
|
||||
curID = windows.IDC_CROSS
|
||||
case pointer.CursorColResize:
|
||||
curID = windows.IDC_SIZEWE
|
||||
case pointer.CursorRowResize:
|
||||
curID = windows.IDC_SIZENS
|
||||
case pointer.CursorNone:
|
||||
return 0, nil
|
||||
}
|
||||
return windows.LoadCursor(curID)
|
||||
}
|
||||
|
||||
func (w *window) ShowTextInput(show bool) {}
|
||||
|
||||
func (w *window) HDC() syscall.Handle {
|
||||
|
||||
@@ -7,8 +7,8 @@ package window
|
||||
/*
|
||||
#cgo openbsd CFLAGS: -I/usr/X11R6/include -I/usr/local/include
|
||||
#cgo openbsd LDFLAGS: -L/usr/X11R6/lib -L/usr/local/lib
|
||||
#cgo freebsd openbsd LDFLAGS: -lX11 -lxkbcommon -lxkbcommon-x11 -lX11-xcb
|
||||
#cgo linux pkg-config: x11 xkbcommon xkbcommon-x11 x11-xcb
|
||||
#cgo freebsd openbsd LDFLAGS: -lX11 -lxkbcommon -lxkbcommon-x11 -lX11-xcb -lXcursor -lXfixes
|
||||
#cgo linux pkg-config: x11 xkbcommon xkbcommon-x11 x11-xcb xcursor xfixes
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
@@ -18,6 +18,8 @@ package window
|
||||
#include <X11/Xresource.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#include <xkbcommon/xkbcommon-x11.h>
|
||||
|
||||
*/
|
||||
@@ -87,6 +89,7 @@ type x11Window struct {
|
||||
write *string
|
||||
content []byte
|
||||
}
|
||||
cursor pointer.CursorName
|
||||
}
|
||||
|
||||
func (w *x11Window) SetAnimating(anim bool) {
|
||||
@@ -112,6 +115,27 @@ func (w *x11Window) WriteClipboard(s string) {
|
||||
w.wakeup()
|
||||
}
|
||||
|
||||
func (w *x11Window) SetCursor(name pointer.CursorName) {
|
||||
if name == pointer.CursorNone {
|
||||
w.cursor = name
|
||||
C.XFixesHideCursor(w.x, w.xw)
|
||||
return
|
||||
}
|
||||
if w.cursor == pointer.CursorNone {
|
||||
C.XFixesShowCursor(w.x, w.xw)
|
||||
}
|
||||
cname := C.CString(string(name))
|
||||
defer C.free(unsafe.Pointer(cname))
|
||||
c := C.XcursorLibraryLoadCursor(w.x, cname)
|
||||
if c == 0 {
|
||||
name = pointer.CursorDefault
|
||||
}
|
||||
w.cursor = name
|
||||
// If c if null (i.e. name was not found),
|
||||
// XDefineCursor will use the default cursor.
|
||||
C.XDefineCursor(w.x, w.xw, c)
|
||||
}
|
||||
|
||||
func (w *x11Window) ShowTextInput(show bool) {}
|
||||
|
||||
// Close the window.
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"gioui.org/gpu/backend"
|
||||
"gioui.org/io/event"
|
||||
"gioui.org/io/pointer"
|
||||
"gioui.org/io/system"
|
||||
"gioui.org/unit"
|
||||
)
|
||||
@@ -60,6 +61,9 @@ type Driver interface {
|
||||
// WriteClipboard requests a clipboard write.
|
||||
WriteClipboard(s string)
|
||||
|
||||
// SetCursor updates the current cursor to name.
|
||||
SetCursor(name pointer.CursorName)
|
||||
|
||||
// Close the window.
|
||||
Close()
|
||||
}
|
||||
|
||||
@@ -61,7 +61,12 @@ const (
|
||||
|
||||
CW_USEDEFAULT = -2147483648
|
||||
|
||||
IDC_ARROW = 32512
|
||||
IDC_ARROW = 32512
|
||||
IDC_IBEAM = 32513
|
||||
IDC_HAND = 32649
|
||||
IDC_CROSS = 32515
|
||||
IDC_SIZENS = 32645
|
||||
IDC_SIZEWE = 32644
|
||||
|
||||
INFINITE = 0xFFFFFFFF
|
||||
|
||||
@@ -146,6 +151,7 @@ const (
|
||||
WM_PAINT = 0x000F
|
||||
WM_CLOSE = 0x0010
|
||||
WM_QUIT = 0x0012
|
||||
WM_SETCURSOR = 0x0020
|
||||
WM_SETFOCUS = 0x0007
|
||||
WM_KILLFOCUS = 0x0008
|
||||
WM_SHOWWINDOW = 0x0018
|
||||
@@ -227,6 +233,7 @@ var (
|
||||
_ScreenToClient = user32.NewProc("ScreenToClient")
|
||||
_ShowWindow = user32.NewProc("ShowWindow")
|
||||
_SetCapture = user32.NewProc("SetCapture")
|
||||
_SetCursor = user32.NewProc("SetCursor")
|
||||
_SetClipboardData = user32.NewProc("SetClipboardData")
|
||||
_SetForegroundWindow = user32.NewProc("SetForegroundWindow")
|
||||
_SetFocus = user32.NewProc("SetFocus")
|
||||
@@ -514,6 +521,10 @@ func SetClipboardData(format uint32, mem syscall.Handle) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetCursor(h syscall.Handle) {
|
||||
_SetCursor.Call(uintptr(h))
|
||||
}
|
||||
|
||||
func SetTimer(hwnd syscall.Handle, nIDEvent uintptr, uElapse uint32, timerProc uintptr) error {
|
||||
r, _, err := _SetTimer.Call(uintptr(hwnd), uintptr(nIDEvent), uintptr(uElapse), timerProc)
|
||||
if r == 0 {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"gioui.org/app/internal/window"
|
||||
"gioui.org/io/event"
|
||||
"gioui.org/io/pointer"
|
||||
"gioui.org/io/profile"
|
||||
"gioui.org/io/router"
|
||||
"gioui.org/io/system"
|
||||
@@ -209,6 +210,13 @@ func (w *Window) WriteClipboard(s string) {
|
||||
})
|
||||
}
|
||||
|
||||
// SetCursorName changes the current window cursor to name.
|
||||
func (w *Window) SetCursorName(name pointer.CursorName) {
|
||||
go w.driverDo(func() {
|
||||
w.driver.SetCursor(name)
|
||||
})
|
||||
}
|
||||
|
||||
// Close the window. The window's event loop should exit when it receives
|
||||
// system.DestroyEvent.
|
||||
//
|
||||
|
||||
@@ -79,9 +79,29 @@ type Source uint8
|
||||
// Buttons is a set of mouse buttons
|
||||
type Buttons uint8
|
||||
|
||||
// CursorName is the name of a cursor.
|
||||
type CursorName string
|
||||
|
||||
// Must match app/internal/input.areaKind
|
||||
type areaKind uint8
|
||||
|
||||
const (
|
||||
// CursorDefault is the default cursor.
|
||||
CursorDefault CursorName = ""
|
||||
// CursorText is the cursor for text.
|
||||
CursorText CursorName = "text"
|
||||
// CursorPointer is the cursor for a link.
|
||||
CursorPointer CursorName = "pointer"
|
||||
// CursorCrossHair is the cursor for precise location.
|
||||
CursorCrossHair CursorName = "crosshair"
|
||||
// CursorColResize is the cursor for vertical resize.
|
||||
CursorColResize CursorName = "col-resize"
|
||||
// CursorRowResize is the cursor for horizontal resize.
|
||||
CursorRowResize CursorName = "row-resize"
|
||||
// CursorNone hides the cursor. To show it again, use any other cursor.
|
||||
CursorNone CursorName = "none"
|
||||
)
|
||||
|
||||
const (
|
||||
// A Cancel event is generated when the current gesture is
|
||||
// interrupted by other handlers or the system.
|
||||
@@ -242,4 +262,11 @@ func (b Buttons) String() string {
|
||||
return strings.Join(strs, "|")
|
||||
}
|
||||
|
||||
func (c CursorName) String() string {
|
||||
if c == CursorDefault {
|
||||
return "default"
|
||||
}
|
||||
return string(c)
|
||||
}
|
||||
|
||||
func (Event) ImplementsEvent() {}
|
||||
|
||||
Reference in New Issue
Block a user