Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/global_keyboard_shortcuts_mac.h" | 5 #include "chrome/browser/global_keyboard_shortcuts_mac.h" |
| 6 | 6 |
| 7 #import <AppKit/AppKit.h> | 7 #import <AppKit/AppKit.h> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 result = item; | 26 result = item; |
| 27 } | 27 } |
| 28 | 28 |
| 29 if (result) | 29 if (result) |
| 30 break; | 30 break; |
| 31 } | 31 } |
| 32 | 32 |
| 33 return result; | 33 return result; |
| 34 } | 34 } |
| 35 | 35 |
| 36 #if DCHECK_IS_ON() | |
| 37 // The three main shortcut tables have been mostly migrated to | |
| 38 // accelerator_table.cc, and should be not used to remove redundant use. | |
| 39 bool IsMacViews() { | |
| 40 // FIXME(mblsha): What's the best way to check for that, that won't trigger on | |
|
tapted
2016/10/26 08:40:47
We should just move the tables into separate files
themblsha
2016/10/26 17:10:03
The normal tables are also used by the
-[ChromeC
tapted
2016/10/28 04:59:48
I think we can still use ChromeCommandDispatcherDe
themblsha
2016/10/28 17:32:22
That's a great idea and is much simpler than what
| |
| 41 // normal Cocoa builds? | |
| 42 return NSClassFromString(@"NativeWidgetMacNSWindow") != nil; | |
| 43 } | |
| 44 #endif // DCHECK_IS_ON() | |
| 45 | |
| 36 } // namespace | 46 } // namespace |
| 37 | 47 |
| 38 // Basically, there are two kinds of keyboard shortcuts: Ones that should work | 48 // Basically, there are two kinds of keyboard shortcuts: Ones that should work |
| 39 // only if the tab contents is focused (BrowserKeyboardShortcut), and ones that | 49 // only if the tab contents is focused (BrowserKeyboardShortcut), and ones that |
| 40 // should work in all other cases (WindowKeyboardShortcut). In the latter case, | 50 // should work in all other cases (WindowKeyboardShortcut). In the latter case, |
| 41 // we differentiate between shortcuts that are checked before any other view | 51 // we differentiate between shortcuts that are checked before any other view |
| 42 // gets the chance to handle them (WindowKeyboardShortcut) or after all views | 52 // gets the chance to handle them (WindowKeyboardShortcut) or after all views |
| 43 // had a chance but did not handle the keypress event | 53 // had a chance but did not handle the keypress event |
| 44 // (DelayedWindowKeyboardShortcut). | 54 // (DelayedWindowKeyboardShortcut). |
| 45 | 55 |
| 46 const KeyboardShortcutData* GetWindowKeyboardShortcutTable( | 56 const KeyboardShortcutData* GetWindowKeyboardShortcutTable( |
| 47 size_t* num_entries) { | 57 size_t* num_entries) { |
| 58 DCHECK(!IsMacViews()); | |
| 48 static const KeyboardShortcutData keyboard_shortcuts[] = { | 59 static const KeyboardShortcutData keyboard_shortcuts[] = { |
| 49 // cmd shift cntrl option | 60 // cmd shift cntrl option |
| 50 // --- ----- ----- ------ | 61 // --- ----- ----- ------ |
| 51 // '{' / '}' characters should be matched earlier than virtual key code | 62 // '{' / '}' characters should be matched earlier than virtual key code |
| 52 // (therefore we can match alt-8 as '{' on german keyboards). | 63 // (therefore we can match alt-8 as '{' on german keyboards). |
| 53 {true, false, false, false, 0, '}', IDC_SELECT_NEXT_TAB}, | 64 {true, false, false, false, 0, '}', IDC_SELECT_NEXT_TAB}, |
| 54 {true, false, false, false, 0, '{', IDC_SELECT_PREVIOUS_TAB}, | 65 {true, false, false, false, 0, '{', IDC_SELECT_PREVIOUS_TAB}, |
| 55 {false, false, true, false, kVK_PageDown, 0, IDC_SELECT_NEXT_TAB}, | 66 {false, false, true, false, kVK_PageDown, 0, IDC_SELECT_NEXT_TAB}, |
| 56 {false, false, true, false, kVK_Tab, 0, IDC_SELECT_NEXT_TAB}, | 67 {false, false, true, false, kVK_Tab, 0, IDC_SELECT_NEXT_TAB}, |
| 57 {false, false, true, false, kVK_PageUp, 0, IDC_SELECT_PREVIOUS_TAB}, | 68 {false, false, true, false, kVK_PageUp, 0, IDC_SELECT_PREVIOUS_TAB}, |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 79 {true, false, false, true, kVK_ANSI_L, 0, IDC_SHOW_DOWNLOADS}, | 90 {true, false, false, true, kVK_ANSI_L, 0, IDC_SHOW_DOWNLOADS}, |
| 80 }; | 91 }; |
| 81 | 92 |
| 82 *num_entries = arraysize(keyboard_shortcuts); | 93 *num_entries = arraysize(keyboard_shortcuts); |
| 83 | 94 |
| 84 return keyboard_shortcuts; | 95 return keyboard_shortcuts; |
| 85 } | 96 } |
| 86 | 97 |
| 87 const KeyboardShortcutData* GetDelayedWindowKeyboardShortcutTable( | 98 const KeyboardShortcutData* GetDelayedWindowKeyboardShortcutTable( |
| 88 size_t* num_entries) { | 99 size_t* num_entries) { |
| 100 DCHECK(!IsMacViews()); | |
| 89 static const KeyboardShortcutData keyboard_shortcuts[] = { | 101 static const KeyboardShortcutData keyboard_shortcuts[] = { |
| 90 //cmd shift cntrl option | 102 //cmd shift cntrl option |
| 91 //--- ----- ----- ------ | 103 //--- ----- ----- ------ |
| 92 {false, false, false, false, kVK_Escape, 0, IDC_STOP}, | 104 {false, false, false, false, kVK_Escape, 0, IDC_STOP}, |
| 93 }; | 105 }; |
| 94 | 106 |
| 95 *num_entries = arraysize(keyboard_shortcuts); | 107 *num_entries = arraysize(keyboard_shortcuts); |
| 96 | 108 |
| 97 return keyboard_shortcuts; | 109 return keyboard_shortcuts; |
| 98 } | 110 } |
| 99 | 111 |
| 100 const KeyboardShortcutData* GetBrowserKeyboardShortcutTable( | 112 const KeyboardShortcutData* GetBrowserKeyboardShortcutTable( |
| 101 size_t* num_entries) { | 113 size_t* num_entries) { |
| 114 DCHECK(!IsMacViews()); | |
| 102 static const KeyboardShortcutData keyboard_shortcuts[] = { | 115 static const KeyboardShortcutData keyboard_shortcuts[] = { |
| 103 //cmd shift cntrl option | 116 //cmd shift cntrl option |
| 104 //--- ----- ----- ------ | 117 //--- ----- ----- ------ |
| 105 {true, false, false, false, kVK_LeftArrow, 0, IDC_BACK}, | 118 {true, false, false, false, kVK_LeftArrow, 0, IDC_BACK}, |
| 106 {true, false, false, false, kVK_RightArrow, 0, IDC_FORWARD}, | 119 {true, false, false, false, kVK_RightArrow, 0, IDC_FORWARD}, |
| 107 {false, false, false, false, kVK_Delete, 0, IDC_BACKSPACE_BACK}, | 120 {false, false, false, false, kVK_Delete, 0, IDC_BACKSPACE_BACK}, |
| 108 {false, true, false, false, kVK_Delete, 0, IDC_BACKSPACE_FORWARD}, | 121 {false, true, false, false, kVK_Delete, 0, IDC_BACKSPACE_FORWARD}, |
| 109 {true, true, false, false, 0, 'c', IDC_DEV_TOOLS_INSPECT}, | 122 {true, true, false, false, 0, 'c', IDC_DEV_TOOLS_INSPECT}, |
| 110 }; | 123 }; |
| 111 | 124 |
| 112 *num_entries = arraysize(keyboard_shortcuts); | 125 *num_entries = arraysize(keyboard_shortcuts); |
| 113 | 126 |
| 114 return keyboard_shortcuts; | 127 return keyboard_shortcuts; |
| 115 } | 128 } |
| 116 | 129 |
| 130 // Lists shortcuts that are impossible to migrate to accelerator_table.cc | |
| 131 // (crbug.com/25946). | |
| 132 const KeyboardShortcutData* GetMacViewsKeyboardShortcutTable( | |
| 133 size_t* num_entries) { | |
| 134 static const KeyboardShortcutData keyboard_shortcuts[] = { | |
| 135 // cmd shift cntrl option | |
| 136 // --- ----- ----- ------ | |
| 137 // '{' / '}' characters should be matched earlier than virtual key code | |
| 138 // (therefore we can match alt-8 as '{' on german keyboards). | |
| 139 {true, false, false, false, 0, '}', IDC_SELECT_NEXT_TAB}, | |
| 140 {true, false, false, false, 0, '{', IDC_SELECT_PREVIOUS_TAB}, | |
| 141 }; | |
| 142 | |
| 143 *num_entries = arraysize(keyboard_shortcuts); | |
| 144 | |
| 145 return keyboard_shortcuts; | |
| 146 } | |
| 147 | |
| 117 static bool MatchesEventForKeyboardShortcut( | 148 static bool MatchesEventForKeyboardShortcut( |
| 118 const KeyboardShortcutData& shortcut, | 149 const KeyboardShortcutData& shortcut, |
| 119 bool command_key, bool shift_key, bool cntrl_key, bool opt_key, | 150 bool command_key, bool shift_key, bool cntrl_key, bool opt_key, |
| 120 int vkey_code, unichar key_char) { | 151 int vkey_code, unichar key_char) { |
| 121 // Expects that one of |key_char| or |vkey_code| is 0. | 152 // Expects that one of |key_char| or |vkey_code| is 0. |
| 122 DCHECK((shortcut.key_char == 0) ^ (shortcut.vkey_code == 0)); | 153 DCHECK((shortcut.key_char == 0) ^ (shortcut.vkey_code == 0)); |
| 123 if (shortcut.key_char) { | 154 if (shortcut.key_char) { |
| 124 // Shortcuts that have a |key_char| and have |opt_key| set are mistakes, | 155 // Shortcuts that have a |key_char| and have |opt_key| set are mistakes, |
| 125 // since |opt_key| is not checked when there is a |key_char|. | 156 // since |opt_key| is not checked when there is a |key_char|. |
| 126 DCHECK(!shortcut.opt_key); | 157 DCHECK(!shortcut.opt_key); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 | 219 |
| 189 int CommandForBrowserKeyboardShortcut( | 220 int CommandForBrowserKeyboardShortcut( |
| 190 bool command_key, bool shift_key, bool cntrl_key, bool opt_key, | 221 bool command_key, bool shift_key, bool cntrl_key, bool opt_key, |
| 191 int vkey_code, unichar key_char) { | 222 int vkey_code, unichar key_char) { |
| 192 return CommandForKeyboardShortcut(GetBrowserKeyboardShortcutTable, | 223 return CommandForKeyboardShortcut(GetBrowserKeyboardShortcutTable, |
| 193 command_key, shift_key, | 224 command_key, shift_key, |
| 194 cntrl_key, opt_key, vkey_code, | 225 cntrl_key, opt_key, vkey_code, |
| 195 key_char); | 226 key_char); |
| 196 } | 227 } |
| 197 | 228 |
| 198 int CommandForKeyEvent(NSEvent* event) { | 229 int CommandForMacViewsKeyboardShortcut( |
| 230 bool command_key, bool shift_key, bool cntrl_key, bool opt_key, | |
| 231 int vkey_code, unichar key_char) { | |
| 232 return CommandForKeyboardShortcut(GetMacViewsKeyboardShortcutTable, | |
| 233 command_key, shift_key, | |
| 234 cntrl_key, opt_key, vkey_code, | |
| 235 key_char); | |
| 236 } | |
| 237 | |
| 238 int CommandForKeyEvent(NSEvent* event, | |
| 239 int (^get_secondary_shortcuts_block)(bool cmdKey, | |
| 240 bool shiftKey, | |
| 241 bool cntrlKey, | |
| 242 bool optKey, | |
| 243 int keyCode, | |
| 244 unichar keyChar)) { | |
| 199 if ([event type] != NSKeyDown) | 245 if ([event type] != NSKeyDown) |
| 200 return -1; | 246 return -1; |
| 201 | 247 |
| 202 // Look in menu. | 248 // Look in menu. |
| 203 NSMenuItem* item = FindMenuItem(event, [NSApp mainMenu]); | 249 NSMenuItem* item = FindMenuItem(event, [NSApp mainMenu]); |
| 204 if (item && [item action] == @selector(commandDispatch:) && [item tag] > 0) | 250 if (item && [item action] == @selector(commandDispatch:) && [item tag] > 0) |
| 205 return [item tag]; | 251 return [item tag]; |
| 206 | 252 |
| 207 // "Close window" doesn't use the |commandDispatch:| mechanism. Menu items | 253 // "Close window" doesn't use the |commandDispatch:| mechanism. Menu items |
| 208 // that do not correspond to IDC_ constants need no special treatment however, | 254 // that do not correspond to IDC_ constants need no special treatment however, |
| 209 // as they can't be blacklisted in | 255 // as they can't be blacklisted in |
| 210 // |BrowserCommandController::IsReservedCommandOrKey()| anyhow. | 256 // |BrowserCommandController::IsReservedCommandOrKey()| anyhow. |
| 211 if (item && [item action] == @selector(performClose:)) | 257 if (item && [item action] == @selector(performClose:)) |
| 212 return IDC_CLOSE_WINDOW; | 258 return IDC_CLOSE_WINDOW; |
| 213 | 259 |
| 214 // "Exit" doesn't use the |commandDispatch:| mechanism either. | 260 // "Exit" doesn't use the |commandDispatch:| mechanism either. |
| 215 if (item && [item action] == @selector(terminate:)) | 261 if (item && [item action] == @selector(terminate:)) |
| 216 return IDC_EXIT; | 262 return IDC_EXIT; |
| 217 | 263 |
| 218 // Look in secondary keyboard shortcuts. | 264 // Look in secondary keyboard shortcuts. |
| 219 NSUInteger modifiers = [event modifierFlags]; | 265 NSUInteger modifiers = [event modifierFlags]; |
| 220 const bool cmdKey = (modifiers & NSCommandKeyMask) != 0; | 266 const bool cmdKey = (modifiers & NSCommandKeyMask) != 0; |
| 221 const bool shiftKey = (modifiers & NSShiftKeyMask) != 0; | 267 const bool shiftKey = (modifiers & NSShiftKeyMask) != 0; |
| 222 const bool cntrlKey = (modifiers & NSControlKeyMask) != 0; | 268 const bool cntrlKey = (modifiers & NSControlKeyMask) != 0; |
| 223 const bool optKey = (modifiers & NSAlternateKeyMask) != 0; | 269 const bool optKey = (modifiers & NSAlternateKeyMask) != 0; |
| 224 const int keyCode = [event keyCode]; | 270 const int keyCode = [event keyCode]; |
| 225 const unichar keyChar = KeyCharacterForEvent(event); | 271 const unichar keyChar = KeyCharacterForEvent(event); |
| 226 | 272 |
| 227 int cmdNum = CommandForWindowKeyboardShortcut( | 273 return get_secondary_shortcuts_block(cmdKey, shiftKey, cntrlKey, optKey, |
| 228 cmdKey, shiftKey, cntrlKey, optKey, keyCode, keyChar); | 274 keyCode, keyChar); |
| 229 if (cmdNum != -1) | 275 } |
| 230 return cmdNum; | |
| 231 | 276 |
| 232 cmdNum = CommandForBrowserKeyboardShortcut( | 277 int CommandForKeyEvent(NSEvent* event) { |
| 233 cmdKey, shiftKey, cntrlKey, optKey, keyCode, keyChar); | 278 return CommandForKeyEvent( |
| 234 if (cmdNum != -1) | 279 event, ^int(bool cmdKey, bool shiftKey, bool cntrlKey, bool optKey, |
|
tapted
2016/10/26 08:40:47
I don't think this needs to be a block -- there's
themblsha
2016/10/28 17:32:22
Ah, yes, the implicit capturing of blocks. Probabl
| |
| 235 return cmdNum; | 280 int keyCode, unichar keyChar) { |
| 281 int cmdNum = CommandForWindowKeyboardShortcut( | |
| 282 cmdKey, shiftKey, cntrlKey, optKey, keyCode, keyChar); | |
| 283 if (cmdNum != -1) | |
| 284 return cmdNum; | |
| 236 | 285 |
| 237 return -1; | 286 cmdNum = CommandForBrowserKeyboardShortcut(cmdKey, shiftKey, cntrlKey, |
| 287 optKey, keyCode, keyChar); | |
| 288 return cmdNum; | |
| 289 }); | |
| 290 } | |
| 291 | |
| 292 int CommandForKeyEventOnMacViews(NSEvent* event) { | |
| 293 return CommandForKeyEvent( | |
| 294 event, ^int(bool cmdKey, bool shiftKey, bool cntrlKey, bool optKey, | |
| 295 int keyCode, unichar keyChar) { | |
| 296 return CommandForMacViewsKeyboardShortcut(cmdKey, shiftKey, cntrlKey, | |
| 297 optKey, keyCode, keyChar); | |
| 298 }); | |
| 238 } | 299 } |
| 239 | 300 |
| 240 unichar KeyCharacterForEvent(NSEvent* event) { | 301 unichar KeyCharacterForEvent(NSEvent* event) { |
| 241 NSString* eventString = [event charactersIgnoringModifiers]; | 302 NSString* eventString = [event charactersIgnoringModifiers]; |
| 242 NSString* characters = [event characters]; | 303 NSString* characters = [event characters]; |
| 243 | 304 |
| 244 if ([eventString length] != 1) | 305 if ([eventString length] != 1) |
| 245 return 0; | 306 return 0; |
| 246 | 307 |
| 247 if ([characters length] != 1) | 308 if ([characters length] != 1) |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 294 } | 355 } |
| 295 } | 356 } |
| 296 | 357 |
| 297 // opt/alt modifier is set (e.g. on german layout we want '{' for opt-8). | 358 // opt/alt modifier is set (e.g. on german layout we want '{' for opt-8). |
| 298 if ([event modifierFlags] & NSAlternateKeyMask) | 359 if ([event modifierFlags] & NSAlternateKeyMask) |
| 299 return rawChar; | 360 return rawChar; |
| 300 } | 361 } |
| 301 | 362 |
| 302 return noModifiersChar; | 363 return noModifiersChar; |
| 303 } | 364 } |
| OLD | NEW |