1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/views/accelerator_table.h"
7 #include "base/basictypes.h"
8 #include "chrome/app/chrome_command_ids.h"
9 #include "ui/base/accelerators/accelerator.h"
10 #include "ui/events/event_constants.h"
13 #include "ash/accelerators/accelerator_table.h"
19 // For many commands, the Mac equivalent uses Cmd instead of Ctrl. We only need
20 // to list the ones that do not have a key equivalent in the main menu, i.e.
21 // only the ones in global_keyboard_shortcuts_mac.mm.
22 // TODO(jackhou): If-def out the accelerators that should not be on Mac.
23 #if defined(OS_MACOSX)
24 const ui::EventFlags kPlatformModifier
= ui::EF_COMMAND_DOWN
;
26 const ui::EventFlags kPlatformModifier
= ui::EF_CONTROL_DOWN
;
29 // NOTE: Keep this list in the same (mostly-alphabetical) order as
30 // the Windows accelerators in ../../app/chrome_dll.rc.
31 // Do not use Ctrl-Alt as a shortcut modifier, as it is used by i18n keyboards:
32 // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/29/101121.aspx
33 const AcceleratorMapping kAcceleratorMap
[] = {
34 { ui::VKEY_LEFT
, ui::EF_ALT_DOWN
, IDC_BACK
},
35 { ui::VKEY_BACK
, ui::EF_NONE
, IDC_BACK
},
36 { ui::VKEY_D
, ui::EF_CONTROL_DOWN
, IDC_BOOKMARK_PAGE
},
37 { ui::VKEY_D
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
38 IDC_BOOKMARK_ALL_TABS
},
39 { ui::VKEY_W
, ui::EF_CONTROL_DOWN
, IDC_CLOSE_TAB
},
40 { ui::VKEY_W
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_CLOSE_WINDOW
},
41 { ui::VKEY_F
, ui::EF_CONTROL_DOWN
, IDC_FIND
},
42 { ui::VKEY_G
, ui::EF_CONTROL_DOWN
, IDC_FIND_NEXT
},
43 { ui::VKEY_G
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_FIND_PREVIOUS
},
44 { ui::VKEY_D
, ui::EF_ALT_DOWN
, IDC_FOCUS_LOCATION
},
45 { ui::VKEY_L
, ui::EF_CONTROL_DOWN
, IDC_FOCUS_LOCATION
},
46 { ui::VKEY_K
, ui::EF_CONTROL_DOWN
, IDC_FOCUS_SEARCH
},
47 { ui::VKEY_E
, ui::EF_CONTROL_DOWN
, IDC_FOCUS_SEARCH
},
48 { ui::VKEY_T
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
, IDC_FOCUS_TOOLBAR
},
49 { ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
, IDC_FOCUS_BOOKMARKS
},
50 { ui::VKEY_A
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
, IDC_FOCUS_INFOBARS
},
51 { ui::VKEY_RIGHT
, ui::EF_ALT_DOWN
, IDC_FORWARD
},
52 { ui::VKEY_BACK
, ui::EF_SHIFT_DOWN
, IDC_FORWARD
},
53 { ui::VKEY_I
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_DEV_TOOLS
},
54 { ui::VKEY_F12
, ui::EF_NONE
, IDC_DEV_TOOLS_TOGGLE
},
55 { ui::VKEY_J
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
56 IDC_DEV_TOOLS_CONSOLE
},
57 { ui::VKEY_C
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
58 IDC_DEV_TOOLS_INSPECT
},
59 { ui::VKEY_O
, ui::EF_CONTROL_DOWN
, IDC_OPEN_FILE
},
60 { ui::VKEY_P
, ui::EF_CONTROL_DOWN
, IDC_PRINT
},
61 #if defined(ENABLE_BASIC_PRINTING)
62 { ui::VKEY_P
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_BASIC_PRINT
},
63 #endif // ENABLE_BASIC_PRINTING
64 { ui::VKEY_R
, ui::EF_CONTROL_DOWN
, IDC_RELOAD
},
65 { ui::VKEY_R
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
66 IDC_RELOAD_IGNORING_CACHE
},
67 { ui::VKEY_HOME
, ui::EF_ALT_DOWN
, IDC_HOME
},
68 { ui::VKEY_S
, ui::EF_CONTROL_DOWN
, IDC_SAVE_PAGE
},
69 { ui::VKEY_9
, kPlatformModifier
, IDC_SELECT_LAST_TAB
},
70 { ui::VKEY_NUMPAD9
, kPlatformModifier
, IDC_SELECT_LAST_TAB
},
71 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
72 { ui::VKEY_9
, ui::EF_ALT_DOWN
, IDC_SELECT_LAST_TAB
},
73 { ui::VKEY_NUMPAD9
, ui::EF_ALT_DOWN
, IDC_SELECT_LAST_TAB
},
74 { ui::VKEY_NEXT
, ui::EF_CONTROL_DOWN
| ui::EF_SHIFT_DOWN
, IDC_MOVE_TAB_NEXT
},
75 { ui::VKEY_PRIOR
, ui::EF_CONTROL_DOWN
| ui::EF_SHIFT_DOWN
,
76 IDC_MOVE_TAB_PREVIOUS
},
78 { ui::VKEY_TAB
, ui::EF_CONTROL_DOWN
, IDC_SELECT_NEXT_TAB
},
79 { ui::VKEY_NEXT
, ui::EF_CONTROL_DOWN
, IDC_SELECT_NEXT_TAB
},
80 { ui::VKEY_TAB
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
81 IDC_SELECT_PREVIOUS_TAB
},
82 { ui::VKEY_PRIOR
, ui::EF_CONTROL_DOWN
, IDC_SELECT_PREVIOUS_TAB
},
83 { ui::VKEY_1
, kPlatformModifier
, IDC_SELECT_TAB_0
},
84 { ui::VKEY_NUMPAD1
, kPlatformModifier
, IDC_SELECT_TAB_0
},
85 { ui::VKEY_2
, kPlatformModifier
, IDC_SELECT_TAB_1
},
86 { ui::VKEY_NUMPAD2
, kPlatformModifier
, IDC_SELECT_TAB_1
},
87 { ui::VKEY_3
, kPlatformModifier
, IDC_SELECT_TAB_2
},
88 { ui::VKEY_NUMPAD3
, kPlatformModifier
, IDC_SELECT_TAB_2
},
89 { ui::VKEY_4
, kPlatformModifier
, IDC_SELECT_TAB_3
},
90 { ui::VKEY_NUMPAD4
, kPlatformModifier
, IDC_SELECT_TAB_3
},
91 { ui::VKEY_5
, kPlatformModifier
, IDC_SELECT_TAB_4
},
92 { ui::VKEY_NUMPAD5
, kPlatformModifier
, IDC_SELECT_TAB_4
},
93 { ui::VKEY_6
, kPlatformModifier
, IDC_SELECT_TAB_5
},
94 { ui::VKEY_NUMPAD6
, kPlatformModifier
, IDC_SELECT_TAB_5
},
95 { ui::VKEY_7
, kPlatformModifier
, IDC_SELECT_TAB_6
},
96 { ui::VKEY_NUMPAD7
, kPlatformModifier
, IDC_SELECT_TAB_6
},
97 { ui::VKEY_8
, kPlatformModifier
, IDC_SELECT_TAB_7
},
98 { ui::VKEY_NUMPAD8
, kPlatformModifier
, IDC_SELECT_TAB_7
},
99 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
100 { ui::VKEY_1
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_0
},
101 { ui::VKEY_NUMPAD1
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_0
},
102 { ui::VKEY_2
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_1
},
103 { ui::VKEY_NUMPAD2
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_1
},
104 { ui::VKEY_3
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_2
},
105 { ui::VKEY_NUMPAD3
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_2
},
106 { ui::VKEY_4
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_3
},
107 { ui::VKEY_NUMPAD4
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_3
},
108 { ui::VKEY_5
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_4
},
109 { ui::VKEY_NUMPAD5
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_4
},
110 { ui::VKEY_6
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_5
},
111 { ui::VKEY_NUMPAD6
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_5
},
112 { ui::VKEY_7
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_6
},
113 { ui::VKEY_NUMPAD7
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_6
},
114 { ui::VKEY_8
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_7
},
115 { ui::VKEY_NUMPAD8
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_7
},
116 { ui::VKEY_BROWSER_FAVORITES
, ui::EF_NONE
, IDC_SHOW_BOOKMARK_BAR
},
118 { ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
119 IDC_SHOW_BOOKMARK_BAR
},
120 { ui::VKEY_O
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
121 IDC_SHOW_BOOKMARK_MANAGER
},
122 { ui::VKEY_J
, ui::EF_CONTROL_DOWN
, IDC_SHOW_DOWNLOADS
},
123 { ui::VKEY_H
, ui::EF_CONTROL_DOWN
, IDC_SHOW_HISTORY
},
124 { ui::VKEY_F
, ui::EF_ALT_DOWN
, IDC_SHOW_APP_MENU
},
125 { ui::VKEY_E
, ui::EF_ALT_DOWN
, IDC_SHOW_APP_MENU
},
126 { ui::VKEY_ESCAPE
, ui::EF_NONE
, IDC_STOP
},
127 { ui::VKEY_OEM_PERIOD
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
128 IDC_TOGGLE_SPEECH_INPUT
},
129 { ui::VKEY_U
, ui::EF_CONTROL_DOWN
, IDC_VIEW_SOURCE
},
130 { ui::VKEY_OEM_MINUS
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_MINUS
},
131 { ui::VKEY_SUBTRACT
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_MINUS
},
132 { ui::VKEY_0
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_NORMAL
},
133 { ui::VKEY_NUMPAD0
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_NORMAL
},
134 { ui::VKEY_OEM_PLUS
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_PLUS
},
135 { ui::VKEY_ADD
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_PLUS
},
136 { ui::VKEY_F1
, ui::EF_NONE
, IDC_HELP_PAGE_VIA_KEYBOARD
},
137 { ui::VKEY_F3
, ui::EF_NONE
, IDC_FIND_NEXT
},
138 { ui::VKEY_F3
, ui::EF_SHIFT_DOWN
, IDC_FIND_PREVIOUS
},
139 { ui::VKEY_F4
, ui::EF_CONTROL_DOWN
, IDC_CLOSE_TAB
},
140 { ui::VKEY_F4
, ui::EF_ALT_DOWN
, IDC_CLOSE_WINDOW
},
141 { ui::VKEY_F5
, ui::EF_NONE
, IDC_RELOAD
},
142 { ui::VKEY_F5
, ui::EF_CONTROL_DOWN
, IDC_RELOAD_IGNORING_CACHE
},
143 { ui::VKEY_F5
, ui::EF_SHIFT_DOWN
, IDC_RELOAD_IGNORING_CACHE
},
144 { ui::VKEY_F6
, ui::EF_NONE
, IDC_FOCUS_NEXT_PANE
},
145 { ui::VKEY_F6
, ui::EF_SHIFT_DOWN
, IDC_FOCUS_PREVIOUS_PANE
},
146 { ui::VKEY_F10
, ui::EF_NONE
, IDC_FOCUS_MENU_BAR
},
147 { ui::VKEY_F11
, ui::EF_NONE
, IDC_FULLSCREEN
},
149 // Platform-specific key maps.
150 #if defined(OS_LINUX)
151 { ui::VKEY_BROWSER_BACK
, ui::EF_NONE
, IDC_BACK
},
152 { ui::VKEY_BROWSER_FORWARD
, ui::EF_NONE
, IDC_FORWARD
},
153 { ui::VKEY_BROWSER_HOME
, ui::EF_NONE
, IDC_HOME
},
154 { ui::VKEY_BROWSER_REFRESH
, ui::EF_NONE
, IDC_RELOAD
},
155 { ui::VKEY_BROWSER_REFRESH
, ui::EF_CONTROL_DOWN
, IDC_RELOAD_IGNORING_CACHE
},
156 { ui::VKEY_BROWSER_REFRESH
, ui::EF_SHIFT_DOWN
, IDC_RELOAD_IGNORING_CACHE
},
157 #endif // defined(OS_LINUX)
159 #if defined(OS_CHROMEOS)
160 // On Chrome OS, VKEY_BROWSER_SEARCH is handled in Ash.
161 { ui::VKEY_BACK
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
162 IDC_CLEAR_BROWSING_DATA
},
163 { ui::VKEY_OEM_2
, ui::EF_CONTROL_DOWN
, IDC_HELP_PAGE_VIA_KEYBOARD
},
164 { ui::VKEY_OEM_2
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
165 IDC_HELP_PAGE_VIA_KEYBOARD
},
166 { ui::VKEY_BROWSER_FAVORITES
, ui::EF_NONE
, IDC_SHOW_BOOKMARK_MANAGER
},
167 { ui::VKEY_BROWSER_STOP
, ui::EF_NONE
, IDC_STOP
},
168 { ui::VKEY_P
, ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
169 IDC_TOUCH_HUD_PROJECTION_TOGGLE
},
171 { ui::VKEY_ESCAPE
, ui::EF_SHIFT_DOWN
, IDC_TASK_MANAGER
},
172 { ui::VKEY_DELETE
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
173 IDC_CLEAR_BROWSING_DATA
},
174 { ui::VKEY_LMENU
, ui::EF_NONE
, IDC_FOCUS_MENU_BAR
},
175 { ui::VKEY_MENU
, ui::EF_NONE
, IDC_FOCUS_MENU_BAR
},
176 { ui::VKEY_RMENU
, ui::EF_NONE
, IDC_FOCUS_MENU_BAR
},
177 // On Windows, all VKEY_BROWSER_* keys except VKEY_BROWSER_SEARCH are handled
178 // via WM_APPCOMMAND.
179 { ui::VKEY_BROWSER_SEARCH
, ui::EF_NONE
, IDC_FOCUS_SEARCH
},
180 { ui::VKEY_M
, ui::EF_SHIFT_DOWN
| kPlatformModifier
, IDC_SHOW_AVATAR_MENU
},
181 // On ChromeOS, these keys are assigned to change UI scale.
182 { ui::VKEY_OEM_PLUS
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_ZOOM_PLUS
},
183 { ui::VKEY_OEM_MINUS
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
185 // For each entry here add an entry into kChromeCmdId2AshActionId below
186 // if Ash has a corresponding accelerator.
187 #if defined(GOOGLE_CHROME_BUILD)
188 { ui::VKEY_I
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
, IDC_FEEDBACK
},
190 { ui::VKEY_Q
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_EXIT
},
191 { ui::VKEY_N
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
192 IDC_NEW_INCOGNITO_WINDOW
},
193 { ui::VKEY_T
, ui::EF_CONTROL_DOWN
, IDC_NEW_TAB
},
194 { ui::VKEY_N
, ui::EF_CONTROL_DOWN
, IDC_NEW_WINDOW
},
195 { ui::VKEY_T
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_RESTORE_TAB
},
198 const size_t kAcceleratorMapLength
= arraysize(kAcceleratorMap
);
201 // Below we map Chrome command ids to Ash action ids for commands that have
202 // an shortcut that is handled by Ash (instead of Chrome). Adding entries
203 // here will show shortcut text on menus. See comment above.
204 struct ChromeCmdId2AshActionId
{
205 const int chrome_cmd_id
;
206 const ash::AcceleratorAction ash_action_id
;
208 const ChromeCmdId2AshActionId kChromeCmdId2AshActionId
[] = {
209 #if defined(GOOGLE_CHROME_BUILD)
210 { IDC_FEEDBACK
, ash::OPEN_FEEDBACK_PAGE
},
212 { IDC_EXIT
, ash::EXIT
},
213 { IDC_NEW_INCOGNITO_WINDOW
, ash::NEW_INCOGNITO_WINDOW
},
214 { IDC_NEW_TAB
, ash::NEW_TAB
},
215 { IDC_NEW_WINDOW
, ash::NEW_WINDOW
},
216 { IDC_RESTORE_TAB
, ash::RESTORE_TAB
},
217 { IDC_TASK_MANAGER
, ash::SHOW_TASK_MANAGER
},
218 #if defined(OS_CHROMEOS)
219 { IDC_TOUCH_HUD_PROJECTION_TOGGLE
, ash::TOUCH_HUD_PROJECTION_TOGGLE
},
222 const size_t kChromeCmdId2AshActionIdLength
=
223 arraysize(kChromeCmdId2AshActionId
);
224 #endif // defined(USE_ASH)
228 std::vector
<AcceleratorMapping
> GetAcceleratorList() {
229 return std::vector
<AcceleratorMapping
>(
230 kAcceleratorMap
, kAcceleratorMap
+ kAcceleratorMapLength
);
233 bool GetAshAcceleratorForCommandId(int command_id
,
234 HostDesktopType host_desktop_type
,
235 ui::Accelerator
* accelerator
) {
237 if (host_desktop_type
!= chrome::HOST_DESKTOP_TYPE_ASH
)
239 for (size_t i
= 0; i
< kChromeCmdId2AshActionIdLength
; ++i
) {
240 if (command_id
== kChromeCmdId2AshActionId
[i
].chrome_cmd_id
) {
241 for (size_t j
= 0; j
< ash::kAcceleratorDataLength
; ++j
) {
242 if (kChromeCmdId2AshActionId
[i
].ash_action_id
==
243 ash::kAcceleratorData
[j
].action
) {
244 *accelerator
= ui::Accelerator(ash::kAcceleratorData
[j
].keycode
,
245 ash::kAcceleratorData
[j
].modifiers
);
251 #endif // defined(USE_ASH)
255 bool GetStandardAcceleratorForCommandId(int command_id
,
256 ui::Accelerator
* accelerator
) {
257 // The standard Ctrl-X, Ctrl-V and Ctrl-C are not defined as accelerators
259 switch (command_id
) {
261 *accelerator
= ui::Accelerator(ui::VKEY_X
, ui::EF_CONTROL_DOWN
);
264 *accelerator
= ui::Accelerator(ui::VKEY_C
, ui::EF_CONTROL_DOWN
);
267 *accelerator
= ui::Accelerator(ui::VKEY_V
, ui::EF_CONTROL_DOWN
);
273 } // namespace chrome