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 // NOTE: Keep this list in the same (mostly-alphabetical) order as
20 // the Windows accelerators in ../../app/chrome_dll.rc.
21 // Do not use Ctrl-Alt as a shortcut modifier, as it is used by i18n keyboards:
22 // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/29/101121.aspx
23 const AcceleratorMapping kAcceleratorMap
[] = {
24 { ui::VKEY_LEFT
, ui::EF_ALT_DOWN
, IDC_BACK
},
25 { ui::VKEY_BACK
, ui::EF_NONE
, IDC_BACK
},
26 { ui::VKEY_D
, ui::EF_CONTROL_DOWN
, IDC_BOOKMARK_PAGE
},
27 { ui::VKEY_D
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
28 IDC_BOOKMARK_ALL_TABS
},
29 { ui::VKEY_W
, ui::EF_CONTROL_DOWN
, IDC_CLOSE_TAB
},
30 { ui::VKEY_W
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_CLOSE_WINDOW
},
31 { ui::VKEY_F
, ui::EF_CONTROL_DOWN
, IDC_FIND
},
32 { ui::VKEY_G
, ui::EF_CONTROL_DOWN
, IDC_FIND_NEXT
},
33 { ui::VKEY_G
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_FIND_PREVIOUS
},
34 { ui::VKEY_D
, ui::EF_ALT_DOWN
, IDC_FOCUS_LOCATION
},
35 { ui::VKEY_L
, ui::EF_CONTROL_DOWN
, IDC_FOCUS_LOCATION
},
36 { ui::VKEY_K
, ui::EF_CONTROL_DOWN
, IDC_FOCUS_SEARCH
},
37 { ui::VKEY_E
, ui::EF_CONTROL_DOWN
, IDC_FOCUS_SEARCH
},
38 { ui::VKEY_T
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
, IDC_FOCUS_TOOLBAR
},
39 { ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
, IDC_FOCUS_BOOKMARKS
},
40 { ui::VKEY_A
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
, IDC_FOCUS_INFOBARS
},
41 { ui::VKEY_RIGHT
, ui::EF_ALT_DOWN
, IDC_FORWARD
},
42 { ui::VKEY_BACK
, ui::EF_SHIFT_DOWN
, IDC_FORWARD
},
43 { ui::VKEY_I
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_DEV_TOOLS
},
44 { ui::VKEY_F12
, ui::EF_NONE
, IDC_DEV_TOOLS_TOGGLE
},
45 { ui::VKEY_J
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
46 IDC_DEV_TOOLS_CONSOLE
},
47 { ui::VKEY_C
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
48 IDC_DEV_TOOLS_INSPECT
},
49 { ui::VKEY_O
, ui::EF_CONTROL_DOWN
, IDC_OPEN_FILE
},
50 { ui::VKEY_P
, ui::EF_CONTROL_DOWN
, IDC_PRINT
},
51 { ui::VKEY_P
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_ADVANCED_PRINT
},
52 { ui::VKEY_R
, ui::EF_CONTROL_DOWN
, IDC_RELOAD
},
53 { ui::VKEY_R
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
54 IDC_RELOAD_IGNORING_CACHE
},
55 { ui::VKEY_HOME
, ui::EF_ALT_DOWN
, IDC_HOME
},
56 { ui::VKEY_S
, ui::EF_CONTROL_DOWN
, IDC_SAVE_PAGE
},
57 { ui::VKEY_9
, ui::EF_CONTROL_DOWN
, IDC_SELECT_LAST_TAB
},
58 { ui::VKEY_NUMPAD9
, ui::EF_CONTROL_DOWN
, IDC_SELECT_LAST_TAB
},
59 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
60 { ui::VKEY_9
, ui::EF_ALT_DOWN
, IDC_SELECT_LAST_TAB
},
61 { ui::VKEY_NUMPAD9
, ui::EF_ALT_DOWN
, IDC_SELECT_LAST_TAB
},
62 { ui::VKEY_NEXT
, ui::EF_CONTROL_DOWN
| ui::EF_SHIFT_DOWN
, IDC_MOVE_TAB_NEXT
},
63 { ui::VKEY_PRIOR
, ui::EF_CONTROL_DOWN
| ui::EF_SHIFT_DOWN
,
64 IDC_MOVE_TAB_PREVIOUS
},
66 { ui::VKEY_TAB
, ui::EF_CONTROL_DOWN
, IDC_SELECT_NEXT_TAB
},
67 { ui::VKEY_NEXT
, ui::EF_CONTROL_DOWN
, IDC_SELECT_NEXT_TAB
},
68 { ui::VKEY_TAB
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
69 IDC_SELECT_PREVIOUS_TAB
},
70 { ui::VKEY_PRIOR
, ui::EF_CONTROL_DOWN
, IDC_SELECT_PREVIOUS_TAB
},
71 { ui::VKEY_1
, ui::EF_CONTROL_DOWN
, IDC_SELECT_TAB_0
},
72 { ui::VKEY_NUMPAD1
, ui::EF_CONTROL_DOWN
, IDC_SELECT_TAB_0
},
73 { ui::VKEY_2
, ui::EF_CONTROL_DOWN
, IDC_SELECT_TAB_1
},
74 { ui::VKEY_NUMPAD2
, ui::EF_CONTROL_DOWN
, IDC_SELECT_TAB_1
},
75 { ui::VKEY_3
, ui::EF_CONTROL_DOWN
, IDC_SELECT_TAB_2
},
76 { ui::VKEY_NUMPAD3
, ui::EF_CONTROL_DOWN
, IDC_SELECT_TAB_2
},
77 { ui::VKEY_4
, ui::EF_CONTROL_DOWN
, IDC_SELECT_TAB_3
},
78 { ui::VKEY_NUMPAD4
, ui::EF_CONTROL_DOWN
, IDC_SELECT_TAB_3
},
79 { ui::VKEY_5
, ui::EF_CONTROL_DOWN
, IDC_SELECT_TAB_4
},
80 { ui::VKEY_NUMPAD5
, ui::EF_CONTROL_DOWN
, IDC_SELECT_TAB_4
},
81 { ui::VKEY_6
, ui::EF_CONTROL_DOWN
, IDC_SELECT_TAB_5
},
82 { ui::VKEY_NUMPAD6
, ui::EF_CONTROL_DOWN
, IDC_SELECT_TAB_5
},
83 { ui::VKEY_7
, ui::EF_CONTROL_DOWN
, IDC_SELECT_TAB_6
},
84 { ui::VKEY_NUMPAD7
, ui::EF_CONTROL_DOWN
, IDC_SELECT_TAB_6
},
85 { ui::VKEY_8
, ui::EF_CONTROL_DOWN
, IDC_SELECT_TAB_7
},
86 { ui::VKEY_NUMPAD8
, ui::EF_CONTROL_DOWN
, IDC_SELECT_TAB_7
},
87 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
88 { ui::VKEY_1
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_0
},
89 { ui::VKEY_NUMPAD1
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_0
},
90 { ui::VKEY_2
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_1
},
91 { ui::VKEY_NUMPAD2
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_1
},
92 { ui::VKEY_3
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_2
},
93 { ui::VKEY_NUMPAD3
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_2
},
94 { ui::VKEY_4
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_3
},
95 { ui::VKEY_NUMPAD4
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_3
},
96 { ui::VKEY_5
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_4
},
97 { ui::VKEY_NUMPAD5
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_4
},
98 { ui::VKEY_6
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_5
},
99 { ui::VKEY_NUMPAD6
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_5
},
100 { ui::VKEY_7
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_6
},
101 { ui::VKEY_NUMPAD7
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_6
},
102 { ui::VKEY_8
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_7
},
103 { ui::VKEY_NUMPAD8
, ui::EF_ALT_DOWN
, IDC_SELECT_TAB_7
},
104 { ui::VKEY_BROWSER_FAVORITES
, ui::EF_NONE
, IDC_SHOW_BOOKMARK_BAR
},
106 { ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
107 IDC_SHOW_BOOKMARK_BAR
},
108 { ui::VKEY_O
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
109 IDC_SHOW_BOOKMARK_MANAGER
},
110 { ui::VKEY_J
, ui::EF_CONTROL_DOWN
, IDC_SHOW_DOWNLOADS
},
111 { ui::VKEY_H
, ui::EF_CONTROL_DOWN
, IDC_SHOW_HISTORY
},
112 { ui::VKEY_F
, ui::EF_ALT_DOWN
, IDC_SHOW_APP_MENU
},
113 { ui::VKEY_E
, ui::EF_ALT_DOWN
, IDC_SHOW_APP_MENU
},
114 { ui::VKEY_ESCAPE
, ui::EF_NONE
, IDC_STOP
},
115 { ui::VKEY_OEM_PERIOD
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
116 IDC_TOGGLE_SPEECH_INPUT
},
117 { ui::VKEY_U
, ui::EF_CONTROL_DOWN
, IDC_VIEW_SOURCE
},
118 { ui::VKEY_OEM_MINUS
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_MINUS
},
119 { ui::VKEY_SUBTRACT
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_MINUS
},
120 { ui::VKEY_0
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_NORMAL
},
121 { ui::VKEY_NUMPAD0
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_NORMAL
},
122 { ui::VKEY_OEM_PLUS
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_PLUS
},
123 { ui::VKEY_ADD
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_PLUS
},
124 { ui::VKEY_F1
, ui::EF_NONE
, IDC_HELP_PAGE_VIA_KEYBOARD
},
125 { ui::VKEY_F3
, ui::EF_NONE
, IDC_FIND_NEXT
},
126 { ui::VKEY_F3
, ui::EF_SHIFT_DOWN
, IDC_FIND_PREVIOUS
},
127 { ui::VKEY_F4
, ui::EF_CONTROL_DOWN
, IDC_CLOSE_TAB
},
128 { ui::VKEY_F4
, ui::EF_ALT_DOWN
, IDC_CLOSE_WINDOW
},
129 { ui::VKEY_F5
, ui::EF_NONE
, IDC_RELOAD
},
130 { ui::VKEY_F5
, ui::EF_CONTROL_DOWN
, IDC_RELOAD_IGNORING_CACHE
},
131 { ui::VKEY_F5
, ui::EF_SHIFT_DOWN
, IDC_RELOAD_IGNORING_CACHE
},
132 { ui::VKEY_F6
, ui::EF_NONE
, IDC_FOCUS_NEXT_PANE
},
133 { ui::VKEY_F6
, ui::EF_SHIFT_DOWN
, IDC_FOCUS_PREVIOUS_PANE
},
134 { ui::VKEY_F10
, ui::EF_NONE
, IDC_FOCUS_MENU_BAR
},
135 { ui::VKEY_F11
, ui::EF_NONE
, IDC_FULLSCREEN
},
137 // Platform-specific key maps.
138 #if defined(OS_LINUX)
139 { ui::VKEY_BROWSER_BACK
, ui::EF_NONE
, IDC_BACK
},
140 { ui::VKEY_BROWSER_FORWARD
, ui::EF_NONE
, IDC_FORWARD
},
141 { ui::VKEY_BROWSER_HOME
, ui::EF_NONE
, IDC_HOME
},
142 { ui::VKEY_BROWSER_REFRESH
, ui::EF_NONE
, IDC_RELOAD
},
143 { ui::VKEY_BROWSER_REFRESH
, ui::EF_CONTROL_DOWN
, IDC_RELOAD_IGNORING_CACHE
},
144 { ui::VKEY_BROWSER_REFRESH
, ui::EF_SHIFT_DOWN
, IDC_RELOAD_IGNORING_CACHE
},
145 #endif // defined(OS_LINUX)
147 #if defined(OS_CHROMEOS)
148 // On Chrome OS, VKEY_BROWSER_SEARCH is handled in Ash.
149 { ui::VKEY_BACK
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
150 IDC_CLEAR_BROWSING_DATA
},
151 { ui::VKEY_OEM_2
, ui::EF_CONTROL_DOWN
, IDC_HELP_PAGE_VIA_KEYBOARD
},
152 { ui::VKEY_OEM_2
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
153 IDC_HELP_PAGE_VIA_KEYBOARD
},
154 { ui::VKEY_BROWSER_FAVORITES
, ui::EF_NONE
, IDC_SHOW_BOOKMARK_MANAGER
},
155 { ui::VKEY_BROWSER_STOP
, ui::EF_NONE
, IDC_STOP
},
156 // Not implemented inside Ash to allow web pages to capture the key.
157 { ui::VKEY_M
, ui::EF_CONTROL_DOWN
, IDC_MINIMIZE_WINDOW
},
159 { ui::VKEY_DELETE
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
160 IDC_CLEAR_BROWSING_DATA
},
161 { ui::VKEY_LMENU
, ui::EF_NONE
, IDC_FOCUS_MENU_BAR
},
162 { ui::VKEY_MENU
, ui::EF_NONE
, IDC_FOCUS_MENU_BAR
},
163 { ui::VKEY_RMENU
, ui::EF_NONE
, IDC_FOCUS_MENU_BAR
},
164 // On Windows, all VKEY_BROWSER_* keys except VKEY_BROWSER_SEARCH are handled
165 // via WM_APPCOMMAND.
166 { ui::VKEY_BROWSER_SEARCH
, ui::EF_NONE
, IDC_FOCUS_SEARCH
},
167 { ui::VKEY_M
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_SHOW_AVATAR_MENU
},
168 // On ChromeOS, these keys are assigned to change UI scale.
169 { ui::VKEY_OEM_PLUS
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_ZOOM_PLUS
},
170 { ui::VKEY_OEM_MINUS
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
172 #endif // OS_CHROMEOS
173 #if !defined(OS_CHROMEOS)
174 // For each entry here add an entry into kChromeCmdId2AshActionId below
175 // if Ash has a corresponding accelerator.
176 #if defined(GOOGLE_CHROME_BUILD)
177 { ui::VKEY_I
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
, IDC_FEEDBACK
},
179 { ui::VKEY_Q
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_EXIT
},
180 { ui::VKEY_N
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
181 IDC_NEW_INCOGNITO_WINDOW
},
182 { ui::VKEY_T
, ui::EF_CONTROL_DOWN
, IDC_NEW_TAB
},
183 { ui::VKEY_N
, ui::EF_CONTROL_DOWN
, IDC_NEW_WINDOW
},
184 { ui::VKEY_T
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_RESTORE_TAB
},
185 { ui::VKEY_ESCAPE
, ui::EF_SHIFT_DOWN
, IDC_TASK_MANAGER
},
188 const size_t kAcceleratorMapLength
= arraysize(kAcceleratorMap
);
191 // Below we map Chrome command ids to Ash action ids for commands that have
192 // an shortcut that is handled by Ash (instead of Chrome). Adding entries
193 // here will show shortcut text on menus. See comment above.
194 struct ChromeCmdId2AshActionId
{
195 const int chrome_cmd_id
;
196 const ash::AcceleratorAction ash_action_id
;
198 const ChromeCmdId2AshActionId kChromeCmdId2AshActionId
[] = {
199 #if defined(GOOGLE_CHROME_BUILD)
200 { IDC_FEEDBACK
, ash::OPEN_FEEDBACK_PAGE
},
202 { IDC_EXIT
, ash::EXIT
},
203 { IDC_NEW_INCOGNITO_WINDOW
, ash::NEW_INCOGNITO_WINDOW
},
204 { IDC_NEW_TAB
, ash::NEW_TAB
},
205 { IDC_NEW_WINDOW
, ash::NEW_WINDOW
},
206 { IDC_RESTORE_TAB
, ash::RESTORE_TAB
},
207 { IDC_TASK_MANAGER
, ash::SHOW_TASK_MANAGER
},
209 const size_t kChromeCmdId2AshActionIdLength
=
210 arraysize(kChromeCmdId2AshActionId
);
211 #endif // defined(USE_ASH)
215 std::vector
<AcceleratorMapping
> GetAcceleratorList() {
216 return std::vector
<AcceleratorMapping
>(
217 kAcceleratorMap
, kAcceleratorMap
+ kAcceleratorMapLength
);
220 bool GetAshAcceleratorForCommandId(int command_id
,
221 HostDesktopType host_desktop_type
,
222 ui::Accelerator
* accelerator
) {
224 if (host_desktop_type
!= chrome::HOST_DESKTOP_TYPE_ASH
)
226 for (size_t i
= 0; i
< kChromeCmdId2AshActionIdLength
; ++i
) {
227 if (command_id
== kChromeCmdId2AshActionId
[i
].chrome_cmd_id
) {
228 for (size_t j
= 0; j
< ash::kAcceleratorDataLength
; ++j
) {
229 if (kChromeCmdId2AshActionId
[i
].ash_action_id
==
230 ash::kAcceleratorData
[j
].action
) {
231 *accelerator
= ui::Accelerator(ash::kAcceleratorData
[j
].keycode
,
232 ash::kAcceleratorData
[j
].modifiers
);
238 #endif // defined(USE_ASH)
242 bool GetStandardAcceleratorForCommandId(int command_id
,
243 ui::Accelerator
* accelerator
) {
244 // The standard Ctrl-X, Ctrl-V and Ctrl-C are not defined as accelerators
246 switch (command_id
) {
248 *accelerator
= ui::Accelerator(ui::VKEY_X
, ui::EF_CONTROL_DOWN
);
251 *accelerator
= ui::Accelerator(ui::VKEY_C
, ui::EF_CONTROL_DOWN
);
254 *accelerator
= ui::Accelerator(ui::VKEY_V
, ui::EF_CONTROL_DOWN
);
260 } // namespace chrome