| Index: chrome/browser/ui/views/accelerator_table.cc
|
| diff --git a/chrome/browser/ui/views/accelerator_table.cc b/chrome/browser/ui/views/accelerator_table.cc
|
| index f674d5a8f92abd8abc18a0c07fd5333fe0b799c3..a250effe5bc4af6d10f7ff3f0d5487d83e6b130d 100644
|
| --- a/chrome/browser/ui/views/accelerator_table.cc
|
| +++ b/chrome/browser/ui/views/accelerator_table.cc
|
| @@ -6,6 +6,11 @@
|
|
|
| #include <stddef.h>
|
|
|
| +#include <algorithm>
|
| +#include <initializer_list>
|
| +#include <set>
|
| +#include <tuple>
|
| +
|
| #include "base/macros.h"
|
| #include "build/build_config.h"
|
| #include "chrome/app/chrome_command_ids.h"
|
| @@ -22,30 +27,33 @@ namespace {
|
| // For many commands, the Mac equivalent uses Cmd instead of Ctrl. We only need
|
| // to list the ones that do not have a key equivalent in the main menu, i.e.
|
| // only the ones in global_keyboard_shortcuts_mac.mm.
|
| -// TODO(jackhou): If-def out the accelerators that should not be on Mac.
|
| #if defined(OS_MACOSX)
|
| const ui::EventFlags kPlatformModifier = ui::EF_COMMAND_DOWN;
|
| #else
|
| const ui::EventFlags kPlatformModifier = ui::EF_CONTROL_DOWN;
|
| #endif
|
|
|
| -// NOTE: Keep this list in the same (mostly-alphabetical) order as
|
| -// the Windows accelerators in ../../app/chrome_dll.rc.
|
| -// Do not use Ctrl-Alt as a shortcut modifier, as it is used by i18n keyboards:
|
| -// http://blogs.msdn.com/b/oldnewthing/archive/2004/03/29/101121.aspx
|
| -const AcceleratorMapping kAcceleratorMap[] = {
|
| +} // namespace
|
| +
|
| +std::vector<AcceleratorMapping> GetUnfilteredAcceleratorListForTesting() {
|
| + // NOTE: Keep this list in the same (mostly-alphabetical) order as the Windows
|
| + // accelerators in ../../app/chrome_dll.rc.
|
| + // Do not use Ctrl-Alt as a shortcut modifier, as it is used by i18n
|
| + // keyboards:
|
| + // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/29/101121.aspx
|
| + return {
|
| { ui::VKEY_LEFT, ui::EF_ALT_DOWN, IDC_BACK },
|
| { ui::VKEY_BACK, ui::EF_NONE, IDC_BACKSPACE_BACK },
|
| - { ui::VKEY_D, ui::EF_CONTROL_DOWN, IDC_BOOKMARK_PAGE },
|
| - { ui::VKEY_D, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
|
| + { ui::VKEY_D, kPlatformModifier, IDC_BOOKMARK_PAGE },
|
| + { ui::VKEY_D, ui::EF_SHIFT_DOWN | kPlatformModifier,
|
| IDC_BOOKMARK_ALL_TABS },
|
| - { ui::VKEY_W, ui::EF_CONTROL_DOWN, IDC_CLOSE_TAB },
|
| - { ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW },
|
| - { ui::VKEY_F, ui::EF_CONTROL_DOWN, IDC_FIND },
|
| - { ui::VKEY_G, ui::EF_CONTROL_DOWN, IDC_FIND_NEXT },
|
| - { ui::VKEY_G, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_FIND_PREVIOUS },
|
| + { ui::VKEY_W, kPlatformModifier, IDC_CLOSE_TAB },
|
| + { ui::VKEY_W, ui::EF_SHIFT_DOWN | kPlatformModifier, IDC_CLOSE_WINDOW },
|
| + { ui::VKEY_F, kPlatformModifier, IDC_FIND },
|
| + { ui::VKEY_G, kPlatformModifier, IDC_FIND_NEXT },
|
| + { ui::VKEY_G, ui::EF_SHIFT_DOWN | kPlatformModifier, IDC_FIND_PREVIOUS },
|
| { ui::VKEY_D, ui::EF_ALT_DOWN, IDC_FOCUS_LOCATION },
|
| - { ui::VKEY_L, ui::EF_CONTROL_DOWN, IDC_FOCUS_LOCATION },
|
| + { ui::VKEY_L, kPlatformModifier, IDC_FOCUS_LOCATION },
|
| { ui::VKEY_K, ui::EF_CONTROL_DOWN, IDC_FOCUS_SEARCH },
|
| { ui::VKEY_E, ui::EF_CONTROL_DOWN, IDC_FOCUS_SEARCH },
|
| { ui::VKEY_T, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, IDC_FOCUS_TOOLBAR },
|
| @@ -59,16 +67,16 @@ const AcceleratorMapping kAcceleratorMap[] = {
|
| IDC_DEV_TOOLS_CONSOLE },
|
| { ui::VKEY_C, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
|
| IDC_DEV_TOOLS_INSPECT },
|
| - { ui::VKEY_O, ui::EF_CONTROL_DOWN, IDC_OPEN_FILE },
|
| - { ui::VKEY_P, ui::EF_CONTROL_DOWN, IDC_PRINT},
|
| + { ui::VKEY_O, kPlatformModifier, IDC_OPEN_FILE },
|
| + { ui::VKEY_P, kPlatformModifier, IDC_PRINT },
|
| #if defined(ENABLE_BASIC_PRINTING)
|
| { ui::VKEY_P, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_BASIC_PRINT},
|
| #endif // ENABLE_BASIC_PRINTING
|
| - { ui::VKEY_R, ui::EF_CONTROL_DOWN, IDC_RELOAD },
|
| - { ui::VKEY_R, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
|
| + { ui::VKEY_R, kPlatformModifier, IDC_RELOAD },
|
| + { ui::VKEY_R, ui::EF_SHIFT_DOWN | kPlatformModifier,
|
| IDC_RELOAD_BYPASSING_CACHE },
|
| { ui::VKEY_HOME, ui::EF_ALT_DOWN, IDC_HOME },
|
| - { ui::VKEY_S, ui::EF_CONTROL_DOWN, IDC_SAVE_PAGE },
|
| + { ui::VKEY_S, kPlatformModifier, IDC_SAVE_PAGE },
|
| { ui::VKEY_9, kPlatformModifier, IDC_SELECT_LAST_TAB },
|
| { ui::VKEY_NUMPAD9, kPlatformModifier, IDC_SELECT_LAST_TAB },
|
| #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
|
| @@ -118,7 +126,7 @@ const AcceleratorMapping kAcceleratorMap[] = {
|
| { ui::VKEY_NUMPAD8, ui::EF_ALT_DOWN, IDC_SELECT_TAB_7 },
|
| { ui::VKEY_BROWSER_FAVORITES, ui::EF_NONE, IDC_SHOW_BOOKMARK_BAR },
|
| #endif
|
| - { ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
|
| + { ui::VKEY_B, ui::EF_SHIFT_DOWN | kPlatformModifier,
|
| IDC_SHOW_BOOKMARK_BAR },
|
| { ui::VKEY_O, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
|
| IDC_SHOW_BOOKMARK_MANAGER },
|
| @@ -128,12 +136,14 @@ const AcceleratorMapping kAcceleratorMap[] = {
|
| { ui::VKEY_E, ui::EF_ALT_DOWN, IDC_SHOW_APP_MENU},
|
| { ui::VKEY_ESCAPE, ui::EF_NONE, IDC_STOP },
|
| { ui::VKEY_U, ui::EF_CONTROL_DOWN, IDC_VIEW_SOURCE },
|
| - { ui::VKEY_OEM_MINUS, ui::EF_CONTROL_DOWN, IDC_ZOOM_MINUS },
|
| - { ui::VKEY_SUBTRACT, ui::EF_CONTROL_DOWN, IDC_ZOOM_MINUS },
|
| - { ui::VKEY_0, ui::EF_CONTROL_DOWN, IDC_ZOOM_NORMAL },
|
| - { ui::VKEY_NUMPAD0, ui::EF_CONTROL_DOWN, IDC_ZOOM_NORMAL },
|
| - { ui::VKEY_OEM_PLUS, ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS },
|
| - { ui::VKEY_ADD, ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS },
|
| + { ui::VKEY_OEM_MINUS, kPlatformModifier, IDC_ZOOM_MINUS },
|
| + { ui::VKEY_SUBTRACT, kPlatformModifier, IDC_ZOOM_MINUS },
|
| + { ui::VKEY_0, kPlatformModifier, IDC_ZOOM_NORMAL },
|
| + { ui::VKEY_NUMPAD0, kPlatformModifier, IDC_ZOOM_NORMAL },
|
| + { ui::VKEY_OEM_PLUS, kPlatformModifier, IDC_ZOOM_PLUS },
|
| + { ui::VKEY_ADD, kPlatformModifier, IDC_ZOOM_PLUS },
|
| +
|
| +#if !defined(OS_MACOSX) // Function keys aren't mapped on Mac.
|
| { ui::VKEY_F1, ui::EF_NONE, IDC_HELP_PAGE_VIA_KEYBOARD },
|
| { ui::VKEY_F3, ui::EF_NONE, IDC_FIND_NEXT },
|
| { ui::VKEY_F3, ui::EF_SHIFT_DOWN, IDC_FIND_PREVIOUS },
|
| @@ -146,6 +156,7 @@ const AcceleratorMapping kAcceleratorMap[] = {
|
| { ui::VKEY_F6, ui::EF_SHIFT_DOWN, IDC_FOCUS_PREVIOUS_PANE },
|
| { ui::VKEY_F10, ui::EF_NONE, IDC_FOCUS_MENU_BAR },
|
| { ui::VKEY_F11, ui::EF_NONE, IDC_FULLSCREEN },
|
| +#endif // !OS_MACOSX
|
|
|
| // Platform-specific key maps.
|
| #if defined(OS_LINUX)
|
| @@ -168,7 +179,7 @@ const AcceleratorMapping kAcceleratorMap[] = {
|
| { ui::VKEY_BROWSER_STOP, ui::EF_NONE, IDC_STOP },
|
| { ui::VKEY_P, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
|
| IDC_TOUCH_HUD_PROJECTION_TOGGLE },
|
| -#else // OS_CHROMEOS
|
| +#else
|
| { ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN, IDC_TASK_MANAGER },
|
| { ui::VKEY_DELETE, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
|
| IDC_CLEAR_BROWSING_DATA },
|
| @@ -178,7 +189,7 @@ const AcceleratorMapping kAcceleratorMap[] = {
|
| // On Windows, all VKEY_BROWSER_* keys except VKEY_BROWSER_SEARCH are handled
|
| // via WM_APPCOMMAND.
|
| { ui::VKEY_BROWSER_SEARCH, ui::EF_NONE, IDC_FOCUS_SEARCH },
|
| - { ui::VKEY_M, ui::EF_SHIFT_DOWN | kPlatformModifier, IDC_SHOW_AVATAR_MENU},
|
| + { ui::VKEY_M, ui::EF_SHIFT_DOWN | kPlatformModifier, IDC_SHOW_AVATAR_MENU },
|
| // On Chrome OS, these keys are assigned to change UI scale.
|
| { ui::VKEY_OEM_PLUS, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS },
|
| { ui::VKEY_OEM_MINUS, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
|
| @@ -189,14 +200,61 @@ const AcceleratorMapping kAcceleratorMap[] = {
|
| { ui::VKEY_I, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, IDC_FEEDBACK },
|
| #endif
|
| { ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_EXIT },
|
| - { ui::VKEY_N, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
|
| + { ui::VKEY_N, ui::EF_SHIFT_DOWN | kPlatformModifier,
|
| IDC_NEW_INCOGNITO_WINDOW },
|
| - { ui::VKEY_T, ui::EF_CONTROL_DOWN, IDC_NEW_TAB },
|
| - { ui::VKEY_N, ui::EF_CONTROL_DOWN, IDC_NEW_WINDOW },
|
| - { ui::VKEY_T, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_RESTORE_TAB },
|
| -#endif
|
| -};
|
| -const size_t kAcceleratorMapLength = arraysize(kAcceleratorMap);
|
| + { ui::VKEY_T, kPlatformModifier, IDC_NEW_TAB },
|
| + { ui::VKEY_N, kPlatformModifier, IDC_NEW_WINDOW },
|
| + { ui::VKEY_T, ui::EF_SHIFT_DOWN | kPlatformModifier, IDC_RESTORE_TAB },
|
| +#endif // !OS_CHROMEOS
|
| +
|
| +#if defined(OS_MACOSX)
|
| + // VKEY_OEM_4 is Left Brace '[{' key.
|
| + { ui::VKEY_OEM_4, ui::EF_COMMAND_DOWN, IDC_BACK },
|
| + { ui::VKEY_LEFT, ui::EF_COMMAND_DOWN, IDC_BACK },
|
| +#if defined(ENABLE_BASIC_PRINTING)
|
| + { ui::VKEY_P, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, IDC_BASIC_PRINT },
|
| +#endif // ENABLE_BASIC_PRINTING
|
| + { ui::VKEY_BACK, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN,
|
| + IDC_CLEAR_BROWSING_DATA },
|
| + { ui::VKEY_V, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN,
|
| + IDC_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE },
|
| + { ui::VKEY_Z, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN,
|
| + IDC_CONTENT_CONTEXT_REDO },
|
| + { ui::VKEY_A, ui::EF_COMMAND_DOWN, IDC_CONTENT_CONTEXT_SELECTALL },
|
| + { ui::VKEY_Z, ui::EF_COMMAND_DOWN, IDC_CONTENT_CONTEXT_UNDO },
|
| + { ui::VKEY_I, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, IDC_DEV_TOOLS },
|
| + { ui::VKEY_J, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, IDC_DEV_TOOLS_CONSOLE },
|
| + { ui::VKEY_C, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN, IDC_DEV_TOOLS_INSPECT},
|
| + { ui::VKEY_I, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN,
|
| + IDC_EMAIL_PAGE_LOCATION },
|
| + { ui::VKEY_Q, ui::EF_COMMAND_DOWN, IDC_EXIT },
|
| + { ui::VKEY_F, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, IDC_FOCUS_SEARCH },
|
| + // VKEY_OEM_6 is Right Brace ']}' key.
|
| + { ui::VKEY_OEM_6, ui::EF_COMMAND_DOWN, IDC_FORWARD },
|
| + { ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN, IDC_FORWARD },
|
| + { ui::VKEY_F, ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN, IDC_FULLSCREEN },
|
| + // VKEY_OEM_2 is Slash '/?' key.
|
| + { ui::VKEY_OEM_2, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN,
|
| + IDC_HELP_PAGE_VIA_MENU },
|
| + { ui::VKEY_H, ui::EF_COMMAND_DOWN, IDC_HIDE_APP },
|
| + { ui::VKEY_H, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN, IDC_HOME },
|
| + { ui::VKEY_M, ui::EF_COMMAND_DOWN, IDC_MINIMIZE_WINDOW },
|
| + { ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
|
| + IDC_SELECT_NEXT_TAB },
|
| + { ui::VKEY_LEFT, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
|
| + IDC_SELECT_PREVIOUS_TAB },
|
| + { ui::VKEY_B, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
|
| + IDC_SHOW_BOOKMARK_MANAGER },
|
| + { ui::VKEY_J, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN, IDC_SHOW_DOWNLOADS },
|
| + { ui::VKEY_L, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, IDC_SHOW_DOWNLOADS },
|
| + { ui::VKEY_Y, ui::EF_COMMAND_DOWN, IDC_SHOW_HISTORY },
|
| + { ui::VKEY_OEM_PERIOD, ui::EF_COMMAND_DOWN, IDC_STOP },
|
| + { ui::VKEY_U, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, IDC_VIEW_SOURCE },
|
| +#endif // OS_MACOSX
|
| + };
|
| +}
|
| +
|
| +namespace {
|
|
|
| const int kRepeatableCommandIds[] = {
|
| IDC_FIND_NEXT,
|
| @@ -239,8 +297,42 @@ const size_t kChromeCmdId2AshActionIdLength =
|
| } // namespace
|
|
|
| std::vector<AcceleratorMapping> GetAcceleratorList() {
|
| - return std::vector<AcceleratorMapping>(
|
| - kAcceleratorMap, kAcceleratorMap + kAcceleratorMapLength);
|
| + static bool is_accelerator_list_initialized = false;
|
| + CR_DEFINE_STATIC_LOCAL(std::vector<AcceleratorMapping>, accelerators,
|
| + (GetUnfilteredAcceleratorListForTesting()));
|
| + if (is_accelerator_list_initialized)
|
| + return accelerators;
|
| +
|
| + is_accelerator_list_initialized = true;
|
| +#if defined(OS_MACOSX)
|
| + // Control modifier is rarely used on Mac, so we allow it only in several
|
| + // whitelisted cases.
|
| + const std::set<int> kControlWhitelist = {
|
| + IDC_SELECT_NEXT_TAB, IDC_SELECT_PREVIOUS_TAB, IDC_FULLSCREEN,
|
| + };
|
| +
|
| + auto remove_accelerators = [&kControlWhitelist](const AcceleratorMapping& m) {
|
| + // Alt by itself (or with just shift) is never used on Mac since it's used
|
| + // to generate non-ASCII characters. Such commands are given Mac-specific
|
| + // bindings as well, so remove the mappings with Alt, but not those with
|
| + // Command or Control.
|
| + constexpr int kNonShiftMask =
|
| + ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN;
|
| + if ((m.modifiers & kNonShiftMask) == ui::EF_ALT_DOWN)
|
| + return true;
|
| +
|
| + // If command uses Control modifier it has to be whitelisted.
|
| + if ((m.modifiers & ui::EF_CONTROL_DOWN) != 0 &&
|
| + kControlWhitelist.count(m.command_id) == 0)
|
| + return true;
|
| +
|
| + return false;
|
| + };
|
| + accelerators.erase(std::remove_if(accelerators.begin(), accelerators.end(),
|
| + remove_accelerators),
|
| + accelerators.end());
|
| +#endif // OS_MACOSX
|
| + return accelerators;
|
| }
|
|
|
| bool GetAshAcceleratorForCommandId(int command_id,
|
| @@ -268,13 +360,13 @@ bool GetStandardAcceleratorForCommandId(int command_id,
|
| // anywhere else.
|
| switch (command_id) {
|
| case IDC_CUT:
|
| - *accelerator = ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN);
|
| + *accelerator = ui::Accelerator(ui::VKEY_X, kPlatformModifier);
|
| return true;
|
| case IDC_COPY:
|
| - *accelerator = ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN);
|
| + *accelerator = ui::Accelerator(ui::VKEY_C, kPlatformModifier);
|
| return true;
|
| case IDC_PASTE:
|
| - *accelerator = ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN);
|
| + *accelerator = ui::Accelerator(ui::VKEY_V, kPlatformModifier);
|
| return true;
|
| }
|
| return false;
|
|
|