From 7e5568674713bedf9318e83b9fb13abbd122382c Mon Sep 17 00:00:00 2001 From: Joe Wreschnig Date: Fri, 8 Mar 2013 17:35:21 +0100 Subject: [PATCH] Allow mapping names to be auto-set based on bundleand executable path names as well bundle names and IDs. Don't let certain bundles (i.e. Flash) participate in @Application handling. --- .../NSRunningApplication+NJPossibleNames.h | 20 +++++++ .../NSRunningApplication+NJPossibleNames.m | 52 +++++++++++++++++++ Classes/EnjoyableApplicationDelegate.m | 7 +-- Classes/NJMappingsController.h | 2 +- Classes/NJMappingsController.m | 32 +++++++----- Enjoyable.xcodeproj/project.pbxproj | 6 +++ Other Sources/Enjoyable_Prefix.pch | 1 + 7 files changed, 102 insertions(+), 18 deletions(-) create mode 100644 Categories/NSRunningApplication+NJPossibleNames.h create mode 100644 Categories/NSRunningApplication+NJPossibleNames.m diff --git a/Categories/NSRunningApplication+NJPossibleNames.h b/Categories/NSRunningApplication+NJPossibleNames.h new file mode 100644 index 0000000..13a6ffb --- /dev/null +++ b/Categories/NSRunningApplication+NJPossibleNames.h @@ -0,0 +1,20 @@ +// +// NSRunningApplication+NJPossibleNames.h +// Enjoyable +// +// Created by Joe Wreschnig on 3/8/13. +// +// + +#import + +@interface NSRunningApplication (NJPossibleNames) + +- (NSArray *)possibleMappingNames; + // Return a list of mapping names this application could match. + +- (NSString *)bestMappingName; + // Return the best mapping name, taking into account ways in which + // application names are often broken. + +@end diff --git a/Categories/NSRunningApplication+NJPossibleNames.m b/Categories/NSRunningApplication+NJPossibleNames.m new file mode 100644 index 0000000..a3fdaf5 --- /dev/null +++ b/Categories/NSRunningApplication+NJPossibleNames.m @@ -0,0 +1,52 @@ +// +// NSRunningApplication+NJPossibleNames.m +// Enjoyable +// +// Created by Joe Wreschnig on 3/8/13. +// +// + +#import "NSRunningApplication+NJPossibleNames.h" + +@implementation NSRunningApplication (NJPossibleNames) + +- (NSArray *)possibleMappingNames { + NSMutableArray *names = [[NSMutableArray alloc] initWithCapacity:4]; + if (self.bundleIdentifier) + [names addObject:self.bundleIdentifier]; + if (self.localizedName) + [names addObject:self.localizedName]; + if (self.bundleURL) + [names addObject:[self.bundleURL.lastPathComponent stringByDeletingPathExtension]]; + if (self.executableURL) + [names addObject:self.executableURL.lastPathComponent]; + return names; +} + +- (NSString *)bestMappingName { + // A number of Flash applications all use the generic Flash bundle + // ID and localized name, but they name their bundle file and + // executable correctly. Don't want to fall back to those IDs + // unless we absolutely have to. + NSArray *genericBundles = @[ + @"com.macromedia.Flash Player Debugger.app", + @"com.macromedia.Flash Player.app", + ]; + BOOL probablyWrong = [genericBundles containsObject:self.bundleIdentifier]; + if (!probablyWrong && self.localizedName) + return self.localizedName; + else if (!probablyWrong && self.bundleIdentifier) + return self.bundleIdentifier; + else if (self.bundleURL) + return [self.bundleURL.lastPathComponent stringByDeletingPathExtension]; + else if (self.executableURL) + return self.executableURL.lastPathComponent; + else if (self.localizedName) + return self.localizedName; + else if (self.bundleIdentifier) + return self.bundleIdentifier; + else + return @"@Application"; +} + +@end diff --git a/Classes/EnjoyableApplicationDelegate.m b/Classes/EnjoyableApplicationDelegate.m index 6fb5141..78b930b 100644 --- a/Classes/EnjoyableApplicationDelegate.m +++ b/Classes/EnjoyableApplicationDelegate.m @@ -17,11 +17,8 @@ - (void)didSwitchApplication:(NSNotification *)note { NSRunningApplication *activeApp = note.userInfo[NSWorkspaceApplicationKey]; - NSString *name = activeApp.localizedName; - if (!name) - name = activeApp.bundleIdentifier; - if (name && ![name isEqualToString:NSRunningApplication.currentApplication.localizedName]) - [self.mappingsController activateMappingForProcess:name]; + if (activeApp) + [self.mappingsController activateMappingForProcess:activeApp]; } - (void)applicationDidFinishLaunching:(NSNotification *)notification { diff --git a/Classes/NJMappingsController.h b/Classes/NJMappingsController.h index b252904..bca6c1f 100644 --- a/Classes/NJMappingsController.h +++ b/Classes/NJMappingsController.h @@ -31,7 +31,7 @@ - (NJMapping *)objectAtIndexedSubscript:(NSUInteger)idx; - (void)addMappingWithContentsOfURL:(NSURL *)url; - (void)activateMapping:(NJMapping *)mapping; -- (void)activateMappingForProcess:(NSString *)processName; +- (void)activateMappingForProcess:(NSRunningApplication *)app; - (void)save; - (void)load; diff --git a/Classes/NJMappingsController.m b/Classes/NJMappingsController.m index ea8137f..2ee4239 100644 --- a/Classes/NJMappingsController.m +++ b/Classes/NJMappingsController.m @@ -65,19 +65,27 @@ count:len]; } -- (void)activateMappingForProcess:(NSString *)processName { - if ([manualMapping.name.lowercaseString isEqualToString:@"@application"]) { - manualMapping.name = processName; - [self mappingsChanged]; - } else { - NJMapping *oldMapping = manualMapping; - NJMapping *newMapping = self[processName]; - if (!newMapping) - newMapping = oldMapping; - if (newMapping != _currentMapping) - [self activateMapping:newMapping]; - manualMapping = oldMapping; +- (void)activateMappingForProcess:(NSRunningApplication *)app { + NJMapping *oldMapping = manualMapping; + NSArray *names = app.possibleMappingNames; + BOOL found = NO; + for (NSString *name in names) { + NJMapping *mapping = self[name]; + if (mapping) { + [self activateMapping:self[name]]; + found = YES; + break; + } + } + + if (!found) { + [self activateMapping:oldMapping]; + if ([oldMapping.name.lowercaseString isEqualToString:@"@application"]) { + oldMapping.name = app.bestMappingName; + [self mappingsChanged]; + } } + manualMapping = oldMapping; } - (void)updateInterfaceForCurrentMapping { diff --git a/Enjoyable.xcodeproj/project.pbxproj b/Enjoyable.xcodeproj/project.pbxproj index 6fe308e..bf9c0d9 100644 --- a/Enjoyable.xcodeproj/project.pbxproj +++ b/Enjoyable.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; D594BF000FAE7397007A85F2 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D594BEFF0FAE7397007A85F2 /* IOKit.framework */; }; EE6A122E16E8F46300EDBD32 /* Icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = EE6A122D16E8F46300EDBD32 /* Icon.icns */; }; + EEE73B1616EA42E5009D9D99 /* NSRunningApplication+NJPossibleNames.m in Sources */ = {isa = PBXBuildFile; fileRef = EEE73B1516EA42E5009D9D99 /* NSRunningApplication+NJPossibleNames.m */; }; EEF17D1916E8E21A00D7DC4D /* com.yukkurigames.Enjoyable.mapping.icns in Resources */ = {isa = PBXBuildFile; fileRef = EEF17D1716E8E21A00D7DC4D /* com.yukkurigames.Enjoyable.mapping.icns */; }; EEF17D1F16E8E23A00D7DC4D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = EEF17D1B16E8E23A00D7DC4D /* InfoPlist.strings */; }; EEF17D2016E8E23A00D7DC4D /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = EEF17D1D16E8E23A00D7DC4D /* MainMenu.xib */; }; @@ -48,6 +49,8 @@ 8D1107320486CEB800E47090 /* Enjoyable.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Enjoyable.app; sourceTree = BUILT_PRODUCTS_DIR; }; D594BEFF0FAE7397007A85F2 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; EE6A122D16E8F46300EDBD32 /* Icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Icon.icns; sourceTree = ""; }; + EEE73B1416EA42E5009D9D99 /* NSRunningApplication+NJPossibleNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSRunningApplication+NJPossibleNames.h"; path = "Categories/NSRunningApplication+NJPossibleNames.h"; sourceTree = ""; }; + EEE73B1516EA42E5009D9D99 /* NSRunningApplication+NJPossibleNames.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSRunningApplication+NJPossibleNames.m"; path = "Categories/NSRunningApplication+NJPossibleNames.m"; sourceTree = ""; }; EEF17D1716E8E21A00D7DC4D /* com.yukkurigames.Enjoyable.mapping.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = com.yukkurigames.Enjoyable.mapping.icns; path = Resources/com.yukkurigames.Enjoyable.mapping.icns; sourceTree = ""; }; EEF17D1C16E8E23A00D7DC4D /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = Resources/English.lproj/InfoPlist.strings; sourceTree = ""; }; EEF17D1E16E8E23A00D7DC4D /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/MainMenu.xib; sourceTree = ""; }; @@ -245,6 +248,8 @@ EEF17D3016E8E2E100D7DC4D /* NSString+FixFilename.m */, EEF17D3116E8E2E100D7DC4D /* NSView+FirstResponder.h */, EEF17D3216E8E2E100D7DC4D /* NSView+FirstResponder.m */, + EEE73B1416EA42E5009D9D99 /* NSRunningApplication+NJPossibleNames.h */, + EEE73B1516EA42E5009D9D99 /* NSRunningApplication+NJPossibleNames.m */, ); name = Categories; sourceTree = ""; @@ -359,6 +364,7 @@ EEF17D6A16E8E2EF00D7DC4D /* NJOutputMouseButton.m in Sources */, EEF17D6B16E8E2EF00D7DC4D /* NJOutputMouseMove.m in Sources */, EEF17D6C16E8E2EF00D7DC4D /* NJOutputMouseScroll.m in Sources */, + EEE73B1616EA42E5009D9D99 /* NSRunningApplication+NJPossibleNames.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Other Sources/Enjoyable_Prefix.pch b/Other Sources/Enjoyable_Prefix.pch index 4845e9d..61d6aee 100644 --- a/Other Sources/Enjoyable_Prefix.pch +++ b/Other Sources/Enjoyable_Prefix.pch @@ -14,3 +14,4 @@ #import "NSMutableArray+MoveObject.h" #import "NSFileManager+UniqueNames.h" #import "NSString+FixFilename.h" +#import "NSRunningApplication+NJPossibleNames.h" -- 2.30.2