diff options
Diffstat (limited to 'Framework/MASShortcut.m')
| -rw-r--r-- | Framework/MASShortcut.m | 116 |
1 files changed, 0 insertions, 116 deletions
diff --git a/Framework/MASShortcut.m b/Framework/MASShortcut.m index 3e1e498..0e834eb 100644 --- a/Framework/MASShortcut.m +++ b/Framework/MASShortcut.m @@ -235,120 +235,4 @@ NSString *const MASShortcutModifierFlags = @"ModifierFlags"; return (count ? [NSString stringWithCharacters:chars length:count] : @""); } -#pragma mark - Validation logic - -- (BOOL)shouldBypass -{ - NSString *codeString = self.keyCodeString; - return (self.modifierFlags == NSCommandKeyMask) && ([codeString isEqualToString:@"W"] || [codeString isEqualToString:@"Q"]); -} - -BOOL MASShortcutAllowsAnyHotkeyWithOptionModifier = NO; - -+ (void)setAllowsAnyHotkeyWithOptionModifier:(BOOL)allow -{ - MASShortcutAllowsAnyHotkeyWithOptionModifier = allow; -} - -+ (BOOL)allowsAnyHotkeyWithOptionModifier -{ - return MASShortcutAllowsAnyHotkeyWithOptionModifier; -} - -- (BOOL)isValid -{ - // Allow any function key with any combination of modifiers - BOOL includesFunctionKey = ((_keyCode == kVK_F1) || (_keyCode == kVK_F2) || (_keyCode == kVK_F3) || (_keyCode == kVK_F4) || - (_keyCode == kVK_F5) || (_keyCode == kVK_F6) || (_keyCode == kVK_F7) || (_keyCode == kVK_F8) || - (_keyCode == kVK_F9) || (_keyCode == kVK_F10) || (_keyCode == kVK_F11) || (_keyCode == kVK_F12) || - (_keyCode == kVK_F13) || (_keyCode == kVK_F14) || (_keyCode == kVK_F15) || (_keyCode == kVK_F16) || - (_keyCode == kVK_F17) || (_keyCode == kVK_F18) || (_keyCode == kVK_F19) || (_keyCode == kVK_F20)); - if (includesFunctionKey) return YES; - - // Do not allow any other key without modifiers - BOOL hasModifierFlags = (_modifierFlags > 0); - if (!hasModifierFlags) return NO; - - // Allow any hotkey containing Control or Command modifier - BOOL includesCommand = ((_modifierFlags & NSCommandKeyMask) > 0); - BOOL includesControl = ((_modifierFlags & NSControlKeyMask) > 0); - if (includesCommand || includesControl) return YES; - - // Allow Option key only in selected cases - BOOL includesOption = ((_modifierFlags & NSAlternateKeyMask) > 0); - if (includesOption) { - - // Always allow Option-Space and Option-Escape because they do not have any bind system commands - if ((_keyCode == kVK_Space) || (_keyCode == kVK_Escape)) return YES; - - // Allow Option modifier with any key even if it will break the system binding - if ([[self class] allowsAnyHotkeyWithOptionModifier]) return YES; - } - - // The hotkey does not have any modifiers or violates system bindings - return NO; -} - -- (BOOL)isKeyEquivalent:(NSString *)keyEquivalent flags:(NSUInteger)flags takenInMenu:(NSMenu *)menu error:(NSError **)outError -{ - for (NSMenuItem *menuItem in menu.itemArray) { - if (menuItem.hasSubmenu && [self isKeyEquivalent:keyEquivalent flags:flags takenInMenu:menuItem.submenu error:outError]) return YES; - - BOOL equalFlags = (MASPickCocoaModifiers(menuItem.keyEquivalentModifierMask) == flags); - BOOL equalHotkeyLowercase = [menuItem.keyEquivalent.lowercaseString isEqualToString:keyEquivalent]; - - // Check if the cases are different, we know ours is lower and that shift is included in our modifiers - // If theirs is capitol, we need to add shift to their modifiers - if (equalHotkeyLowercase && ![menuItem.keyEquivalent isEqualToString:keyEquivalent]) { - equalFlags = (MASPickCocoaModifiers(menuItem.keyEquivalentModifierMask | NSShiftKeyMask) == flags); - } - - if (equalFlags && equalHotkeyLowercase) { - if (outError) { - NSString *format = NSLocalizedString(@"This shortcut cannot be used because it is already used by the menu item ‘%@’.", - @"Message for alert when shortcut is already used"); - NSDictionary *info = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:format, menuItem.title] - forKey:NSLocalizedDescriptionKey]; - *outError = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:info]; - } - return YES; - } - } - return NO; -} - -- (BOOL)isTakenError:(NSError **)outError -{ - CFArrayRef globalHotKeys; - BOOL isTaken = NO; - if (CopySymbolicHotKeys(&globalHotKeys) == noErr) { - - // Enumerate all global hotkeys and check if any of them matches current shortcut - for (CFIndex i = 0, count = CFArrayGetCount(globalHotKeys); i < count; i++) { - CFDictionaryRef hotKeyInfo = CFArrayGetValueAtIndex(globalHotKeys, i); - CFNumberRef code = CFDictionaryGetValue(hotKeyInfo, kHISymbolicHotKeyCode); - CFNumberRef flags = CFDictionaryGetValue(hotKeyInfo, kHISymbolicHotKeyModifiers); - CFNumberRef enabled = CFDictionaryGetValue(hotKeyInfo, kHISymbolicHotKeyEnabled); - - if (([(__bridge NSNumber *)code unsignedIntegerValue] == self.keyCode) && - ([(__bridge NSNumber *)flags unsignedIntegerValue] == self.carbonFlags) && - ([(__bridge NSNumber *)enabled boolValue])) { - - if (outError) { - NSString *description = NSLocalizedString(@"This combination cannot be used because it is already used by a system-wide " - @"keyboard shortcut.\nIf you really want to use this key combination, most shortcuts " - @"can be changed in the Keyboard & Mouse panel in System Preferences.", - @"Message for alert when shortcut is already used by the system"); - NSDictionary *info = [NSDictionary dictionaryWithObject:description forKey:NSLocalizedDescriptionKey]; - *outError = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:info]; - } - isTaken = YES; - break; - } - } - CFRelease(globalHotKeys); - } - return (isTaken || [self isKeyEquivalent:self.keyCodeStringForKeyEquivalent flags:self.modifierFlags takenInMenu:[NSApp mainMenu] error:outError]); -} - @end |
