mirror of
https://github.com/darlinghq/darling-cocotron.git
synced 2024-11-23 20:19:40 +00:00
Add support for opening files from arguments
Arguments can supplied in the command line. If the application is already runnning, they're passed to the running instance from a pipe. Application receives the files via application:openFile: or application:openFiles:.
This commit is contained in:
parent
9ef2b1c8c3
commit
fd73436436
@ -71,12 +71,6 @@ NSString * const NSApplicationDidChangeScreenParametersNotification=@"NSApplicat
|
||||
|
||||
id NSApp=nil;
|
||||
|
||||
+(void)initialize {
|
||||
if(self==[NSApplication class]){
|
||||
[NSClassFromString(@"Win32RunningCopyPipe") performSelector:@selector(startRunningCopyPipe)];
|
||||
}
|
||||
}
|
||||
|
||||
+(NSApplication *)sharedApplication {
|
||||
|
||||
if(NSApp==nil){
|
||||
@ -408,6 +402,40 @@ id NSApp=nil;
|
||||
#endif
|
||||
}
|
||||
|
||||
-(BOOL)openFiles
|
||||
{
|
||||
BOOL opened = NO;
|
||||
if(_delegate) {
|
||||
id nsOpen = [[NSUserDefaults standardUserDefaults] objectForKey:@"NSOpen"];
|
||||
NSArray *openFiles = nil;
|
||||
if ([nsOpen isKindOfClass:[NSString class]] && [nsOpen length]) {
|
||||
openFiles = [NSArray arrayWithObject:nsOpen];
|
||||
} else if ([nsOpen isKindOfClass:[NSArray class]]) {
|
||||
openFiles = nsOpen;
|
||||
}
|
||||
if ([openFiles count] > 0) {
|
||||
if ([openFiles count] == 1 && [_delegate respondsToSelector: @selector(application:openFile:)]) {
|
||||
|
||||
if([_delegate application: self openFile: [openFiles lastObject]]) {
|
||||
opened = YES;
|
||||
}
|
||||
} else {
|
||||
if ([_delegate respondsToSelector: @selector(application:openFiles:)]) {
|
||||
[_delegate application: self openFiles: openFiles];
|
||||
opened = YES;
|
||||
|
||||
} else if ([_delegate respondsToSelector: @selector(application:openFile:)]) {
|
||||
for (NSString *aFile in openFiles) {
|
||||
opened |= [_delegate application: self openFile: aFile];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"NSOpen"];
|
||||
}
|
||||
return opened;
|
||||
}
|
||||
|
||||
-(void)finishLaunching {
|
||||
NSAutoreleasePool *pool=[NSAutoreleasePool new];
|
||||
BOOL needsUntitled=YES;
|
||||
@ -440,15 +468,9 @@ id NSApp=nil;
|
||||
objectForKey:@"CFBundleDocumentTypes"];
|
||||
if([types count] > 0)
|
||||
controller = [NSDocumentController sharedDocumentController];
|
||||
|
||||
if(_delegate && [_delegate respondsToSelector: @selector(application:openFile:)]) {
|
||||
NSString *openFile = [[NSUserDefaults standardUserDefaults]
|
||||
stringForKey:@"NSOpen"];
|
||||
|
||||
if([openFile length] > 0) {
|
||||
if([_delegate application: self openFile: openFile])
|
||||
needsUntitled = NO;
|
||||
}
|
||||
if ([self openFiles]) {
|
||||
needsUntitled = NO;
|
||||
}
|
||||
|
||||
if(needsUntitled && _delegate &&
|
||||
@ -1267,26 +1289,67 @@ standardAboutPanel] retain];
|
||||
|
||||
int NSApplicationMain(int argc, const char *argv[]) {
|
||||
NSInitializeProcess(argc,(const char **)argv);
|
||||
{
|
||||
NSAutoreleasePool *pool=[NSAutoreleasePool new];
|
||||
NSBundle *bundle=[NSBundle mainBundle];
|
||||
Class class=[bundle principalClass];
|
||||
NSString *nibFile=[[bundle infoDictionary] objectForKey:@"NSMainNibFile"];
|
||||
|
||||
if(class==Nil)
|
||||
class=[NSApplication class];
|
||||
NSAutoreleasePool *pool=[NSAutoreleasePool new];
|
||||
NSBundle *bundle=[NSBundle mainBundle];
|
||||
Class class=[bundle principalClass];
|
||||
NSString *nibFile=[[bundle infoDictionary] objectForKey:@"NSMainNibFile"];
|
||||
|
||||
[class sharedApplication];
|
||||
|
||||
nibFile=[nibFile stringByDeletingPathExtension];
|
||||
|
||||
if(![NSBundle loadNibNamed:nibFile owner:NSApp])
|
||||
NSLog(@"Unable to load main nib file %@",nibFile);
|
||||
|
||||
[pool release];
|
||||
|
||||
[NSApp run];
|
||||
if (argc > 1) {
|
||||
BOOL noMoreArgs = NO;
|
||||
BOOL skip = NO;
|
||||
NSMutableArray *theArguments = [NSMutableArray array];
|
||||
for (int ii = 1; ii < argc; ii++) {
|
||||
if (skip) {
|
||||
skip = NO;
|
||||
continue;
|
||||
}
|
||||
const char *arg = argv[ii];
|
||||
if (noMoreArgs || arg[0] != '-') {
|
||||
NSString *anArg = [NSString stringWithCString:arg encoding:NSUTF8StringEncoding];
|
||||
if ([anArg length]) {
|
||||
[theArguments addObject:anArg];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!noMoreArgs) {
|
||||
if (arg[0] == '-') {
|
||||
if (arg[1] == '-' && arg[2] == '\0') {
|
||||
noMoreArgs = YES;
|
||||
} else if (strcmp(arg, "-NSOpen") != 0) {
|
||||
skip = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ([theArguments count] > 0) {
|
||||
id nsOpen;
|
||||
if ([theArguments count] == 1) {
|
||||
nsOpen = [theArguments lastObject];
|
||||
} else {
|
||||
nsOpen = theArguments;
|
||||
}
|
||||
[[NSUserDefaults standardUserDefaults] setObject:nsOpen forKey:@"NSOpen"];
|
||||
}
|
||||
}
|
||||
|
||||
[NSClassFromString(@"Win32RunningCopyPipe") performSelector:@selector(startRunningCopyPipe)];
|
||||
|
||||
if(class==Nil) {
|
||||
class=[NSApplication class];
|
||||
}
|
||||
|
||||
[class sharedApplication];
|
||||
|
||||
nibFile=[nibFile stringByDeletingPathExtension];
|
||||
|
||||
if(![NSBundle loadNibNamed:nibFile owner:NSApp]) {
|
||||
NSLog(@"Unable to load main nib file %@",nibFile);
|
||||
}
|
||||
|
||||
[pool release];
|
||||
|
||||
[NSApp run];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
} _state;
|
||||
OVERLAPPED _readOverlap;
|
||||
DWORD _readCount;
|
||||
unichar _readBuffer[65536];
|
||||
char _readBuffer[65536];
|
||||
}
|
||||
|
||||
+(void)invalidateRunningCopyPipe;
|
||||
|
@ -23,37 +23,42 @@ static Win32RunningCopyPipe *_runningCopyPipe=nil;
|
||||
_readOverlap.hEvent=_event;
|
||||
|
||||
if(_state==STATE_CONNECTING){
|
||||
if(!ConnectNamedPipe(_pipe,&_readOverlap)){
|
||||
if(GetLastError()!=ERROR_IO_PENDING)
|
||||
NSLog(@"ConnectNamedPipe failed");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(!ReadFile(_pipe,_readBuffer,65536,&_readCount,&_readOverlap)){
|
||||
if(GetLastError()!=ERROR_IO_PENDING)
|
||||
NSLog(@"ReadFile failed");
|
||||
}
|
||||
if(!ConnectNamedPipe(_pipe, &_readOverlap)){
|
||||
if(GetLastError()!=ERROR_IO_PENDING) {
|
||||
NSLog(@"ConnectNamedPipe failed");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(!ReadFile(_pipe,_readBuffer, sizeof(_readBuffer), &_readCount ,&_readOverlap)){
|
||||
if(GetLastError()!=ERROR_IO_PENDING) {
|
||||
NSLog(@"ReadFile failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void)handleMonitorIndicatesSignaled:(NSHandleMonitor_win32 *)monitor {
|
||||
if(!GetOverlappedResult(_pipe,&_readOverlap,&_readCount,TRUE))
|
||||
NSLog(@"GetOverlappedResult failed %d", GetLastError());
|
||||
if(!GetOverlappedResult(_pipe,&_readOverlap,&_readCount,TRUE)) {
|
||||
NSLog(@"GetOverlappedResult failed %d", GetLastError());
|
||||
}
|
||||
|
||||
if(_state==STATE_CONNECTING)
|
||||
_state=STATE_READING;
|
||||
else {
|
||||
NSString *path=[NSString stringWithCharacters:_readBuffer length:_readCount/2];
|
||||
if(_state==STATE_CONNECTING) {
|
||||
_state=STATE_READING;
|
||||
|
||||
if(!DisconnectNamedPipe(_pipe))
|
||||
NSLog(@"DisconnectNamedPipe failed");
|
||||
_state=STATE_CONNECTING;
|
||||
|
||||
if([path isEqual:@"@reopen"]) [NSApp _reopen];
|
||||
else
|
||||
if([[NSApp delegate] respondsToSelector:@selector(application:openFile:)]){
|
||||
[[NSApp delegate] application:NSApp openFile:path];
|
||||
}
|
||||
} else {
|
||||
NSData *data = [NSData dataWithBytesNoCopy:_readBuffer length:_readCount freeWhenDone:NO];
|
||||
NSArray *nsOpen = [NSKeyedUnarchiver unarchiveObjectWithData:data];
|
||||
|
||||
if(!DisconnectNamedPipe(_pipe)) {
|
||||
NSLog(@"DisconnectNamedPipe failed");
|
||||
}
|
||||
_state=STATE_CONNECTING;
|
||||
if([nsOpen count] == 1 && [[nsOpen lastObject] isEqual:@"@reopen"]) {
|
||||
[NSApp _reopen];
|
||||
} else {
|
||||
[[NSUserDefaults standardUserDefaults] setObject:nsOpen forKey:@"NSOpen"];
|
||||
[NSApp performSelector:@selector(openFiles)];
|
||||
}
|
||||
}
|
||||
|
||||
[self startReading];
|
||||
@ -106,40 +111,38 @@ static Win32RunningCopyPipe *_runningCopyPipe=nil;
|
||||
}
|
||||
|
||||
+(void)_startRunningCopyPipe {
|
||||
if(![self createRunningCopyPipe]){
|
||||
NSString *path;
|
||||
if(![self createRunningCopyPipe]) {
|
||||
NSArray *paths;
|
||||
|
||||
if([[NSUserDefaults standardUserDefaults] stringForKey:@"NSUseRunningCopy"]!=nil){
|
||||
if(![[NSUserDefaults standardUserDefaults] boolForKey:@"NSUseRunningCopy"])
|
||||
return;
|
||||
}
|
||||
if([[NSUserDefaults standardUserDefaults] stringForKey:@"NSUseRunningCopy"]!=nil &&
|
||||
![[NSUserDefaults standardUserDefaults] boolForKey:@"NSUseRunningCopy"]) {
|
||||
|
||||
path=[[NSUserDefaults standardUserDefaults] stringForKey:@"NSOpen"];
|
||||
|
||||
if([path length]==0) path=@"@reopen";
|
||||
|
||||
|
||||
|
||||
//if([path length]>0)
|
||||
{
|
||||
HANDLE pipe=CreateFile([[self pipeName] cString],GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
|
||||
|
||||
if(pipe==INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
else {
|
||||
unsigned length=[path length];
|
||||
unichar buffer[length];
|
||||
DWORD wrote;
|
||||
|
||||
[path getCharacters:buffer];
|
||||
|
||||
if(!WriteFile(pipe,buffer,length*2,&wrote,NULL)){
|
||||
NSLog(@"WriteFile failed");
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
|
||||
id nsOpen = [[NSUserDefaults standardUserDefaults] objectForKey:@"NSOpen"];
|
||||
|
||||
if ([nsOpen isKindOfClass:[NSString class]] && [nsOpen length]) {
|
||||
paths = [NSArray arrayWithObject:nsOpen];
|
||||
} else if ([nsOpen isKindOfClass:[NSArray class]] && [nsOpen count]) {
|
||||
paths = nsOpen;
|
||||
} else {
|
||||
paths = [NSArray arrayWithObject:@"@reopen"];
|
||||
}
|
||||
|
||||
HANDLE pipe=CreateFile([[self pipeName] cString],GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
|
||||
|
||||
if(pipe==INVALID_HANDLE_VALUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:paths];
|
||||
DWORD written = 0;
|
||||
|
||||
if(!WriteFile(pipe, [data bytes], [data length], &written,NULL) || written != [data length]) {
|
||||
NSLog(@"WriteFile failed");
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user