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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "content/browser/cocoa/system_hotkey_map.h"
#pragma mark - NSDictionary Helper Functions
namespace {
// All 4 following functions return nil if the object doesn't exist, or isn't of
// the right class.
id ObjectForKey(NSDictionary* dict, NSString* key, Class aClass) {
id object = [dict objectForKey:key];
if (![object isKindOfClass:aClass])
return nil;
return object;
}
NSDictionary* DictionaryForKey(NSDictionary* dict, NSString* key) {
return ObjectForKey(dict, key, [NSDictionary class]);
}
NSArray* ArrayForKey(NSDictionary* dict, NSString* key) {
return ObjectForKey(dict, key, [NSArray class]);
}
NSNumber* NumberForKey(NSDictionary* dict, NSString* key) {
return ObjectForKey(dict, key, [NSNumber class]);
}
NSString* StringForKey(NSDictionary* dict, NSString* key) {
return ObjectForKey(dict, key, [NSString class]);
}
} // namespace
#pragma mark - SystemHotkey
namespace content {
struct SystemHotkey {
unsigned short key_code;
NSUInteger modifiers;
};
#pragma mark - SystemHotkeyMap
SystemHotkeyMap::SystemHotkeyMap() {
}
SystemHotkeyMap::~SystemHotkeyMap() {
}
NSDictionary* SystemHotkeyMap::DictionaryFromData(NSData* data) {
if (!data)
return nil;
NSError* error = nil;
NSPropertyListFormat format;
NSDictionary* dictionary =
[NSPropertyListSerialization propertyListWithData:data
options:0
format:&format
error:&error];
if (![dictionary isKindOfClass:[NSDictionary class]])
return nil;
return dictionary;
}
bool SystemHotkeyMap::ParseDictionary(NSDictionary* dictionary) {
system_hotkeys_.clear();
if (!dictionary)
return false;
NSDictionary* hotkey_dictionaries =
DictionaryForKey(dictionary, @"AppleSymbolicHotKeys");
if (!hotkey_dictionaries)
return false;
for (NSString* hotkey_system_effect in [hotkey_dictionaries allKeys]) {
if (![hotkey_system_effect isKindOfClass:[NSString class]])
continue;
NSDictionary* hotkey_dictionary =
[hotkey_dictionaries objectForKey:hotkey_system_effect];
if (![hotkey_dictionary isKindOfClass:[NSDictionary class]])
continue;
NSNumber* enabled = NumberForKey(hotkey_dictionary, @"enabled");
if (!enabled || enabled.boolValue == NO)
continue;
NSDictionary* value = DictionaryForKey(hotkey_dictionary, @"value");
if (!value)
continue;
NSString* type = StringForKey(value, @"type");
if (!type || ![type isEqualToString:@"standard"])
continue;
NSArray* parameters = ArrayForKey(value, @"parameters");
if (!parameters || [parameters count] != 3)
continue;
NSNumber* key_code = [parameters objectAtIndex:1];
if (![key_code isKindOfClass:[NSNumber class]])
continue;
NSNumber* modifiers = [parameters objectAtIndex:2];
if (![modifiers isKindOfClass:[NSNumber class]])
continue;
ReserveHotkey(key_code.unsignedShortValue,
modifiers.unsignedIntegerValue,
hotkey_system_effect);
}
return true;
}
bool SystemHotkeyMap::IsEventReserved(NSEvent* event) const {
return IsHotkeyReserved(event.keyCode, event.modifierFlags);
}
bool SystemHotkeyMap::IsHotkeyReserved(unsigned short key_code,
NSUInteger modifiers) const {
modifiers &= NSDeviceIndependentModifierFlagsMask;
std::vector<SystemHotkey>::const_iterator it;
for (it = system_hotkeys_.begin(); it != system_hotkeys_.end(); ++it) {
if (it->key_code == key_code && it->modifiers == modifiers)
return true;
}
return false;
}
void SystemHotkeyMap::ReserveHotkey(unsigned short key_code,
NSUInteger modifiers,
NSString* system_effect) {
ReserveHotkey(key_code, modifiers);
// If a hotkey exists for toggling through the windows of an application, then
// adding shift to that hotkey toggles through the windows backwards.
if ([system_effect isEqualToString:@"27"])
ReserveHotkey(key_code, modifiers | NSShiftKeyMask);
}
void SystemHotkeyMap::ReserveHotkey(unsigned short key_code,
NSUInteger modifiers) {
// Hotkeys require at least one of control, command, or alternate keys to be
// down.
NSUInteger required_modifiers =
NSControlKeyMask | NSCommandKeyMask | NSAlternateKeyMask;
if ((modifiers & required_modifiers) == 0)
return;
SystemHotkey hotkey;
hotkey.key_code = key_code;
hotkey.modifiers = modifiers;
system_hotkeys_.push_back(hotkey);
}
} // namespace content
|