From 6e39cc3e2df159e10fd9925c9a8fdfa1cd3df093 Mon Sep 17 00:00:00 2001 From: Antonin Hildebrand Date: Sat, 26 Sep 2009 06:17:18 +0200 Subject: [PATCH] using new NSRunningApplication API for restoring focus of previous application (fast) removed applescript detection of running applications (this was slow, fixes #42) --- src/Visor.h | 4 +- src/Visor.m | 61 ++++++++++++++++++++--------- src/Visor.pch | 1 + src/Visor.xcodeproj/project.pbxproj | 6 +++ src/res/RestoreApp.scpt | 21 ++-------- 5 files changed, 56 insertions(+), 37 deletions(-) diff --git a/src/Visor.h b/src/Visor.h index 610a2a1..bc2c544 100644 --- a/src/Visor.h +++ b/src/Visor.h @@ -11,7 +11,8 @@ NSUInteger hotModifiersState_; NSTimeInterval lastHotModifiersEventCheckedTime_; EventHotKeyRef escapeHotKey; - NSString* previouslyActiveApp; + NSString* previouslyActiveAppPath; + NSNumber* previouslyActiveAppPID; BOOL isHidden; BOOL justLaunched; BOOL isMain; @@ -28,6 +29,7 @@ NSString* restoreAppAppleScriptSource; NSDictionary* scriptError; BOOL ignoreResizeNotifications; + id runningApplicationClass; } - (IBAction)pinAction:(id)sender; - (IBAction)toggleVisor:(id)sender; diff --git a/src/Visor.m b/src/Visor.m index 35be59c..88c40ee 100644 --- a/src/Visor.m +++ b/src/Visor.m @@ -517,7 +517,9 @@ - (id) init { self = [super init]; if (!self) return self; - LOG(@"init"); + LOG(@"Visor init"); + + runningApplicationClass = NSClassFromString(@"NSRunningApplication"); // 10.6 NSString* path = [[NSBundle bundleForClass:[self class]] pathForResource:@"RestoreApp" ofType:@"scpt"]; restoreAppAppleScriptSource = [[NSString alloc] initWithContentsOfFile:path encoding:NSMacOSRomanStringEncoding error:NULL]; @@ -531,7 +533,7 @@ - (id) init { NSUserDefaults* ud = [NSUserDefaults standardUserDefaults]; NSUserDefaultsController* udc = [NSUserDefaultsController sharedUserDefaultsController]; - previouslyActiveApp = nil; + previouslyActiveAppPath = nil; isHidden = true; isMain = false; isKey = false; @@ -841,26 +843,49 @@ - (void)applyWindowPositioning:(id)win { - (void)storePreviouslyActiveApp { LOG(@"storePreviouslyActiveApp"); - NSDictionary *activeAppDict = [[NSWorkspace sharedWorkspace] activeApplication]; - if (previouslyActiveApp) { - [previouslyActiveApp release]; - previouslyActiveApp = nil; - } - if ([[activeAppDict objectForKey:@"NSApplicationBundleIdentifier"] compare:@"com.apple.Terminal"]) { - previouslyActiveApp = [[NSString alloc] initWithString:[activeAppDict objectForKey:@"NSApplicationPath"]]; + if (!runningApplicationClass) { + // 10.5 path + NSDictionary *activeAppDict = [[NSWorkspace sharedWorkspace] activeApplication]; + previouslyActiveAppPath = nil; + if ([[activeAppDict objectForKey:@"NSApplicationBundleIdentifier"] compare:@"com.apple.Terminal"]) { + previouslyActiveAppPath = [[NSString alloc] initWithString:[activeAppDict objectForKey:@"NSApplicationPath"]]; + } + LOG(@" (10.5) -> %@", previouslyActiveAppPath); + } else { + // 10.6+ path + NSDictionary *activeAppDict = [[NSWorkspace sharedWorkspace] activeApplication]; + previouslyActiveAppPID = nil; + if ([[activeAppDict objectForKey:@"NSApplicationBundleIdentifier"] compare:@"com.apple.Terminal"]) { + previouslyActiveAppPID = [activeAppDict objectForKey:@"NSApplicationProcessIdentifier"]; + } + LOG(@" (10.6) -> %@", previouslyActiveAppPID); } } - (void)restorePreviouslyActiveApp { - if (!previouslyActiveApp) return; - LOG(@"restorePreviouslyActiveApp %@", previouslyActiveApp); - NSString* scriptSource = [[NSString alloc] initWithFormat:restoreAppAppleScriptSource, previouslyActiveApp]; - NSAppleScript* appleScript = [[NSAppleScript alloc] initWithSource:scriptSource]; - [appleScript executeAndReturnError: &scriptError]; - [appleScript release]; - [scriptSource release]; - [previouslyActiveApp release]; - previouslyActiveApp = nil; + if (!runningApplicationClass) { + if (!previouslyActiveAppPath) return; + LOG(@"restorePreviouslyActiveApp %@", previouslyActiveAppPath); + // 10.5 path + // Visor crashes when trying to return focus to non-running application? (http://github.com/darwin/visor/issues#issue/12) + NSString* scriptSource = [[NSString alloc] initWithFormat:restoreAppAppleScriptSource, previouslyActiveAppPath]; + NSAppleScript* appleScript = [[NSAppleScript alloc] initWithSource:scriptSource]; + [appleScript executeAndReturnError: &scriptError]; + [appleScript release]; + [scriptSource release]; + previouslyActiveAppPath = nil; + } else { + // 10.6+ path + LOG(@"xrestorePreviouslyActiveApp %@", previouslyActiveAppPID); + if (!previouslyActiveAppPID) return; + LOG(@"restorePreviouslyActiveApp %@", previouslyActiveAppPID); + id app = [runningApplicationClass runningApplicationWithProcessIdentifier: [previouslyActiveAppPID intValue]]; + if (app) { + LOG(@" ... activating %@", app); + [app activateWithOptions:0]; + } + previouslyActiveAppPID = nil; + } } - (void)onReopenVisor { diff --git a/src/Visor.pch b/src/Visor.pch index c1f8a73..47c2583 100644 --- a/src/Visor.pch +++ b/src/Visor.pch @@ -5,4 +5,5 @@ #ifdef __OBJC__ #import #import +#import #endif \ No newline at end of file diff --git a/src/Visor.xcodeproj/project.pbxproj b/src/Visor.xcodeproj/project.pbxproj index 2dead37..c03bc53 100644 --- a/src/Visor.xcodeproj/project.pbxproj +++ b/src/Visor.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; D62204AF1051CC3700FAEA30 /* TerminalColours.m in Sources */ = {isa = PBXBuildFile; fileRef = D62204AE1051CC3700FAEA30 /* TerminalColours.m */; }; D62204B21051CC6A00FAEA30 /* JRSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = D62204B11051CC6A00FAEA30 /* JRSwizzle.m */; }; + D648D9FA106DBF7300EA640F /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 089C167FFE841241C02AAC07 /* AppKit.framework */; }; D65FF865105D82B500B54560 /* GTMHotKeyTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = D65FF864105D82B500B54560 /* GTMHotKeyTextField.m */; }; D65FF874105D845B00B54560 /* GTMNSObject+KeyValueObserving.m in Sources */ = {isa = PBXBuildFile; fileRef = D65FF870105D845B00B54560 /* GTMNSObject+KeyValueObserving.m */; }; D65FF875105D845B00B54560 /* GTMSystemVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = D65FF873105D845B00B54560 /* GTMSystemVersion.m */; }; @@ -84,6 +85,7 @@ files = ( 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */, D6716ED210659A6300970560 /* WebKit.framework in Frameworks */, + D648D9FA106DBF7300EA640F /* AppKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -358,10 +360,12 @@ GCC_WARN_UNDECLARED_SELECTOR = YES; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Library/Bundles"; + MACOSX_DEPLOYMENT_TARGET = 10.5; ONLY_ACTIVE_ARCH = NO; PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; PRODUCT_NAME = Visor; RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = macosx10.6; SKIP_INSTALL = YES; VALID_ARCHS = "i386 x86_64"; WRAPPER_EXTENSION = bundle; @@ -388,8 +392,10 @@ GCC_WARN_INHIBIT_ALL_WARNINGS = YES; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Library/Bundles"; + MACOSX_DEPLOYMENT_TARGET = 10.5; PRODUCT_NAME = Visor; RUN_CLANG_STATIC_ANALYZER = NO; + SDKROOT = macosx10.6; VALID_ARCHS = "x86_64 i386 ppc"; WRAPPER_EXTENSION = bundle; }; diff --git a/src/res/RestoreApp.scpt b/src/res/RestoreApp.scpt index 910b597..e09bb22 100644 --- a/src/res/RestoreApp.scpt +++ b/src/res/RestoreApp.scpt @@ -4,26 +4,11 @@ -- Visor launches app when returning focus (http://github.com/darwin/visor/issues#issue/8) -- Visor crashes when trying to return focus to non-running application? (http://github.com/darwin/visor/issues#issue/12) -on appIsRunning(appName) - tell application "System Events" - repeat with p in processes - set f to file of p - try - set u to POSIX path of f - if u is appName then return true - end try - end repeat - end tell - return false -end appIsRunning - on restoreApp(appName) with timeout of 1 second - if appIsRunning(appName) then - tell application appName - activate - end tell - end if + tell application appName + activate + end tell end timeout end restoreApp