[macOS] Always execute editor instances using NSWorkspace to ensure app window is registered and activated correctly.
This commit is contained in:
parent
d5adb9e4b4
commit
ed25a160ea
2 changed files with 55 additions and 0 deletions
|
@ -249,6 +249,7 @@ public:
|
||||||
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
|
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
|
||||||
|
|
||||||
virtual String get_executable_path() const;
|
virtual String get_executable_path() const;
|
||||||
|
virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr);
|
||||||
|
|
||||||
virtual LatinKeyboardVariant get_latin_keyboard_variant() const;
|
virtual LatinKeyboardVariant get_latin_keyboard_variant() const;
|
||||||
virtual int keyboard_get_layout_count() const;
|
virtual int keyboard_get_layout_count() const;
|
||||||
|
|
|
@ -2955,6 +2955,60 @@ String OS_OSX::get_executable_path() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error OS_OSX::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
|
||||||
|
if (@available(macOS 10.15, *)) {
|
||||||
|
NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
|
||||||
|
// If executable is bundled, always execute editor instances using NSWorkspace to ensure app window is registered and activated correctly.
|
||||||
|
if (p_path == get_executable_path() && nsappname != nil) {
|
||||||
|
if (p_blocking && r_pipe) {
|
||||||
|
ERR_FAIL_V_MSG(ERR_CANT_OPEN, "Cannot pipe stream from process running as app bundle.");
|
||||||
|
}
|
||||||
|
NSMutableArray *arguments = [[NSMutableArray alloc] init];
|
||||||
|
for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {
|
||||||
|
[arguments addObject:[NSString stringWithUTF8String:E->get().utf8().get_data()]];
|
||||||
|
}
|
||||||
|
NSWorkspaceOpenConfiguration *configuration = [[NSWorkspaceOpenConfiguration alloc] init];
|
||||||
|
[configuration setArguments:arguments];
|
||||||
|
[configuration setCreatesNewApplicationInstance:YES];
|
||||||
|
__block dispatch_semaphore_t lock = dispatch_semaphore_create(0);
|
||||||
|
__block Error err = ERR_TIMEOUT;
|
||||||
|
__block pid_t pid = 0;
|
||||||
|
[[NSWorkspace sharedWorkspace] openApplicationAtURL:[[NSBundle mainBundle] bundleURL]
|
||||||
|
configuration:configuration
|
||||||
|
completionHandler:^(NSRunningApplication *app, NSError *error) {
|
||||||
|
if (error) {
|
||||||
|
err = ERR_CANT_FORK;
|
||||||
|
NSLog(@"Failed to execute: %@", error.localizedDescription);
|
||||||
|
} else {
|
||||||
|
pid = [app processIdentifier];
|
||||||
|
err = OK;
|
||||||
|
}
|
||||||
|
dispatch_semaphore_signal(lock);
|
||||||
|
}];
|
||||||
|
dispatch_semaphore_wait(lock, dispatch_time(DISPATCH_TIME_NOW, 20000000000)); // 20 sec timeout, wait for app to launch.
|
||||||
|
dispatch_release(lock);
|
||||||
|
|
||||||
|
if (err == OK) {
|
||||||
|
if (p_blocking) {
|
||||||
|
int status;
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
if (r_exitcode) {
|
||||||
|
*r_exitcode = WIFEXITED(status) ? WEXITSTATUS(status) : status;
|
||||||
|
}
|
||||||
|
} else if (r_child_id) {
|
||||||
|
*r_child_id = (ProcessID)pid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
} else {
|
||||||
|
return OS_Unix::execute(p_path, p_arguments, p_blocking, r_child_id, r_pipe, r_exitcode, read_stderr, p_pipe_mutex);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return OS_Unix::execute(p_path, p_arguments, p_blocking, r_child_id, r_pipe, r_exitcode, read_stderr, p_pipe_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Returns string representation of keys, if they are printable.
|
// Returns string representation of keys, if they are printable.
|
||||||
//
|
//
|
||||||
static NSString *createStringForKeys(const CGKeyCode *keyCode, int length) {
|
static NSString *createStringForKeys(const CGKeyCode *keyCode, int length) {
|
||||||
|
|
Loading…
Reference in a new issue