Merge pull request #41222 from bruvzg/2.1

Cherry-picks for the 2.1 branch (macOS)
This commit is contained in:
Rémi Verschelde 2020-08-14 11:36:36 +02:00 committed by GitHub
commit 4a8350bbe3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 12 deletions

View File

@ -286,6 +286,14 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
#endif #endif
while (I) { while (I) {
#ifdef OSX_ENABLED
// Ignore the process serial number argument passed by macOS Gatekeeper.
// Otherwise, Godot would try to open a non-existent project on the first start and abort.
if (I->get().begins_with("-psn_")) {
I = I->next();
continue;
}
#endif
List<String>::Element *N = I->next(); List<String>::Element *N = I->next();

View File

@ -84,5 +84,5 @@ int main(int argc, char **argv) {
os.run(); // it is actually the OS that decides how to run os.run(); // it is actually the OS that decides how to run
Main::cleanup(); Main::cleanup();
return 0; return os.get_exit_code();
}; };

View File

@ -138,10 +138,44 @@ static bool mouse_down_control = false;
@end @end
@interface GodotApplicationDelegate : NSObject @interface GodotApplicationDelegate : NSObject
- (void)forceUnbundledWindowActivationHackStep1;
- (void)forceUnbundledWindowActivationHackStep2;
- (void)forceUnbundledWindowActivationHackStep3;
@end @end
@implementation GodotApplicationDelegate @implementation GodotApplicationDelegate
- (void)forceUnbundledWindowActivationHackStep1 {
// Step1: Switch focus to macOS Dock.
// Required to perform step 2, TransformProcessType will fail if app is already the in focus.
for (NSRunningApplication *app in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"]) {
[app activateWithOptions:NSApplicationActivateIgnoringOtherApps];
break;
}
[self performSelector:@selector(forceUnbundledWindowActivationHackStep2) withObject:nil afterDelay:0.02];
}
- (void)forceUnbundledWindowActivationHackStep2 {
// Step 2: Register app as foreground process.
ProcessSerialNumber psn = { 0, kCurrentProcess };
(void)TransformProcessType(&psn, kProcessTransformToForegroundApplication);
[self performSelector:@selector(forceUnbundledWindowActivationHackStep3) withObject:nil afterDelay:0.02];
}
- (void)forceUnbundledWindowActivationHackStep3 {
// Step 3: Switch focus back to app window.
[[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps];
}
- (void)applicationDidFinishLaunching:(NSNotification *)notice {
NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
if (nsappname == nil) {
// If executable is not a bundled, macOS WindowServer won't register and activate app window correctly (menu and title bar are grayed out and input ignored).
[self performSelector:@selector(forceUnbundledWindowActivationHackStep1) withObject:nil afterDelay:0.02];
}
}
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
if (OS_OSX::singleton->get_main_loop()) if (OS_OSX::singleton->get_main_loop())
OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST); OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
@ -221,12 +255,8 @@ static bool mouse_down_control = false;
//Update context //Update context
if (OS_OSX::singleton->main_loop) { if (OS_OSX::singleton->main_loop) {
[OS_OSX::singleton->context update]; //Force window resize event
[self windowDidResize:notification];
//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];
} }
} }
} }
@ -1423,13 +1453,18 @@ void OS_OSX::make_rendering_thread() {
} }
Error OS_OSX::shell_open(String p_uri) { Error OS_OSX::shell_open(String p_uri) {
NSString *string = [NSString stringWithUTF8String:p_uri.utf8().get_data()];
[[NSWorkspace sharedWorkspace] openURL:[[NSURL alloc] initWithString:[NSString stringWithUTF8String:p_uri.utf8().get_data()]]]; NSURL *uri = [[NSURL alloc] initWithString:string];
// Escape special characters in filenames
if (!uri || !uri.scheme || [uri.scheme isEqual:@"file"]) {
uri = [[NSURL alloc] initWithString:[string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]];
}
[[NSWorkspace sharedWorkspace] openURL:uri];
return OK; return OK;
} }
String OS_OSX::get_locale() const { String OS_OSX::get_locale() const {
NSString *locale_code = [[NSLocale currentLocale] localeIdentifier]; NSString *locale_code = [[NSLocale preferredLanguages] objectAtIndex:0];
return [locale_code UTF8String]; return [locale_code UTF8String];
} }
@ -1738,7 +1773,8 @@ bool OS_OSX::is_window_maximized() const {
void OS_OSX::move_window_to_foreground() { void OS_OSX::move_window_to_foreground() {
[window_object orderFrontRegardless]; [[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
[window_object makeKeyAndOrderFront:nil];
} }
void OS_OSX::set_window_always_on_top(bool p_enabled) { void OS_OSX::set_window_always_on_top(bool p_enabled) {
@ -2041,7 +2077,7 @@ OS_OSX::OS_OSX() {
NSMenuItem *menu_item; NSMenuItem *menu_item;
NSString *title; NSString *title;
NSString *nsappname = [[[NSBundle mainBundle] performSelector:@selector(localizedInfoDictionary)] objectForKey:@"CFBundleName"]; NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
if (nsappname == nil) if (nsappname == nil)
nsappname = [[NSProcessInfo processInfo] processName]; nsappname = [[NSProcessInfo processInfo] processName];