mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-21 10:40:59 +02:00
Merge pull request #16026 from mattr1x/use-execve-to-launch
DEV-263: HQ Launcher/Interface (Mac) - appear to consolidate apps
This commit is contained in:
commit
c92187d643
4 changed files with 102 additions and 16 deletions
|
@ -43,6 +43,8 @@ set(src_files
|
||||||
src/LaunchInterface.h
|
src/LaunchInterface.h
|
||||||
src/CustomUI.h
|
src/CustomUI.h
|
||||||
src/CustomUI.m
|
src/CustomUI.m
|
||||||
|
src/NSTask+NSTaskExecveAdditions.h
|
||||||
|
src/NSTask+NSTaskExecveAdditions.m
|
||||||
src/main.mm
|
src/main.mm
|
||||||
nib/Window.xib
|
nib/Window.xib
|
||||||
nib/SplashScreen.xib
|
nib/SplashScreen.xib
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#import "ProcessScreen.h"
|
#import "ProcessScreen.h"
|
||||||
#import "ErrorViewController.h"
|
#import "ErrorViewController.h"
|
||||||
#import "Settings.h"
|
#import "Settings.h"
|
||||||
|
#import "NSTask+NSTaskExecveAdditions.h"
|
||||||
|
|
||||||
@interface Launcher ()
|
@interface Launcher ()
|
||||||
|
|
||||||
|
@ -456,8 +457,6 @@ static BOOL const DELETE_ZIP_FILES = TRUE;
|
||||||
NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
|
NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
|
||||||
NSURL *url = [NSURL fileURLWithPath:[workspace fullPathForApplication:[[self getAppPath] stringByAppendingString:@"interface.app/Contents/MacOS/interface"]]];
|
NSURL *url = [NSURL fileURLWithPath:[workspace fullPathForApplication:[[self getAppPath] stringByAppendingString:@"interface.app/Contents/MacOS/interface"]]];
|
||||||
|
|
||||||
NSError *error = nil;
|
|
||||||
|
|
||||||
NSString* contentPath = [[self getDownloadPathForContentAndScripts] stringByAppendingString:@"content"];
|
NSString* contentPath = [[self getDownloadPathForContentAndScripts] stringByAppendingString:@"content"];
|
||||||
NSString* displayName = [ self displayName];
|
NSString* displayName = [ self displayName];
|
||||||
NSString* scriptsPath = [[self getAppPath] stringByAppendingString:@"interface.app/Contents/Resources/scripts/simplifiedUIBootstrapper.js"];
|
NSString* scriptsPath = [[self getAppPath] stringByAppendingString:@"interface.app/Contents/Resources/scripts/simplifiedUIBootstrapper.js"];
|
||||||
|
@ -484,13 +483,11 @@ static BOOL const DELETE_ZIP_FILES = TRUE;
|
||||||
@"--no-updater",
|
@"--no-updater",
|
||||||
@"--no-launcher", nil];
|
@"--no-launcher", nil];
|
||||||
}
|
}
|
||||||
[workspace launchApplicationAtURL:url options:NSWorkspaceLaunchNewInstance configuration:[NSDictionary dictionaryWithObject:arguments forKey:NSWorkspaceLaunchConfigurationArguments] error:&error];
|
|
||||||
|
|
||||||
[NSTimer scheduledTimerWithTimeInterval: 3.0
|
NSTask *task = [[NSTask alloc] init];
|
||||||
target: self
|
task.launchPath = [url path];
|
||||||
selector: @selector(exitLauncher:)
|
task.arguments = arguments;
|
||||||
userInfo:nil
|
[task replaceThisProcess];
|
||||||
repeats: NO];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (ProcessState) currentProccessState
|
- (ProcessState) currentProccessState
|
||||||
|
@ -500,15 +497,20 @@ static BOOL const DELETE_ZIP_FILES = TRUE;
|
||||||
|
|
||||||
- (void) callLaunchInterface:(NSTimer*) timer
|
- (void) callLaunchInterface:(NSTimer*) timer
|
||||||
{
|
{
|
||||||
|
NSWindow* mainWindow = [[[NSApplication sharedApplication] windows] objectAtIndex:0];
|
||||||
|
|
||||||
ProcessScreen* processScreen = [[ProcessScreen alloc] initWithNibName:@"ProcessScreen" bundle:nil];
|
ProcessScreen* processScreen = [[ProcessScreen alloc] initWithNibName:@"ProcessScreen" bundle:nil];
|
||||||
[[[[NSApplication sharedApplication] windows] objectAtIndex:0] setContentViewController: processScreen];
|
[mainWindow setContentViewController: processScreen];
|
||||||
|
@try
|
||||||
|
{
|
||||||
[self launchInterface];
|
[self launchInterface];
|
||||||
}
|
}
|
||||||
|
@catch (NSException *exception)
|
||||||
|
{
|
||||||
- (void) exitLauncher:(NSTimer*) timer
|
NSLog(@"Caught exception: Name: %@, Reason: %@", exception.name, exception.reason);
|
||||||
{
|
ErrorViewController* errorViewController = [[ErrorViewController alloc] initWithNibName:@"ErrorScreen" bundle:nil];
|
||||||
[NSApp terminate:self];
|
[mainWindow setContentViewController: errorViewController];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
9
launchers/darwin/src/NSTask+NSTaskExecveAdditions.h
Normal file
9
launchers/darwin/src/NSTask+NSTaskExecveAdditions.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface NSTask (NSTaskExecveAdditions)
|
||||||
|
- (void) replaceThisProcess;
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
73
launchers/darwin/src/NSTask+NSTaskExecveAdditions.m
Normal file
73
launchers/darwin/src/NSTask+NSTaskExecveAdditions.m
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#import "NSTask+NSTaskExecveAdditions.h"
|
||||||
|
|
||||||
|
#import <libgen.h>
|
||||||
|
|
||||||
|
char **
|
||||||
|
toCArray(NSArray<NSString *> *array)
|
||||||
|
{
|
||||||
|
// Add one to count to accommodate the NULL that terminates the array.
|
||||||
|
char **cArray = (char **) calloc([array count] + 1, sizeof(char *));
|
||||||
|
if (cArray == NULL) {
|
||||||
|
NSException *exception = [NSException
|
||||||
|
exceptionWithName:@"MemoryException"
|
||||||
|
reason:@"malloc failed"
|
||||||
|
userInfo:nil];
|
||||||
|
@throw exception;
|
||||||
|
}
|
||||||
|
char *str;
|
||||||
|
for (int i = 0; i < [array count]; i++) {
|
||||||
|
str = (char *) [array[i] UTF8String];
|
||||||
|
if (str == NULL) {
|
||||||
|
NSException *exception = [NSException
|
||||||
|
exceptionWithName:@"NULLStringException"
|
||||||
|
reason:@"UTF8String was NULL"
|
||||||
|
userInfo:nil];
|
||||||
|
@throw exception;
|
||||||
|
}
|
||||||
|
if (asprintf(&cArray[i], "%s", str) == -1) {
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
free(cArray[j]);
|
||||||
|
}
|
||||||
|
free(cArray);
|
||||||
|
NSException *exception = [NSException
|
||||||
|
exceptionWithName:@"MemoryException"
|
||||||
|
reason:@"malloc failed"
|
||||||
|
userInfo:nil];
|
||||||
|
@throw exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@implementation NSTask (NSTaskExecveAdditions)
|
||||||
|
|
||||||
|
- (void) replaceThisProcess {
|
||||||
|
char **args = toCArray([@[[self launchPath]] arrayByAddingObjectsFromArray:[self arguments]]);
|
||||||
|
|
||||||
|
NSMutableArray *env = [[NSMutableArray alloc] init];
|
||||||
|
NSDictionary* environvment = [[NSProcessInfo processInfo] environment];
|
||||||
|
for (NSString* key in environvment) {
|
||||||
|
NSString* environmentVariable = [[key stringByAppendingString:@"="] stringByAppendingString:environvment[key]];
|
||||||
|
[env addObject:environmentVariable];
|
||||||
|
}
|
||||||
|
|
||||||
|
char** envp = toCArray(env);
|
||||||
|
// `execve` replaces the current process with `path`.
|
||||||
|
// It will only return if it fails to replace the current process.
|
||||||
|
chdir(dirname(args[0]));
|
||||||
|
execve(args[0], (char * const *)args, envp);
|
||||||
|
|
||||||
|
// If we're here `execve` failed. :(
|
||||||
|
for (int i = 0; i < [[self arguments] count]; i++) {
|
||||||
|
free((void *) args[i]);
|
||||||
|
}
|
||||||
|
free((void *) args);
|
||||||
|
|
||||||
|
NSException *exception = [NSException
|
||||||
|
exceptionWithName:@"ExecveException"
|
||||||
|
reason:[NSString stringWithFormat:@"couldn't execve: %s", strerror(errno)]
|
||||||
|
userInfo:nil];
|
||||||
|
@throw exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
Loading…
Reference in a new issue