For example, Ebiten doesn't add cursors GLFW_HRESIZE_CURSOR and GLFW_VRESIZE_CURSOR since they seem different on macOS from other platforms. Actually they seem like col-resize and row-resize in CSS on macOS instead of ew-resize and ns-resize shapes in CSS (See the NSCursor API document). To show ew-resize and nw-resize on macOS, we'd need to use undocumented APIs unfortunately. Then, instead of relying on GLFW APIs, we'd need to use native APIs directly.
If we could use native APIs directly, we could add more various system cursors.
I'd like to tackle this issue. Could you assign it?
This is what I have so far...
static void setNativeCursor(int cursorID) {
id cursor = [[NSCursor class] performSelector:@selector(arrowCursor)];
switch(cursorID){
case 0:
cursor = [[NSCursor class] performSelector:@selector(_horizontalResizeCursor)];
break;
case 1:
cursor = [[NSCursor class] performSelector:@selector(_verticalResizeCursor)];
break;
}
[cursor push];
}
func (u *UserInterface) setNativeCursor(cursor driver.CursorShape) {
switch cursor {
case driver.CursorShapeHorizontalResize:
C.setNativeCursor(C.int(0))
case driver.CursorShapeVerticalResize:
C.setNativeCursor(C.int(1))
}
}
Extended to support existing cursors.
Awesome! Please go ahead.
Unsure as how to approach Windows. https://docs.microsoft.com/en-us/windows/win32/menurc/using-cursors
Need access to the winapi message loop 馃
How does GLFW do to change the cursor shape?
Hmm
I'll test later if it's possible to call anywhere
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{
if (cursorInContentArea(window))
updateCursorImage(window);
}
static void updateCursorImage(_GLFWwindow* window)
{
if (window->cursorMode == GLFW_CURSOR_NORMAL)
{
if (window->cursor)
SetCursor(window->cursor->win32.handle);
else
SetCursor(LoadCursorW(NULL, IDC_ARROW));
}
else
SetCursor(NULL);
}
Currently tearing apart the chain of functions from ebiten to glfw that set the cursor
We need to load a cursor https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadcursora
Yes. Actually Ebiten loads system cursors at the initialization phase.
Any idea where that location is?
Ah yes. So I guess for MacOS we only need the native implementation. Windows and Unix should already support horizontal and vertical resize.
For horizontal and vertical resize shapes, yes. For other shapes that GLFW doesn't have, we'd have to implement by ourselves.
Should I make stubs for setNativeCursor in ui_unix.go and ui_windows.go?
Then I just do this
func (u *UserInterface) SetCursorShape(shape driver.CursorShape) {
old := u.setCursorShape(shape)
if old == shape {
return
}
if !u.isRunning() {
return
}
if runtime.GOOS == "darwin" {
_ = u.t.Call(func() error {
u.setNativeCursor(shape)
return nil
})
} else {
_ = u.t.Call(func() error {
u.window.SetCursor(glfwSystemCursors[shape])
return nil
})
}
}
Should I make stubs for setNativeCursor in ui_unix.go and ui_windows.go?
Yes, just empty functions should be fine.
EDIT: what does setNativeCursor do?
It calls an objc function that sets the cursors
func (u *UserInterface) setNativeCursor(cursor driver.CursorShape) {
switch cursor {
case driver.CursorShapeHorizontalResize:
C.setNativeCursor(C.int(0))
case driver.CursorShapeVerticalResize:
C.setNativeCursor(C.int(1))
case driver.CursorShapeDefault:
C.setNativeCursor(C.int(2))
case driver.CursorShapePointer:
C.setNativeCursor(C.int(3))
case driver.CursorShapeText:
C.setNativeCursor(C.int(4))
}
}
=>
```objc
static void setNativeCursor(int cursorID) {
id cursor = [[NSCursor class] performSelector:@selector(arrowCursor)];
switch(cursorID){
case 0:
cursor = [[NSCursor class] performSelector:@selector(_windowResizeEastWestCursor)];
break;
case 1:
cursor = [[NSCursor class] performSelector:@selector(_windowResizeNorthSouthCursor)];
break;
case 2:
cursor = [[NSCursor class] performSelector:@selector(arrowCursor)];
break;
case 3:
cursor = [[NSCursor class] performSelector:@selector(openHandCursor)];
break;
case 4:
cursor = [[NSCursor class] performSelector:@selector(IBeamCursor)];
break;
}
[cursor push];
}
Thanks. Let's have setNativeCursor with u.window.SetCursor for Windows and Linux/UNIX, and leave TODO comment to use the native APIs in the future.