mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-25 17:52:02 +02:00
Implement mouse shape support for macOS
Code for loading hidden system cursors not available via NCursor comes from the SDL library, with thanks.
This commit is contained in:
@@ -2505,27 +2505,86 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
||||
return true;
|
||||
}
|
||||
|
||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape)
|
||||
{
|
||||
static NSCursor*
|
||||
load_hidden_system_cursor(NSString *name, SEL fallback) {
|
||||
// this implementation comes from SDL_cocoamouse.m
|
||||
NSString *cursorPath = [@"/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/Resources/cursors" stringByAppendingPathComponent:name];
|
||||
NSDictionary *info = [NSDictionary dictionaryWithContentsOfFile:[cursorPath stringByAppendingPathComponent:@"info.plist"]];
|
||||
/* we can't do animation atm. :/ */
|
||||
const int frames = (int)[[info valueForKey:@"frames"] integerValue];
|
||||
NSCursor *cursor;
|
||||
NSImage *image = [[NSImage alloc] initWithContentsOfFile:[cursorPath stringByAppendingPathComponent:@"cursor.pdf"]];
|
||||
if ((image == nil) || (image.isValid == NO)) {
|
||||
return [NSCursor performSelector:fallback];
|
||||
}
|
||||
|
||||
if (frames > 1) {
|
||||
#ifdef MAC_OS_VERSION_12_0 /* same value as deprecated symbol. */
|
||||
const NSCompositingOperation operation = NSCompositingOperationCopy;
|
||||
#else
|
||||
const NSCompositingOperation operation = NSCompositeCopy;
|
||||
#endif
|
||||
const NSSize cropped_size = NSMakeSize(image.size.width, (int)(image.size.height / frames));
|
||||
NSImage *cropped = [[NSImage alloc] initWithSize:cropped_size];
|
||||
if (cropped == nil) {
|
||||
return [NSCursor performSelector:fallback];
|
||||
}
|
||||
|
||||
[cropped lockFocus];
|
||||
{
|
||||
const NSRect cropped_rect = NSMakeRect(0, 0, cropped_size.width, cropped_size.height);
|
||||
[image drawInRect:cropped_rect fromRect:cropped_rect operation:operation fraction:1];
|
||||
}
|
||||
[cropped unlockFocus];
|
||||
image = cropped;
|
||||
}
|
||||
|
||||
cursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint([[info valueForKey:@"hotx"] doubleValue], [[info valueForKey:@"hoty"] doubleValue])];
|
||||
return cursor;
|
||||
}
|
||||
|
||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape) {
|
||||
#define C(name, val) case name: cursor->ns.object = [NSCursor val]; break;
|
||||
#define U(name, val) case name: cursor->ns.object = [[NSCursor class] performSelector:@selector(val)]; break;
|
||||
#define U(name, val) case name: cursor->ns.object = [NSCursor performSelector:@selector(val)]; break;
|
||||
#define S(name, val, fallback) case name: cursor->ns.object = load_hidden_system_cursor(@#val, @selector(val)); break;
|
||||
switch(shape) {
|
||||
C(GLFW_ARROW_CURSOR, arrowCursor);
|
||||
C(GLFW_IBEAM_CURSOR, IBeamCursor);
|
||||
/* start glfw to cocoa (auto generated by gen-key-constants.py do not edit) */
|
||||
C(GLFW_DEFAULT_CURSOR, arrowCursor);
|
||||
C(GLFW_TEXT_CURSOR, IBeamCursor);
|
||||
C(GLFW_POINTER_CURSOR, pointingHandCursor);
|
||||
S(GLFW_HELP_CURSOR, help, arrowCursor);
|
||||
S(GLFW_WAIT_CURSOR, busybutclickable, arrowCursor);
|
||||
S(GLFW_PROGRESS_CURSOR, busybutclickable, arrowCursor);
|
||||
C(GLFW_CROSSHAIR_CURSOR, crosshairCursor);
|
||||
C(GLFW_HAND_CURSOR, pointingHandCursor);
|
||||
C(GLFW_HRESIZE_CURSOR, resizeLeftRightCursor);
|
||||
C(GLFW_VRESIZE_CURSOR, resizeUpDownCursor);
|
||||
U(GLFW_NW_RESIZE_CURSOR, _windowResizeNorthWestSouthEastCursor);
|
||||
U(GLFW_NE_RESIZE_CURSOR, _windowResizeNorthEastSouthWestCursor);
|
||||
U(GLFW_SW_RESIZE_CURSOR, _windowResizeNorthEastSouthWestCursor);
|
||||
U(GLFW_SE_RESIZE_CURSOR, _windowResizeNorthWestSouthEastCursor);
|
||||
C(GLFW_VERTICAL_TEXT_CURSOR, IBeamCursorForVerticalLayout);
|
||||
S(GLFW_MOVE_CURSOR, move, openHandCursor);
|
||||
C(GLFW_E_RESIZE_CURSOR, resizeRightCursor);
|
||||
S(GLFW_NE_RESIZE_CURSOR, resizenortheast, _windowResizeNorthEastSouthWestCursor);
|
||||
S(GLFW_NW_RESIZE_CURSOR, resizenorthwest, _windowResizeNorthWestSouthEastCursor);
|
||||
C(GLFW_N_RESIZE_CURSOR, resizeUpCursor);
|
||||
S(GLFW_SE_RESIZE_CURSOR, resizesoutheast, _windowResizeNorthWestSouthEastCursor);
|
||||
S(GLFW_SW_RESIZE_CURSOR, resizesouthwest, _windowResizeNorthEastSouthWestCursor);
|
||||
C(GLFW_S_RESIZE_CURSOR, resizeDownCursor);
|
||||
C(GLFW_W_RESIZE_CURSOR, resizeLeftCursor);
|
||||
C(GLFW_EW_RESIZE_CURSOR, resizeLeftRightCursor);
|
||||
C(GLFW_NS_RESIZE_CURSOR, resizeUpDownCursor);
|
||||
U(GLFW_NESW_RESIZE_CURSOR, _windowResizeNorthEastSouthWestCursor);
|
||||
U(GLFW_NWSE_RESIZE_CURSOR, _windowResizeNorthWestSouthEastCursor);
|
||||
S(GLFW_ZOOM_IN_CURSOR, zoomin, arrowCursor);
|
||||
S(GLFW_ZOOM_OUT_CURSOR, zoomout, arrowCursor);
|
||||
C(GLFW_ALIAS_CURSOR, dragLinkCursor);
|
||||
C(GLFW_COPY_CURSOR, dragCopyCursor);
|
||||
C(GLFW_NOT_ALLOWED_CURSOR, operationNotAllowedCursor);
|
||||
C(GLFW_NO_DROP_CURSOR, operationNotAllowedCursor);
|
||||
C(GLFW_GRAB_CURSOR, openHandCursor);
|
||||
C(GLFW_GRABBING_CURSOR, closedHandCursor);
|
||||
/* end glfw to cocoa */
|
||||
case GLFW_INVALID_CURSOR:
|
||||
return false;
|
||||
}
|
||||
#undef C
|
||||
#undef U
|
||||
|
||||
#undef S
|
||||
if (!cursor->ns.object)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
|
||||
Reference in New Issue
Block a user