├── .gitignore ├── LICENSE ├── Podfile ├── Podfile.lock ├── Pods ├── Headers │ ├── Private │ │ └── MASShortcut │ │ │ ├── MASDictionaryTransformer.h │ │ │ ├── MASHotKey.h │ │ │ ├── MASKeyCodes.h │ │ │ ├── MASLocalization.h │ │ │ ├── MASShortcut.h │ │ │ ├── MASShortcutBinder.h │ │ │ ├── MASShortcutMonitor.h │ │ │ ├── MASShortcutValidator.h │ │ │ ├── MASShortcutView+Bindings.h │ │ │ ├── MASShortcutView.h │ │ │ └── Shortcut.h │ └── Public │ │ └── MASShortcut │ │ ├── MASDictionaryTransformer.h │ │ ├── MASHotKey.h │ │ ├── MASKeyCodes.h │ │ ├── MASLocalization.h │ │ ├── MASShortcut.h │ │ ├── MASShortcutBinder.h │ │ ├── MASShortcutMonitor.h │ │ ├── MASShortcutValidator.h │ │ ├── MASShortcutView+Bindings.h │ │ ├── MASShortcutView.h │ │ └── Shortcut.h ├── MASShortcut │ ├── Framework │ │ ├── MASDictionaryTransformer.h │ │ ├── MASDictionaryTransformer.m │ │ ├── MASHotKey.h │ │ ├── MASHotKey.m │ │ ├── MASKeyCodes.h │ │ ├── MASLocalization.h │ │ ├── MASLocalization.m │ │ ├── MASShortcut.h │ │ ├── MASShortcut.m │ │ ├── MASShortcut.modulemap │ │ ├── MASShortcutBinder.h │ │ ├── MASShortcutBinder.m │ │ ├── MASShortcutMonitor.h │ │ ├── MASShortcutMonitor.m │ │ ├── MASShortcutValidator.h │ │ ├── MASShortcutValidator.m │ │ ├── MASShortcutView+Bindings.h │ │ ├── MASShortcutView+Bindings.m │ │ ├── MASShortcutView.h │ │ ├── MASShortcutView.m │ │ └── Shortcut.h │ ├── LICENSE │ └── README.md ├── Manifest.lock ├── Pods.xcodeproj │ ├── project.pbxproj │ └── xcuserdata │ │ └── raj.xcuserdatad │ │ └── xcschemes │ │ ├── MASShortcut.xcscheme │ │ ├── Pods-SplitViewShortcut.xcscheme │ │ └── xcschememanagement.plist └── Target Support Files │ ├── MASShortcut │ ├── MASShortcut-Private.xcconfig │ ├── MASShortcut-dummy.m │ ├── MASShortcut-prefix.pch │ └── MASShortcut.xcconfig │ └── Pods-SplitViewShortcut │ ├── Pods-SplitViewShortcut-acknowledgements.markdown │ ├── Pods-SplitViewShortcut-acknowledgements.plist │ ├── Pods-SplitViewShortcut-dummy.m │ ├── Pods-SplitViewShortcut-resources.sh │ ├── Pods-SplitViewShortcut.debug.xcconfig │ └── Pods-SplitViewShortcut.release.xcconfig ├── README.md ├── SplitViewShortcut.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── raj.xcuserdatad │ └── xcschemes │ ├── SplitViewShortcut.xcscheme │ └── xcschememanagement.plist ├── SplitViewShortcut.xcworkspace ├── contents.xcworkspacedata └── xcuserdata │ └── raj.xcuserdatad │ └── xcdebugger │ └── Breakpoints_v2.xcbkptlist ├── SplitViewShortcut ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── 1024.png │ │ ├── 128.png │ │ ├── 16.png │ │ ├── 256-1.png │ │ ├── 256.png │ │ ├── 32-1.png │ │ ├── 32.png │ │ ├── 512-1.png │ │ ├── 512.png │ │ ├── 64.png │ │ └── Contents.json │ ├── Contents.json │ └── StatusIcon.imageset │ │ ├── 16.png │ │ ├── 32.png │ │ ├── 64.png │ │ └── Contents.json ├── Base.lproj │ └── MainMenu.xib ├── Bridging-Header.h └── Info.plist ├── icons ├── 1024.png ├── 128.png ├── 16.png ├── 256.png ├── 32.png ├── 512.png ├── 64.png └── master.png └── preview.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | # Pods/ 27 | 28 | # Carthage 29 | # 30 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 31 | # Carthage/Checkouts 32 | 33 | Carthage/Build 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Rajarshi Nigam 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '6.0' 3 | 4 | target 'SplitViewShortcut' do 5 | pod 'MASShortcut' 6 | end 7 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - MASShortcut (2.3.1) 3 | 4 | DEPENDENCIES: 5 | - MASShortcut 6 | 7 | SPEC CHECKSUMS: 8 | MASShortcut: 865f14caa35979ded96ca3863dc073c109982db8 9 | 10 | COCOAPODS: 0.38.2 11 | -------------------------------------------------------------------------------- /Pods/Headers/Private/MASShortcut/MASDictionaryTransformer.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASDictionaryTransformer.h -------------------------------------------------------------------------------- /Pods/Headers/Private/MASShortcut/MASHotKey.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASHotKey.h -------------------------------------------------------------------------------- /Pods/Headers/Private/MASShortcut/MASKeyCodes.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASKeyCodes.h -------------------------------------------------------------------------------- /Pods/Headers/Private/MASShortcut/MASLocalization.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASLocalization.h -------------------------------------------------------------------------------- /Pods/Headers/Private/MASShortcut/MASShortcut.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASShortcut.h -------------------------------------------------------------------------------- /Pods/Headers/Private/MASShortcut/MASShortcutBinder.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASShortcutBinder.h -------------------------------------------------------------------------------- /Pods/Headers/Private/MASShortcut/MASShortcutMonitor.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASShortcutMonitor.h -------------------------------------------------------------------------------- /Pods/Headers/Private/MASShortcut/MASShortcutValidator.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASShortcutValidator.h -------------------------------------------------------------------------------- /Pods/Headers/Private/MASShortcut/MASShortcutView+Bindings.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASShortcutView+Bindings.h -------------------------------------------------------------------------------- /Pods/Headers/Private/MASShortcut/MASShortcutView.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASShortcutView.h -------------------------------------------------------------------------------- /Pods/Headers/Private/MASShortcut/Shortcut.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/Shortcut.h -------------------------------------------------------------------------------- /Pods/Headers/Public/MASShortcut/MASDictionaryTransformer.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASDictionaryTransformer.h -------------------------------------------------------------------------------- /Pods/Headers/Public/MASShortcut/MASHotKey.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASHotKey.h -------------------------------------------------------------------------------- /Pods/Headers/Public/MASShortcut/MASKeyCodes.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASKeyCodes.h -------------------------------------------------------------------------------- /Pods/Headers/Public/MASShortcut/MASLocalization.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASLocalization.h -------------------------------------------------------------------------------- /Pods/Headers/Public/MASShortcut/MASShortcut.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASShortcut.h -------------------------------------------------------------------------------- /Pods/Headers/Public/MASShortcut/MASShortcutBinder.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASShortcutBinder.h -------------------------------------------------------------------------------- /Pods/Headers/Public/MASShortcut/MASShortcutMonitor.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASShortcutMonitor.h -------------------------------------------------------------------------------- /Pods/Headers/Public/MASShortcut/MASShortcutValidator.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASShortcutValidator.h -------------------------------------------------------------------------------- /Pods/Headers/Public/MASShortcut/MASShortcutView+Bindings.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASShortcutView+Bindings.h -------------------------------------------------------------------------------- /Pods/Headers/Public/MASShortcut/MASShortcutView.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/MASShortcutView.h -------------------------------------------------------------------------------- /Pods/Headers/Public/MASShortcut/Shortcut.h: -------------------------------------------------------------------------------- 1 | ../../../MASShortcut/Framework/Shortcut.h -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASDictionaryTransformer.h: -------------------------------------------------------------------------------- 1 | extern NSString *const MASDictionaryTransformerName; 2 | 3 | /** 4 | Converts shortcuts for storage in user defaults. 5 | 6 | User defaults can’t stored custom types directly, they have to 7 | be serialized to `NSData` or some other supported type like an 8 | `NSDictionary`. In Cocoa Bindings, the conversion can be done 9 | using value transformers like this one. 10 | 11 | There’s a built-in transformer (`NSKeyedUnarchiveFromDataTransformerName`) 12 | that converts any `NSCoding` types to `NSData`, but with shortcuts 13 | it makes sense to use a dictionary instead – the defaults look better 14 | when inspected with the `defaults` command-line utility and the 15 | format is compatible with an older sortcut library called Shortcut 16 | Recorder. 17 | */ 18 | @interface MASDictionaryTransformer : NSValueTransformer 19 | @end 20 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASDictionaryTransformer.m: -------------------------------------------------------------------------------- 1 | #import "MASDictionaryTransformer.h" 2 | #import "MASShortcut.h" 3 | 4 | NSString *const MASDictionaryTransformerName = @"MASDictionaryTransformer"; 5 | 6 | static NSString *const MASKeyCodeKey = @"keyCode"; 7 | static NSString *const MASModifierFlagsKey = @"modifierFlags"; 8 | 9 | @implementation MASDictionaryTransformer 10 | 11 | + (BOOL) allowsReverseTransformation 12 | { 13 | return YES; 14 | } 15 | 16 | // Storing nil values as an empty dictionary lets us differ between 17 | // “not available, use default value” and “explicitly set to none”. 18 | // See http://stackoverflow.com/questions/5540760 for details. 19 | - (NSDictionary*) reverseTransformedValue: (MASShortcut*) shortcut 20 | { 21 | if (shortcut == nil) { 22 | return [NSDictionary dictionary]; 23 | } else { 24 | return @{ 25 | MASKeyCodeKey: @([shortcut keyCode]), 26 | MASModifierFlagsKey: @([shortcut modifierFlags]) 27 | }; 28 | } 29 | } 30 | 31 | - (MASShortcut*) transformedValue: (NSDictionary*) dictionary 32 | { 33 | // We have to be defensive here as the value may come from user defaults. 34 | if (![dictionary isKindOfClass:[NSDictionary class]]) { 35 | return nil; 36 | } 37 | 38 | id keyCodeBox = [dictionary objectForKey:MASKeyCodeKey]; 39 | id modifierFlagsBox = [dictionary objectForKey:MASModifierFlagsKey]; 40 | 41 | SEL integerValue = @selector(integerValue); 42 | if (![keyCodeBox respondsToSelector:integerValue] || ![modifierFlagsBox respondsToSelector:integerValue]) { 43 | return nil; 44 | } 45 | 46 | return [MASShortcut 47 | shortcutWithKeyCode:[keyCodeBox integerValue] 48 | modifierFlags:[modifierFlagsBox integerValue]]; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASHotKey.h: -------------------------------------------------------------------------------- 1 | #import "MASShortcut.h" 2 | 3 | extern FourCharCode const MASHotKeySignature; 4 | 5 | @interface MASHotKey : NSObject 6 | 7 | @property(readonly) UInt32 carbonID; 8 | @property(copy) dispatch_block_t action; 9 | 10 | + (instancetype) registeredHotKeyWithShortcut: (MASShortcut*) shortcut; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASHotKey.m: -------------------------------------------------------------------------------- 1 | #import "MASHotKey.h" 2 | 3 | FourCharCode const MASHotKeySignature = 'MASS'; 4 | 5 | @interface MASHotKey () 6 | @property(assign) EventHotKeyRef hotKeyRef; 7 | @property(assign) UInt32 carbonID; 8 | @end 9 | 10 | @implementation MASHotKey 11 | 12 | - (instancetype) initWithShortcut: (MASShortcut*) shortcut 13 | { 14 | self = [super init]; 15 | 16 | static UInt32 CarbonHotKeyID = 0; 17 | 18 | _carbonID = ++CarbonHotKeyID; 19 | EventHotKeyID hotKeyID = { .signature = MASHotKeySignature, .id = _carbonID }; 20 | 21 | OSStatus status = RegisterEventHotKey([shortcut carbonKeyCode], [shortcut carbonFlags], 22 | hotKeyID, GetEventDispatcherTarget(), 0, &_hotKeyRef); 23 | 24 | if (status != noErr) { 25 | return nil; 26 | } 27 | 28 | return self; 29 | } 30 | 31 | + (instancetype) registeredHotKeyWithShortcut: (MASShortcut*) shortcut 32 | { 33 | return [[self alloc] initWithShortcut:shortcut]; 34 | } 35 | 36 | - (void) dealloc 37 | { 38 | if (_hotKeyRef) { 39 | UnregisterEventHotKey(_hotKeyRef); 40 | _hotKeyRef = NULL; 41 | } 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASKeyCodes.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | // These glyphs are missed in Carbon.h 5 | enum { 6 | kMASShortcutGlyphEject = 0x23CF, 7 | kMASShortcutGlyphClear = 0x2715, 8 | kMASShortcutGlyphDeleteLeft = 0x232B, 9 | kMASShortcutGlyphDeleteRight = 0x2326, 10 | kMASShortcutGlyphLeftArrow = 0x2190, 11 | kMASShortcutGlyphRightArrow = 0x2192, 12 | kMASShortcutGlyphUpArrow = 0x2191, 13 | kMASShortcutGlyphDownArrow = 0x2193, 14 | kMASShortcutGlyphEscape = 0x238B, 15 | kMASShortcutGlyphHelp = 0x003F, 16 | kMASShortcutGlyphPageDown = 0x21DF, 17 | kMASShortcutGlyphPageUp = 0x21DE, 18 | kMASShortcutGlyphTabRight = 0x21E5, 19 | kMASShortcutGlyphReturn = 0x2305, 20 | kMASShortcutGlyphReturnR2L = 0x21A9, 21 | kMASShortcutGlyphPadClear = 0x2327, 22 | kMASShortcutGlyphNorthwestArrow = 0x2196, 23 | kMASShortcutGlyphSoutheastArrow = 0x2198, 24 | }; 25 | 26 | NS_INLINE NSString* NSStringFromMASKeyCode(unsigned short ch) 27 | { 28 | return [NSString stringWithFormat:@"%C", ch]; 29 | } 30 | 31 | NS_INLINE NSUInteger MASPickCocoaModifiers(NSUInteger flags) 32 | { 33 | return (flags & (NSControlKeyMask | NSShiftKeyMask | NSAlternateKeyMask | NSCommandKeyMask)); 34 | } 35 | 36 | NS_INLINE UInt32 MASCarbonModifiersFromCocoaModifiers(NSUInteger cocoaFlags) 37 | { 38 | return 39 | (cocoaFlags & NSCommandKeyMask ? cmdKey : 0) 40 | | (cocoaFlags & NSAlternateKeyMask ? optionKey : 0) 41 | | (cocoaFlags & NSControlKeyMask ? controlKey : 0) 42 | | (cocoaFlags & NSShiftKeyMask ? shiftKey : 0); 43 | } 44 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASLocalization.h: -------------------------------------------------------------------------------- 1 | /** 2 | Reads a localized string from the framework’s bundle. 3 | 4 | Normally you would use NSLocalizedString to read the localized 5 | strings, but that’s just a shortcut for loading the strings from 6 | the main bundle. And once the framework ends up in an app, the 7 | main bundle will be the app’s bundle and won’t contain our strings. 8 | So we introduced this helper function that makes sure to load the 9 | strings from the framework’s bundle. Please avoid using 10 | NSLocalizedString throughout the framework, it wouldn’t work 11 | properly. 12 | */ 13 | NSString *MASLocalizedString(NSString *key, NSString *comment); -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASLocalization.m: -------------------------------------------------------------------------------- 1 | #import "MASLocalization.h" 2 | #import "MASShortcut.h" 3 | 4 | NSString *MASLocalizedString(NSString *key, NSString *comment) { 5 | NSBundle *frameworkBundle = [NSBundle bundleForClass:[MASShortcut class]]; 6 | return [frameworkBundle localizedStringForKey:key value:@"XXX" table:@"Localizable"]; 7 | } 8 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASShortcut.h: -------------------------------------------------------------------------------- 1 | #import "MASKeyCodes.h" 2 | 3 | /** 4 | A model class to hold a key combination. 5 | 6 | This class just represents a combination of keys. It does not care if 7 | the combination is valid or can be used as a hotkey, it doesn’t watch 8 | the input system for the shortcut appearance, nor it does access user 9 | defaults. 10 | */ 11 | @interface MASShortcut : NSObject 12 | 13 | /** 14 | The virtual key code for the keyboard key. 15 | 16 | Hardware independent, same as in `NSEvent`. See `Events.h` in the HIToolbox 17 | framework for a complete list, or Command-click this symbol: `kVK_ANSI_A`. 18 | */ 19 | @property (nonatomic, readonly) NSUInteger keyCode; 20 | 21 | /** 22 | Cocoa keyboard modifier flags. 23 | 24 | Same as in `NSEvent`: `NSCommandKeyMask`, `NSAlternateKeyMask`, etc. 25 | */ 26 | @property (nonatomic, readonly) NSUInteger modifierFlags; 27 | 28 | /** 29 | Same as `keyCode`, just a different type. 30 | */ 31 | @property (nonatomic, readonly) UInt32 carbonKeyCode; 32 | 33 | /** 34 | Carbon modifier flags. 35 | 36 | A bit sum of `cmdKey`, `optionKey`, etc. 37 | */ 38 | @property (nonatomic, readonly) UInt32 carbonFlags; 39 | 40 | /** 41 | A string representing the “key” part of a shortcut, like the `5` in `⌘5`. 42 | 43 | @warning The value may change depending on the active keyboard layout. 44 | For example for the `^2` keyboard shortcut (`kVK_ANSI_2+NSControlKeyMask` 45 | to be precise) the `keyCodeString` is `2` on the US keyboard, but `ě` when 46 | the Czech keyboard layout is active. See the spec for details. 47 | */ 48 | @property (nonatomic, readonly) NSString *keyCodeString; 49 | 50 | /** 51 | A key-code string used in key equivalent matching. 52 | 53 | For precise meaning of “key equivalents” see the `keyEquivalent` 54 | property of `NSMenuItem`. Here the string is used to support shortcut 55 | validation (“is the shortcut already taken in this menu?”) and 56 | for display in `NSMenu`. 57 | 58 | The value of this property may differ from `keyCodeString`. For example 59 | the Russian keyboard has a `Г` (Ge) Cyrillic character in place of the 60 | latin `U` key. This means you can create a `^Г` shortcut, but in menus 61 | that’s always displayed as `^U`. So the `keyCodeString` returns `Г` 62 | and `keyCodeStringForKeyEquivalent` returns `U`. 63 | */ 64 | @property (nonatomic, readonly) NSString *keyCodeStringForKeyEquivalent; 65 | 66 | /** 67 | A string representing the shortcut modifiers, like the `⌘` in `⌘5`. 68 | */ 69 | @property (nonatomic, readonly) NSString *modifierFlagsString; 70 | 71 | - (instancetype)initWithKeyCode:(NSUInteger)code modifierFlags:(NSUInteger)flags; 72 | + (instancetype)shortcutWithKeyCode:(NSUInteger)code modifierFlags:(NSUInteger)flags; 73 | 74 | /** 75 | Creates a new shortcut from an `NSEvent` object. 76 | 77 | This is just a convenience initializer that reads the key code and modifiers from an `NSEvent`. 78 | */ 79 | + (instancetype)shortcutWithEvent:(NSEvent *)anEvent; 80 | 81 | @end 82 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASShortcut.m: -------------------------------------------------------------------------------- 1 | #import "MASShortcut.h" 2 | #import "MASLocalization.h" 3 | 4 | static NSString *const MASShortcutKeyCode = @"KeyCode"; 5 | static NSString *const MASShortcutModifierFlags = @"ModifierFlags"; 6 | 7 | @implementation MASShortcut 8 | 9 | #pragma mark Initialization 10 | 11 | - (instancetype)initWithKeyCode:(NSUInteger)code modifierFlags:(NSUInteger)flags 12 | { 13 | self = [super init]; 14 | if (self) { 15 | _keyCode = code; 16 | _modifierFlags = MASPickCocoaModifiers(flags); 17 | } 18 | return self; 19 | } 20 | 21 | + (instancetype)shortcutWithKeyCode:(NSUInteger)code modifierFlags:(NSUInteger)flags 22 | { 23 | return [[self alloc] initWithKeyCode:code modifierFlags:flags]; 24 | } 25 | 26 | + (instancetype)shortcutWithEvent:(NSEvent *)event 27 | { 28 | return [[self alloc] initWithKeyCode:event.keyCode modifierFlags:event.modifierFlags]; 29 | } 30 | 31 | #pragma mark Shortcut Accessors 32 | 33 | - (UInt32)carbonKeyCode 34 | { 35 | return (self.keyCode == NSNotFound ? 0 : (UInt32)self.keyCode); 36 | } 37 | 38 | - (UInt32)carbonFlags 39 | { 40 | return MASCarbonModifiersFromCocoaModifiers(self.modifierFlags); 41 | } 42 | 43 | - (NSString *)description 44 | { 45 | return [NSString stringWithFormat:@"%@%@", self.modifierFlagsString, self.keyCodeString]; 46 | } 47 | 48 | - (NSString *)keyCodeStringForKeyEquivalent 49 | { 50 | NSString *keyCodeString = self.keyCodeString; 51 | if (keyCodeString.length > 1) { 52 | switch (self.keyCode) { 53 | case kVK_F1: return NSStringFromMASKeyCode(0xF704); 54 | case kVK_F2: return NSStringFromMASKeyCode(0xF705); 55 | case kVK_F3: return NSStringFromMASKeyCode(0xF706); 56 | case kVK_F4: return NSStringFromMASKeyCode(0xF707); 57 | case kVK_F5: return NSStringFromMASKeyCode(0xF708); 58 | case kVK_F6: return NSStringFromMASKeyCode(0xF709); 59 | case kVK_F7: return NSStringFromMASKeyCode(0xF70a); 60 | case kVK_F8: return NSStringFromMASKeyCode(0xF70b); 61 | case kVK_F9: return NSStringFromMASKeyCode(0xF70c); 62 | case kVK_F10: return NSStringFromMASKeyCode(0xF70d); 63 | case kVK_F11: return NSStringFromMASKeyCode(0xF70e); 64 | case kVK_F12: return NSStringFromMASKeyCode(0xF70f); 65 | // From this point down I am guessing F13 etc come sequentially, I don't have a keyboard to test. 66 | case kVK_F13: return NSStringFromMASKeyCode(0xF710); 67 | case kVK_F14: return NSStringFromMASKeyCode(0xF711); 68 | case kVK_F15: return NSStringFromMASKeyCode(0xF712); 69 | case kVK_F16: return NSStringFromMASKeyCode(0xF713); 70 | case kVK_F17: return NSStringFromMASKeyCode(0xF714); 71 | case kVK_F18: return NSStringFromMASKeyCode(0xF715); 72 | case kVK_F19: return NSStringFromMASKeyCode(0xF716); 73 | case kVK_Space: return NSStringFromMASKeyCode(0x20); 74 | default: return @""; 75 | } 76 | } 77 | return keyCodeString.lowercaseString; 78 | } 79 | 80 | - (NSString *)keyCodeString 81 | { 82 | // Some key codes don't have an equivalent 83 | switch (self.keyCode) { 84 | case NSNotFound: return @""; 85 | case kVK_F1: return @"F1"; 86 | case kVK_F2: return @"F2"; 87 | case kVK_F3: return @"F3"; 88 | case kVK_F4: return @"F4"; 89 | case kVK_F5: return @"F5"; 90 | case kVK_F6: return @"F6"; 91 | case kVK_F7: return @"F7"; 92 | case kVK_F8: return @"F8"; 93 | case kVK_F9: return @"F9"; 94 | case kVK_F10: return @"F10"; 95 | case kVK_F11: return @"F11"; 96 | case kVK_F12: return @"F12"; 97 | case kVK_F13: return @"F13"; 98 | case kVK_F14: return @"F14"; 99 | case kVK_F15: return @"F15"; 100 | case kVK_F16: return @"F16"; 101 | case kVK_F17: return @"F17"; 102 | case kVK_F18: return @"F18"; 103 | case kVK_F19: return @"F19"; 104 | case kVK_Space: return MASLocalizedString(@"Space", @"Shortcut glyph name for SPACE key"); 105 | case kVK_Escape: return NSStringFromMASKeyCode(kMASShortcutGlyphEscape); 106 | case kVK_Delete: return NSStringFromMASKeyCode(kMASShortcutGlyphDeleteLeft); 107 | case kVK_ForwardDelete: return NSStringFromMASKeyCode(kMASShortcutGlyphDeleteRight); 108 | case kVK_LeftArrow: return NSStringFromMASKeyCode(kMASShortcutGlyphLeftArrow); 109 | case kVK_RightArrow: return NSStringFromMASKeyCode(kMASShortcutGlyphRightArrow); 110 | case kVK_UpArrow: return NSStringFromMASKeyCode(kMASShortcutGlyphUpArrow); 111 | case kVK_DownArrow: return NSStringFromMASKeyCode(kMASShortcutGlyphDownArrow); 112 | case kVK_Help: return NSStringFromMASKeyCode(kMASShortcutGlyphHelp); 113 | case kVK_PageUp: return NSStringFromMASKeyCode(kMASShortcutGlyphPageUp); 114 | case kVK_PageDown: return NSStringFromMASKeyCode(kMASShortcutGlyphPageDown); 115 | case kVK_Tab: return NSStringFromMASKeyCode(kMASShortcutGlyphTabRight); 116 | case kVK_Return: return NSStringFromMASKeyCode(kMASShortcutGlyphReturnR2L); 117 | 118 | // Keypad 119 | case kVK_ANSI_Keypad0: return @"0"; 120 | case kVK_ANSI_Keypad1: return @"1"; 121 | case kVK_ANSI_Keypad2: return @"2"; 122 | case kVK_ANSI_Keypad3: return @"3"; 123 | case kVK_ANSI_Keypad4: return @"4"; 124 | case kVK_ANSI_Keypad5: return @"5"; 125 | case kVK_ANSI_Keypad6: return @"6"; 126 | case kVK_ANSI_Keypad7: return @"7"; 127 | case kVK_ANSI_Keypad8: return @"8"; 128 | case kVK_ANSI_Keypad9: return @"9"; 129 | case kVK_ANSI_KeypadDecimal: return @"."; 130 | case kVK_ANSI_KeypadMultiply: return @"*"; 131 | case kVK_ANSI_KeypadPlus: return @"+"; 132 | case kVK_ANSI_KeypadClear: return NSStringFromMASKeyCode(kMASShortcutGlyphPadClear); 133 | case kVK_ANSI_KeypadDivide: return @"/"; 134 | case kVK_ANSI_KeypadEnter: return NSStringFromMASKeyCode(kMASShortcutGlyphReturn); 135 | case kVK_ANSI_KeypadMinus: return @"–"; 136 | case kVK_ANSI_KeypadEquals: return @"="; 137 | 138 | // Hardcode 139 | case 119: return NSStringFromMASKeyCode(kMASShortcutGlyphSoutheastArrow); 140 | case 115: return NSStringFromMASKeyCode(kMASShortcutGlyphNorthwestArrow); 141 | } 142 | 143 | // Everything else should be printable so look it up in the current ASCII capable keyboard layout 144 | OSStatus error = noErr; 145 | NSString *keystroke = nil; 146 | TISInputSourceRef inputSource = TISCopyCurrentASCIICapableKeyboardLayoutInputSource(); 147 | if (inputSource) { 148 | CFDataRef layoutDataRef = TISGetInputSourceProperty(inputSource, kTISPropertyUnicodeKeyLayoutData); 149 | if (layoutDataRef) { 150 | UCKeyboardLayout *layoutData = (UCKeyboardLayout *)CFDataGetBytePtr(layoutDataRef); 151 | UniCharCount length = 0; 152 | UniChar chars[256] = { 0 }; 153 | UInt32 deadKeyState = 0; 154 | error = UCKeyTranslate(layoutData, (UInt16)self.keyCode, kUCKeyActionDisplay, 0, // No modifiers 155 | LMGetKbdType(), kUCKeyTranslateNoDeadKeysMask, &deadKeyState, 156 | sizeof(chars) / sizeof(UniChar), &length, chars); 157 | keystroke = ((error == noErr) && length ? [NSString stringWithCharacters:chars length:length] : @""); 158 | } 159 | CFRelease(inputSource); 160 | } 161 | 162 | // Validate keystroke 163 | if (keystroke.length) { 164 | static NSMutableCharacterSet *validChars = nil; 165 | if (validChars == nil) { 166 | validChars = [[NSMutableCharacterSet alloc] init]; 167 | [validChars formUnionWithCharacterSet:[NSCharacterSet alphanumericCharacterSet]]; 168 | [validChars formUnionWithCharacterSet:[NSCharacterSet punctuationCharacterSet]]; 169 | [validChars formUnionWithCharacterSet:[NSCharacterSet symbolCharacterSet]]; 170 | } 171 | for (NSUInteger i = 0, length = keystroke.length; i < length; i++) { 172 | if (![validChars characterIsMember:[keystroke characterAtIndex:i]]) { 173 | keystroke = @""; 174 | break; 175 | } 176 | } 177 | } 178 | 179 | // Finally, we've got a shortcut! 180 | return keystroke.uppercaseString; 181 | } 182 | 183 | - (NSString *)modifierFlagsString 184 | { 185 | unichar chars[4]; 186 | NSUInteger count = 0; 187 | // These are in the same order as the menu manager shows them 188 | if (self.modifierFlags & NSControlKeyMask) chars[count++] = kControlUnicode; 189 | if (self.modifierFlags & NSAlternateKeyMask) chars[count++] = kOptionUnicode; 190 | if (self.modifierFlags & NSShiftKeyMask) chars[count++] = kShiftUnicode; 191 | if (self.modifierFlags & NSCommandKeyMask) chars[count++] = kCommandUnicode; 192 | return (count ? [NSString stringWithCharacters:chars length:count] : @""); 193 | } 194 | 195 | #pragma mark NSObject 196 | 197 | - (BOOL) isEqual: (MASShortcut*) object 198 | { 199 | return [object isKindOfClass:[self class]] 200 | && (object.keyCode == self.keyCode) 201 | && (object.modifierFlags == self.modifierFlags); 202 | } 203 | 204 | - (NSUInteger) hash 205 | { 206 | return self.keyCode + self.modifierFlags; 207 | } 208 | 209 | #pragma mark NSCoding 210 | 211 | - (void)encodeWithCoder:(NSCoder *)coder 212 | { 213 | [coder encodeInteger:(self.keyCode != NSNotFound ? (NSInteger)self.keyCode : - 1) forKey:MASShortcutKeyCode]; 214 | [coder encodeInteger:(NSInteger)self.modifierFlags forKey:MASShortcutModifierFlags]; 215 | } 216 | 217 | - (instancetype)initWithCoder:(NSCoder *)decoder 218 | { 219 | self = [super init]; 220 | if (self) { 221 | NSInteger code = [decoder decodeIntegerForKey:MASShortcutKeyCode]; 222 | _keyCode = (code < 0 ? NSNotFound : (NSUInteger)code); 223 | _modifierFlags = [decoder decodeIntegerForKey:MASShortcutModifierFlags]; 224 | } 225 | return self; 226 | } 227 | 228 | #pragma mark NSSecureCoding 229 | 230 | + (BOOL)supportsSecureCoding 231 | { 232 | return YES; 233 | } 234 | 235 | #pragma mark NSCopying 236 | 237 | - (instancetype) copyWithZone:(NSZone *)zone 238 | { 239 | return [[self class] shortcutWithKeyCode:_keyCode modifierFlags:_modifierFlags]; 240 | } 241 | 242 | @end 243 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASShortcut.modulemap: -------------------------------------------------------------------------------- 1 | framework module MASShortcut { 2 | umbrella header "Shortcut.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASShortcutBinder.h: -------------------------------------------------------------------------------- 1 | #import "MASShortcutMonitor.h" 2 | 3 | /** 4 | Binds actions to user defaults keys. 5 | 6 | If you store shortcuts in user defaults (for example by binding 7 | a `MASShortcutView` to user defaults), you can use this class to 8 | connect an action directly to a user defaults key. If the shortcut 9 | stored under the key changes, the action will get automatically 10 | updated to the new one. 11 | 12 | This class is mostly a wrapper around a `MASShortcutMonitor`. It 13 | watches the changes in user defaults and updates the shortcut monitor 14 | accordingly with the new shortcuts. 15 | */ 16 | @interface MASShortcutBinder : NSObject 17 | 18 | /** 19 | A convenience shared instance. 20 | 21 | You may use it so that you don’t have to manage an instance by hand, 22 | but it’s perfectly fine to allocate and use a separate instance instead. 23 | */ 24 | + (instancetype) sharedBinder; 25 | 26 | /** 27 | The underlying shortcut monitor. 28 | */ 29 | @property(strong) MASShortcutMonitor *shortcutMonitor; 30 | 31 | /** 32 | Binding options customizing the access to user defaults. 33 | 34 | As an example, you can use `NSValueTransformerNameBindingOption` to customize 35 | the storage format used for the shortcuts. By default the shortcuts are converted 36 | from `NSData` (`NSKeyedUnarchiveFromDataTransformerName`). Note that if the 37 | binder is to work with `MASShortcutView`, both object have to use the same storage 38 | format. 39 | */ 40 | @property(copy) NSDictionary *bindingOptions; 41 | 42 | /** 43 | Binds given action to a shortcut stored under the given defaults key. 44 | 45 | In other words, no matter what shortcut you store under the given key, 46 | pressing it will always trigger the given action. 47 | */ 48 | - (void) bindShortcutWithDefaultsKey: (NSString*) defaultsKeyName toAction: (dispatch_block_t) action; 49 | 50 | /** 51 | Disconnect the binding between user defaults and action. 52 | 53 | In other words, the shortcut stored under the given key will no longer trigger an action. 54 | */ 55 | - (void) breakBindingWithDefaultsKey: (NSString*) defaultsKeyName; 56 | 57 | /** 58 | Register default shortcuts in user defaults. 59 | 60 | This is a convenience frontent to `[NSUserDefaults registerDefaults]`. 61 | The dictionary should contain a map of user defaults’ keys to appropriate 62 | keyboard shortcuts. The shortcuts will be transformed according to 63 | `bindingOptions` and registered using `registerDefaults`. 64 | */ 65 | - (void) registerDefaultShortcuts: (NSDictionary*) defaultShortcuts; 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASShortcutBinder.m: -------------------------------------------------------------------------------- 1 | #import "MASShortcutBinder.h" 2 | #import "MASShortcut.h" 3 | 4 | @interface MASShortcutBinder () 5 | @property(strong) NSMutableDictionary *actions; 6 | @property(strong) NSMutableDictionary *shortcuts; 7 | @end 8 | 9 | @implementation MASShortcutBinder 10 | 11 | #pragma mark Initialization 12 | 13 | - (id) init 14 | { 15 | self = [super init]; 16 | [self setActions:[NSMutableDictionary dictionary]]; 17 | [self setShortcuts:[NSMutableDictionary dictionary]]; 18 | [self setShortcutMonitor:[MASShortcutMonitor sharedMonitor]]; 19 | [self setBindingOptions:@{NSValueTransformerNameBindingOption: NSKeyedUnarchiveFromDataTransformerName}]; 20 | return self; 21 | } 22 | 23 | - (void) dealloc 24 | { 25 | for (NSString *bindingName in [_actions allKeys]) { 26 | [self unbind:bindingName]; 27 | } 28 | } 29 | 30 | + (instancetype) sharedBinder 31 | { 32 | static dispatch_once_t once; 33 | static MASShortcutBinder *sharedInstance; 34 | dispatch_once(&once, ^{ 35 | sharedInstance = [[self alloc] init]; 36 | }); 37 | return sharedInstance; 38 | } 39 | 40 | #pragma mark Registration 41 | 42 | - (void) bindShortcutWithDefaultsKey: (NSString*) defaultsKeyName toAction: (dispatch_block_t) action 43 | { 44 | NSAssert([defaultsKeyName rangeOfString:@"."].location == NSNotFound, 45 | @"Illegal character in binding name (“.”), please see http://git.io/x5YS."); 46 | NSAssert([defaultsKeyName rangeOfString:@" "].location == NSNotFound, 47 | @"Illegal character in binding name (“ ”), please see http://git.io/x5YS."); 48 | [_actions setObject:[action copy] forKey:defaultsKeyName]; 49 | [self bind:defaultsKeyName 50 | toObject:[NSUserDefaultsController sharedUserDefaultsController] 51 | withKeyPath:[@"values." stringByAppendingString:defaultsKeyName] 52 | options:_bindingOptions]; 53 | } 54 | 55 | - (void) breakBindingWithDefaultsKey: (NSString*) defaultsKeyName 56 | { 57 | [_shortcutMonitor unregisterShortcut:[_shortcuts objectForKey:defaultsKeyName]]; 58 | [_shortcuts removeObjectForKey:defaultsKeyName]; 59 | [_actions removeObjectForKey:defaultsKeyName]; 60 | [self unbind:defaultsKeyName]; 61 | } 62 | 63 | - (void) registerDefaultShortcuts: (NSDictionary*) defaultShortcuts 64 | { 65 | NSValueTransformer *transformer = [_bindingOptions valueForKey:NSValueTransformerBindingOption]; 66 | if (transformer == nil) { 67 | NSString *transformerName = [_bindingOptions valueForKey:NSValueTransformerNameBindingOption]; 68 | if (transformerName) { 69 | transformer = [NSValueTransformer valueTransformerForName:transformerName]; 70 | } 71 | } 72 | 73 | NSAssert(transformer != nil, @"Can’t register default shortcuts without a transformer."); 74 | 75 | [defaultShortcuts enumerateKeysAndObjectsUsingBlock:^(NSString *defaultsKey, MASShortcut *shortcut, BOOL *stop) { 76 | id value = [transformer reverseTransformedValue:shortcut]; 77 | [[NSUserDefaults standardUserDefaults] registerDefaults:@{defaultsKey:value}]; 78 | }]; 79 | } 80 | 81 | #pragma mark Bindings 82 | 83 | - (BOOL) isRegisteredAction: (NSString*) name 84 | { 85 | return !![_actions objectForKey:name]; 86 | } 87 | 88 | - (id) valueForUndefinedKey: (NSString*) key 89 | { 90 | return [self isRegisteredAction:key] ? 91 | [_shortcuts objectForKey:key] : 92 | [super valueForUndefinedKey:key]; 93 | } 94 | 95 | - (void) setValue: (id) value forUndefinedKey: (NSString*) key 96 | { 97 | if (![self isRegisteredAction:key]) { 98 | [super setValue:value forUndefinedKey:key]; 99 | return; 100 | } 101 | 102 | MASShortcut *newShortcut = value; 103 | MASShortcut *currentShortcut = [_shortcuts objectForKey:key]; 104 | 105 | // Unbind previous shortcut if any 106 | if (currentShortcut != nil) { 107 | [_shortcutMonitor unregisterShortcut:currentShortcut]; 108 | } 109 | 110 | // Just deleting the old shortcut 111 | if (newShortcut == nil) { 112 | [_shortcuts removeObjectForKey:key]; 113 | return; 114 | } 115 | 116 | // Bind new shortcut 117 | [_shortcuts setObject:newShortcut forKey:key]; 118 | [_shortcutMonitor registerShortcut:newShortcut withAction:[_actions objectForKey:key]]; 119 | } 120 | 121 | @end 122 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASShortcutMonitor.h: -------------------------------------------------------------------------------- 1 | #import "MASShortcut.h" 2 | 3 | /** 4 | Executes action when a shortcut is pressed. 5 | 6 | There can only be one instance of this class, otherwise things 7 | will probably not work. (There’s a Carbon event handler inside 8 | and there can only be one Carbon event handler of a given type.) 9 | */ 10 | @interface MASShortcutMonitor : NSObject 11 | 12 | - (instancetype) init __unavailable; 13 | + (instancetype) sharedMonitor; 14 | 15 | /** 16 | Register a shortcut along with an action. 17 | 18 | Attempting to insert an already registered shortcut probably won’t work. 19 | It may burn your house or cut your fingers. You have been warned. 20 | */ 21 | - (BOOL) registerShortcut: (MASShortcut*) shortcut withAction: (dispatch_block_t) action; 22 | - (BOOL) isShortcutRegistered: (MASShortcut*) shortcut; 23 | 24 | - (void) unregisterShortcut: (MASShortcut*) shortcut; 25 | - (void) unregisterAllShortcuts; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASShortcutMonitor.m: -------------------------------------------------------------------------------- 1 | #import "MASShortcutMonitor.h" 2 | #import "MASHotKey.h" 3 | 4 | @interface MASShortcutMonitor () 5 | @property(assign) EventHandlerRef eventHandlerRef; 6 | @property(strong) NSMutableDictionary *hotKeys; 7 | @end 8 | 9 | static OSStatus MASCarbonEventCallback(EventHandlerCallRef, EventRef, void*); 10 | 11 | @implementation MASShortcutMonitor 12 | 13 | #pragma mark Initialization 14 | 15 | - (instancetype) init 16 | { 17 | self = [super init]; 18 | [self setHotKeys:[NSMutableDictionary dictionary]]; 19 | EventTypeSpec hotKeyPressedSpec = { .eventClass = kEventClassKeyboard, .eventKind = kEventHotKeyPressed }; 20 | OSStatus status = InstallEventHandler(GetEventDispatcherTarget(), MASCarbonEventCallback, 21 | 1, &hotKeyPressedSpec, (__bridge void*)self, &_eventHandlerRef); 22 | if (status != noErr) { 23 | return nil; 24 | } 25 | return self; 26 | } 27 | 28 | - (void) dealloc 29 | { 30 | if (_eventHandlerRef) { 31 | RemoveEventHandler(_eventHandlerRef); 32 | _eventHandlerRef = NULL; 33 | } 34 | } 35 | 36 | + (instancetype) sharedMonitor 37 | { 38 | static dispatch_once_t once; 39 | static MASShortcutMonitor *sharedInstance; 40 | dispatch_once(&once, ^{ 41 | sharedInstance = [[self alloc] init]; 42 | }); 43 | return sharedInstance; 44 | } 45 | 46 | #pragma mark Registration 47 | 48 | - (BOOL) registerShortcut: (MASShortcut*) shortcut withAction: (dispatch_block_t) action 49 | { 50 | MASHotKey *hotKey = [MASHotKey registeredHotKeyWithShortcut:shortcut]; 51 | if (hotKey) { 52 | [hotKey setAction:action]; 53 | [_hotKeys setObject:hotKey forKey:shortcut]; 54 | return YES; 55 | } else { 56 | return NO; 57 | } 58 | } 59 | 60 | - (void) unregisterShortcut: (MASShortcut*) shortcut 61 | { 62 | if (shortcut) { 63 | [_hotKeys removeObjectForKey:shortcut]; 64 | } 65 | } 66 | 67 | - (void) unregisterAllShortcuts 68 | { 69 | [_hotKeys removeAllObjects]; 70 | } 71 | 72 | - (BOOL) isShortcutRegistered: (MASShortcut*) shortcut 73 | { 74 | return !![_hotKeys objectForKey:shortcut]; 75 | } 76 | 77 | #pragma mark Event Handling 78 | 79 | - (void) handleEvent: (EventRef) event 80 | { 81 | if (GetEventClass(event) != kEventClassKeyboard) { 82 | return; 83 | } 84 | 85 | EventHotKeyID hotKeyID; 86 | OSStatus status = GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(hotKeyID), NULL, &hotKeyID); 87 | if (status != noErr || hotKeyID.signature != MASHotKeySignature) { 88 | return; 89 | } 90 | 91 | [_hotKeys enumerateKeysAndObjectsUsingBlock:^(MASShortcut *shortcut, MASHotKey *hotKey, BOOL *stop) { 92 | if (hotKeyID.id == [hotKey carbonID]) { 93 | if ([hotKey action]) { 94 | dispatch_async(dispatch_get_main_queue(), [hotKey action]); 95 | } 96 | *stop = YES; 97 | } 98 | }]; 99 | } 100 | 101 | @end 102 | 103 | static OSStatus MASCarbonEventCallback(EventHandlerCallRef _, EventRef event, void *context) 104 | { 105 | MASShortcutMonitor *dispatcher = (__bridge id)context; 106 | [dispatcher handleEvent:event]; 107 | return noErr; 108 | } 109 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASShortcutValidator.h: -------------------------------------------------------------------------------- 1 | #import "MASShortcut.h" 2 | 3 | @interface MASShortcutValidator : NSObject 4 | 5 | // The following API enable hotkeys with the Option key as the only modifier 6 | // For example, Option-G will not generate © and Option-R will not paste ® 7 | @property(assign) BOOL allowAnyShortcutWithOptionModifier; 8 | 9 | + (instancetype) sharedValidator; 10 | 11 | - (BOOL) isShortcutValid: (MASShortcut*) shortcut; 12 | - (BOOL) isShortcut: (MASShortcut*) shortcut alreadyTakenInMenu: (NSMenu*) menu explanation: (NSString**) explanation; 13 | - (BOOL) isShortcutAlreadyTakenBySystem: (MASShortcut*) shortcut explanation: (NSString**) explanation; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASShortcutValidator.m: -------------------------------------------------------------------------------- 1 | #import "MASShortcutValidator.h" 2 | #import "MASLocalization.h" 3 | 4 | @implementation MASShortcutValidator 5 | 6 | + (instancetype) sharedValidator 7 | { 8 | static dispatch_once_t once; 9 | static MASShortcutValidator *sharedInstance; 10 | dispatch_once(&once, ^{ 11 | sharedInstance = [[self alloc] init]; 12 | }); 13 | return sharedInstance; 14 | } 15 | 16 | - (BOOL) isShortcutValid: (MASShortcut*) shortcut 17 | { 18 | NSUInteger keyCode = [shortcut keyCode]; 19 | NSUInteger modifiers = [shortcut modifierFlags]; 20 | 21 | // Allow any function key with any combination of modifiers 22 | BOOL includesFunctionKey = ((keyCode == kVK_F1) || (keyCode == kVK_F2) || (keyCode == kVK_F3) || (keyCode == kVK_F4) || 23 | (keyCode == kVK_F5) || (keyCode == kVK_F6) || (keyCode == kVK_F7) || (keyCode == kVK_F8) || 24 | (keyCode == kVK_F9) || (keyCode == kVK_F10) || (keyCode == kVK_F11) || (keyCode == kVK_F12) || 25 | (keyCode == kVK_F13) || (keyCode == kVK_F14) || (keyCode == kVK_F15) || (keyCode == kVK_F16) || 26 | (keyCode == kVK_F17) || (keyCode == kVK_F18) || (keyCode == kVK_F19) || (keyCode == kVK_F20)); 27 | if (includesFunctionKey) return YES; 28 | 29 | // Do not allow any other key without modifiers 30 | BOOL hasModifierFlags = (modifiers > 0); 31 | if (!hasModifierFlags) return NO; 32 | 33 | // Allow any hotkey containing Control or Command modifier 34 | BOOL includesCommand = ((modifiers & NSCommandKeyMask) > 0); 35 | BOOL includesControl = ((modifiers & NSControlKeyMask) > 0); 36 | if (includesCommand || includesControl) return YES; 37 | 38 | // Allow Option key only in selected cases 39 | BOOL includesOption = ((modifiers & NSAlternateKeyMask) > 0); 40 | if (includesOption) { 41 | 42 | // Always allow Option-Space and Option-Escape because they do not have any bind system commands 43 | if ((keyCode == kVK_Space) || (keyCode == kVK_Escape)) return YES; 44 | 45 | // Allow Option modifier with any key even if it will break the system binding 46 | if (_allowAnyShortcutWithOptionModifier) return YES; 47 | } 48 | 49 | // The hotkey does not have any modifiers or violates system bindings 50 | return NO; 51 | } 52 | 53 | - (BOOL) isShortcut: (MASShortcut*) shortcut alreadyTakenInMenu: (NSMenu*) menu explanation: (NSString**) explanation 54 | { 55 | NSString *keyEquivalent = [shortcut keyCodeStringForKeyEquivalent]; 56 | NSUInteger flags = [shortcut modifierFlags]; 57 | 58 | for (NSMenuItem *menuItem in menu.itemArray) { 59 | if (menuItem.hasSubmenu && [self isShortcut:shortcut alreadyTakenInMenu:[menuItem submenu] explanation:explanation]) return YES; 60 | 61 | BOOL equalFlags = (MASPickCocoaModifiers(menuItem.keyEquivalentModifierMask) == flags); 62 | BOOL equalHotkeyLowercase = [menuItem.keyEquivalent.lowercaseString isEqualToString:keyEquivalent]; 63 | 64 | // Check if the cases are different, we know ours is lower and that shift is included in our modifiers 65 | // If theirs is capitol, we need to add shift to their modifiers 66 | if (equalHotkeyLowercase && ![menuItem.keyEquivalent isEqualToString:keyEquivalent]) { 67 | equalFlags = (MASPickCocoaModifiers(menuItem.keyEquivalentModifierMask | NSShiftKeyMask) == flags); 68 | } 69 | 70 | if (equalFlags && equalHotkeyLowercase) { 71 | if (explanation) { 72 | *explanation = MASLocalizedString(@"This shortcut cannot be used because it is already used by the menu item ‘%@’.", 73 | @"Message for alert when shortcut is already used"); 74 | *explanation = [NSString stringWithFormat:*explanation, menuItem.title]; 75 | } 76 | return YES; 77 | } 78 | } 79 | return NO; 80 | } 81 | 82 | - (BOOL) isShortcutAlreadyTakenBySystem: (MASShortcut*) shortcut explanation: (NSString**) explanation 83 | { 84 | CFArrayRef globalHotKeys; 85 | if (CopySymbolicHotKeys(&globalHotKeys) == noErr) { 86 | 87 | // Enumerate all global hotkeys and check if any of them matches current shortcut 88 | for (CFIndex i = 0, count = CFArrayGetCount(globalHotKeys); i < count; i++) { 89 | CFDictionaryRef hotKeyInfo = CFArrayGetValueAtIndex(globalHotKeys, i); 90 | CFNumberRef code = CFDictionaryGetValue(hotKeyInfo, kHISymbolicHotKeyCode); 91 | CFNumberRef flags = CFDictionaryGetValue(hotKeyInfo, kHISymbolicHotKeyModifiers); 92 | CFNumberRef enabled = CFDictionaryGetValue(hotKeyInfo, kHISymbolicHotKeyEnabled); 93 | 94 | if (([(__bridge NSNumber *)code unsignedIntegerValue] == [shortcut keyCode]) && 95 | ([(__bridge NSNumber *)flags unsignedIntegerValue] == [shortcut carbonFlags]) && 96 | ([(__bridge NSNumber *)enabled boolValue])) { 97 | 98 | if (explanation) { 99 | *explanation = MASLocalizedString(@"This combination cannot be used because it is already used by a system-wide " 100 | @"keyboard shortcut.\nIf you really want to use this key combination, most shortcuts " 101 | @"can be changed in the Keyboard & Mouse panel in System Preferences.", 102 | @"Message for alert when shortcut is already used by the system"); 103 | } 104 | return YES; 105 | } 106 | } 107 | CFRelease(globalHotKeys); 108 | } 109 | return [self isShortcut:shortcut alreadyTakenInMenu:[NSApp mainMenu] explanation:explanation]; 110 | } 111 | 112 | @end 113 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASShortcutView+Bindings.h: -------------------------------------------------------------------------------- 1 | #import "MASShortcutView.h" 2 | 3 | /** 4 | A simplified interface to bind the recorder value to user defaults. 5 | 6 | You can bind the `shortcutValue` to user defaults using the standard 7 | `bind:toObject:withKeyPath:options:` call, but since that’s a lot to type 8 | and read, here’s a simpler option. 9 | 10 | Setting the `associatedUserDefaultsKey` binds the view’s shortcut value 11 | to the given user defaults key. You can supply a value transformer to convert 12 | values between user defaults and `MASShortcut`. If you don’t supply 13 | a transformer, the `NSUnarchiveFromDataTransformerName` will be used 14 | automatically. 15 | 16 | Set `associatedUserDefaultsKey` to `nil` to disconnect the binding. 17 | */ 18 | @interface MASShortcutView (Bindings) 19 | 20 | @property(copy) NSString *associatedUserDefaultsKey; 21 | 22 | - (void) setAssociatedUserDefaultsKey: (NSString*) newKey withTransformer: (NSValueTransformer*) transformer; 23 | - (void) setAssociatedUserDefaultsKey: (NSString*) newKey withTransformerName: (NSString*) transformerName; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASShortcutView+Bindings.m: -------------------------------------------------------------------------------- 1 | #import "MASShortcutView+Bindings.h" 2 | 3 | @implementation MASShortcutView (Bindings) 4 | 5 | - (NSString*) associatedUserDefaultsKey 6 | { 7 | NSDictionary* bindingInfo = [self infoForBinding:MASShortcutBinding]; 8 | if (bindingInfo != nil) { 9 | NSString *keyPath = [bindingInfo objectForKey:NSObservedKeyPathKey]; 10 | NSString *key = [keyPath stringByReplacingOccurrencesOfString:@"values." withString:@""]; 11 | return key; 12 | } else { 13 | return nil; 14 | } 15 | } 16 | 17 | - (void) setAssociatedUserDefaultsKey: (NSString*) newKey withTransformer: (NSValueTransformer*) transformer 18 | { 19 | // Break previous binding if any 20 | NSString *currentKey = [self associatedUserDefaultsKey]; 21 | if (currentKey != nil) { 22 | [self unbind:currentKey]; 23 | } 24 | 25 | // Stop if the new binding is nil 26 | if (newKey == nil) { 27 | return; 28 | } 29 | 30 | NSDictionary *options = transformer ? 31 | @{NSValueTransformerBindingOption:transformer} : 32 | nil; 33 | 34 | [self bind:MASShortcutBinding 35 | toObject:[NSUserDefaultsController sharedUserDefaultsController] 36 | withKeyPath:[@"values." stringByAppendingString:newKey] 37 | options:options]; 38 | } 39 | 40 | - (void) setAssociatedUserDefaultsKey: (NSString*) newKey withTransformerName: (NSString*) transformerName 41 | { 42 | [self setAssociatedUserDefaultsKey:newKey withTransformer:[NSValueTransformer valueTransformerForName:transformerName]]; 43 | } 44 | 45 | - (void) setAssociatedUserDefaultsKey: (NSString*) newKey 46 | { 47 | [self setAssociatedUserDefaultsKey:newKey withTransformerName:NSKeyedUnarchiveFromDataTransformerName]; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASShortcutView.h: -------------------------------------------------------------------------------- 1 | @class MASShortcut, MASShortcutValidator; 2 | 3 | extern NSString *const MASShortcutBinding; 4 | 5 | typedef enum { 6 | MASShortcutViewStyleDefault = 0, // Height = 19 px 7 | MASShortcutViewStyleTexturedRect, // Height = 25 px 8 | MASShortcutViewStyleRounded, // Height = 43 px 9 | MASShortcutViewStyleFlat 10 | } MASShortcutViewStyle; 11 | 12 | @interface MASShortcutView : NSView 13 | 14 | @property (nonatomic, strong) MASShortcut *shortcutValue; 15 | @property (nonatomic, strong) MASShortcutValidator *shortcutValidator; 16 | @property (nonatomic, getter = isRecording) BOOL recording; 17 | @property (nonatomic, getter = isEnabled) BOOL enabled; 18 | @property (nonatomic, copy) void (^shortcutValueChange)(MASShortcutView *sender); 19 | @property (nonatomic, assign) MASShortcutViewStyle style; 20 | 21 | /// Returns custom class for drawing control. 22 | + (Class)shortcutCellClass; 23 | 24 | - (void)setAcceptsFirstResponder:(BOOL)value; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/MASShortcutView.m: -------------------------------------------------------------------------------- 1 | #import "MASShortcutView.h" 2 | #import "MASShortcutValidator.h" 3 | #import "MASLocalization.h" 4 | 5 | NSString *const MASShortcutBinding = @"shortcutValue"; 6 | 7 | static const CGFloat MASHintButtonWidth = 23; 8 | static const CGFloat MASButtonFontSize = 11; 9 | 10 | #pragma mark - 11 | 12 | @interface MASShortcutView () // Private accessors 13 | 14 | @property (nonatomic, getter = isHinting) BOOL hinting; 15 | @property (nonatomic, copy) NSString *shortcutPlaceholder; 16 | @property (nonatomic, assign) BOOL showsDeleteButton; 17 | 18 | @end 19 | 20 | #pragma mark - 21 | 22 | @implementation MASShortcutView { 23 | NSButtonCell *_shortcutCell; 24 | NSInteger _shortcutToolTipTag; 25 | NSInteger _hintToolTipTag; 26 | NSTrackingArea *_hintArea; 27 | BOOL _acceptsFirstResponder; 28 | } 29 | 30 | #pragma mark - 31 | 32 | + (Class)shortcutCellClass 33 | { 34 | return [NSButtonCell class]; 35 | } 36 | 37 | - (id)initWithFrame:(CGRect)frameRect 38 | { 39 | self = [super initWithFrame:frameRect]; 40 | if (self) { 41 | [self commonInit]; 42 | } 43 | return self; 44 | } 45 | 46 | - (id)initWithCoder:(NSCoder *)coder 47 | { 48 | self = [super initWithCoder:coder]; 49 | if (self) { 50 | [self commonInit]; 51 | } 52 | return self; 53 | } 54 | 55 | - (void)commonInit 56 | { 57 | _shortcutCell = [[[self.class shortcutCellClass] alloc] init]; 58 | _shortcutCell.buttonType = NSPushOnPushOffButton; 59 | _shortcutCell.font = [[NSFontManager sharedFontManager] convertFont:_shortcutCell.font toSize:MASButtonFontSize]; 60 | _shortcutValidator = [MASShortcutValidator sharedValidator]; 61 | _enabled = YES; 62 | _showsDeleteButton = YES; 63 | _acceptsFirstResponder = NO; 64 | [self resetShortcutCellStyle]; 65 | } 66 | 67 | - (void)dealloc 68 | { 69 | [self activateEventMonitoring:NO]; 70 | [self activateResignObserver:NO]; 71 | } 72 | 73 | #pragma mark - Public accessors 74 | 75 | - (void)setEnabled:(BOOL)flag 76 | { 77 | if (_enabled != flag) { 78 | _enabled = flag; 79 | [self updateTrackingAreas]; 80 | self.recording = NO; 81 | [self setNeedsDisplay:YES]; 82 | } 83 | } 84 | 85 | - (void)setStyle:(MASShortcutViewStyle)newStyle 86 | { 87 | if (_style != newStyle) { 88 | _style = newStyle; 89 | [self resetShortcutCellStyle]; 90 | [self setNeedsDisplay:YES]; 91 | } 92 | } 93 | 94 | - (void)resetShortcutCellStyle 95 | { 96 | switch (_style) { 97 | case MASShortcutViewStyleDefault: { 98 | _shortcutCell.bezelStyle = NSRoundRectBezelStyle; 99 | break; 100 | } 101 | case MASShortcutViewStyleTexturedRect: { 102 | _shortcutCell.bezelStyle = NSTexturedRoundedBezelStyle; 103 | break; 104 | } 105 | case MASShortcutViewStyleRounded: { 106 | _shortcutCell.bezelStyle = NSRoundedBezelStyle; 107 | break; 108 | } 109 | case MASShortcutViewStyleFlat: { 110 | self.wantsLayer = YES; 111 | _shortcutCell.backgroundColor = [NSColor clearColor]; 112 | _shortcutCell.bordered = NO; 113 | break; 114 | } 115 | } 116 | } 117 | 118 | - (void)setRecording:(BOOL)flag 119 | { 120 | // Only one recorder can be active at the moment 121 | static MASShortcutView *currentRecorder = nil; 122 | if (flag && (currentRecorder != self)) { 123 | currentRecorder.recording = NO; 124 | currentRecorder = flag ? self : nil; 125 | } 126 | 127 | // Only enabled view supports recording 128 | if (flag && !self.enabled) return; 129 | 130 | // Only care about changes in state 131 | if (flag == _recording) return; 132 | 133 | _recording = flag; 134 | self.shortcutPlaceholder = nil; 135 | [self resetToolTips]; 136 | [self activateEventMonitoring:_recording]; 137 | [self activateResignObserver:_recording]; 138 | [self setNeedsDisplay:YES]; 139 | 140 | // Give VoiceOver users feedback on the result. Requires at least 10.9 to run. 141 | if (_recording == NO && (&NSAccessibilityPriorityKey != NULL)) { 142 | NSString* msg = _shortcutValue ? 143 | MASLocalizedString(@"Shortcut set", @"VoiceOver: Shortcut set") : 144 | MASLocalizedString(@"Shortcut cleared", @"VoiceOver: Shortcut cleared"); 145 | NSDictionary *announcementInfo = @{ 146 | NSAccessibilityAnnouncementKey : msg, 147 | NSAccessibilityPriorityKey : @(NSAccessibilityPriorityHigh), 148 | }; 149 | NSAccessibilityPostNotificationWithUserInfo(self, NSAccessibilityAnnouncementRequestedNotification, announcementInfo); 150 | } 151 | } 152 | 153 | - (void)setShortcutValue:(MASShortcut *)shortcutValue 154 | { 155 | _shortcutValue = shortcutValue; 156 | [self resetToolTips]; 157 | [self setNeedsDisplay:YES]; 158 | [self propagateValue:shortcutValue forBinding:MASShortcutBinding]; 159 | 160 | if (self.shortcutValueChange) { 161 | self.shortcutValueChange(self); 162 | } 163 | } 164 | 165 | - (void)setShortcutPlaceholder:(NSString *)shortcutPlaceholder 166 | { 167 | _shortcutPlaceholder = shortcutPlaceholder.copy; 168 | [self setNeedsDisplay:YES]; 169 | } 170 | 171 | #pragma mark - Drawing 172 | 173 | - (BOOL)isFlipped 174 | { 175 | return YES; 176 | } 177 | 178 | - (void)drawInRect:(CGRect)frame withTitle:(NSString *)title alignment:(NSTextAlignment)alignment state:(NSInteger)state 179 | { 180 | _shortcutCell.title = title; 181 | _shortcutCell.alignment = alignment; 182 | _shortcutCell.state = state; 183 | _shortcutCell.enabled = self.enabled; 184 | 185 | switch (_style) { 186 | case MASShortcutViewStyleDefault: { 187 | [_shortcutCell drawWithFrame:frame inView:self]; 188 | break; 189 | } 190 | case MASShortcutViewStyleTexturedRect: { 191 | [_shortcutCell drawWithFrame:CGRectOffset(frame, 0.0, 1.0) inView:self]; 192 | break; 193 | } 194 | case MASShortcutViewStyleRounded: { 195 | [_shortcutCell drawWithFrame:CGRectOffset(frame, 0.0, 1.0) inView:self]; 196 | break; 197 | } 198 | case MASShortcutViewStyleFlat: { 199 | [_shortcutCell drawWithFrame:frame inView:self]; 200 | break; 201 | } 202 | } 203 | } 204 | 205 | - (void)drawRect:(CGRect)dirtyRect 206 | { 207 | if (self.shortcutValue) { 208 | NSString *buttonTitle; 209 | if (self.recording) { 210 | buttonTitle = NSStringFromMASKeyCode(kMASShortcutGlyphEscape); 211 | } else if (self.showsDeleteButton) { 212 | buttonTitle = NSStringFromMASKeyCode(kMASShortcutGlyphClear); 213 | } 214 | if (buttonTitle != nil) { 215 | [self drawInRect:self.bounds withTitle:buttonTitle alignment:NSRightTextAlignment state:NSOffState]; 216 | } 217 | CGRect shortcutRect; 218 | [self getShortcutRect:&shortcutRect hintRect:NULL]; 219 | NSString *title = (self.recording 220 | ? (_hinting 221 | ? MASLocalizedString(@"Use Old Shortcut", @"Cancel action button for non-empty shortcut in recording state") 222 | : (self.shortcutPlaceholder.length > 0 223 | ? self.shortcutPlaceholder 224 | : MASLocalizedString(@"Type New Shortcut", @"Non-empty shortcut button in recording state"))) 225 | : _shortcutValue ? _shortcutValue.description : @""); 226 | [self drawInRect:shortcutRect withTitle:title alignment:NSCenterTextAlignment state:self.isRecording ? NSOnState : NSOffState]; 227 | } 228 | else { 229 | if (self.recording) 230 | { 231 | [self drawInRect:self.bounds withTitle:NSStringFromMASKeyCode(kMASShortcutGlyphEscape) alignment:NSRightTextAlignment state:NSOffState]; 232 | 233 | CGRect shortcutRect; 234 | [self getShortcutRect:&shortcutRect hintRect:NULL]; 235 | NSString *title = (_hinting 236 | ? MASLocalizedString(@"Cancel", @"Cancel action button in recording state") 237 | : (self.shortcutPlaceholder.length > 0 238 | ? self.shortcutPlaceholder 239 | : MASLocalizedString(@"Type Shortcut", @"Empty shortcut button in recording state"))); 240 | [self drawInRect:shortcutRect withTitle:title alignment:NSCenterTextAlignment state:NSOnState]; 241 | } 242 | else 243 | { 244 | [self drawInRect:self.bounds withTitle:MASLocalizedString(@"Record Shortcut", @"Empty shortcut button in normal state") 245 | alignment:NSCenterTextAlignment state:NSOffState]; 246 | } 247 | } 248 | } 249 | 250 | #pragma mark - Mouse handling 251 | 252 | - (void)getShortcutRect:(CGRect *)shortcutRectRef hintRect:(CGRect *)hintRectRef 253 | { 254 | CGRect shortcutRect, hintRect; 255 | CGFloat hintButtonWidth = MASHintButtonWidth; 256 | switch (self.style) { 257 | case MASShortcutViewStyleTexturedRect: hintButtonWidth += 2.0; break; 258 | case MASShortcutViewStyleRounded: hintButtonWidth += 3.0; break; 259 | case MASShortcutViewStyleFlat: hintButtonWidth -= 8.0 - (_shortcutCell.font.pointSize - MASButtonFontSize); break; 260 | default: break; 261 | } 262 | CGRectDivide(self.bounds, &hintRect, &shortcutRect, hintButtonWidth, CGRectMaxXEdge); 263 | if (shortcutRectRef) *shortcutRectRef = shortcutRect; 264 | if (hintRectRef) *hintRectRef = hintRect; 265 | } 266 | 267 | - (BOOL)locationInShortcutRect:(CGPoint)location 268 | { 269 | CGRect shortcutRect; 270 | [self getShortcutRect:&shortcutRect hintRect:NULL]; 271 | return CGRectContainsPoint(shortcutRect, [self convertPoint:location fromView:nil]); 272 | } 273 | 274 | - (BOOL)locationInHintRect:(CGPoint)location 275 | { 276 | CGRect hintRect; 277 | [self getShortcutRect:NULL hintRect:&hintRect]; 278 | return CGRectContainsPoint(hintRect, [self convertPoint:location fromView:nil]); 279 | } 280 | 281 | - (void)mouseDown:(NSEvent *)event 282 | { 283 | if (self.enabled) { 284 | if (self.shortcutValue) { 285 | if (self.recording) { 286 | if ([self locationInHintRect:event.locationInWindow]) { 287 | self.recording = NO; 288 | } 289 | } 290 | else { 291 | if ([self locationInShortcutRect:event.locationInWindow]) { 292 | self.recording = YES; 293 | } 294 | else { 295 | self.shortcutValue = nil; 296 | } 297 | } 298 | } 299 | else { 300 | if (self.recording) { 301 | if ([self locationInHintRect:event.locationInWindow]) { 302 | self.recording = NO; 303 | } 304 | } 305 | else { 306 | self.recording = YES; 307 | } 308 | } 309 | } 310 | else { 311 | [super mouseDown:event]; 312 | } 313 | } 314 | 315 | #pragma mark - Handling mouse over 316 | 317 | - (void)updateTrackingAreas 318 | { 319 | [super updateTrackingAreas]; 320 | 321 | if (_hintArea) { 322 | [self removeTrackingArea:_hintArea]; 323 | _hintArea = nil; 324 | } 325 | 326 | // Forbid hinting if view is disabled 327 | if (!self.enabled) return; 328 | 329 | CGRect hintRect; 330 | [self getShortcutRect:NULL hintRect:&hintRect]; 331 | NSTrackingAreaOptions options = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingAssumeInside); 332 | _hintArea = [[NSTrackingArea alloc] initWithRect:hintRect options:options owner:self userInfo:nil]; 333 | [self addTrackingArea:_hintArea]; 334 | } 335 | 336 | - (void)setHinting:(BOOL)flag 337 | { 338 | if (_hinting != flag) { 339 | _hinting = flag; 340 | [self setNeedsDisplay:YES]; 341 | } 342 | } 343 | 344 | - (void)mouseEntered:(NSEvent *)event 345 | { 346 | self.hinting = YES; 347 | } 348 | 349 | - (void)mouseExited:(NSEvent *)event 350 | { 351 | self.hinting = NO; 352 | } 353 | 354 | void *kUserDataShortcut = &kUserDataShortcut; 355 | void *kUserDataHint = &kUserDataHint; 356 | 357 | - (void)resetToolTips 358 | { 359 | if (_shortcutToolTipTag) { 360 | [self removeToolTip:_shortcutToolTipTag], _shortcutToolTipTag = 0; 361 | } 362 | if (_hintToolTipTag) { 363 | [self removeToolTip:_hintToolTipTag], _hintToolTipTag = 0; 364 | } 365 | 366 | if ((self.shortcutValue == nil) || self.recording || !self.enabled) return; 367 | 368 | CGRect shortcutRect, hintRect; 369 | [self getShortcutRect:&shortcutRect hintRect:&hintRect]; 370 | _shortcutToolTipTag = [self addToolTipRect:shortcutRect owner:self userData:kUserDataShortcut]; 371 | _hintToolTipTag = [self addToolTipRect:hintRect owner:self userData:kUserDataHint]; 372 | } 373 | 374 | - (NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(CGPoint)point userData:(void *)data 375 | { 376 | if (data == kUserDataShortcut) { 377 | return MASLocalizedString(@"Click to record new shortcut", @"Tooltip for non-empty shortcut button"); 378 | } 379 | else if (data == kUserDataHint) { 380 | return MASLocalizedString(@"Delete shortcut", @"Tooltip for hint button near the non-empty shortcut"); 381 | } 382 | return nil; 383 | } 384 | 385 | #pragma mark - Event monitoring 386 | 387 | - (void)activateEventMonitoring:(BOOL)shouldActivate 388 | { 389 | static BOOL isActive = NO; 390 | if (isActive == shouldActivate) return; 391 | isActive = shouldActivate; 392 | 393 | static id eventMonitor = nil; 394 | if (shouldActivate) { 395 | __unsafe_unretained MASShortcutView *weakSelf = self; 396 | NSEventMask eventMask = (NSKeyDownMask | NSFlagsChangedMask); 397 | eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^(NSEvent *event) { 398 | 399 | // Create a shortcut from the event 400 | MASShortcut *shortcut = [MASShortcut shortcutWithEvent:event]; 401 | 402 | // Tab key must pass through. 403 | if (shortcut.keyCode == kVK_Tab){ 404 | return event; 405 | } 406 | 407 | // If the shortcut is a plain Delete or Backspace, clear the current shortcut and cancel recording 408 | if (!shortcut.modifierFlags && ((shortcut.keyCode == kVK_Delete) || (shortcut.keyCode == kVK_ForwardDelete))) { 409 | weakSelf.shortcutValue = nil; 410 | weakSelf.recording = NO; 411 | event = nil; 412 | } 413 | 414 | // If the shortcut is a plain Esc, cancel recording 415 | else if (!shortcut.modifierFlags && shortcut.keyCode == kVK_Escape) { 416 | weakSelf.recording = NO; 417 | event = nil; 418 | } 419 | 420 | // If the shortcut is Cmd-W or Cmd-Q, cancel recording and pass the event through 421 | else if ((shortcut.modifierFlags == NSCommandKeyMask) && (shortcut.keyCode == kVK_ANSI_W || shortcut.keyCode == kVK_ANSI_Q)) { 422 | weakSelf.recording = NO; 423 | } 424 | 425 | else { 426 | // Verify possible shortcut 427 | if (shortcut.keyCodeString.length > 0) { 428 | if ([_shortcutValidator isShortcutValid:shortcut]) { 429 | // Verify that shortcut is not used 430 | NSString *explanation = nil; 431 | if ([_shortcutValidator isShortcutAlreadyTakenBySystem:shortcut explanation:&explanation]) { 432 | // Prevent cancel of recording when Alert window is key 433 | [weakSelf activateResignObserver:NO]; 434 | [weakSelf activateEventMonitoring:NO]; 435 | NSString *format = MASLocalizedString(@"The key combination %@ cannot be used", 436 | @"Title for alert when shortcut is already used"); 437 | NSAlert* alert = [[NSAlert alloc]init]; 438 | alert.alertStyle = NSCriticalAlertStyle; 439 | alert.informativeText = explanation; 440 | alert.messageText = [NSString stringWithFormat:format, shortcut]; 441 | [alert addButtonWithTitle:MASLocalizedString(@"OK", @"Alert button when shortcut is already used")]; 442 | 443 | [alert runModal]; 444 | weakSelf.shortcutPlaceholder = nil; 445 | [weakSelf activateResignObserver:YES]; 446 | [weakSelf activateEventMonitoring:YES]; 447 | } 448 | else { 449 | weakSelf.shortcutValue = shortcut; 450 | weakSelf.recording = NO; 451 | } 452 | } 453 | else { 454 | // Key press with or without SHIFT is not valid input 455 | NSBeep(); 456 | } 457 | } 458 | else { 459 | // User is playing with modifier keys 460 | weakSelf.shortcutPlaceholder = shortcut.modifierFlagsString; 461 | } 462 | event = nil; 463 | } 464 | return event; 465 | }]; 466 | } 467 | else { 468 | [NSEvent removeMonitor:eventMonitor]; 469 | } 470 | } 471 | 472 | - (void)activateResignObserver:(BOOL)shouldActivate 473 | { 474 | static BOOL isActive = NO; 475 | if (isActive == shouldActivate) return; 476 | isActive = shouldActivate; 477 | 478 | static id observer = nil; 479 | NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; 480 | if (shouldActivate) { 481 | __unsafe_unretained MASShortcutView *weakSelf = self; 482 | observer = [notificationCenter addObserverForName:NSWindowDidResignKeyNotification object:self.window 483 | queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) { 484 | weakSelf.recording = NO; 485 | }]; 486 | } 487 | else { 488 | [notificationCenter removeObserver:observer]; 489 | } 490 | } 491 | 492 | #pragma mark Bindings 493 | 494 | // http://tomdalling.com/blog/cocoa/implementing-your-own-cocoa-bindings/ 495 | -(void) propagateValue:(id)value forBinding:(NSString*)binding 496 | { 497 | NSParameterAssert(binding != nil); 498 | 499 | //WARNING: bindingInfo contains NSNull, so it must be accounted for 500 | NSDictionary* bindingInfo = [self infoForBinding:binding]; 501 | if(!bindingInfo) 502 | return; //there is no binding 503 | 504 | //apply the value transformer, if one has been set 505 | NSDictionary* bindingOptions = [bindingInfo objectForKey:NSOptionsKey]; 506 | if(bindingOptions){ 507 | NSValueTransformer* transformer = [bindingOptions valueForKey:NSValueTransformerBindingOption]; 508 | if(!transformer || (id)transformer == [NSNull null]){ 509 | NSString* transformerName = [bindingOptions valueForKey:NSValueTransformerNameBindingOption]; 510 | if(transformerName && (id)transformerName != [NSNull null]){ 511 | transformer = [NSValueTransformer valueTransformerForName:transformerName]; 512 | } 513 | } 514 | 515 | if(transformer && (id)transformer != [NSNull null]){ 516 | if([[transformer class] allowsReverseTransformation]){ 517 | value = [transformer reverseTransformedValue:value]; 518 | } else { 519 | NSLog(@"WARNING: binding \"%@\" has value transformer, but it doesn't allow reverse transformations in %s", binding, __PRETTY_FUNCTION__); 520 | } 521 | } 522 | } 523 | 524 | id boundObject = [bindingInfo objectForKey:NSObservedObjectKey]; 525 | if(!boundObject || boundObject == [NSNull null]){ 526 | NSLog(@"ERROR: NSObservedObjectKey was nil for binding \"%@\" in %s", binding, __PRETTY_FUNCTION__); 527 | return; 528 | } 529 | 530 | NSString* boundKeyPath = [bindingInfo objectForKey:NSObservedKeyPathKey]; 531 | if(!boundKeyPath || (id)boundKeyPath == [NSNull null]){ 532 | NSLog(@"ERROR: NSObservedKeyPathKey was nil for binding \"%@\" in %s", binding, __PRETTY_FUNCTION__); 533 | return; 534 | } 535 | 536 | [boundObject setValue:value forKeyPath:boundKeyPath]; 537 | } 538 | 539 | #pragma mark - Accessibility 540 | 541 | - (BOOL)accessibilityIsIgnored 542 | { 543 | return NO; 544 | } 545 | 546 | - (NSString *)accessibilityHelp 547 | { 548 | return MASLocalizedString(@"To record a new shortcut, click this button, and then type the" 549 | @" new shortcut, or press delete to clear an existing shortcut.", 550 | @"VoiceOver shortcut help"); 551 | } 552 | 553 | - (NSString *)accessibilityLabel 554 | { 555 | NSString* title = _shortcutValue.description ?: @"Empty"; 556 | title = [title stringByAppendingFormat:@" %@", MASLocalizedString(@"keyboard shortcut", @"VoiceOver title")]; 557 | return title; 558 | } 559 | 560 | - (BOOL)accessibilityPerformPress 561 | { 562 | if (self.isRecording == NO) { 563 | self.recording = YES; 564 | return YES; 565 | } 566 | else { 567 | return NO; 568 | } 569 | } 570 | 571 | - (NSString *)accessibilityRole 572 | { 573 | return NSAccessibilityButtonRole; 574 | } 575 | 576 | - (BOOL)acceptsFirstResponder 577 | { 578 | return _acceptsFirstResponder; 579 | } 580 | 581 | - (void)setAcceptsFirstResponder:(BOOL)value 582 | { 583 | _acceptsFirstResponder = value; 584 | } 585 | 586 | - (BOOL)becomeFirstResponder 587 | { 588 | [self setNeedsDisplay:YES]; 589 | return [super becomeFirstResponder]; 590 | } 591 | 592 | - (BOOL)resignFirstResponder 593 | { 594 | [self setNeedsDisplay:YES]; 595 | return [super resignFirstResponder]; 596 | } 597 | 598 | - (void)drawFocusRingMask 599 | { 600 | [_shortcutCell drawFocusRingMaskWithFrame:[self bounds] inView:self]; 601 | } 602 | 603 | - (NSRect)focusRingMaskBounds 604 | { 605 | return [self bounds]; 606 | } 607 | 608 | @end 609 | -------------------------------------------------------------------------------- /Pods/MASShortcut/Framework/Shortcut.h: -------------------------------------------------------------------------------- 1 | #import "MASShortcut.h" 2 | #import "MASShortcutValidator.h" 3 | #import "MASShortcutMonitor.h" 4 | #import "MASShortcutBinder.h" 5 | #import "MASDictionaryTransformer.h" 6 | #import "MASShortcutView.h" 7 | #import "MASShortcutView+Bindings.h" -------------------------------------------------------------------------------- /Pods/MASShortcut/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2013, Vadim Shpakovski 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /Pods/MASShortcut/README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/shpakovski/MASShortcut.svg?branch=master)](https://travis-ci.org/shpakovski/MASShortcut) 2 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 3 | 4 | # Intro 5 | 6 | Some time ago Cocoa developers used a brilliant framework [ShortcutRecorder](http://wafflesoftware.net/shortcut/) for managing keyboard shortcuts in application preferences. However, it became incompatible with the new plugin architecture of Xcode 4. 7 | 8 | The MASShortcut project introduces a modern API and user interface for recording, storing and using system-wide keyboard shortcuts. 9 | 10 | ![Screenshot of the demo project](https://raw.githubusercontent.com/shpakovski/MASShortcut/master/Demo/screenshot.png "This is how the demo looks like") 11 | 12 | Features: 13 | 14 | * Record and display keyboard shortcuts 15 | * Watch for shortcuts and execute actions, system-wide 16 | * A nice, [documented API](http://cocoadocs.org/docsets/MASShortcut/) 17 | * Can be configured to be compatible with Shortcut Recorder 18 | * Can be installed both through CocoaPods and as a Git submodule 19 | * Mac App Store friendly 20 | * Works on OS X 10.6 and up 21 | * Hacking-friendly codebase covered with tests 22 | * Basic accessibility support 23 | 24 | Important features currently missing: 25 | 26 | * Localisation 27 | 28 | Pull requests welcome :) 29 | 30 | # Installation 31 | 32 | You can use [CocoaPods](http://cocoapods.org/), adding the following line to your Podfile: 33 | 34 | pod 'MASShortcut' 35 | 36 | If you want to stick to the 1.x branch, you can use the version smart match operator: 37 | 38 | pod 'MASShortcut', '~> 1' 39 | 40 | You can also install via [Carthage](https://github.com/Carthage/Carthage), or you can use Git submodules and link against the MASShortcut framework manually. 41 | 42 | # Usage 43 | 44 | I hope, it is really easy: 45 | 46 | ```objective-c 47 | #import 48 | 49 | // Drop a custom view into XIB, set its class to MASShortcutView 50 | // and its height to 19. If you select another appearance style, 51 | // look up the correct height values in MASShortcutView.h. 52 | @property (nonatomic, weak) IBOutlet MASShortcutView *shortcutView; 53 | 54 | // Pick a preference key to store the shortcut between launches 55 | static NSString *const kPreferenceGlobalShortcut = @"GlobalShortcut"; 56 | 57 | // Associate the shortcut view with user defaults 58 | self.shortcutView.associatedUserDefaultsKey = kPreferenceGlobalShortcut; 59 | 60 | // Associate the preference key with an action 61 | [[MASShortcutBinder sharedBinder] 62 | bindShortcutWithDefaultsKey:kPreferenceGlobalShortcut 63 | toAction:^{ 64 | // Let me know if you find a better or a more convenient API. 65 | }]; 66 | ``` 67 | 68 | You can see a real usage example in the Demo target. Enjoy! 69 | 70 | # Shortcut Recorder Compatibility 71 | 72 | By default, MASShortcut uses a different User Defaults storage format incompatible with Shortcut Recorder. But it’s easily possible to change that, so that you can replace Shortcut Recorder with MASShortcut without having to migrate the shortcuts previously stored by your apps. There are two parts of the story: 73 | 74 | If you bind the recorder control (`MASShortcutView`) to User defaults, set the Value Transformer field in the Interface Builder to `MASDictionaryTransformer`. This makes sure the shortcuts are written in the Shortcut Recorder format. 75 | 76 | If you use `MASShortcutBinder` to automatically load shortcuts from User Defaults, set the `bindingOptions` accordingly: 77 | 78 | ```objective-c 79 | [[MASShortcutBinder sharedBinder] setBindingOptions:@{NSValueTransformerNameBindingOption:MASDictionaryTransformerName}]; 80 | ``` 81 | 82 | This makes sure that the shortcuts in the Shortcut Recorder format are loaded correctly. 83 | 84 | # Notifications 85 | 86 | By registering for KVO notifications from `NSUserDefaultsController`, you can get a callback whenever a user changes the shortcut, allowing you to perform any UI updates, or other code handling tasks. 87 | 88 | This is just as easy to implement: 89 | 90 | ```objective-c 91 | // Declare an ivar for key path in the user defaults controller 92 | NSString *_observableKeyPath; 93 | 94 | // Make a global context reference 95 | void *kGlobalShortcutContext = &kGlobalShortcutContext; 96 | 97 | // Implement when loading view 98 | _observableKeyPath = [@"values." stringByAppendingString:kPreferenceGlobalShortcut]; 99 | [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:_observableKeyPath 100 | options:NSKeyValueObservingOptionInitial 101 | context:kGlobalShortcutContext]; 102 | 103 | // Capture the KVO change and do something 104 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)obj 105 | change:(NSDictionary *)change context:(void *)ctx 106 | { 107 | if (ctx == kGlobalShortcutContext) { 108 | NSLog(@"Shortcut has changed"); 109 | } 110 | else { 111 | [super observeValueForKeyPath:keyPath ofObject:obj change:change context:ctx]; 112 | } 113 | } 114 | 115 | // Do not forget to remove the observer 116 | [[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self 117 | forKeyPath:_observableKeyPath 118 | context:kGlobalShortcutContext]; 119 | ``` 120 | 121 | # Using in Swift projects 122 | 123 | 1. Install as a Pod using the latest CocoaPods with Swift support. 124 | 2. Create a bridging header file [using the instructions here](http://swiftalicio.us/2014/11/using-cocoapods-from-swift/) 125 | 3. Your bridging header file should contain the following [two](https://github.com/shpakovski/MASShortcut/issues/36) imports: 126 | 127 | ```objective-c 128 | #import 129 | #import 130 | ``` 131 | 132 | # Copyright 133 | 134 | MASShortcut is licensed under the 2-clause BSD license. 135 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - MASShortcut (2.3.1) 3 | 4 | DEPENDENCIES: 5 | - MASShortcut 6 | 7 | SPEC CHECKSUMS: 8 | MASShortcut: 865f14caa35979ded96ca3863dc073c109982db8 9 | 10 | COCOAPODS: 0.38.2 11 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0F0BD4BCA034338A2E7D15D8A1CB7FBB /* MASShortcutValidator.h in Headers */ = {isa = PBXBuildFile; fileRef = 7265DA93477C2AA7E24DAFE8CD521E92 /* MASShortcutValidator.h */; }; 11 | 14F902E9FF0F799CBBC67FCA7996F4D0 /* MASKeyCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 8664727DE4D437C9B37BEC65F739E2D2 /* MASKeyCodes.h */; }; 12 | 16F13D320D4B43D2D7D0AC900CACFBDC /* MASShortcut.h in Headers */ = {isa = PBXBuildFile; fileRef = A044B74326CA1F91C52F252808563481 /* MASShortcut.h */; }; 13 | 214FC6A6B3213477CA5A328376AA58A0 /* MASShortcutView+Bindings.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AEBDB4A40D7B26008CBD9170F89A3CC /* MASShortcutView+Bindings.h */; }; 14 | 25492E5EBF0FE5DC8A779C2A29039907 /* Pods-SplitViewShortcut-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 28B379ACF6CC159427C1C92A80500815 /* Pods-SplitViewShortcut-dummy.m */; }; 15 | 2EAAA00863A07972D72A396C0FDF98D8 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6031F584AE37838C378BF4CC33D063FD /* AppKit.framework */; }; 16 | 3338957B5CA297FBBAEB71FDFC26C4D2 /* MASDictionaryTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = F78409B37EE4B5D6F40BD1485264B0AA /* MASDictionaryTransformer.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; 17 | 44852064C42158D2A2A7EF820E9BBAF5 /* MASShortcutBinder.h in Headers */ = {isa = PBXBuildFile; fileRef = CEA94802F3433CFA5E33BEF2D2818F6A /* MASShortcutBinder.h */; }; 18 | 4556F077447061D1E227BD7D1471E681 /* MASHotKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 186E2A0E54C490D134570794E0E1E6C1 /* MASHotKey.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; 19 | 4947535203334EC79ABAC7B10EFE9A6A /* MASShortcutView.h in Headers */ = {isa = PBXBuildFile; fileRef = 927F885214B3F30C7E304FBC5B93E019 /* MASShortcutView.h */; }; 20 | 5D49184866E8EA84DD468A66FB7EFDE9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 072843709EBBEE15A251499950CB3E15 /* Carbon.framework */; }; 21 | 5E36E1E5A1C13B6A2BFC04306AD99B6B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5467CF67F71CCFB6C9ED8C375EE7EF41 /* Cocoa.framework */; }; 22 | 640AB3F25E7587457C88A99A59A81805 /* MASShortcutBinder.m in Sources */ = {isa = PBXBuildFile; fileRef = 62532C7F5881E91621BD96D6316E77BF /* MASShortcutBinder.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; 23 | 67E2C44B93856A50C1F82AF937BC6774 /* MASShortcutMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B229DDAC8F754A5DEE674917D59FBB5 /* MASShortcutMonitor.h */; }; 24 | 67F1164F0E77B1D0B3CD0DB5EA568AA0 /* MASShortcutMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DC6D6D2FF7C64FCC3B227430BBD394F /* MASShortcutMonitor.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; 25 | 727D26CE848B01E82AEC3D28ECEFFC7D /* MASLocalization.h in Headers */ = {isa = PBXBuildFile; fileRef = D4509C491CB8FEDAE83D83A143A99655 /* MASLocalization.h */; }; 26 | 7AF4B508B5683DF30CCF311AA573CE6D /* MASHotKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 45E032D99CD17B6BCFB885909BD2B426 /* MASHotKey.h */; }; 27 | 812B84208B9085595B2D2AE350A3D16F /* MASShortcut-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 27F693B7FBF43DDAC8928503683A3F34 /* MASShortcut-dummy.m */; }; 28 | 976B25925AAA2D48173F9C25D9C477B8 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5467CF67F71CCFB6C9ED8C375EE7EF41 /* Cocoa.framework */; }; 29 | 9BEF50FE26409E0280AB41586749F774 /* MASLocalization.m in Sources */ = {isa = PBXBuildFile; fileRef = C4C5D2C9FBD953719BC76C4E805A474D /* MASLocalization.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; 30 | C6177989AFD10E02674B990150C17D39 /* MASShortcutValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = A54C93330F342F200D84AAE20B07A01D /* MASShortcutValidator.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; 31 | C9F76D46985CF3EB2874621B5E191BD3 /* MASShortcutView.m in Sources */ = {isa = PBXBuildFile; fileRef = ADD902FA401FAF2619F912E8822D0C5C /* MASShortcutView.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; 32 | E23BC023E8A68C364D75E9B5391BA6F8 /* Shortcut.h in Headers */ = {isa = PBXBuildFile; fileRef = E8273DEFABE333BEBA4FE1DF5B7EE6AF /* Shortcut.h */; }; 33 | E9D2C5F312559FEDEBE4B64A3E01DF39 /* MASDictionaryTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5EEE786C9B4B125461FE0B6D2D78A92E /* MASDictionaryTransformer.h */; }; 34 | F8A59CD7F994C5CC96021BAAED0B3A77 /* MASShortcutView+Bindings.m in Sources */ = {isa = PBXBuildFile; fileRef = F061590215E5085968BDF67AB5300B42 /* MASShortcutView+Bindings.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; 35 | F8FE701B087864B7FCD4AC2B3A0C09C8 /* MASShortcut.m in Sources */ = {isa = PBXBuildFile; fileRef = 3022CA252D3BE4372B42D230EA5938C1 /* MASShortcut.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; 36 | /* End PBXBuildFile section */ 37 | 38 | /* Begin PBXContainerItemProxy section */ 39 | 47D65A17320AFC8F3BA07B876D63D9F6 /* PBXContainerItemProxy */ = { 40 | isa = PBXContainerItemProxy; 41 | containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 42 | proxyType = 1; 43 | remoteGlobalIDString = C55CCA5DB45C7BA3EA89283B8BBD070A; 44 | remoteInfo = MASShortcut; 45 | }; 46 | /* End PBXContainerItemProxy section */ 47 | 48 | /* Begin PBXFileReference section */ 49 | 072843709EBBEE15A251499950CB3E15 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/System/Library/Frameworks/Carbon.framework; sourceTree = DEVELOPER_DIR; }; 50 | 154F9061E02A8DF8E1C437584CFE8387 /* MASShortcut-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MASShortcut-prefix.pch"; sourceTree = ""; }; 51 | 1591324E4F10777909DC0EE744401E88 /* libMASShortcut.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMASShortcut.a; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 186E2A0E54C490D134570794E0E1E6C1 /* MASHotKey.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASHotKey.m; path = Framework/MASHotKey.m; sourceTree = ""; }; 53 | 1DC6D6D2FF7C64FCC3B227430BBD394F /* MASShortcutMonitor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutMonitor.m; path = Framework/MASShortcutMonitor.m; sourceTree = ""; }; 54 | 27F693B7FBF43DDAC8928503683A3F34 /* MASShortcut-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "MASShortcut-dummy.m"; sourceTree = ""; }; 55 | 28B379ACF6CC159427C1C92A80500815 /* Pods-SplitViewShortcut-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-SplitViewShortcut-dummy.m"; sourceTree = ""; }; 56 | 3022CA252D3BE4372B42D230EA5938C1 /* MASShortcut.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcut.m; path = Framework/MASShortcut.m; sourceTree = ""; }; 57 | 30599A9D01ED4B5A6FDB62190B59DD32 /* Pods-SplitViewShortcut-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SplitViewShortcut-resources.sh"; sourceTree = ""; }; 58 | 45E032D99CD17B6BCFB885909BD2B426 /* MASHotKey.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASHotKey.h; path = Framework/MASHotKey.h; sourceTree = ""; }; 59 | 4B1F731C94E7C9363D38938E0A3FCF0B /* Pods-SplitViewShortcut.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SplitViewShortcut.debug.xcconfig"; sourceTree = ""; }; 60 | 4FF715B6B72B42069B9CE8AB204E6CFE /* MASShortcut-Private.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "MASShortcut-Private.xcconfig"; sourceTree = ""; }; 61 | 5467CF67F71CCFB6C9ED8C375EE7EF41 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; }; 62 | 5B229DDAC8F754A5DEE674917D59FBB5 /* MASShortcutMonitor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutMonitor.h; path = Framework/MASShortcutMonitor.h; sourceTree = ""; }; 63 | 5EEE786C9B4B125461FE0B6D2D78A92E /* MASDictionaryTransformer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASDictionaryTransformer.h; path = Framework/MASDictionaryTransformer.h; sourceTree = ""; }; 64 | 6031F584AE37838C378BF4CC33D063FD /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/System/Library/Frameworks/AppKit.framework; sourceTree = DEVELOPER_DIR; }; 65 | 62532C7F5881E91621BD96D6316E77BF /* MASShortcutBinder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutBinder.m; path = Framework/MASShortcutBinder.m; sourceTree = ""; }; 66 | 7265DA93477C2AA7E24DAFE8CD521E92 /* MASShortcutValidator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutValidator.h; path = Framework/MASShortcutValidator.h; sourceTree = ""; }; 67 | 7FD52F01BD52C708C7B4A0C5E2A7EEE8 /* Pods-SplitViewShortcut-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-SplitViewShortcut-acknowledgements.markdown"; sourceTree = ""; }; 68 | 8664727DE4D437C9B37BEC65F739E2D2 /* MASKeyCodes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASKeyCodes.h; path = Framework/MASKeyCodes.h; sourceTree = ""; }; 69 | 8AEBDB4A40D7B26008CBD9170F89A3CC /* MASShortcutView+Bindings.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "MASShortcutView+Bindings.h"; path = "Framework/MASShortcutView+Bindings.h"; sourceTree = ""; }; 70 | 927F885214B3F30C7E304FBC5B93E019 /* MASShortcutView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutView.h; path = Framework/MASShortcutView.h; sourceTree = ""; }; 71 | 9CD92F6CAD73F8CE9354AA6F3CB32249 /* MASShortcut.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MASShortcut.xcconfig; sourceTree = ""; }; 72 | A044B74326CA1F91C52F252808563481 /* MASShortcut.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcut.h; path = Framework/MASShortcut.h; sourceTree = ""; }; 73 | A54C93330F342F200D84AAE20B07A01D /* MASShortcutValidator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutValidator.m; path = Framework/MASShortcutValidator.m; sourceTree = ""; }; 74 | ADD902FA401FAF2619F912E8822D0C5C /* MASShortcutView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutView.m; path = Framework/MASShortcutView.m; sourceTree = ""; }; 75 | B98D570F4AB78F6F145AE8A94861A9EF /* libPods-SplitViewShortcut.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SplitViewShortcut.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 76 | BA6428E9F66FD5A23C0A2E06ED26CD2F /* Podfile */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 77 | BF06D6520E7102E5FFC831E39039E570 /* Pods-SplitViewShortcut-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-SplitViewShortcut-acknowledgements.plist"; sourceTree = ""; }; 78 | C4C5D2C9FBD953719BC76C4E805A474D /* MASLocalization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASLocalization.m; path = Framework/MASLocalization.m; sourceTree = ""; }; 79 | CEA94802F3433CFA5E33BEF2D2818F6A /* MASShortcutBinder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutBinder.h; path = Framework/MASShortcutBinder.h; sourceTree = ""; }; 80 | D4509C491CB8FEDAE83D83A143A99655 /* MASLocalization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASLocalization.h; path = Framework/MASLocalization.h; sourceTree = ""; }; 81 | DE68FDC14DB617AC2DEB249536B24774 /* Pods-SplitViewShortcut.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SplitViewShortcut.release.xcconfig"; sourceTree = ""; }; 82 | E8273DEFABE333BEBA4FE1DF5B7EE6AF /* Shortcut.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Shortcut.h; path = Framework/Shortcut.h; sourceTree = ""; }; 83 | F061590215E5085968BDF67AB5300B42 /* MASShortcutView+Bindings.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "MASShortcutView+Bindings.m"; path = "Framework/MASShortcutView+Bindings.m"; sourceTree = ""; }; 84 | F78409B37EE4B5D6F40BD1485264B0AA /* MASDictionaryTransformer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASDictionaryTransformer.m; path = Framework/MASDictionaryTransformer.m; sourceTree = ""; }; 85 | /* End PBXFileReference section */ 86 | 87 | /* Begin PBXFrameworksBuildPhase section */ 88 | C5886C14B72107949A63C8BB85206A80 /* Frameworks */ = { 89 | isa = PBXFrameworksBuildPhase; 90 | buildActionMask = 2147483647; 91 | files = ( 92 | 2EAAA00863A07972D72A396C0FDF98D8 /* AppKit.framework in Frameworks */, 93 | 5D49184866E8EA84DD468A66FB7EFDE9 /* Carbon.framework in Frameworks */, 94 | 5E36E1E5A1C13B6A2BFC04306AD99B6B /* Cocoa.framework in Frameworks */, 95 | ); 96 | runOnlyForDeploymentPostprocessing = 0; 97 | }; 98 | F1BDF47B1611D968DB4474DC9E9C63E5 /* Frameworks */ = { 99 | isa = PBXFrameworksBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | 976B25925AAA2D48173F9C25D9C477B8 /* Cocoa.framework in Frameworks */, 103 | ); 104 | runOnlyForDeploymentPostprocessing = 0; 105 | }; 106 | /* End PBXFrameworksBuildPhase section */ 107 | 108 | /* Begin PBXGroup section */ 109 | 467ED5A85620396014EA1350E308DBFE /* Pods-SplitViewShortcut */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 7FD52F01BD52C708C7B4A0C5E2A7EEE8 /* Pods-SplitViewShortcut-acknowledgements.markdown */, 113 | BF06D6520E7102E5FFC831E39039E570 /* Pods-SplitViewShortcut-acknowledgements.plist */, 114 | 28B379ACF6CC159427C1C92A80500815 /* Pods-SplitViewShortcut-dummy.m */, 115 | 30599A9D01ED4B5A6FDB62190B59DD32 /* Pods-SplitViewShortcut-resources.sh */, 116 | 4B1F731C94E7C9363D38938E0A3FCF0B /* Pods-SplitViewShortcut.debug.xcconfig */, 117 | DE68FDC14DB617AC2DEB249536B24774 /* Pods-SplitViewShortcut.release.xcconfig */, 118 | ); 119 | name = "Pods-SplitViewShortcut"; 120 | path = "Target Support Files/Pods-SplitViewShortcut"; 121 | sourceTree = ""; 122 | }; 123 | 7DB346D0F39D3F0E887471402A8071AB = { 124 | isa = PBXGroup; 125 | children = ( 126 | BA6428E9F66FD5A23C0A2E06ED26CD2F /* Podfile */, 127 | 96D996393384F21972E2DD81788EE22C /* Frameworks */, 128 | F0CB4CA13BC647AD7E7B617747EED65E /* Pods */, 129 | CCA510CFBEA2D207524CDA0D73C3B561 /* Products */, 130 | 948F56EA54DAC9F9B80D35F29281EC0E /* Targets Support Files */, 131 | ); 132 | sourceTree = ""; 133 | }; 134 | 948F56EA54DAC9F9B80D35F29281EC0E /* Targets Support Files */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | 467ED5A85620396014EA1350E308DBFE /* Pods-SplitViewShortcut */, 138 | ); 139 | name = "Targets Support Files"; 140 | sourceTree = ""; 141 | }; 142 | 96D996393384F21972E2DD81788EE22C /* Frameworks */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | D9C4ADE76DCB8F96503F1A9F8F7F107B /* OS X */, 146 | ); 147 | name = Frameworks; 148 | sourceTree = ""; 149 | }; 150 | AEC60091892493F742D2B9E07C26A267 /* MASShortcut */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 5EEE786C9B4B125461FE0B6D2D78A92E /* MASDictionaryTransformer.h */, 154 | F78409B37EE4B5D6F40BD1485264B0AA /* MASDictionaryTransformer.m */, 155 | 45E032D99CD17B6BCFB885909BD2B426 /* MASHotKey.h */, 156 | 186E2A0E54C490D134570794E0E1E6C1 /* MASHotKey.m */, 157 | 8664727DE4D437C9B37BEC65F739E2D2 /* MASKeyCodes.h */, 158 | D4509C491CB8FEDAE83D83A143A99655 /* MASLocalization.h */, 159 | C4C5D2C9FBD953719BC76C4E805A474D /* MASLocalization.m */, 160 | A044B74326CA1F91C52F252808563481 /* MASShortcut.h */, 161 | 3022CA252D3BE4372B42D230EA5938C1 /* MASShortcut.m */, 162 | CEA94802F3433CFA5E33BEF2D2818F6A /* MASShortcutBinder.h */, 163 | 62532C7F5881E91621BD96D6316E77BF /* MASShortcutBinder.m */, 164 | 5B229DDAC8F754A5DEE674917D59FBB5 /* MASShortcutMonitor.h */, 165 | 1DC6D6D2FF7C64FCC3B227430BBD394F /* MASShortcutMonitor.m */, 166 | 7265DA93477C2AA7E24DAFE8CD521E92 /* MASShortcutValidator.h */, 167 | A54C93330F342F200D84AAE20B07A01D /* MASShortcutValidator.m */, 168 | 927F885214B3F30C7E304FBC5B93E019 /* MASShortcutView.h */, 169 | ADD902FA401FAF2619F912E8822D0C5C /* MASShortcutView.m */, 170 | 8AEBDB4A40D7B26008CBD9170F89A3CC /* MASShortcutView+Bindings.h */, 171 | F061590215E5085968BDF67AB5300B42 /* MASShortcutView+Bindings.m */, 172 | E8273DEFABE333BEBA4FE1DF5B7EE6AF /* Shortcut.h */, 173 | B359AAEC0DF64D5CA97A2AAE21BF5EBE /* Support Files */, 174 | ); 175 | path = MASShortcut; 176 | sourceTree = ""; 177 | }; 178 | B359AAEC0DF64D5CA97A2AAE21BF5EBE /* Support Files */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | 9CD92F6CAD73F8CE9354AA6F3CB32249 /* MASShortcut.xcconfig */, 182 | 4FF715B6B72B42069B9CE8AB204E6CFE /* MASShortcut-Private.xcconfig */, 183 | 27F693B7FBF43DDAC8928503683A3F34 /* MASShortcut-dummy.m */, 184 | 154F9061E02A8DF8E1C437584CFE8387 /* MASShortcut-prefix.pch */, 185 | ); 186 | name = "Support Files"; 187 | path = "../Target Support Files/MASShortcut"; 188 | sourceTree = ""; 189 | }; 190 | CCA510CFBEA2D207524CDA0D73C3B561 /* Products */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | 1591324E4F10777909DC0EE744401E88 /* libMASShortcut.a */, 194 | B98D570F4AB78F6F145AE8A94861A9EF /* libPods-SplitViewShortcut.a */, 195 | ); 196 | name = Products; 197 | sourceTree = ""; 198 | }; 199 | D9C4ADE76DCB8F96503F1A9F8F7F107B /* OS X */ = { 200 | isa = PBXGroup; 201 | children = ( 202 | 6031F584AE37838C378BF4CC33D063FD /* AppKit.framework */, 203 | 072843709EBBEE15A251499950CB3E15 /* Carbon.framework */, 204 | 5467CF67F71CCFB6C9ED8C375EE7EF41 /* Cocoa.framework */, 205 | ); 206 | name = "OS X"; 207 | sourceTree = ""; 208 | }; 209 | F0CB4CA13BC647AD7E7B617747EED65E /* Pods */ = { 210 | isa = PBXGroup; 211 | children = ( 212 | AEC60091892493F742D2B9E07C26A267 /* MASShortcut */, 213 | ); 214 | name = Pods; 215 | sourceTree = ""; 216 | }; 217 | /* End PBXGroup section */ 218 | 219 | /* Begin PBXHeadersBuildPhase section */ 220 | 7514955E996637DDA533A86159428876 /* Headers */ = { 221 | isa = PBXHeadersBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | E9D2C5F312559FEDEBE4B64A3E01DF39 /* MASDictionaryTransformer.h in Headers */, 225 | 7AF4B508B5683DF30CCF311AA573CE6D /* MASHotKey.h in Headers */, 226 | 14F902E9FF0F799CBBC67FCA7996F4D0 /* MASKeyCodes.h in Headers */, 227 | 727D26CE848B01E82AEC3D28ECEFFC7D /* MASLocalization.h in Headers */, 228 | 16F13D320D4B43D2D7D0AC900CACFBDC /* MASShortcut.h in Headers */, 229 | 44852064C42158D2A2A7EF820E9BBAF5 /* MASShortcutBinder.h in Headers */, 230 | 67E2C44B93856A50C1F82AF937BC6774 /* MASShortcutMonitor.h in Headers */, 231 | 0F0BD4BCA034338A2E7D15D8A1CB7FBB /* MASShortcutValidator.h in Headers */, 232 | 214FC6A6B3213477CA5A328376AA58A0 /* MASShortcutView+Bindings.h in Headers */, 233 | 4947535203334EC79ABAC7B10EFE9A6A /* MASShortcutView.h in Headers */, 234 | E23BC023E8A68C364D75E9B5391BA6F8 /* Shortcut.h in Headers */, 235 | ); 236 | runOnlyForDeploymentPostprocessing = 0; 237 | }; 238 | /* End PBXHeadersBuildPhase section */ 239 | 240 | /* Begin PBXNativeTarget section */ 241 | 2FE2B1A6270491576E242471D14B38CA /* Pods-SplitViewShortcut */ = { 242 | isa = PBXNativeTarget; 243 | buildConfigurationList = 400467532FD05B2D1DF5198FB6489F75 /* Build configuration list for PBXNativeTarget "Pods-SplitViewShortcut" */; 244 | buildPhases = ( 245 | EACFF2FDE89DC8DBE234D699F39BE678 /* Sources */, 246 | F1BDF47B1611D968DB4474DC9E9C63E5 /* Frameworks */, 247 | ); 248 | buildRules = ( 249 | ); 250 | dependencies = ( 251 | BD16B5FC6A6FD4BE76FDD8EF1C5D7AAB /* PBXTargetDependency */, 252 | ); 253 | name = "Pods-SplitViewShortcut"; 254 | productName = "Pods-SplitViewShortcut"; 255 | productReference = B98D570F4AB78F6F145AE8A94861A9EF /* libPods-SplitViewShortcut.a */; 256 | productType = "com.apple.product-type.library.static"; 257 | }; 258 | C55CCA5DB45C7BA3EA89283B8BBD070A /* MASShortcut */ = { 259 | isa = PBXNativeTarget; 260 | buildConfigurationList = F6F8AF58F3227A59CA4A509E90C635A8 /* Build configuration list for PBXNativeTarget "MASShortcut" */; 261 | buildPhases = ( 262 | 4C4DE95C76037BBAB93D15D0241ED9FB /* Sources */, 263 | C5886C14B72107949A63C8BB85206A80 /* Frameworks */, 264 | 7514955E996637DDA533A86159428876 /* Headers */, 265 | ); 266 | buildRules = ( 267 | ); 268 | dependencies = ( 269 | ); 270 | name = MASShortcut; 271 | productName = MASShortcut; 272 | productReference = 1591324E4F10777909DC0EE744401E88 /* libMASShortcut.a */; 273 | productType = "com.apple.product-type.library.static"; 274 | }; 275 | /* End PBXNativeTarget section */ 276 | 277 | /* Begin PBXProject section */ 278 | D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { 279 | isa = PBXProject; 280 | attributes = { 281 | LastSwiftUpdateCheck = 0700; 282 | LastUpgradeCheck = 0700; 283 | }; 284 | buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; 285 | compatibilityVersion = "Xcode 3.2"; 286 | developmentRegion = English; 287 | hasScannedForEncodings = 0; 288 | knownRegions = ( 289 | en, 290 | ); 291 | mainGroup = 7DB346D0F39D3F0E887471402A8071AB; 292 | productRefGroup = CCA510CFBEA2D207524CDA0D73C3B561 /* Products */; 293 | projectDirPath = ""; 294 | projectRoot = ""; 295 | targets = ( 296 | C55CCA5DB45C7BA3EA89283B8BBD070A /* MASShortcut */, 297 | 2FE2B1A6270491576E242471D14B38CA /* Pods-SplitViewShortcut */, 298 | ); 299 | }; 300 | /* End PBXProject section */ 301 | 302 | /* Begin PBXSourcesBuildPhase section */ 303 | 4C4DE95C76037BBAB93D15D0241ED9FB /* Sources */ = { 304 | isa = PBXSourcesBuildPhase; 305 | buildActionMask = 2147483647; 306 | files = ( 307 | 3338957B5CA297FBBAEB71FDFC26C4D2 /* MASDictionaryTransformer.m in Sources */, 308 | 4556F077447061D1E227BD7D1471E681 /* MASHotKey.m in Sources */, 309 | 9BEF50FE26409E0280AB41586749F774 /* MASLocalization.m in Sources */, 310 | 812B84208B9085595B2D2AE350A3D16F /* MASShortcut-dummy.m in Sources */, 311 | F8FE701B087864B7FCD4AC2B3A0C09C8 /* MASShortcut.m in Sources */, 312 | 640AB3F25E7587457C88A99A59A81805 /* MASShortcutBinder.m in Sources */, 313 | 67F1164F0E77B1D0B3CD0DB5EA568AA0 /* MASShortcutMonitor.m in Sources */, 314 | C6177989AFD10E02674B990150C17D39 /* MASShortcutValidator.m in Sources */, 315 | F8A59CD7F994C5CC96021BAAED0B3A77 /* MASShortcutView+Bindings.m in Sources */, 316 | C9F76D46985CF3EB2874621B5E191BD3 /* MASShortcutView.m in Sources */, 317 | ); 318 | runOnlyForDeploymentPostprocessing = 0; 319 | }; 320 | EACFF2FDE89DC8DBE234D699F39BE678 /* Sources */ = { 321 | isa = PBXSourcesBuildPhase; 322 | buildActionMask = 2147483647; 323 | files = ( 324 | 25492E5EBF0FE5DC8A779C2A29039907 /* Pods-SplitViewShortcut-dummy.m in Sources */, 325 | ); 326 | runOnlyForDeploymentPostprocessing = 0; 327 | }; 328 | /* End PBXSourcesBuildPhase section */ 329 | 330 | /* Begin PBXTargetDependency section */ 331 | BD16B5FC6A6FD4BE76FDD8EF1C5D7AAB /* PBXTargetDependency */ = { 332 | isa = PBXTargetDependency; 333 | name = MASShortcut; 334 | target = C55CCA5DB45C7BA3EA89283B8BBD070A /* MASShortcut */; 335 | targetProxy = 47D65A17320AFC8F3BA07B876D63D9F6 /* PBXContainerItemProxy */; 336 | }; 337 | /* End PBXTargetDependency section */ 338 | 339 | /* Begin XCBuildConfiguration section */ 340 | 10B2EE21B5D67EE2C819831CCC43832B /* Debug */ = { 341 | isa = XCBuildConfiguration; 342 | buildSettings = { 343 | ALWAYS_SEARCH_USER_PATHS = NO; 344 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 345 | CLANG_CXX_LIBRARY = "libc++"; 346 | CLANG_ENABLE_MODULES = YES; 347 | CLANG_ENABLE_OBJC_ARC = YES; 348 | CLANG_WARN_BOOL_CONVERSION = YES; 349 | CLANG_WARN_CONSTANT_CONVERSION = YES; 350 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; 351 | CLANG_WARN_EMPTY_BODY = YES; 352 | CLANG_WARN_ENUM_CONVERSION = YES; 353 | CLANG_WARN_INT_CONVERSION = YES; 354 | CLANG_WARN_OBJC_ROOT_CLASS = YES; 355 | CLANG_WARN_UNREACHABLE_CODE = YES; 356 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 357 | COPY_PHASE_STRIP = NO; 358 | GCC_C_LANGUAGE_STANDARD = gnu99; 359 | GCC_DYNAMIC_NO_PIC = NO; 360 | GCC_OPTIMIZATION_LEVEL = 0; 361 | GCC_PREPROCESSOR_DEFINITIONS = ( 362 | "DEBUG=1", 363 | "$(inherited)", 364 | ); 365 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 366 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 367 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 368 | GCC_WARN_UNDECLARED_SELECTOR = YES; 369 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 370 | GCC_WARN_UNUSED_FUNCTION = YES; 371 | GCC_WARN_UNUSED_VARIABLE = YES; 372 | MACOSX_DEPLOYMENT_TARGET = 10.11; 373 | ONLY_ACTIVE_ARCH = YES; 374 | STRIP_INSTALLED_PRODUCT = NO; 375 | SYMROOT = "${SRCROOT}/../build"; 376 | }; 377 | name = Debug; 378 | }; 379 | 38620F86A4446FB9EAF581C0776091DE /* Debug */ = { 380 | isa = XCBuildConfiguration; 381 | baseConfigurationReference = 4FF715B6B72B42069B9CE8AB204E6CFE /* MASShortcut-Private.xcconfig */; 382 | buildSettings = { 383 | ENABLE_STRICT_OBJC_MSGSEND = YES; 384 | EXECUTABLE_PREFIX = lib; 385 | GCC_PREFIX_HEADER = "Target Support Files/MASShortcut/MASShortcut-prefix.pch"; 386 | MACOSX_DEPLOYMENT_TARGET = 10.11; 387 | MTL_ENABLE_DEBUG_INFO = YES; 388 | OTHER_LDFLAGS = ""; 389 | OTHER_LIBTOOLFLAGS = ""; 390 | PRODUCT_NAME = "$(TARGET_NAME)"; 391 | SDKROOT = macosx; 392 | }; 393 | name = Debug; 394 | }; 395 | 7C07D96CC7C445E83983A6C6420BC692 /* Release */ = { 396 | isa = XCBuildConfiguration; 397 | buildSettings = { 398 | ALWAYS_SEARCH_USER_PATHS = NO; 399 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 400 | CLANG_CXX_LIBRARY = "libc++"; 401 | CLANG_ENABLE_MODULES = YES; 402 | CLANG_ENABLE_OBJC_ARC = YES; 403 | CLANG_WARN_BOOL_CONVERSION = YES; 404 | CLANG_WARN_CONSTANT_CONVERSION = YES; 405 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; 406 | CLANG_WARN_EMPTY_BODY = YES; 407 | CLANG_WARN_ENUM_CONVERSION = YES; 408 | CLANG_WARN_INT_CONVERSION = YES; 409 | CLANG_WARN_OBJC_ROOT_CLASS = YES; 410 | CLANG_WARN_UNREACHABLE_CODE = YES; 411 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 412 | COPY_PHASE_STRIP = YES; 413 | ENABLE_NS_ASSERTIONS = NO; 414 | GCC_C_LANGUAGE_STANDARD = gnu99; 415 | GCC_PREPROCESSOR_DEFINITIONS = "RELEASE=1"; 416 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 417 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 418 | GCC_WARN_UNDECLARED_SELECTOR = YES; 419 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 420 | GCC_WARN_UNUSED_FUNCTION = YES; 421 | GCC_WARN_UNUSED_VARIABLE = YES; 422 | MACOSX_DEPLOYMENT_TARGET = 10.11; 423 | STRIP_INSTALLED_PRODUCT = NO; 424 | SYMROOT = "${SRCROOT}/../build"; 425 | VALIDATE_PRODUCT = YES; 426 | }; 427 | name = Release; 428 | }; 429 | 94A97E8D3CBA36ED80B1CDFD9765C713 /* Release */ = { 430 | isa = XCBuildConfiguration; 431 | baseConfigurationReference = 4FF715B6B72B42069B9CE8AB204E6CFE /* MASShortcut-Private.xcconfig */; 432 | buildSettings = { 433 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 434 | ENABLE_STRICT_OBJC_MSGSEND = YES; 435 | EXECUTABLE_PREFIX = lib; 436 | GCC_PREFIX_HEADER = "Target Support Files/MASShortcut/MASShortcut-prefix.pch"; 437 | MACOSX_DEPLOYMENT_TARGET = 10.11; 438 | MTL_ENABLE_DEBUG_INFO = NO; 439 | OTHER_LDFLAGS = ""; 440 | OTHER_LIBTOOLFLAGS = ""; 441 | PRODUCT_NAME = "$(TARGET_NAME)"; 442 | SDKROOT = macosx; 443 | }; 444 | name = Release; 445 | }; 446 | B7986C117D79C70522BF01399CCE197F /* Release */ = { 447 | isa = XCBuildConfiguration; 448 | baseConfigurationReference = DE68FDC14DB617AC2DEB249536B24774 /* Pods-SplitViewShortcut.release.xcconfig */; 449 | buildSettings = { 450 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 451 | ENABLE_STRICT_OBJC_MSGSEND = YES; 452 | EXECUTABLE_PREFIX = lib; 453 | MACOSX_DEPLOYMENT_TARGET = 10.11; 454 | MTL_ENABLE_DEBUG_INFO = NO; 455 | OTHER_LDFLAGS = ""; 456 | OTHER_LIBTOOLFLAGS = ""; 457 | PODS_ROOT = "$(SRCROOT)"; 458 | PRODUCT_NAME = "$(TARGET_NAME)"; 459 | SDKROOT = macosx; 460 | SKIP_INSTALL = YES; 461 | }; 462 | name = Release; 463 | }; 464 | D417C1307BF5E57DE48FCC336E1D05F8 /* Debug */ = { 465 | isa = XCBuildConfiguration; 466 | baseConfigurationReference = 4B1F731C94E7C9363D38938E0A3FCF0B /* Pods-SplitViewShortcut.debug.xcconfig */; 467 | buildSettings = { 468 | ENABLE_STRICT_OBJC_MSGSEND = YES; 469 | EXECUTABLE_PREFIX = lib; 470 | MACOSX_DEPLOYMENT_TARGET = 10.11; 471 | MTL_ENABLE_DEBUG_INFO = YES; 472 | OTHER_LDFLAGS = ""; 473 | OTHER_LIBTOOLFLAGS = ""; 474 | PODS_ROOT = "$(SRCROOT)"; 475 | PRODUCT_NAME = "$(TARGET_NAME)"; 476 | SDKROOT = macosx; 477 | SKIP_INSTALL = YES; 478 | }; 479 | name = Debug; 480 | }; 481 | /* End XCBuildConfiguration section */ 482 | 483 | /* Begin XCConfigurationList section */ 484 | 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { 485 | isa = XCConfigurationList; 486 | buildConfigurations = ( 487 | 10B2EE21B5D67EE2C819831CCC43832B /* Debug */, 488 | 7C07D96CC7C445E83983A6C6420BC692 /* Release */, 489 | ); 490 | defaultConfigurationIsVisible = 0; 491 | defaultConfigurationName = Release; 492 | }; 493 | 400467532FD05B2D1DF5198FB6489F75 /* Build configuration list for PBXNativeTarget "Pods-SplitViewShortcut" */ = { 494 | isa = XCConfigurationList; 495 | buildConfigurations = ( 496 | D417C1307BF5E57DE48FCC336E1D05F8 /* Debug */, 497 | B7986C117D79C70522BF01399CCE197F /* Release */, 498 | ); 499 | defaultConfigurationIsVisible = 0; 500 | defaultConfigurationName = Release; 501 | }; 502 | F6F8AF58F3227A59CA4A509E90C635A8 /* Build configuration list for PBXNativeTarget "MASShortcut" */ = { 503 | isa = XCConfigurationList; 504 | buildConfigurations = ( 505 | 38620F86A4446FB9EAF581C0776091DE /* Debug */, 506 | 94A97E8D3CBA36ED80B1CDFD9765C713 /* Release */, 507 | ); 508 | defaultConfigurationIsVisible = 0; 509 | defaultConfigurationName = Release; 510 | }; 511 | /* End XCConfigurationList section */ 512 | }; 513 | rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 514 | } 515 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/raj.xcuserdatad/xcschemes/MASShortcut.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 47 | 48 | 54 | 55 | 57 | 58 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/raj.xcuserdatad/xcschemes/Pods-SplitViewShortcut.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 47 | 48 | 54 | 55 | 57 | 58 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/raj.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MASShortcut.xcscheme 8 | 9 | isShown 10 | 11 | 12 | Pods-SplitViewShortcut.xcscheme 13 | 14 | isShown 15 | 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 2FE2B1A6270491576E242471D14B38CA 21 | 22 | primary 23 | 24 | 25 | C55CCA5DB45C7BA3EA89283B8BBD070A 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Pods/Target Support Files/MASShortcut/MASShortcut-Private.xcconfig: -------------------------------------------------------------------------------- 1 | #include "MASShortcut.xcconfig" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/MASShortcut" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MASShortcut" 4 | OTHER_LDFLAGS = ${MASSHORTCUT_OTHER_LDFLAGS} 5 | PODS_ROOT = ${SRCROOT} 6 | SKIP_INSTALL = YES -------------------------------------------------------------------------------- /Pods/Target Support Files/MASShortcut/MASShortcut-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_MASShortcut : NSObject 3 | @end 4 | @implementation PodsDummy_MASShortcut 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/MASShortcut/MASShortcut-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Pods/Target Support Files/MASShortcut/MASShortcut.xcconfig: -------------------------------------------------------------------------------- 1 | MASSHORTCUT_OTHER_LDFLAGS = -framework "AppKit" -framework "Carbon" -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SplitViewShortcut/Pods-SplitViewShortcut-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## MASShortcut 5 | 6 | Copyright (c) 2012-2013, Vadim Shpakovski 7 | All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without 10 | modification, are permitted provided that the following conditions are met: 11 | 12 | 1. Redistributions of source code must retain the above copyright notice, this 13 | list of conditions and the following disclaimer. 14 | 2. Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | Generated by CocoaPods - http://cocoapods.org 30 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SplitViewShortcut/Pods-SplitViewShortcut-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2012-2013, Vadim Shpakovski 18 | All rights reserved. 19 | 20 | Redistribution and use in source and binary forms, with or without 21 | modification, are permitted provided that the following conditions are met: 22 | 23 | 1. Redistributions of source code must retain the above copyright notice, this 24 | list of conditions and the following disclaimer. 25 | 2. Redistributions in binary form must reproduce the above copyright notice, 26 | this list of conditions and the following disclaimer in the documentation 27 | and/or other materials provided with the distribution. 28 | 29 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 30 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 31 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 32 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 33 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 34 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 35 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 36 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 38 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 | 40 | Title 41 | MASShortcut 42 | Type 43 | PSGroupSpecifier 44 | 45 | 46 | FooterText 47 | Generated by CocoaPods - http://cocoapods.org 48 | Title 49 | 50 | Type 51 | PSGroupSpecifier 52 | 53 | 54 | StringsTable 55 | Acknowledgements 56 | Title 57 | Acknowledgements 58 | 59 | 60 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SplitViewShortcut/Pods-SplitViewShortcut-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_SplitViewShortcut : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_SplitViewShortcut 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SplitViewShortcut/Pods-SplitViewShortcut-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | realpath() { 12 | DIRECTORY="$(cd "${1%/*}" && pwd)" 13 | FILENAME="${1##*/}" 14 | echo "$DIRECTORY/$FILENAME" 15 | } 16 | 17 | install_resource() 18 | { 19 | case $1 in 20 | *.storyboard) 21 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 22 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 23 | ;; 24 | *.xib) 25 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 26 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 27 | ;; 28 | *.framework) 29 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 30 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 31 | echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 32 | rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 33 | ;; 34 | *.xcdatamodel) 35 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" 36 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" 37 | ;; 38 | *.xcdatamodeld) 39 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" 40 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" 41 | ;; 42 | *.xcmappingmodel) 43 | echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\"" 44 | xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm" 45 | ;; 46 | *.xcassets) 47 | ABSOLUTE_XCASSET_FILE=$(realpath "${PODS_ROOT}/$1") 48 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 49 | ;; 50 | /*) 51 | echo "$1" 52 | echo "$1" >> "$RESOURCES_TO_COPY" 53 | ;; 54 | *) 55 | echo "${PODS_ROOT}/$1" 56 | echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" 57 | ;; 58 | esac 59 | } 60 | 61 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 62 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 63 | if [[ "${ACTION}" == "install" ]]; then 64 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 65 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 66 | fi 67 | rm -f "$RESOURCES_TO_COPY" 68 | 69 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 70 | then 71 | case "${TARGETED_DEVICE_FAMILY}" in 72 | 1,2) 73 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 74 | ;; 75 | 1) 76 | TARGET_DEVICE_ARGS="--target-device iphone" 77 | ;; 78 | 2) 79 | TARGET_DEVICE_ARGS="--target-device ipad" 80 | ;; 81 | *) 82 | TARGET_DEVICE_ARGS="--target-device mac" 83 | ;; 84 | esac 85 | 86 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 87 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 88 | while read line; do 89 | if [[ $line != "`realpath $PODS_ROOT`*" ]]; then 90 | XCASSET_FILES+=("$line") 91 | fi 92 | done <<<"$OTHER_XCASSETS" 93 | 94 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 95 | fi 96 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SplitViewShortcut/Pods-SplitViewShortcut.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MASShortcut" 3 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/MASShortcut" 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"MASShortcut" -framework "AppKit" -framework "Carbon" 5 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SplitViewShortcut/Pods-SplitViewShortcut.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MASShortcut" 3 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/MASShortcut" 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"MASShortcut" -framework "AppKit" -framework "Carbon" 5 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UPDATE: BetterTouchTool (http://www.boastr.net/) has added support for this, I recommend you use that instead. 2 | 3 | ![](https://raw.githubusercontent.com/rajington/SplitViewShortcut/master/preview.gif) 4 | 5 | # Split View Shortcut 6 | 7 | This is a hacky but effective solution to the lack of a keyboard shortcut to trigger OS X's new [**Split View**](https://www.apple.com/osx/elcapitan-preview/) action. 8 | 9 | ##### [Download latest release.](https://github.com/rajington/SplitViewShortcut/releases) 10 | 11 | ## What do you mean hacky? 12 | 13 | The utility finds the zoom button using Accessibility, and then creates a click-and-hold mouse event to start Split View. If there's a better way to do this let me know, I'll keep a list here of things I looked for: 14 | 15 | * A method on `NSWindow` to toggle Split View like [`toggleFullScreen`](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSWindow_Class/#//apple_ref/occ/instm/NSWindow/toggleFullScreen:). 16 | 17 | * An accessibility object action for starting Split View found using [`AXUIElementCopyActionNames`](https://developer.apple.com/library/mac/documentation/ApplicationServices/Reference/AXUIElement_header_reference/index.html#//apple_ref/c/func/AXUIElementPerformAction) on the window's zoom button. 18 | 19 | * A way to trigger click-and-hold mouse event other than `sleep` and `CGEventCreateMouseEvent`s 20 | 21 | ## Why not Spectacle or other window management apps? 22 | 23 | [Spectacle](https://github.com/eczarny/spectacle/issues/282) and other apps cannot achieve true fullscreen because the Dock reserves pixels along the edge. They're still a lot more customizable and worth checking out if you haven't though. 24 | 25 | ## Disclaimer 26 | 27 | Use this at your own risk and please submit bugs, features, or pull requests, and I will use those to prioritize my tasks. This is my first Swift project, my first Accessibility scripting project, and also even my first native Desktop application in a long time. There are things like Sparkle and Homebrew I might look into later if necessary. 28 | -------------------------------------------------------------------------------- /SplitViewShortcut.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 357B406B1BB8FBC300A3AD2D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 357B406A1BB8FBC300A3AD2D /* AppDelegate.swift */; }; 11 | 357B406D1BB8FBC300A3AD2D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 357B406C1BB8FBC300A3AD2D /* Assets.xcassets */; }; 12 | 357B40701BB8FBC300A3AD2D /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 357B406E1BB8FBC300A3AD2D /* MainMenu.xib */; }; 13 | E351B458F7973F9105B30BCB /* libPods-SplitViewShortcut.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 54D462292C27C84620A2393F /* libPods-SplitViewShortcut.a */; }; 14 | /* End PBXBuildFile section */ 15 | 16 | /* Begin PBXFileReference section */ 17 | 357B40671BB8FBC300A3AD2D /* SplitViewShortcut.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SplitViewShortcut.app; sourceTree = BUILT_PRODUCTS_DIR; }; 18 | 357B406A1BB8FBC300A3AD2D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 19 | 357B406C1BB8FBC300A3AD2D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 20 | 357B406F1BB8FBC300A3AD2D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 21 | 357B40711BB8FBC300A3AD2D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 22 | 357B40771BB8FD8B00A3AD2D /* Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Bridging-Header.h"; sourceTree = ""; }; 23 | 54D462292C27C84620A2393F /* libPods-SplitViewShortcut.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SplitViewShortcut.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 24 | 78396FE5EAA9D05F3C33648B /* Pods-SplitViewShortcut.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SplitViewShortcut.release.xcconfig"; path = "Pods/Target Support Files/Pods-SplitViewShortcut/Pods-SplitViewShortcut.release.xcconfig"; sourceTree = ""; }; 25 | B6F4A57DEA856E0C706A4761 /* Pods-SplitViewShortcut.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SplitViewShortcut.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SplitViewShortcut/Pods-SplitViewShortcut.debug.xcconfig"; sourceTree = ""; }; 26 | /* End PBXFileReference section */ 27 | 28 | /* Begin PBXFrameworksBuildPhase section */ 29 | 357B40641BB8FBC300A3AD2D /* Frameworks */ = { 30 | isa = PBXFrameworksBuildPhase; 31 | buildActionMask = 2147483647; 32 | files = ( 33 | E351B458F7973F9105B30BCB /* libPods-SplitViewShortcut.a in Frameworks */, 34 | ); 35 | runOnlyForDeploymentPostprocessing = 0; 36 | }; 37 | /* End PBXFrameworksBuildPhase section */ 38 | 39 | /* Begin PBXGroup section */ 40 | 2A86E2A9ED97CA3F459D4A2A /* Frameworks */ = { 41 | isa = PBXGroup; 42 | children = ( 43 | 54D462292C27C84620A2393F /* libPods-SplitViewShortcut.a */, 44 | ); 45 | name = Frameworks; 46 | sourceTree = ""; 47 | }; 48 | 357B405E1BB8FBC300A3AD2D = { 49 | isa = PBXGroup; 50 | children = ( 51 | 357B40691BB8FBC300A3AD2D /* SplitViewShortcut */, 52 | 357B40681BB8FBC300A3AD2D /* Products */, 53 | FE0D173BBABC0A5D29E980C4 /* Pods */, 54 | 2A86E2A9ED97CA3F459D4A2A /* Frameworks */, 55 | ); 56 | sourceTree = ""; 57 | }; 58 | 357B40681BB8FBC300A3AD2D /* Products */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 357B40671BB8FBC300A3AD2D /* SplitViewShortcut.app */, 62 | ); 63 | name = Products; 64 | sourceTree = ""; 65 | }; 66 | 357B40691BB8FBC300A3AD2D /* SplitViewShortcut */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | 357B406A1BB8FBC300A3AD2D /* AppDelegate.swift */, 70 | 357B406C1BB8FBC300A3AD2D /* Assets.xcassets */, 71 | 357B406E1BB8FBC300A3AD2D /* MainMenu.xib */, 72 | 357B40711BB8FBC300A3AD2D /* Info.plist */, 73 | 357B40771BB8FD8B00A3AD2D /* Bridging-Header.h */, 74 | ); 75 | path = SplitViewShortcut; 76 | sourceTree = ""; 77 | }; 78 | FE0D173BBABC0A5D29E980C4 /* Pods */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | B6F4A57DEA856E0C706A4761 /* Pods-SplitViewShortcut.debug.xcconfig */, 82 | 78396FE5EAA9D05F3C33648B /* Pods-SplitViewShortcut.release.xcconfig */, 83 | ); 84 | name = Pods; 85 | sourceTree = ""; 86 | }; 87 | /* End PBXGroup section */ 88 | 89 | /* Begin PBXNativeTarget section */ 90 | 357B40661BB8FBC300A3AD2D /* SplitViewShortcut */ = { 91 | isa = PBXNativeTarget; 92 | buildConfigurationList = 357B40741BB8FBC300A3AD2D /* Build configuration list for PBXNativeTarget "SplitViewShortcut" */; 93 | buildPhases = ( 94 | 5A0FDD48701527B509D6DC2C /* Check Pods Manifest.lock */, 95 | 357B40631BB8FBC300A3AD2D /* Sources */, 96 | 357B40641BB8FBC300A3AD2D /* Frameworks */, 97 | 357B40651BB8FBC300A3AD2D /* Resources */, 98 | BD34E1E57FB5E4C940241598 /* Copy Pods Resources */, 99 | ); 100 | buildRules = ( 101 | ); 102 | dependencies = ( 103 | ); 104 | name = SplitViewShortcut; 105 | productName = SplitViewShortcut; 106 | productReference = 357B40671BB8FBC300A3AD2D /* SplitViewShortcut.app */; 107 | productType = "com.apple.product-type.application"; 108 | }; 109 | /* End PBXNativeTarget section */ 110 | 111 | /* Begin PBXProject section */ 112 | 357B405F1BB8FBC300A3AD2D /* Project object */ = { 113 | isa = PBXProject; 114 | attributes = { 115 | LastUpgradeCheck = 0700; 116 | TargetAttributes = { 117 | 357B40661BB8FBC300A3AD2D = { 118 | CreatedOnToolsVersion = 7.0; 119 | }; 120 | }; 121 | }; 122 | buildConfigurationList = 357B40621BB8FBC300A3AD2D /* Build configuration list for PBXProject "SplitViewShortcut" */; 123 | compatibilityVersion = "Xcode 3.2"; 124 | developmentRegion = English; 125 | hasScannedForEncodings = 0; 126 | knownRegions = ( 127 | en, 128 | Base, 129 | ); 130 | mainGroup = 357B405E1BB8FBC300A3AD2D; 131 | productRefGroup = 357B40681BB8FBC300A3AD2D /* Products */; 132 | projectDirPath = ""; 133 | projectRoot = ""; 134 | targets = ( 135 | 357B40661BB8FBC300A3AD2D /* SplitViewShortcut */, 136 | ); 137 | }; 138 | /* End PBXProject section */ 139 | 140 | /* Begin PBXResourcesBuildPhase section */ 141 | 357B40651BB8FBC300A3AD2D /* Resources */ = { 142 | isa = PBXResourcesBuildPhase; 143 | buildActionMask = 2147483647; 144 | files = ( 145 | 357B406D1BB8FBC300A3AD2D /* Assets.xcassets in Resources */, 146 | 357B40701BB8FBC300A3AD2D /* MainMenu.xib in Resources */, 147 | ); 148 | runOnlyForDeploymentPostprocessing = 0; 149 | }; 150 | /* End PBXResourcesBuildPhase section */ 151 | 152 | /* Begin PBXShellScriptBuildPhase section */ 153 | 5A0FDD48701527B509D6DC2C /* Check Pods Manifest.lock */ = { 154 | isa = PBXShellScriptBuildPhase; 155 | buildActionMask = 2147483647; 156 | files = ( 157 | ); 158 | inputPaths = ( 159 | ); 160 | name = "Check Pods Manifest.lock"; 161 | outputPaths = ( 162 | ); 163 | runOnlyForDeploymentPostprocessing = 0; 164 | shellPath = /bin/sh; 165 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 166 | showEnvVarsInLog = 0; 167 | }; 168 | BD34E1E57FB5E4C940241598 /* Copy Pods Resources */ = { 169 | isa = PBXShellScriptBuildPhase; 170 | buildActionMask = 2147483647; 171 | files = ( 172 | ); 173 | inputPaths = ( 174 | ); 175 | name = "Copy Pods Resources"; 176 | outputPaths = ( 177 | ); 178 | runOnlyForDeploymentPostprocessing = 0; 179 | shellPath = /bin/sh; 180 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SplitViewShortcut/Pods-SplitViewShortcut-resources.sh\"\n"; 181 | showEnvVarsInLog = 0; 182 | }; 183 | /* End PBXShellScriptBuildPhase section */ 184 | 185 | /* Begin PBXSourcesBuildPhase section */ 186 | 357B40631BB8FBC300A3AD2D /* Sources */ = { 187 | isa = PBXSourcesBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | 357B406B1BB8FBC300A3AD2D /* AppDelegate.swift in Sources */, 191 | ); 192 | runOnlyForDeploymentPostprocessing = 0; 193 | }; 194 | /* End PBXSourcesBuildPhase section */ 195 | 196 | /* Begin PBXVariantGroup section */ 197 | 357B406E1BB8FBC300A3AD2D /* MainMenu.xib */ = { 198 | isa = PBXVariantGroup; 199 | children = ( 200 | 357B406F1BB8FBC300A3AD2D /* Base */, 201 | ); 202 | name = MainMenu.xib; 203 | sourceTree = ""; 204 | }; 205 | /* End PBXVariantGroup section */ 206 | 207 | /* Begin XCBuildConfiguration section */ 208 | 357B40721BB8FBC300A3AD2D /* Debug */ = { 209 | isa = XCBuildConfiguration; 210 | buildSettings = { 211 | ALWAYS_SEARCH_USER_PATHS = NO; 212 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 213 | CLANG_CXX_LIBRARY = "libc++"; 214 | CLANG_ENABLE_MODULES = YES; 215 | CLANG_ENABLE_OBJC_ARC = YES; 216 | CLANG_WARN_BOOL_CONVERSION = YES; 217 | CLANG_WARN_CONSTANT_CONVERSION = YES; 218 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 219 | CLANG_WARN_EMPTY_BODY = YES; 220 | CLANG_WARN_ENUM_CONVERSION = YES; 221 | CLANG_WARN_INT_CONVERSION = YES; 222 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 223 | CLANG_WARN_UNREACHABLE_CODE = YES; 224 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 225 | CODE_SIGN_IDENTITY = "-"; 226 | COPY_PHASE_STRIP = NO; 227 | DEBUG_INFORMATION_FORMAT = dwarf; 228 | ENABLE_STRICT_OBJC_MSGSEND = YES; 229 | ENABLE_TESTABILITY = YES; 230 | GCC_C_LANGUAGE_STANDARD = gnu99; 231 | GCC_DYNAMIC_NO_PIC = NO; 232 | GCC_NO_COMMON_BLOCKS = YES; 233 | GCC_OPTIMIZATION_LEVEL = 0; 234 | GCC_PREPROCESSOR_DEFINITIONS = ( 235 | "DEBUG=1", 236 | "$(inherited)", 237 | ); 238 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 239 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 240 | GCC_WARN_UNDECLARED_SELECTOR = YES; 241 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 242 | GCC_WARN_UNUSED_FUNCTION = YES; 243 | GCC_WARN_UNUSED_VARIABLE = YES; 244 | MACOSX_DEPLOYMENT_TARGET = 10.11; 245 | MTL_ENABLE_DEBUG_INFO = YES; 246 | ONLY_ACTIVE_ARCH = YES; 247 | SDKROOT = macosx; 248 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 249 | }; 250 | name = Debug; 251 | }; 252 | 357B40731BB8FBC300A3AD2D /* Release */ = { 253 | isa = XCBuildConfiguration; 254 | buildSettings = { 255 | ALWAYS_SEARCH_USER_PATHS = NO; 256 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 257 | CLANG_CXX_LIBRARY = "libc++"; 258 | CLANG_ENABLE_MODULES = YES; 259 | CLANG_ENABLE_OBJC_ARC = YES; 260 | CLANG_WARN_BOOL_CONVERSION = YES; 261 | CLANG_WARN_CONSTANT_CONVERSION = YES; 262 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 263 | CLANG_WARN_EMPTY_BODY = YES; 264 | CLANG_WARN_ENUM_CONVERSION = YES; 265 | CLANG_WARN_INT_CONVERSION = YES; 266 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 267 | CLANG_WARN_UNREACHABLE_CODE = YES; 268 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 269 | CODE_SIGN_IDENTITY = "-"; 270 | COPY_PHASE_STRIP = NO; 271 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 272 | ENABLE_NS_ASSERTIONS = NO; 273 | ENABLE_STRICT_OBJC_MSGSEND = YES; 274 | GCC_C_LANGUAGE_STANDARD = gnu99; 275 | GCC_NO_COMMON_BLOCKS = YES; 276 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 277 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 278 | GCC_WARN_UNDECLARED_SELECTOR = YES; 279 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 280 | GCC_WARN_UNUSED_FUNCTION = YES; 281 | GCC_WARN_UNUSED_VARIABLE = YES; 282 | MACOSX_DEPLOYMENT_TARGET = 10.11; 283 | MTL_ENABLE_DEBUG_INFO = NO; 284 | SDKROOT = macosx; 285 | }; 286 | name = Release; 287 | }; 288 | 357B40751BB8FBC300A3AD2D /* Debug */ = { 289 | isa = XCBuildConfiguration; 290 | baseConfigurationReference = B6F4A57DEA856E0C706A4761 /* Pods-SplitViewShortcut.debug.xcconfig */; 291 | buildSettings = { 292 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 293 | COMBINE_HIDPI_IMAGES = YES; 294 | INFOPLIST_FILE = SplitViewShortcut/Info.plist; 295 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 296 | PRODUCT_BUNDLE_IDENTIFIER = com.nigam.SplitViewShortcut; 297 | PRODUCT_NAME = "$(TARGET_NAME)"; 298 | SWIFT_OBJC_BRIDGING_HEADER = "SplitViewShortcut/Bridging-Header.h"; 299 | USER_HEADER_SEARCH_PATHS = "Pods/**"; 300 | }; 301 | name = Debug; 302 | }; 303 | 357B40761BB8FBC300A3AD2D /* Release */ = { 304 | isa = XCBuildConfiguration; 305 | baseConfigurationReference = 78396FE5EAA9D05F3C33648B /* Pods-SplitViewShortcut.release.xcconfig */; 306 | buildSettings = { 307 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 308 | COMBINE_HIDPI_IMAGES = YES; 309 | INFOPLIST_FILE = SplitViewShortcut/Info.plist; 310 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 311 | PRODUCT_BUNDLE_IDENTIFIER = com.nigam.SplitViewShortcut; 312 | PRODUCT_NAME = "$(TARGET_NAME)"; 313 | SWIFT_OBJC_BRIDGING_HEADER = "SplitViewShortcut/Bridging-Header.h"; 314 | USER_HEADER_SEARCH_PATHS = "Pods/**"; 315 | }; 316 | name = Release; 317 | }; 318 | /* End XCBuildConfiguration section */ 319 | 320 | /* Begin XCConfigurationList section */ 321 | 357B40621BB8FBC300A3AD2D /* Build configuration list for PBXProject "SplitViewShortcut" */ = { 322 | isa = XCConfigurationList; 323 | buildConfigurations = ( 324 | 357B40721BB8FBC300A3AD2D /* Debug */, 325 | 357B40731BB8FBC300A3AD2D /* Release */, 326 | ); 327 | defaultConfigurationIsVisible = 0; 328 | defaultConfigurationName = Release; 329 | }; 330 | 357B40741BB8FBC300A3AD2D /* Build configuration list for PBXNativeTarget "SplitViewShortcut" */ = { 331 | isa = XCConfigurationList; 332 | buildConfigurations = ( 333 | 357B40751BB8FBC300A3AD2D /* Debug */, 334 | 357B40761BB8FBC300A3AD2D /* Release */, 335 | ); 336 | defaultConfigurationIsVisible = 0; 337 | defaultConfigurationName = Release; 338 | }; 339 | /* End XCConfigurationList section */ 340 | }; 341 | rootObject = 357B405F1BB8FBC300A3AD2D /* Project object */; 342 | } 343 | -------------------------------------------------------------------------------- /SplitViewShortcut.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SplitViewShortcut.xcodeproj/xcuserdata/raj.xcuserdatad/xcschemes/SplitViewShortcut.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /SplitViewShortcut.xcodeproj/xcuserdata/raj.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SplitViewShortcut.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 357B40661BB8FBC300A3AD2D 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /SplitViewShortcut.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SplitViewShortcut.xcworkspace/xcuserdata/raj.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /SplitViewShortcut/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SplitViewShortcut 4 | // 5 | // Created by rajington on 9/28/15. 6 | // 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | @IBOutlet weak var window: NSWindow! 14 | @IBOutlet weak var statusMenu: NSMenu! 15 | @IBOutlet weak var customShortcutView: MASShortcutView! 16 | 17 | let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(NSVariableStatusItemLength) 18 | 19 | func applicationDidFinishLaunching(aNotification: NSNotification) { 20 | window.level = Int(CGWindowLevelKey.MaximumWindowLevelKey.rawValue) 21 | 22 | let icon = NSImage(named: "StatusIcon") 23 | icon?.template = true 24 | statusItem.image = icon 25 | statusItem.menu = statusMenu 26 | 27 | customShortcutView.setAssociatedUserDefaultsKey("shortcut", withTransformerName: NSKeyedUnarchiveFromDataTransformerName) 28 | MASShortcutBinder.sharedBinder().bindShortcutWithDefaultsKey("shortcut", toAction: splitView) 29 | 30 | let previousLaunched = NSUserDefaults.standardUserDefaults().boolForKey("previousLaunched") 31 | if !previousLaunched { 32 | window.makeKeyAndOrderFront(nil) 33 | NSUserDefaults.standardUserDefaults().setBool(true, forKey: "previousLaunched") 34 | } 35 | } 36 | 37 | @IBAction func startSplitView(sender: NSMenuItem) { 38 | splitView() 39 | } 40 | 41 | 42 | @IBAction func changeShortcut(sender: NSMenuItem) { 43 | window.makeKeyAndOrderFront(sender) 44 | } 45 | 46 | func splitView(){ 47 | // get app 48 | let appRef:AXUIElement! = AXUIElementCreateApplication((NSWorkspace.sharedWorkspace().frontmostApplication?.processIdentifier)!).takeRetainedValue() 49 | 50 | // get app's window 51 | var winRef:AnyObject? 52 | if AXUIElementCopyAttributeValue(appRef, kAXFocusedWindowAttribute, &winRef) != AXError.Success {return} 53 | 54 | // get window's zoom button 55 | var zoomRef:AnyObject? 56 | if AXUIElementCopyAttributeValue(winRef as! AXUIElementRef, kAXZoomButtonAttribute, &zoomRef) != AXError.Success {return} 57 | 58 | // get zoom button's position 59 | var position:AnyObject? 60 | if AXUIElementCopyAttributeValue(zoomRef as! AXUIElementRef, kAXPositionAttribute, &position) != AXError.Success {return} 61 | 62 | // get zoom button's position value 63 | var p = CGPoint() 64 | if !AXValueGetValue(position as! AXValue, AXValueType(rawValue: kAXValueCGPointType)!, &p) {return} 65 | 66 | // get zoom button's size 67 | var size:AnyObject? 68 | if AXUIElementCopyAttributeValue(zoomRef as! AXUIElementRef, kAXSizeAttribute, &size) != AXError.Success {return} 69 | 70 | // get zoom button's size value 71 | var s = CGPoint() 72 | if !AXValueGetValue(size as! AXValue, AXValueType(rawValue: kAXValueCGSizeType)!, &s) {return} 73 | 74 | // get zoom button's center 75 | let bounds:CGRect = CGRectMake(p.x, p.y, s.x, s.y) 76 | let center:CGPoint = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds)) 77 | 78 | CGEventPost(CGEventTapLocation.CGHIDEventTap, CGEventCreateMouseEvent(nil, CGEventType.LeftMouseDown, center, CGMouseButton.Left)); 79 | usleep(600000) 80 | CGEventPost(CGEventTapLocation.CGHIDEventTap, CGEventCreateMouseEvent(nil, CGEventType.LeftMouseUp, center, CGMouseButton.Left)); 81 | } 82 | } 83 | 84 | -------------------------------------------------------------------------------- /SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/128.png -------------------------------------------------------------------------------- /SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/16.png -------------------------------------------------------------------------------- /SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/256-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/256-1.png -------------------------------------------------------------------------------- /SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/256.png -------------------------------------------------------------------------------- /SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/32-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/32-1.png -------------------------------------------------------------------------------- /SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/32.png -------------------------------------------------------------------------------- /SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/512-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/512-1.png -------------------------------------------------------------------------------- /SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/512.png -------------------------------------------------------------------------------- /SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/64.png -------------------------------------------------------------------------------- /SplitViewShortcut/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "32-1.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "256-1.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "512-1.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /SplitViewShortcut/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SplitViewShortcut/Assets.xcassets/StatusIcon.imageset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/SplitViewShortcut/Assets.xcassets/StatusIcon.imageset/16.png -------------------------------------------------------------------------------- /SplitViewShortcut/Assets.xcassets/StatusIcon.imageset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/SplitViewShortcut/Assets.xcassets/StatusIcon.imageset/32.png -------------------------------------------------------------------------------- /SplitViewShortcut/Assets.xcassets/StatusIcon.imageset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/SplitViewShortcut/Assets.xcassets/StatusIcon.imageset/64.png -------------------------------------------------------------------------------- /SplitViewShortcut/Assets.xcassets/StatusIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "16.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "32.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "64.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /SplitViewShortcut/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /SplitViewShortcut/Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Bridging-Header.h 3 | // SplitViewShortcut 4 | // 5 | // Created by rajington on 9/28/15. 6 | // 7 | // 8 | 9 | #ifndef Bridging_Header_h 10 | #define Bridging_Header_h 11 | 12 | #import "MASShortcut/Shortcut.h" 13 | 14 | #endif /* Bridging_Header_h */ 15 | -------------------------------------------------------------------------------- /SplitViewShortcut/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | LSUIElement 6 | 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | $(PRODUCT_NAME) 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1 27 | LSMinimumSystemVersion 28 | $(MACOSX_DEPLOYMENT_TARGET) 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /icons/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/icons/1024.png -------------------------------------------------------------------------------- /icons/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/icons/128.png -------------------------------------------------------------------------------- /icons/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/icons/16.png -------------------------------------------------------------------------------- /icons/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/icons/256.png -------------------------------------------------------------------------------- /icons/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/icons/32.png -------------------------------------------------------------------------------- /icons/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/icons/512.png -------------------------------------------------------------------------------- /icons/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/icons/64.png -------------------------------------------------------------------------------- /icons/master.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/icons/master.png -------------------------------------------------------------------------------- /preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajington/SplitViewShortcut/58e9641b85f25da3489c6b90653d03396ea81498/preview.gif --------------------------------------------------------------------------------