diff options
author | gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3> | 2009-04-27 22:15:20 +0000 |
---|---|---|
committer | gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3> | 2009-04-27 22:15:20 +0000 |
commit | a81570d9175bd8ef8079a76148e478eb67dafd95 (patch) | |
tree | 4aa5bf8653e81c94963a6b0c397debb8d07d536c /Foundation | |
parent | b4d9a4e890c31751a6b3b8dea090912ccd16a79d (diff) |
[Author: dmaclach]
Adds faster version of [NSWorkspace launchedApplications] and forces
AppleScript execution onto the main thread.
DELTA=136 (111 added, 14 deleted, 11 changed)
R=thomasvl
Diffstat (limited to 'Foundation')
-rw-r--r-- | Foundation/GTMNSAppleScript+Handler.m | 71 |
1 files changed, 49 insertions, 22 deletions
diff --git a/Foundation/GTMNSAppleScript+Handler.m b/Foundation/GTMNSAppleScript+Handler.m index 8c23649..dd548e4 100644 --- a/Foundation/GTMNSAppleScript+Handler.m +++ b/Foundation/GTMNSAppleScript+Handler.m @@ -24,6 +24,12 @@ #import "GTMMethodCheck.h" #import "GTMDebugThreadValidation.h" +// Keys for passing AppleScript calls from other threads to the main thread +// and back through gtm_internalExecuteAppleEvent: +static NSString *const GTMNSAppleScriptEventKey = @"GTMNSAppleScriptEvent"; +static NSString *const GTMNSAppleScriptResultKey = @"GTMNSAppleScriptResult"; +static NSString *const GTMNSAppleScriptErrorKey = @"GTMNSAppleScriptError"; + // Some private methods that we need to call @interface NSAppleScript (NSPrivate) + (ComponentInstance)_defaultScriptingComponent; @@ -68,6 +74,8 @@ // Utility methods for converting between real and generic OSAIDs. - (OSAID)gtm_genericID:(OSAID)osaID forComponent:(ComponentInstance)component; - (OSAID)gtm_realIDAndComponent:(ComponentInstance*)component; + +- (void)gtm_internalExecuteAppleEvent:(NSMutableDictionary *)data; @end @implementation NSAppleScript(GTMAppleScriptHandlerAdditions) @@ -105,29 +113,15 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); - (NSAppleEventDescriptor *)gtm_executeAppleEvent:(NSAppleEventDescriptor *)event error:(NSDictionary **)error { - GTMAssertRunningOnMainThread(); - if (![self isCompiled]) { - if (![self compileAndReturnError:error]) { - return nil; - } - } - NSAppleEventDescriptor *desc = nil; - ComponentInstance component; - OSAID scriptID = [self gtm_realIDAndComponent:&component]; - OSAID valueID; - OSAError err = OSAExecuteEvent(component, [event aeDesc], scriptID, - kOSAModeNull, &valueID); - if (err == noErr) { - // descForScriptID:component: is what sets this apart from the - // standard executeAppelEvent:error: in that it handles - // taking script results and turning them into AEDescs of typeGTMOSAID - // instead of typeScript. - desc = [self descForScriptID:valueID component:component]; - } - if (err && error) { - *error = [NSAppleScript _infoForOSAError:err]; + NSMutableDictionary *data = [NSMutableDictionary dictionaryWithObjectsAndKeys: + event, GTMNSAppleScriptEventKey, nil]; + [self performSelectorOnMainThread:@selector(gtm_internalExecuteAppleEvent:) + withObject:data + waitUntilDone:YES]; + if (error) { + *error = [data objectForKey:GTMNSAppleScriptErrorKey]; } - return desc; + return [data objectForKey:GTMNSAppleScriptResultKey]; } - (NSAppleEventDescriptor*)gtm_executePositionalHandler:(NSString*)handler @@ -463,6 +457,39 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); return genericID; } +- (void)gtm_internalExecuteAppleEvent:(NSMutableDictionary *)data { + GTMAssertRunningOnMainThread(); + NSDictionary *error = nil; + if (![self isCompiled]) { + [self compileAndReturnError:&error]; + } + if (!error) { + NSAppleEventDescriptor *desc = nil; + NSAppleEventDescriptor *event = [data objectForKey:GTMNSAppleScriptEventKey]; + ComponentInstance component; + OSAID scriptID = [self gtm_realIDAndComponent:&component]; + OSAID valueID; + OSAError err = OSAExecuteEvent(component, [event aeDesc], scriptID, + kOSAModeNull, &valueID); + if (err == noErr) { + // descForScriptID:component: is what sets this apart from the + // standard executeAppelEvent:error: in that it handles + // taking script results and turning them into AEDescs of typeGTMOSAID + // instead of typeScript. + desc = [self descForScriptID:valueID component:component]; + if (desc) { + [data setObject:desc forKey:GTMNSAppleScriptResultKey]; + } + } + if (err) { + error = [NSAppleScript _infoForOSAError:err]; + } + } + if (error) { + [data setObject:error forKey:GTMNSAppleScriptErrorKey]; + } +} + @end // Private methods for dealing with Scripts/Events and NSAppleEventDescriptors |