Skip to content

Commit

Permalink
Setup iTerm2 hot key to restore focus of last app
Browse files Browse the repository at this point in the history
  • Loading branch information
cehoffman committed May 14, 2012
1 parent 8d11355 commit ad78411
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 4 deletions.
2 changes: 1 addition & 1 deletion os/mac/Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ task :install do
puts "installing #{plist} to ~/Library/LaunchAgents"
open(dest , 'w') { |file| file << contents }

if %x[launchctl list] =~ /#{plist}/
if %x[launchctl list] =~ /#{plist.sub(/\.plist/, '')}/
puts "shutting down #{plist}"
system 'launchctl', 'unload', '-w', dest
end
Expand Down
67 changes: 64 additions & 3 deletions os/mac/iTerm2HotKey.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,40 @@

NSString *iTerm2Identifier = @"com.googlecode.iterm2";
EventHotKeyRef hotKeyRef;
pid_t lastActive = 0;

@interface AppListener : NSObject
+(AppListener *)sharedListener;
-(void)notified:(NSNotification *)theNotification;
@end

@implementation AppListener
+(AppListener *)sharedListener {
static __strong AppListener *_shared = nil;
if (_shared == nil) _shared = [[self alloc] init];
return _shared;
}

void shutdown(int signum) {
UnregisterEventHotKey(hotKeyRef);
[[[NSWorkspace sharedWorkspace] notificationCenter]
removeObserver:[AppListener sharedListener]];
[[NSApplication sharedApplication] terminate:nil];
}

-(void)notified:(NSNotification *)aNotification {
NSRunningApplication *sender;
NSString *ident;

sender = [[aNotification userInfo] valueForKey:NSWorkspaceApplicationKey];
ident = [sender bundleIdentifier];

if (ident && ![ident isEqualToString:iTerm2Identifier]) {
lastActive = [sender processIdentifier];
}
}
@end

OSStatus hotkey_handler(EventHandlerCallRef next, EventRef event, void *data) {
NSRunningApplication *iTerm2;
NSArray *apps = [NSRunningApplication
Expand All @@ -20,7 +48,19 @@ OSStatus hotkey_handler(EventHandlerCallRef next, EventRef event, void *data) {
if (!iTerm2) return noErr;

if ([iTerm2 ownsMenuBar]) {
[iTerm2 hide];
// This guards incase we have not initialized the last active on startup
if (lastActive) {
// Recheck lastActive application to make sure it is still in existence
NSRunningApplication *lastApp = [NSRunningApplication
runningApplicationWithProcessIdentifier:lastActive];

if (lastApp) {
[lastApp activateWithOptions:NSApplicationActivateIgnoringOtherApps];
}
} else {
// Since we don't know who to active, just hide to achieve effect
[iTerm2 hide];
}
} else {
[iTerm2 activateWithOptions:NSApplicationActivateIgnoringOtherApps];
}
Expand All @@ -40,15 +80,36 @@ int main(int argc, char **argv) {

InstallApplicationEventHandler(&hotkey_handler, 1, &eventType, NULL, NULL);

// Installed F1 as the hotkey to watch for
// Install F1 as the hotkey to watch for
if (!RegisterEventHotKey(122, 0x800000, hotKeyID,
GetEventDispatcherTarget(), 0, &hotKeyRef)) {
signal(SIGTERM, shutdown);
signal(SIGINT, shutdown);

// Needed to use notification on application loading so the selector
// version of listening for application deactivations doesn't complain
// about release autopools that I can't setup when using ARC
__block __weak id observer = [[NSNotificationCenter defaultCenter]
addObserverForName:NSApplicationDidFinishLaunchingNotification
object:nil
queue:nil
usingBlock: ^(NSNotification *aNotification) {
[[NSNotificationCenter defaultCenter] removeObserver:observer];

// The block form apparently has some sort of bug, but it does
// not work for notification from the workspace
[[[NSWorkspace sharedWorkspace] notificationCenter]
addObserver:[AppListener sharedListener]
selector:@selector(notified:)
name:NSWorkspaceDidDeactivateApplicationNotification
object:nil];
}];

// Really wish I could figure out the run loop magic to make the hotkey
// presses deliverable, but so far this is the only way I've found
[[NSApplication sharedApplication] run];
[NSApplication sharedApplication];
[NSApp disableRelaunchOnLogin];
[NSApp run];
}

return EXIT_FAILURE;
Expand Down

0 comments on commit ad78411

Please sign in to comment.