This doc is useful if you need to:
Many Mac apps define hotkeys in nib files. We configure them in code.
Hotkeys populate Chrome‘s menus but we don’t use the normal AppKit machinery to trigger their commands. Websites can override most hotkeys, which means we want to sometimes defer first to the renderer before falling back on a command in the menus.
- [ChromeCommandDispatcherDelegate prePerformKeyEquivalent:window:]
- [RenderWidgetHostViewCocoa performKeyEquivalent:]
NO
for any system-reserved hotkeys per the SystemHotkeyMap-keyEvent:wasKeyEquivalent:
- [RenderWidgetHostViewCocoa keyEvent:wasKeyEquivalent:]
_hostHelper->ForwardKeyboardEventWithCommands()
, which gives the website a chance to consume them- [CommandDispatcher redispatchKeyEvent:]
- [ChromeCommandDispatcherDelegate postPerformKeyEquivalent:window:isRedispatch:]
CommandForKeyEvent()
to locate the NSMenuItem with the corresponding hotkey and executes its command cr_firesForKeyEquivalentEvent:
on each menu item until it finds one with the same hotkeycr_firesForKeyEquivalentEvent:
on a set of invisible NSMenuItems that have been assigned the hidden hotkeys - [NSMenuItem cr_firesForKeyEquivalentEvent:]
YES
if the menu item‘s hotkey matches the event’scharacters
, charactersIgnoringModifiers
, and virtual keyCode
to decide if they matchkVK_ANSI_1
through kVK_ANSI_0
), this method matches the event to the hotkeys that select a window tab (⌘1, etc.), regardless of the actual characters
or charactersIgnoringModifiers
in the event kVK_Return
is the virtual keycode for the last key in the fourth row from the top in the US keyboard layoutkVK_ANSI_A
is the virtual keycode for the key next to ‘Caps Lock’ in the US keyboard layoutKeyboardCodeFromKeyCode()
and MacKeyCodeForWindowsKeyCode()
translate between the two worldsVKEY_LSHIFT
and VKEY_RSHIFT
are ‘located’ keyboard codes while VKEY_SHIFT
is their non-located representationWhen debugging new hotkey / keycode issues, the following fixed bugs may help suggest a place to start.
The default hotkey assignments for ⌘[ and ⌘], which select the “next” and “previous” tabs, respectively, needed to be swapped for RTL users. These hotkey definitions live in AcceleratorsCocoa(), which sets up the mapping of Chrome commands to hotkeys. After checking for RTL, the code exchanged the hotkey assignments.
In many non-US keyboard mappings, [hotkeyEvent charactersIgnoringModifiers]
returns a non-ASCII character while [hotkeyEvent characters]
returns an ASCII character. In these situations, as a quick hack we use the ASCII character string to determine which hotkey the user is triggering. Some keys in some non-US keyboard mappings, however, return ASCII for both -characters and -charactersIgnoringModifiers. This is the case for the kVK_ANSI_Q
key in the Hebrew layout. As a result, pressing ⌘Q in the layout resulted in a ⌘\ hotkey event. No code looks for ⌘, and the original event filtered down to a layer that processed the ⌘Q correctly, but without the “Warn Before Quitting” check.
The solution was to check for this special “Q” / "" combination in [NSMenuItem(ChromeAdditions) cr_firesForKeyEquivalentEvent:]
and interpret the event as ⌘Q.
Chrome Mac interprets ⌘kVK_ANSI_1
through ⌘kVK_ANSI_0
as a tab switch hotkey. However, certain flavors of Dvorak don't generate numbers from the numbered ANSI keys. For example, kVK_ANSI_8
generates a “p”, so ⌘kVK_ANSI_8
should be interpreted as ⌘P (Print) but instead switched the browser to the eighth tab.
The solution was to add an exception for the Dvorak keyboards in [NSMenuItem(ChromeAdditions) cr_firesForKeyEquivalentEvent:]
.