| Index: chrome/browser/ui/cocoa/accelerators_cocoa.mm | 
| diff --git a/chrome/browser/ui/cocoa/accelerators_cocoa.mm b/chrome/browser/ui/cocoa/accelerators_cocoa.mm | 
| index 154be6f91bda7a0fc604d4a68d84a687ebd5fdfc..b4ee27147603a181e7b2d3599cfc21a5083949e0 100644 | 
| --- a/chrome/browser/ui/cocoa/accelerators_cocoa.mm | 
| +++ b/chrome/browser/ui/cocoa/accelerators_cocoa.mm | 
| @@ -6,53 +6,144 @@ | 
|  | 
| #import <Cocoa/Cocoa.h> | 
|  | 
| +#include "base/logging.h" | 
| #include "base/memory/singleton.h" | 
| #include "chrome/app/chrome_command_ids.h" | 
| #import "ui/base/accelerators/platform_accelerator_cocoa.h" | 
| +#import "ui/base/cocoa/cocoa_event_utils.h" | 
| +#import "ui/events/keycodes/keyboard_code_conversion_mac.h" | 
|  | 
| namespace { | 
|  | 
| +// These accelerators are not associated with a command_id. | 
| +const struct AcceleratorListing { | 
| +  NSUInteger modifiers;  // The Cocoa modifiers. | 
| +  ui::KeyboardCode key_code;  // The key used for cross-platform compatibility. | 
| +} kAcceleratorList [] = { | 
| +  {NSCommandKeyMask | NSAlternateKeyMask, ui::VKEY_H}, | 
| +  {NSCommandKeyMask | NSAlternateKeyMask, ui::VKEY_W}, | 
| +  {NSCommandKeyMask | NSAlternateKeyMask | NSShiftKeyMask, ui::VKEY_V}, | 
| +  {NSCommandKeyMask, ui::VKEY_E}, | 
| +  {NSCommandKeyMask, ui::VKEY_J}, | 
| +  {NSCommandKeyMask, ui::VKEY_OEM_1}, | 
| +  {NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_OEM_1}, | 
| +  {NSCommandKeyMask, ui::VKEY_OEM_COMMA}, | 
| +  {NSCommandKeyMask | NSControlKeyMask, ui::VKEY_SPACE}, | 
| +}; | 
| + | 
| const struct AcceleratorMapping { | 
| int command_id; | 
| -  NSString* key; | 
| -  NSUInteger modifiers; | 
| +  NSUInteger modifiers;  // The Cocoa modifiers. | 
| +  ui::KeyboardCode key_code;  // The key used for cross-platform compatibility. | 
| } kAcceleratorMap[] = { | 
| -  { IDC_CLEAR_BROWSING_DATA, @"\x8", NSCommandKeyMask | NSShiftKeyMask }, | 
| -  { IDC_COPY, @"c", NSCommandKeyMask }, | 
| -  { IDC_CUT, @"x", NSCommandKeyMask }, | 
| -  { IDC_DEV_TOOLS, @"i", NSCommandKeyMask | NSAlternateKeyMask }, | 
| -  { IDC_DEV_TOOLS_CONSOLE, @"j", NSCommandKeyMask | NSAlternateKeyMask }, | 
| -  { IDC_FIND, @"f", NSCommandKeyMask }, | 
| -  { IDC_FULLSCREEN, @"f", NSCommandKeyMask | NSShiftKeyMask }, | 
| -  { IDC_NEW_INCOGNITO_WINDOW, @"n", NSCommandKeyMask | NSShiftKeyMask }, | 
| -  { IDC_NEW_TAB, @"t", NSCommandKeyMask }, | 
| -  { IDC_NEW_WINDOW, @"n", NSCommandKeyMask }, | 
| -  { IDC_OPTIONS, @",", NSCommandKeyMask }, | 
| -  { IDC_PASTE, @"v", NSCommandKeyMask }, | 
| -  { IDC_PRINT, @"p", NSCommandKeyMask }, | 
| -  { IDC_RESTORE_TAB, @"t", NSCommandKeyMask | NSShiftKeyMask }, | 
| -  { IDC_SAVE_PAGE, @"s", NSCommandKeyMask }, | 
| -  { IDC_SHOW_BOOKMARK_BAR, @"b", NSCommandKeyMask | NSShiftKeyMask }, | 
| -  { IDC_SHOW_BOOKMARK_MANAGER, @"b", NSCommandKeyMask | NSAlternateKeyMask }, | 
| -  { IDC_BOOKMARK_PAGE, @"d", NSCommandKeyMask }, | 
| -  { IDC_SHOW_DOWNLOADS, @"j", NSCommandKeyMask | NSShiftKeyMask }, | 
| -  { IDC_SHOW_HISTORY, @"y", NSCommandKeyMask }, | 
| -  { IDC_VIEW_SOURCE, @"u", NSCommandKeyMask | NSAlternateKeyMask }, | 
| -  { IDC_ZOOM_MINUS, @"-", NSCommandKeyMask }, | 
| -  { IDC_ZOOM_PLUS, @"+", NSCommandKeyMask } | 
| +  // Accelerators used in the toolbar menu. | 
| +  {IDC_CLEAR_BROWSING_DATA, NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_BACK}, | 
| +  {IDC_COPY, NSCommandKeyMask, ui::VKEY_C}, | 
| +  {IDC_CUT, NSCommandKeyMask, ui::VKEY_X}, | 
| +  {IDC_DEV_TOOLS, NSCommandKeyMask | NSAlternateKeyMask, ui::VKEY_I}, | 
| +  {IDC_DEV_TOOLS_CONSOLE, NSCommandKeyMask | NSAlternateKeyMask, ui::VKEY_J}, | 
| +  {IDC_FIND, NSCommandKeyMask, ui::VKEY_F}, | 
| +  {IDC_FULLSCREEN, NSCommandKeyMask | NSControlKeyMask, ui::VKEY_F}, | 
| +  {IDC_NEW_INCOGNITO_WINDOW, NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_N}, | 
| +  {IDC_NEW_TAB, NSCommandKeyMask, ui::VKEY_T}, | 
| +  {IDC_NEW_WINDOW, NSCommandKeyMask, ui::VKEY_N}, | 
| +  {IDC_PASTE, NSCommandKeyMask, ui::VKEY_V}, | 
| +  {IDC_PRINT, NSCommandKeyMask, ui::VKEY_P}, | 
| +  {IDC_RESTORE_TAB, NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_T}, | 
| +  {IDC_SAVE_PAGE, NSCommandKeyMask, ui::VKEY_S}, | 
| +  {IDC_SHOW_BOOKMARK_BAR, NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_B}, | 
| +  {IDC_SHOW_BOOKMARK_MANAGER, NSCommandKeyMask | NSAlternateKeyMask, | 
| +   ui::VKEY_B}, | 
| +  {IDC_BOOKMARK_PAGE, NSCommandKeyMask, ui::VKEY_D}, | 
| +  {IDC_SHOW_DOWNLOADS, NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_J}, | 
| +  {IDC_SHOW_HISTORY, NSCommandKeyMask, ui::VKEY_Y}, | 
| +  {IDC_VIEW_SOURCE, NSCommandKeyMask | NSAlternateKeyMask, ui::VKEY_U}, | 
| +  {IDC_ZOOM_MINUS, NSCommandKeyMask, ui::VKEY_OEM_MINUS}, | 
| +  {IDC_ZOOM_PLUS, NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_OEM_PLUS}, | 
| + | 
| +  // Accelerators used in MainMenu.xib, but not the toolbar menu. | 
| +  {IDC_HIDE_APP, NSCommandKeyMask, ui::VKEY_H}, | 
| +  {IDC_EXIT, NSCommandKeyMask, ui::VKEY_Q}, | 
| +  {IDC_OPEN_FILE, NSCommandKeyMask, ui::VKEY_O}, | 
| +  {IDC_FOCUS_LOCATION, NSCommandKeyMask, ui::VKEY_L}, | 
| +  {IDC_CLOSE_WINDOW, NSCommandKeyMask, ui::VKEY_W}, | 
| +  {IDC_EMAIL_PAGE_LOCATION, NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_I}, | 
| +  {IDC_ADVANCED_PRINT, NSCommandKeyMask | NSAlternateKeyMask, ui::VKEY_P}, | 
| +  {IDC_CONTENT_CONTEXT_UNDO, NSCommandKeyMask, ui::VKEY_Z}, | 
| +  {IDC_CONTENT_CONTEXT_REDO, NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_Z}, | 
| +  {IDC_CONTENT_CONTEXT_CUT, NSCommandKeyMask, ui::VKEY_X}, | 
| +  {IDC_CONTENT_CONTEXT_COPY, NSCommandKeyMask, ui::VKEY_C}, | 
| +  {IDC_CONTENT_CONTEXT_PASTE, NSCommandKeyMask, ui::VKEY_V}, | 
| +  {IDC_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE, | 
| +   NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_V}, | 
| +  {IDC_CONTENT_CONTEXT_SELECTALL, NSCommandKeyMask, ui::VKEY_A}, | 
| +  {IDC_FOCUS_SEARCH, NSCommandKeyMask | NSAlternateKeyMask, ui::VKEY_F}, | 
| +  {IDC_FIND_NEXT, NSCommandKeyMask, ui::VKEY_G}, | 
| +  {IDC_FIND_PREVIOUS, NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_G}, | 
| +  {IDC_ZOOM_PLUS, NSCommandKeyMask, ui::VKEY_OEM_PLUS}, | 
| +  {IDC_ZOOM_MINUS, NSCommandKeyMask, ui::VKEY_OEM_MINUS}, | 
| +  {IDC_STOP, NSCommandKeyMask, ui::VKEY_OEM_PERIOD}, | 
| +  {IDC_RELOAD, NSCommandKeyMask, ui::VKEY_R}, | 
| +  {IDC_RELOAD_IGNORING_CACHE, NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_R}, | 
| +  {IDC_PRESENTATION_MODE, NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_F}, | 
| +  {IDC_ZOOM_NORMAL, NSCommandKeyMask, ui::VKEY_0}, | 
| +  {IDC_HOME, NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_H}, | 
| +  {IDC_BACK, NSCommandKeyMask, ui::VKEY_OEM_4}, | 
| +  {IDC_FORWARD, NSCommandKeyMask, ui::VKEY_OEM_6}, | 
| +  {IDC_BOOKMARK_ALL_TABS, NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_D}, | 
| +  {IDC_MINIMIZE_WINDOW, NSCommandKeyMask, ui::VKEY_M}, | 
| +  {IDC_SELECT_NEXT_TAB, NSCommandKeyMask | NSAlternateKeyMask, ui::VKEY_RIGHT}, | 
| +  {IDC_SELECT_PREVIOUS_TAB, NSCommandKeyMask | NSAlternateKeyMask, | 
| +   ui::VKEY_LEFT}, | 
| +  {IDC_TABPOSE, NSCommandKeyMask | NSControlKeyMask, ui::VKEY_T}, | 
| +  {IDC_HELP_PAGE_VIA_MENU, NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_OEM_2}, | 
| }; | 
|  | 
| +// Create a Cocoa platform accelerator given a cross platform |key_code| and | 
| +// the |cocoa_modifiers|. | 
| +scoped_ptr<ui::PlatformAccelerator> PlatformAcceleratorFromKeyCode( | 
| +    ui::KeyboardCode key_code, | 
| +    NSUInteger cocoa_modifiers) { | 
| +  unichar character; | 
| +  unichar char_no_modifiers; | 
| +  int result = ui::MacKeyCodeForWindowsKeyCode( | 
| +      key_code, cocoa_modifiers, &character, &char_no_modifiers); | 
| +  DCHECK(result != -1); | 
| +  NSString* key_equivalent = [NSString stringWithFormat:@"%C", character]; | 
| + | 
| +  return scoped_ptr<ui::PlatformAccelerator>( | 
| +      new ui::PlatformAcceleratorCocoa(key_equivalent, cocoa_modifiers)); | 
| +} | 
| + | 
| +// Create a cross platform accelerator given a cross platform |key_code| and | 
| +// the |cocoa_modifiers|. | 
| +ui::Accelerator AcceleratorFromKeyCode(ui::KeyboardCode key_code, | 
| +                                       NSUInteger cocoa_modifiers) { | 
| +  int cross_platform_modifiers = ui::EventFlagsFromModifiers(cocoa_modifiers); | 
| +  ui::Accelerator accelerator(key_code, cross_platform_modifiers); | 
| + | 
| +  scoped_ptr<ui::PlatformAccelerator> platform_accelerator = | 
| +      PlatformAcceleratorFromKeyCode(key_code, cocoa_modifiers); | 
| +  accelerator.set_platform_accelerator(platform_accelerator.Pass()); | 
| +  return accelerator; | 
| +} | 
| + | 
| }  // namespace | 
|  | 
| AcceleratorsCocoa::AcceleratorsCocoa() { | 
| for (size_t i = 0; i < arraysize(kAcceleratorMap); ++i) { | 
| const AcceleratorMapping& entry = kAcceleratorMap[i]; | 
| -    ui::Accelerator accelerator(ui::VKEY_UNKNOWN, 0); | 
| -    scoped_ptr<ui::PlatformAccelerator> platform_accelerator( | 
| -        new ui::PlatformAcceleratorCocoa(entry.key, entry.modifiers)); | 
| -    accelerator.set_platform_accelerator(platform_accelerator.Pass()); | 
| +    ui::Accelerator accelerator = | 
| +        AcceleratorFromKeyCode(entry.key_code, entry.modifiers); | 
| accelerators_.insert(std::make_pair(entry.command_id, accelerator)); | 
| } | 
| + | 
| +  for (size_t i = 0; i < arraysize(kAcceleratorList); ++i) { | 
| +    const AcceleratorListing& entry = kAcceleratorList[i]; | 
| +    ui::Accelerator accelerator = | 
| +        AcceleratorFromKeyCode(entry.key_code, entry.modifiers); | 
| +    accelerator_vector_.push_back(accelerator); | 
| +  } | 
| } | 
|  | 
| AcceleratorsCocoa::~AcceleratorsCocoa() {} | 
| @@ -69,3 +160,34 @@ const ui::Accelerator* AcceleratorsCocoa::GetAcceleratorForCommand( | 
| return NULL; | 
| return &it->second; | 
| } | 
| + | 
| +const ui::Accelerator* AcceleratorsCocoa::GetAcceleratorForHotKey( | 
| +    NSString* key_equivalent, NSUInteger modifiers) const { | 
| +  for (AcceleratorVector::const_iterator it = accelerator_vector_.begin(); | 
| +       it != accelerator_vector_.end(); | 
| +       ++it) { | 
| +    const ui::Accelerator& accelerator = *it; | 
| +    const ui::PlatformAcceleratorCocoa* platform_accelerator = | 
| +        static_cast<const ui::PlatformAcceleratorCocoa*>( | 
| +            accelerator.platform_accelerator()); | 
| +    unichar character; | 
| +    unichar char_no_modifiers; | 
| +    int result = | 
| +        ui::MacKeyCodeForWindowsKeyCode(accelerator.key_code(), | 
| +                                        platform_accelerator->modifier_mask(), | 
| +                                        &character, | 
| +                                        &char_no_modifiers); | 
| +    if (result == -1) | 
| +      return NULL; | 
| + | 
| +    // Check for a match in the modifiers and key_equivalent. | 
| +    NSUInteger mask = platform_accelerator->modifier_mask(); | 
| +    BOOL maskEqual = | 
| +        (mask == modifiers) || ((mask & (~NSShiftKeyMask)) == modifiers); | 
| +    NSString* string = [NSString stringWithFormat:@"%C", character]; | 
| +    if ([string isEqual:key_equivalent] && maskEqual) | 
| +      return &*it; | 
| +  } | 
| + | 
| +  return NULL; | 
| +} | 
|  |