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
},
105 { ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
106 IDC_SHOW_BOOKMARK_BAR
},
107 { ui::VKEY_O
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
108 IDC_SHOW_BOOKMARK_MANAGER
},
109 { ui::VKEY_J
, ui::EF_CONTROL_DOWN
, IDC_SHOW_DOWNLOADS
},
110 { ui::VKEY_H
, ui::EF_CONTROL_DOWN
, IDC_SHOW_HISTORY
},
111 { ui::VKEY_F
, ui::EF_ALT_DOWN
, IDC_SHOW_APP_MENU
},
112 { ui::VKEY_E
, ui::EF_ALT_DOWN
, IDC_SHOW_APP_MENU
},
113 { ui::VKEY_ESCAPE
, ui::EF_NONE
, IDC_STOP
},
114 { ui::VKEY_OEM_PERIOD
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
115 IDC_TOGGLE_SPEECH_INPUT
},
116 { ui::VKEY_U
, ui::EF_CONTROL_DOWN
, IDC_VIEW_SOURCE
},
117 { ui::VKEY_OEM_MINUS
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_MINUS
},
118 { ui::VKEY_SUBTRACT
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_MINUS
},
119 { ui::VKEY_0
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_NORMAL
},
120 { ui::VKEY_NUMPAD0
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_NORMAL
},
121 { ui::VKEY_OEM_PLUS
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_PLUS
},
122 { ui::VKEY_ADD
, ui::EF_CONTROL_DOWN
, IDC_ZOOM_PLUS
},
123 { ui::VKEY_F1
, ui::EF_NONE
, IDC_HELP_PAGE_VIA_KEYBOARD
},
124 { ui::VKEY_F3
, ui::EF_NONE
, IDC_FIND_NEXT
},
125 { ui::VKEY_F3
, ui::EF_SHIFT_DOWN
, IDC_FIND_PREVIOUS
},
126 { ui::VKEY_F4
, ui::EF_CONTROL_DOWN
, IDC_CLOSE_TAB
},
127 { ui::VKEY_F4
, ui::EF_ALT_DOWN
, IDC_CLOSE_WINDOW
},
128 { ui::VKEY_F5
, ui::EF_NONE
, IDC_RELOAD
},
129 { ui::VKEY_F5
, ui::EF_CONTROL_DOWN
, IDC_RELOAD_IGNORING_CACHE
},
130 { ui::VKEY_F5
, ui::EF_SHIFT_DOWN
, IDC_RELOAD_IGNORING_CACHE
},
131 { ui::VKEY_F6
, ui::EF_NONE
, IDC_FOCUS_NEXT_PANE
},
132 { ui::VKEY_F6
, ui::EF_SHIFT_DOWN
, IDC_FOCUS_PREVIOUS_PANE
},
133 { ui::VKEY_F10
, ui::EF_NONE
, IDC_FOCUS_MENU_BAR
},
134 { ui::VKEY_F11
, ui::EF_NONE
, IDC_FULLSCREEN
},
136 // Platform-specific key maps.
137 #if defined(OS_CHROMEOS)
138 // On Chrome OS, VKEY_BROWSER_SEARCH is handled in Ash.
139 { ui::VKEY_BROWSER_BACK
, ui::EF_NONE
, IDC_BACK
},
140 { ui::VKEY_BACK
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
141 IDC_CLEAR_BROWSING_DATA
},
142 { ui::VKEY_BROWSER_FORWARD
, ui::EF_NONE
, IDC_FORWARD
},
143 { ui::VKEY_OEM_2
, ui::EF_CONTROL_DOWN
, IDC_HELP_PAGE_VIA_KEYBOARD
},
144 { ui::VKEY_OEM_2
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
145 IDC_HELP_PAGE_VIA_KEYBOARD
},
146 { ui::VKEY_BROWSER_HOME
, ui::EF_NONE
, IDC_HOME
},
147 { ui::VKEY_BROWSER_REFRESH
, ui::EF_NONE
, IDC_RELOAD
},
148 { ui::VKEY_BROWSER_REFRESH
, ui::EF_CONTROL_DOWN
, IDC_RELOAD_IGNORING_CACHE
},
149 { ui::VKEY_BROWSER_REFRESH
, ui::EF_SHIFT_DOWN
, IDC_RELOAD_IGNORING_CACHE
},
150 { ui::VKEY_BROWSER_FAVORITES
, ui::EF_NONE
, IDC_SHOW_BOOKMARK_MANAGER
},
151 { ui::VKEY_BROWSER_STOP
, ui::EF_NONE
, IDC_STOP
},
152 // Not implemented inside Ash to allow web pages to capture the key.
153 { ui::VKEY_M
, ui::EF_CONTROL_DOWN
, IDC_MINIMIZE_WINDOW
},
155 { ui::VKEY_DELETE
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
156 IDC_CLEAR_BROWSING_DATA
},
157 { ui::VKEY_LMENU
, ui::EF_NONE
, IDC_FOCUS_MENU_BAR
},
158 { ui::VKEY_MENU
, ui::EF_NONE
, IDC_FOCUS_MENU_BAR
},
159 { ui::VKEY_RMENU
, ui::EF_NONE
, IDC_FOCUS_MENU_BAR
},
160 // On Windows, all VKEY_BROWSER_* keys except VKEY_BROWSER_SEARCH are handled
161 // via WM_APPCOMMAND.
162 { ui::VKEY_BROWSER_SEARCH
, ui::EF_NONE
, IDC_FOCUS_SEARCH
},
163 { ui::VKEY_M
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_SHOW_AVATAR_MENU
},
164 // On ChromeOS, these keys are assigned to change UI scale.
165 { ui::VKEY_OEM_PLUS
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_ZOOM_PLUS
},
166 { ui::VKEY_OEM_MINUS
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
168 #endif // OS_CHROMEOS
169 #if !defined(OS_CHROMEOS)
170 // For each entry here add an entry into kChromeCmdId2AshActionId below
171 // if Ash has a corresponding accelerator.
172 #if defined(GOOGLE_CHROME_BUILD)
173 { ui::VKEY_I
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
, IDC_FEEDBACK
},
175 { ui::VKEY_Q
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_EXIT
},
176 { ui::VKEY_N
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
177 IDC_NEW_INCOGNITO_WINDOW
},
178 { ui::VKEY_T
, ui::EF_CONTROL_DOWN
, IDC_NEW_TAB
},
179 { ui::VKEY_N
, ui::EF_CONTROL_DOWN
, IDC_NEW_WINDOW
},
180 { ui::VKEY_T
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
, IDC_RESTORE_TAB
},
181 { ui::VKEY_ESCAPE
, ui::EF_SHIFT_DOWN
, IDC_TASK_MANAGER
},
184 const size_t kAcceleratorMapLength
= arraysize(kAcceleratorMap
);
187 // Below we map Chrome command ids to Ash action ids for commands that have
188 // an shortcut that is handled by Ash (instead of Chrome). Adding entries
189 // here will show shortcut text on menus. See comment above.
190 struct ChromeCmdId2AshActionId
{
191 const int chrome_cmd_id
;
192 const ash::AcceleratorAction ash_action_id
;
194 const ChromeCmdId2AshActionId kChromeCmdId2AshActionId
[] = {
195 #if defined(GOOGLE_CHROME_BUILD)
196 { IDC_FEEDBACK
, ash::OPEN_FEEDBACK_PAGE
},
198 { IDC_EXIT
, ash::EXIT
},
199 { IDC_NEW_INCOGNITO_WINDOW
, ash::NEW_INCOGNITO_WINDOW
},
200 { IDC_NEW_TAB
, ash::NEW_TAB
},
201 { IDC_NEW_WINDOW
, ash::NEW_WINDOW
},
202 { IDC_RESTORE_TAB
, ash::RESTORE_TAB
},
203 { IDC_TASK_MANAGER
, ash::SHOW_TASK_MANAGER
},
205 const size_t kChromeCmdId2AshActionIdLength
=
206 arraysize(kChromeCmdId2AshActionId
);
207 #endif // defined(USE_ASH)
211 std::vector
<AcceleratorMapping
> GetAcceleratorList() {
212 return std::vector
<AcceleratorMapping
>(
213 kAcceleratorMap
, kAcceleratorMap
+ kAcceleratorMapLength
);
216 bool GetAshAcceleratorForCommandId(int command_id
,
217 HostDesktopType host_desktop_type
,
218 ui::Accelerator
* accelerator
) {
220 if (host_desktop_type
!= chrome::HOST_DESKTOP_TYPE_ASH
)
222 for (size_t i
= 0; i
< kChromeCmdId2AshActionIdLength
; ++i
) {
223 if (command_id
== kChromeCmdId2AshActionId
[i
].chrome_cmd_id
) {
224 for (size_t j
= 0; j
< ash::kAcceleratorDataLength
; ++j
) {
225 if (kChromeCmdId2AshActionId
[i
].ash_action_id
==
226 ash::kAcceleratorData
[j
].action
) {
227 *accelerator
= ui::Accelerator(ash::kAcceleratorData
[j
].keycode
,
228 ash::kAcceleratorData
[j
].modifiers
);
234 #endif // defined(USE_ASH)
238 bool GetStandardAcceleratorForCommandId(int command_id
,
239 ui::Accelerator
* accelerator
) {
240 // The standard Ctrl-X, Ctrl-V and Ctrl-C are not defined as accelerators
242 switch (command_id
) {
244 *accelerator
= ui::Accelerator(ui::VKEY_X
, ui::EF_CONTROL_DOWN
);
247 *accelerator
= ui::Accelerator(ui::VKEY_C
, ui::EF_CONTROL_DOWN
);
250 *accelerator
= ui::Accelerator(ui::VKEY_V
, ui::EF_CONTROL_DOWN
);
256 } // namespace chrome