mirror of https://github.com/encounter/SDL.git
cocoa: Try to use better system cursors.
These try to pull from the .pdf files that are installed with macOS, which fit our needs better, and fall back to the most reasonable defaults available from NSCursor if we can't load them. Since these are installed under /System, they should be sandbox accessible, and if this totally fails, it should still go on, albeit with a less good cursor. Reference Issue #2123.
This commit is contained in:
parent
a12ffbd532
commit
56665e1d9d
|
@ -105,6 +105,45 @@ Cocoa_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
|
||||||
return cursor;
|
return cursor;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
/* there are .pdf files of some of the cursors we need, installed by default on macOS, but not available through NSCursor.
|
||||||
|
If we can load them ourselves, use them, otherwise fallback to something standard but not super-great.
|
||||||
|
Since these are under /System, they should be available even to sandboxed apps. */
|
||||||
|
static NSCursor *
|
||||||
|
LoadHiddenSystemCursor(NSString *cursorName, SEL fallback)
|
||||||
|
{
|
||||||
|
NSString *cursorPath = [@"/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/Resources/cursors" stringByAppendingPathComponent:cursorName];
|
||||||
|
NSImage *image = [[NSImage alloc] initWithContentsOfFile:[cursorPath stringByAppendingPathComponent:@"cursor.pdf"]];
|
||||||
|
if ((image == nil) || (image.valid == NO)) {
|
||||||
|
return [NSCursor performSelector:fallback];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSDictionary *info = [NSDictionary dictionaryWithContentsOfFile:[cursorPath stringByAppendingPathComponent:@"info.plist"]];
|
||||||
|
|
||||||
|
/* we can't do animation atm. :/ */
|
||||||
|
const int frames = [[info valueForKey:@"frames"] integerValue];
|
||||||
|
if (frames > 1) {
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MAC_OS_VERSION_12_0 /* same value as deprecated symbol. */
|
||||||
|
const NSCompositingOperation operation = NSCompositingOperationCopy;
|
||||||
|
#else
|
||||||
|
const NSCompositingOperation operation = NSCompositeCopy;
|
||||||
|
#endif
|
||||||
|
[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;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSCursor *cursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint([[info valueForKey:@"hotx"] doubleValue], [[info valueForKey:@"hoty"] doubleValue])];
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
|
||||||
static SDL_Cursor *
|
static SDL_Cursor *
|
||||||
Cocoa_CreateSystemCursor(SDL_SystemCursor id)
|
Cocoa_CreateSystemCursor(SDL_SystemCursor id)
|
||||||
{ @autoreleasepool
|
{ @autoreleasepool
|
||||||
|
@ -119,27 +158,29 @@ Cocoa_CreateSystemCursor(SDL_SystemCursor id)
|
||||||
case SDL_SYSTEM_CURSOR_IBEAM:
|
case SDL_SYSTEM_CURSOR_IBEAM:
|
||||||
nscursor = [NSCursor IBeamCursor];
|
nscursor = [NSCursor IBeamCursor];
|
||||||
break;
|
break;
|
||||||
case SDL_SYSTEM_CURSOR_WAIT:
|
|
||||||
nscursor = [NSCursor arrowCursor];
|
|
||||||
break;
|
|
||||||
case SDL_SYSTEM_CURSOR_CROSSHAIR:
|
case SDL_SYSTEM_CURSOR_CROSSHAIR:
|
||||||
nscursor = [NSCursor crosshairCursor];
|
nscursor = [NSCursor crosshairCursor];
|
||||||
break;
|
break;
|
||||||
case SDL_SYSTEM_CURSOR_WAITARROW:
|
case SDL_SYSTEM_CURSOR_WAIT: /* !!! FIXME: this is more like WAITARROW */
|
||||||
nscursor = [NSCursor arrowCursor];
|
nscursor = LoadHiddenSystemCursor(@"busybutclickable", @selector(arrowCursor));
|
||||||
|
break;
|
||||||
|
case SDL_SYSTEM_CURSOR_WAITARROW: /* !!! FIXME: this is meant to be animated */
|
||||||
|
nscursor = LoadHiddenSystemCursor(@"busybutclickable", @selector(arrowCursor));
|
||||||
break;
|
break;
|
||||||
case SDL_SYSTEM_CURSOR_SIZENWSE:
|
case SDL_SYSTEM_CURSOR_SIZENWSE:
|
||||||
|
nscursor = LoadHiddenSystemCursor(@"resizenorthwestsoutheast", @selector(closedHandCursor));
|
||||||
|
break;
|
||||||
case SDL_SYSTEM_CURSOR_SIZENESW:
|
case SDL_SYSTEM_CURSOR_SIZENESW:
|
||||||
nscursor = [NSCursor closedHandCursor];
|
nscursor = LoadHiddenSystemCursor(@"resizenortheastsouthwest", @selector(closedHandCursor));
|
||||||
break;
|
break;
|
||||||
case SDL_SYSTEM_CURSOR_SIZEWE:
|
case SDL_SYSTEM_CURSOR_SIZEWE:
|
||||||
nscursor = [NSCursor resizeLeftRightCursor];
|
nscursor = LoadHiddenSystemCursor(@"resizeeastwest", @selector(resizeLeftRightCursor));
|
||||||
break;
|
break;
|
||||||
case SDL_SYSTEM_CURSOR_SIZENS:
|
case SDL_SYSTEM_CURSOR_SIZENS:
|
||||||
nscursor = [NSCursor resizeUpDownCursor];
|
nscursor = LoadHiddenSystemCursor(@"resizenorthsouth", @selector(resizeUpDownCursor));
|
||||||
break;
|
break;
|
||||||
case SDL_SYSTEM_CURSOR_SIZEALL:
|
case SDL_SYSTEM_CURSOR_SIZEALL:
|
||||||
nscursor = [NSCursor closedHandCursor];
|
nscursor = LoadHiddenSystemCursor(@"move", @selector(closedHandCursor));
|
||||||
break;
|
break;
|
||||||
case SDL_SYSTEM_CURSOR_NO:
|
case SDL_SYSTEM_CURSOR_NO:
|
||||||
nscursor = [NSCursor operationNotAllowedCursor];
|
nscursor = [NSCursor operationNotAllowedCursor];
|
||||||
|
|
Loading…
Reference in New Issue