| 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 <AppKit/NSEvent.h> | 5 #import <AppKit/AppKit.h> |
| 6 #include <Carbon/Carbon.h> | 6 #include <Carbon/Carbon.h> |
| 7 | 7 |
| 8 #include "chrome/browser/global_keyboard_shortcuts_mac.h" | 8 #include "chrome/browser/global_keyboard_shortcuts_mac.h" |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "chrome/app/chrome_command_ids.h" | 12 #include "chrome/app/chrome_command_ids.h" |
| 13 #import "chrome/browser/ui/cocoa/nsmenuitem_additions.h" |
| 14 |
| 15 namespace { |
| 16 |
| 17 // Returns the menu item associated with |key| in |menu|, or nil if not found. |
| 18 NSMenuItem* FindMenuItem(NSEvent* key, NSMenu* menu) { |
| 19 NSMenuItem* result = nil; |
| 20 |
| 21 for (NSMenuItem* item in [menu itemArray]) { |
| 22 NSMenu* submenu = [item submenu]; |
| 23 if (submenu) { |
| 24 if (submenu != [NSApp servicesMenu]) |
| 25 result = FindMenuItem(key, submenu); |
| 26 } else if ([item cr_firesForKeyEventIfEnabled:key]) { |
| 27 result = item; |
| 28 } |
| 29 |
| 30 if (result) |
| 31 break; |
| 32 } |
| 33 |
| 34 return result; |
| 35 } |
| 36 |
| 37 } // namespace |
| 13 | 38 |
| 14 // Basically, there are two kinds of keyboard shortcuts: Ones that should work | 39 // Basically, there are two kinds of keyboard shortcuts: Ones that should work |
| 15 // only if the tab contents is focused (BrowserKeyboardShortcut), and ones that | 40 // only if the tab contents is focused (BrowserKeyboardShortcut), and ones that |
| 16 // should work in all other cases (WindowKeyboardShortcut). In the latter case, | 41 // should work in all other cases (WindowKeyboardShortcut). In the latter case, |
| 17 // we differentiate between shortcuts that are checked before any other view | 42 // we differentiate between shortcuts that are checked before any other view |
| 18 // gets the chance to handle them (WindowKeyboardShortcut) or after all views | 43 // gets the chance to handle them (WindowKeyboardShortcut) or after all views |
| 19 // had a chance but did not handle the keypress event | 44 // had a chance but did not handle the keypress event |
| 20 // (DelayedWindowKeyboardShortcut). | 45 // (DelayedWindowKeyboardShortcut). |
| 21 | 46 |
| 22 const KeyboardShortcutData* GetWindowKeyboardShortcutTable( | 47 const KeyboardShortcutData* GetWindowKeyboardShortcutTable( |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 | 187 |
| 163 int CommandForBrowserKeyboardShortcut( | 188 int CommandForBrowserKeyboardShortcut( |
| 164 bool command_key, bool shift_key, bool cntrl_key, bool opt_key, | 189 bool command_key, bool shift_key, bool cntrl_key, bool opt_key, |
| 165 int vkey_code, unichar key_char) { | 190 int vkey_code, unichar key_char) { |
| 166 return CommandForKeyboardShortcut(GetBrowserKeyboardShortcutTable, | 191 return CommandForKeyboardShortcut(GetBrowserKeyboardShortcutTable, |
| 167 command_key, shift_key, | 192 command_key, shift_key, |
| 168 cntrl_key, opt_key, vkey_code, | 193 cntrl_key, opt_key, vkey_code, |
| 169 key_char); | 194 key_char); |
| 170 } | 195 } |
| 171 | 196 |
| 197 int CommandForKeyEvent(NSEvent* event) { |
| 198 if ([event type] != NSKeyDown) |
| 199 return -1; |
| 200 |
| 201 // Look in menu. |
| 202 NSMenuItem* item = FindMenuItem(event, [NSApp mainMenu]); |
| 203 if (item && [item action] == @selector(commandDispatch:) && [item tag] > 0) |
| 204 return [item tag]; |
| 205 |
| 206 // "Close window" doesn't use the |commandDispatch:| mechanism. Menu items |
| 207 // that do not correspond to IDC_ constants need no special treatment however, |
| 208 // as they can't be blacklisted in |
| 209 // |BrowserCommandController::IsReservedCommandOrKey()| anyhow. |
| 210 if (item && [item action] == @selector(performClose:)) |
| 211 return IDC_CLOSE_WINDOW; |
| 212 |
| 213 // "Exit" doesn't use the |commandDispatch:| mechanism either. |
| 214 if (item && [item action] == @selector(terminate:)) |
| 215 return IDC_EXIT; |
| 216 |
| 217 // Look in secondary keyboard shortcuts. |
| 218 NSUInteger modifiers = [event modifierFlags]; |
| 219 const bool cmdKey = (modifiers & NSCommandKeyMask) != 0; |
| 220 const bool shiftKey = (modifiers & NSShiftKeyMask) != 0; |
| 221 const bool cntrlKey = (modifiers & NSControlKeyMask) != 0; |
| 222 const bool optKey = (modifiers & NSAlternateKeyMask) != 0; |
| 223 const int keyCode = [event keyCode]; |
| 224 const unichar keyChar = KeyCharacterForEvent(event); |
| 225 |
| 226 int cmdNum = CommandForWindowKeyboardShortcut( |
| 227 cmdKey, shiftKey, cntrlKey, optKey, keyCode, keyChar); |
| 228 if (cmdNum != -1) |
| 229 return cmdNum; |
| 230 |
| 231 cmdNum = CommandForBrowserKeyboardShortcut( |
| 232 cmdKey, shiftKey, cntrlKey, optKey, keyCode, keyChar); |
| 233 if (cmdNum != -1) |
| 234 return cmdNum; |
| 235 |
| 236 return -1; |
| 237 } |
| 238 |
| 172 unichar KeyCharacterForEvent(NSEvent* event) { | 239 unichar KeyCharacterForEvent(NSEvent* event) { |
| 173 NSString* eventString = [event charactersIgnoringModifiers]; | 240 NSString* eventString = [event charactersIgnoringModifiers]; |
| 174 NSString* characters = [event characters]; | 241 NSString* characters = [event characters]; |
| 175 | 242 |
| 176 if ([eventString length] != 1) | 243 if ([eventString length] != 1) |
| 177 return 0; | 244 return 0; |
| 178 | 245 |
| 179 if ([characters length] != 1) | 246 if ([characters length] != 1) |
| 180 return [eventString characterAtIndex:0]; | 247 return [eventString characterAtIndex:0]; |
| 181 | 248 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 } | 293 } |
| 227 } | 294 } |
| 228 | 295 |
| 229 // opt/alt modifier is set (e.g. on german layout we want '{' for opt-8). | 296 // opt/alt modifier is set (e.g. on german layout we want '{' for opt-8). |
| 230 if ([event modifierFlags] & NSAlternateKeyMask) | 297 if ([event modifierFlags] & NSAlternateKeyMask) |
| 231 return rawChar; | 298 return rawChar; |
| 232 } | 299 } |
| 233 | 300 |
| 234 return noModifiersChar; | 301 return noModifiersChar; |
| 235 } | 302 } |
| OLD | NEW |