summaryrefslogtreecommitdiff
path: root/platform/osx/os_osx.mm
diff options
context:
space:
mode:
Diffstat (limited to 'platform/osx/os_osx.mm')
-rw-r--r--platform/osx/os_osx.mm138
1 files changed, 58 insertions, 80 deletions
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index ba3ac9862e..bc77ac3cfd 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -115,19 +115,18 @@ static Vector2 get_mouse_pos(NSPoint locationInWindow, CGFloat backingScaleFacto
return Vector2(mouse_x, mouse_y);
}
-// DisplayLinkCallback is called from our DisplayLink OS thread informing us right before
-// a screen update is required. We can use it to work around the broken vsync.
-static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *now, const CVTimeStamp *outputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext) {
- OS_OSX *os = (OS_OSX *)displayLinkContext;
-
- // Set flag so we know we can output our next frame and signal our conditional lock
- // if we're not doing vsync this will be ignored
- [os->vsync_condition lock];
- os->waiting_for_vsync = false;
- [os->vsync_condition signal];
- [os->vsync_condition unlock];
-
- return kCVReturnSuccess;
+static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) {
+ if ([NSCursor respondsToSelector:selector]) {
+ id object = [NSCursor performSelector:selector];
+ if ([object isKindOfClass:[NSCursor class]]) {
+ return object;
+ }
+ }
+ if (fallback) {
+ // Fallback should be a reasonable default, no need to check.
+ return [NSCursor performSelector:fallback];
+ }
+ return [NSCursor arrowCursor];
}
@interface GodotApplication : NSApplication
@@ -355,12 +354,8 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
//Update context
if (OS_OSX::singleton->main_loop) {
- [OS_OSX::singleton->context update];
-
- //Force window resize ???
- NSRect frame = [OS_OSX::singleton->window_object frame];
- [OS_OSX::singleton->window_object setFrame:NSMakeRect(frame.origin.x, frame.origin.y, 1, 1) display:YES];
- [OS_OSX::singleton->window_object setFrame:frame display:YES];
+ //Force window resize event
+ [self windowDidResize:notification];
}
}
}
@@ -412,9 +407,6 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
}
- (void)windowDidBecomeKey:(NSNotification *)notification {
- //_GodotInputWindowFocus(window, GL_TRUE);
- //_GodotPlatformSetCursorMode(window, window->cursorMode);
-
if (OS_OSX::singleton->get_main_loop()) {
get_mouse_pos(
[OS_OSX::singleton->window_object mouseLocationOutsideOfEventStream],
@@ -423,25 +415,31 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
}
+
+ OS_OSX::singleton->window_focused = true;
}
- (void)windowDidResignKey:(NSNotification *)notification {
- //_GodotInputWindowFocus(window, GL_FALSE);
- //_GodotPlatformSetCursorMode(window, Godot_CURSOR_NORMAL);
if (OS_OSX::singleton->get_main_loop())
OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
+
+ OS_OSX::singleton->window_focused = false;
}
- (void)windowDidMiniaturize:(NSNotification *)notification {
OS_OSX::singleton->wm_minimized(true);
if (OS_OSX::singleton->get_main_loop())
OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
+
+ OS_OSX::singleton->window_focused = false;
};
- (void)windowDidDeminiaturize:(NSNotification *)notification {
OS_OSX::singleton->wm_minimized(false);
if (OS_OSX::singleton->get_main_loop())
OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
+
+ OS_OSX::singleton->window_focused = true;
};
@end
@@ -495,7 +493,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
}
- (NSRange)markedRange {
- return (markedText.length > 0) ? NSMakeRange(0, markedText.length - 1) : kEmptyRange;
+ return NSMakeRange(0, markedText.length);
}
- (NSRange)selectedRange {
@@ -508,6 +506,10 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
} else {
[markedText initWithString:aString];
}
+ if (markedText.length == 0) {
+ [self unmarkText];
+ return;
+ }
if (OS_OSX::singleton->im_active) {
imeInputEventInProgress = true;
OS_OSX::singleton->im_text.parse_utf8([[markedText mutableString] UTF8String]);
@@ -1581,15 +1583,6 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
[context makeCurrentContext];
- // setup our display link, this will inform us when a refresh is needed
- CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
- CVDisplayLinkSetOutputCallback(displayLink, &DisplayLinkCallback, this);
- CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, context.CGLContextObj, pixelFormat.CGLPixelFormatObj);
- CVDisplayLinkStart(displayLink);
-
- // initialise a conditional lock object
- vsync_condition = [[NSCondition alloc] init];
-
set_use_vsync(p_desired.use_vsync);
[NSApp activateIgnoringOtherApps:YES];
@@ -1656,8 +1649,6 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
visual_server->init();
AudioDriverManager::initialize(p_audio_driver);
- camera_server = memnew(CameraOSX);
-
input = memnew(InputDefault);
joypad_osx = memnew(JoypadOSX);
@@ -1682,21 +1673,11 @@ void OS_OSX::finalize() {
midi_driver.close();
#endif
- if (displayLink) {
- CVDisplayLinkRelease(displayLink);
- }
- [vsync_condition release];
-
CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), NULL, kTISNotifySelectedKeyboardInputSourceChanged, NULL);
CGDisplayRemoveReconfigurationCallback(displays_arrangement_changed, NULL);
delete_main_loop();
- if (camera_server) {
- memdelete(camera_server);
- camera_server = NULL;
- }
-
memdelete(joypad_osx);
memdelete(input);
@@ -1846,15 +1827,15 @@ void OS_OSX::set_cursor_shape(CursorShape p_shape) {
case CURSOR_BUSY: [[NSCursor arrowCursor] set]; break;
case CURSOR_DRAG: [[NSCursor closedHandCursor] set]; break;
case CURSOR_CAN_DROP: [[NSCursor openHandCursor] set]; break;
- case CURSOR_FORBIDDEN: [[NSCursor arrowCursor] set]; break;
- case CURSOR_VSIZE: [[NSCursor resizeUpDownCursor] set]; break;
- case CURSOR_HSIZE: [[NSCursor resizeLeftRightCursor] set]; break;
- case CURSOR_BDIAGSIZE: [[NSCursor arrowCursor] set]; break;
- case CURSOR_FDIAGSIZE: [[NSCursor arrowCursor] set]; break;
+ case CURSOR_FORBIDDEN: [[NSCursor operationNotAllowedCursor] set]; break;
+ case CURSOR_VSIZE: [cursorFromSelector(@selector(_windowResizeNorthSouthCursor), @selector(resizeUpDownCursor)) set]; break;
+ case CURSOR_HSIZE: [cursorFromSelector(@selector(_windowResizeEastWestCursor), @selector(resizeLeftRightCursor)) set]; break;
+ case CURSOR_BDIAGSIZE: [cursorFromSelector(@selector(_windowResizeNorthEastSouthWestCursor)) set]; break;
+ case CURSOR_FDIAGSIZE: [cursorFromSelector(@selector(_windowResizeNorthWestSouthEastCursor)) set]; break;
case CURSOR_MOVE: [[NSCursor arrowCursor] set]; break;
case CURSOR_VSPLIT: [[NSCursor resizeUpDownCursor] set]; break;
case CURSOR_HSPLIT: [[NSCursor resizeLeftRightCursor] set]; break;
- case CURSOR_HELP: [[NSCursor arrowCursor] set]; break;
+ case CURSOR_HELP: [cursorFromSelector(@selector(_helpCursor)) set]; break;
default: {
};
}
@@ -2148,6 +2129,19 @@ String OS_OSX::get_cache_path() const {
}
}
+String OS_OSX::get_bundle_resource_dir() const {
+
+ NSBundle *main = [NSBundle mainBundle];
+ NSString *resourcePath = [main resourcePath];
+
+ char *utfs = strdup([resourcePath UTF8String]);
+ String ret;
+ ret.parse_utf8(utfs);
+ free(utfs);
+
+ return ret;
+}
+
// Get properly capitalized engine name for system paths
String OS_OSX::get_godot_dir_name() const {
@@ -2253,23 +2247,11 @@ Error OS_OSX::shell_open(String p_uri) {
}
String OS_OSX::get_locale() const {
- NSString *locale_code = [[NSLocale currentLocale] localeIdentifier];
+ NSString *locale_code = [[NSLocale preferredLanguages] objectAtIndex:0];
return [locale_code UTF8String];
}
void OS_OSX::swap_buffers() {
- if (is_vsync_enabled()) {
- // Wait until our DisplayLink callback unsets our flag...
- [vsync_condition lock];
- while (waiting_for_vsync)
- [vsync_condition wait];
-
- // Make sure we wait again next frame around
- waiting_for_vsync = true;
-
- [vsync_condition unlock];
- }
-
[context flushBuffer];
}
@@ -2659,6 +2641,10 @@ bool OS_OSX::is_window_always_on_top() const {
return [window_object level] == NSFloatingWindowLevel;
}
+bool OS_OSX::is_window_focused() const {
+ return window_focused;
+}
+
void OS_OSX::request_attention() {
[NSApp requestUserAttention:NSCriticalRequest];
@@ -2945,7 +2931,7 @@ void OS_OSX::run() {
quit = true;
}
} @catch (NSException *exception) {
- ERR_PRINTS("NSException: " + String([exception reason].UTF8String));
+ ERR_PRINT("NSException: " + String([exception reason].UTF8String));
}
};
@@ -3001,7 +2987,7 @@ Error OS_OSX::move_to_trash(const String &p_path) {
NSError *err;
if (![fm trashItemAtURL:url resultingItemURL:nil error:&err]) {
- ERR_PRINTS("trashItemAtURL error: " + String(err.localizedDescription.UTF8String));
+ ERR_PRINT("trashItemAtURL error: " + String(err.localizedDescription.UTF8String));
return FAILED;
}
@@ -3009,20 +2995,11 @@ Error OS_OSX::move_to_trash(const String &p_path) {
}
void OS_OSX::_set_use_vsync(bool p_enable) {
- // CGLCPSwapInterval broke in OSX 10.14 and it seems Apple is not interested in fixing
- // it as OpenGL is now deprecated and Metal solves this differently.
- // Following SDLs example we're working around this using DisplayLink
- // When vsync is enabled we set a flag "waiting_for_vsync" to true.
- // This flag is set to false when DisplayLink informs us our display is about to refresh.
-
- /* CGLContextObj ctx = CGLGetCurrentContext();
+ CGLContextObj ctx = CGLGetCurrentContext();
if (ctx) {
GLint swapInterval = p_enable ? 1 : 0;
CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval);
- }*/
-
- ///TODO Maybe pause/unpause display link?
- waiting_for_vsync = p_enable;
+ }
}
OS_OSX *OS_OSX::singleton = NULL;
@@ -3120,6 +3097,7 @@ OS_OSX::OS_OSX() {
window_size = Vector2(1024, 600);
zoomed = false;
resizable = false;
+ window_focused = true;
Vector<Logger *> loggers;
loggers.push_back(memnew(OSXTerminalLogger));