diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2018-03-03 12:53:01 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-03 12:53:01 +0100 |
commit | 26d42cd9a4fb533a1682fcda6ca57a3943a7ce0e (patch) | |
tree | bb75d37fa17b892da0f8a824e36a2153997e6bc3 | |
parent | 618b22bbec68bd2fbabef879007bb4f682d101b5 (diff) | |
parent | 506e17ee7075b107b96cc52854b72c9f2bc3014f (diff) |
Merge pull request #17187 from bruvzg/macos_unbundled_app_focus_hack
[macOS] Hack to force window activation for non-bundled app.
-rw-r--r-- | platform/osx/os_osx.mm | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 049191c7de..f530da8b71 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -150,10 +150,44 @@ static Vector2 get_mouse_pos(NSEvent *event) { @end @interface GodotApplicationDelegate : NSObject +- (void)forceUnbundledWindowActivationHackStep1; +- (void)forceUnbundledWindowActivationHackStep2; +- (void)forceUnbundledWindowActivationHackStep3; @end @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]; + } +} + - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename { // Note: called before main loop init! char *utfs = strdup([filename UTF8String]); @@ -2340,7 +2374,7 @@ OS_OSX::OS_OSX() { NSMenuItem *menu_item; NSString *title; - NSString *nsappname = [[[NSBundle mainBundle] performSelector:@selector(localizedInfoDictionary)] objectForKey:@"CFBundleName"]; + NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; if (nsappname == nil) nsappname = [[NSProcessInfo processInfo] processName]; |