|
@@ -47,14 +47,20 @@
|
|
|
#include <sys/sysctl.h>
|
|
|
|
|
|
void OS_MacOS::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context) {
|
|
|
- // Prevent main loop from sleeping and redraw window during modal popup display.
|
|
|
- // Do not redraw when rendering is done from the separate thread, it will conflict with the OpenGL context updates.
|
|
|
-
|
|
|
- DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
|
|
- if (get_singleton()->get_main_loop() && ds && !get_singleton()->is_separate_thread_rendering_enabled() && !ds->get_is_resizing()) {
|
|
|
- Main::force_redraw();
|
|
|
- if (!Main::is_iterating()) { // Avoid cyclic loop.
|
|
|
- Main::iteration();
|
|
|
+ OS_MacOS *os = static_cast<OS_MacOS *>(OS::get_singleton());
|
|
|
+
|
|
|
+ @autoreleasepool {
|
|
|
+ @try {
|
|
|
+ if (DisplayServer::get_singleton()) {
|
|
|
+ static_cast<DisplayServerMacOS *>(DisplayServer::get_singleton())->_process_events(false); // Get rid of pending events.
|
|
|
+ }
|
|
|
+ os->joypad_apple->process_joypads();
|
|
|
+
|
|
|
+ if (Main::iteration()) {
|
|
|
+ os->terminate();
|
|
|
+ }
|
|
|
+ } @catch (NSException *exception) {
|
|
|
+ ERR_PRINT("NSException: " + String::utf8([exception reason].UTF8String));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -823,36 +829,69 @@ OS::PreferredTextureFormat OS_MacOS::get_preferred_texture_format() const {
|
|
|
}
|
|
|
|
|
|
void OS_MacOS::run() {
|
|
|
- if (!main_loop) {
|
|
|
- return;
|
|
|
- }
|
|
|
+ [NSApp run];
|
|
|
+}
|
|
|
|
|
|
+void OS_MacOS::start_main() {
|
|
|
+ Error err;
|
|
|
@autoreleasepool {
|
|
|
- main_loop->initialize();
|
|
|
+ err = Main::setup(execpath, argc, argv);
|
|
|
}
|
|
|
|
|
|
- bool quit = false;
|
|
|
- while (!quit) {
|
|
|
+ if (err == OK) {
|
|
|
+ int ret;
|
|
|
@autoreleasepool {
|
|
|
- @try {
|
|
|
- if (DisplayServer::get_singleton()) {
|
|
|
- DisplayServer::get_singleton()->process_events(); // Get rid of pending events.
|
|
|
- }
|
|
|
- joypad_apple->process_joypads();
|
|
|
-
|
|
|
- if (Main::iteration()) {
|
|
|
- quit = true;
|
|
|
+ ret = Main::start();
|
|
|
+ }
|
|
|
+ if (ret == EXIT_SUCCESS) {
|
|
|
+ if (main_loop) {
|
|
|
+ @autoreleasepool {
|
|
|
+ main_loop->initialize();
|
|
|
}
|
|
|
- } @catch (NSException *exception) {
|
|
|
- ERR_PRINT("NSException: " + String::utf8([exception reason].UTF8String));
|
|
|
+ pre_wait_observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, true, 0, &pre_wait_observer_cb, nullptr);
|
|
|
+ CFRunLoopAddObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
|
|
|
+ return;
|
|
|
}
|
|
|
+ } else {
|
|
|
+ set_exit_code(EXIT_FAILURE);
|
|
|
}
|
|
|
+ } else if (err == ERR_HELP) { // Returned by --help and --version, so success.
|
|
|
+ set_exit_code(EXIT_SUCCESS);
|
|
|
+ } else {
|
|
|
+ set_exit_code(EXIT_FAILURE);
|
|
|
+ }
|
|
|
+
|
|
|
+ terminate();
|
|
|
+}
|
|
|
+
|
|
|
+void OS_MacOS::activate() {
|
|
|
+ [delegate activate];
|
|
|
+}
|
|
|
+
|
|
|
+void OS_MacOS::terminate() {
|
|
|
+ if (pre_wait_observer) {
|
|
|
+ CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
|
|
|
+ CFRelease(pre_wait_observer);
|
|
|
+ pre_wait_observer = nil;
|
|
|
}
|
|
|
|
|
|
- main_loop->finalize();
|
|
|
+ should_terminate = true;
|
|
|
+ [NSApp terminate:nil];
|
|
|
+}
|
|
|
+
|
|
|
+void OS_MacOS::cleanup() {
|
|
|
+ if (main_loop) {
|
|
|
+ main_loop->finalize();
|
|
|
+ @autoreleasepool {
|
|
|
+ Main::cleanup();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-OS_MacOS::OS_MacOS() {
|
|
|
+OS_MacOS::OS_MacOS(const char *p_execpath, int p_argc, char **p_argv) {
|
|
|
+ execpath = p_execpath;
|
|
|
+ argc = p_argc;
|
|
|
+ argv = p_argv;
|
|
|
if (is_sandboxed()) {
|
|
|
// Load security-scoped bookmarks, request access, remove stale or invalid bookmarks.
|
|
|
NSArray *bookmarks = [[NSUserDefaults standardUserDefaults] arrayForKey:@"sec_bookmarks"];
|
|
@@ -886,7 +925,7 @@ OS_MacOS::OS_MacOS() {
|
|
|
[GodotApplication sharedApplication];
|
|
|
|
|
|
// In case we are unbundled, make us a proper UI application.
|
|
|
- [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
|
|
+ [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
|
|
|
|
|
|
// Menu bar setup must go between sharedApplication above and
|
|
|
// finishLaunching below, in order to properly emulate the behavior
|
|
@@ -894,35 +933,13 @@ OS_MacOS::OS_MacOS() {
|
|
|
|
|
|
NSMenu *main_menu = [[NSMenu alloc] initWithTitle:@""];
|
|
|
[NSApp setMainMenu:main_menu];
|
|
|
- [NSApp finishLaunching];
|
|
|
|
|
|
- id delegate = [[GodotApplicationDelegate alloc] init];
|
|
|
+ delegate = [[GodotApplicationDelegate alloc] init];
|
|
|
ERR_FAIL_NULL(delegate);
|
|
|
[NSApp setDelegate:delegate];
|
|
|
[NSApp registerUserInterfaceItemSearchHandler:delegate];
|
|
|
-
|
|
|
- pre_wait_observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, true, 0, &pre_wait_observer_cb, nullptr);
|
|
|
- CFRunLoopAddObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
|
|
|
-
|
|
|
- // Process application:openFile: event.
|
|
|
- while (true) {
|
|
|
- NSEvent *event = [NSApp
|
|
|
- nextEventMatchingMask:NSEventMaskAny
|
|
|
- untilDate:[NSDate distantPast]
|
|
|
- inMode:NSDefaultRunLoopMode
|
|
|
- dequeue:YES];
|
|
|
-
|
|
|
- if (event == nil) {
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- [NSApp sendEvent:event];
|
|
|
- }
|
|
|
-
|
|
|
- [NSApp activateIgnoringOtherApps:YES];
|
|
|
}
|
|
|
|
|
|
OS_MacOS::~OS_MacOS() {
|
|
|
- CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
|
|
|
- CFRelease(pre_wait_observer);
|
|
|
+ // NOP
|
|
|
}
|