Skip to content

Commit

Permalink
using new NSRunningApplication API for restoring focus of previous ap…
Browse files Browse the repository at this point in the history
…plication (fast)

removed applescript detection of running applications (this was slow, fixes #42)
  • Loading branch information
darwin committed Sep 26, 2009
1 parent 8877270 commit 6e39cc3
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 37 deletions.
4 changes: 3 additions & 1 deletion src/Visor.h
Expand Up @@ -11,7 +11,8 @@
NSUInteger hotModifiersState_;
NSTimeInterval lastHotModifiersEventCheckedTime_;
EventHotKeyRef escapeHotKey;
NSString* previouslyActiveApp;
NSString* previouslyActiveAppPath;
NSNumber* previouslyActiveAppPID;
BOOL isHidden;
BOOL justLaunched;
BOOL isMain;
Expand All @@ -28,6 +29,7 @@
NSString* restoreAppAppleScriptSource;
NSDictionary* scriptError;
BOOL ignoreResizeNotifications;
id runningApplicationClass;
}
- (IBAction)pinAction:(id)sender;
- (IBAction)toggleVisor:(id)sender;
Expand Down
61 changes: 43 additions & 18 deletions src/Visor.m
Expand Up @@ -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];
Expand All @@ -531,7 +533,7 @@ - (id) init {
NSUserDefaults* ud = [NSUserDefaults standardUserDefaults];
NSUserDefaultsController* udc = [NSUserDefaultsController sharedUserDefaultsController];

previouslyActiveApp = nil;
previouslyActiveAppPath = nil;
isHidden = true;
isMain = false;
isKey = false;
Expand Down Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions src/Visor.pch
Expand Up @@ -5,4 +5,5 @@
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>
#import <AppKit/AppKit.h>
#endif
6 changes: 6 additions & 0 deletions src/Visor.xcodeproj/project.pbxproj
Expand Up @@ -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 */; };
Expand Down Expand Up @@ -84,6 +85,7 @@
files = (
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */,
D6716ED210659A6300970560 /* WebKit.framework in Frameworks */,
D648D9FA106DBF7300EA640F /* AppKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -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;
Expand All @@ -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;
};
Expand Down
21 changes: 3 additions & 18 deletions src/res/RestoreApp.scpt
Expand Up @@ -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

Expand Down

0 comments on commit 6e39cc3

Please sign in to comment.