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/gtk/accelerators_gtk.h"
8 #include <gdk/gdkkeysyms.h>
9 #include <X11/XF86keysym.h>
11 #include "base/memory/singleton.h"
12 #include "chrome/app/chrome_command_ids.h"
13 #include "ui/base/accelerators/platform_accelerator_gtk.h"
14 #include "ui/events/keycodes/keyboard_code_conversion_gtk.h"
18 // A mostly complete list of chrome's accelerators. When one command has
19 // multiple shortcuts, the first one in this list is considered "primary",
20 // meaning that it will be displayed in context menus.
21 const struct AcceleratorMapping
{
24 GdkModifierType modifier_type
;
25 } kAcceleratorMap
[] = {
27 { GDK_k
, IDC_FOCUS_SEARCH
, GDK_CONTROL_MASK
},
28 { GDK_e
, IDC_FOCUS_SEARCH
, GDK_CONTROL_MASK
},
29 { XF86XK_Search
, IDC_FOCUS_SEARCH
, GdkModifierType(0) },
30 { GDK_l
, IDC_FOCUS_LOCATION
, GDK_CONTROL_MASK
},
31 { GDK_d
, IDC_FOCUS_LOCATION
, GDK_MOD1_MASK
},
32 { GDK_F6
, IDC_FOCUS_LOCATION
, GdkModifierType(0) },
33 { XF86XK_OpenURL
, IDC_FOCUS_LOCATION
, GdkModifierType(0) },
34 { XF86XK_Go
, IDC_FOCUS_LOCATION
, GdkModifierType(0) },
36 // Tab/window controls.
37 { GDK_Page_Down
, IDC_SELECT_NEXT_TAB
, GDK_CONTROL_MASK
},
38 { GDK_Page_Up
, IDC_SELECT_PREVIOUS_TAB
, GDK_CONTROL_MASK
},
39 { GDK_Page_Down
, IDC_MOVE_TAB_NEXT
,
40 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
41 { GDK_Page_Up
, IDC_MOVE_TAB_PREVIOUS
,
42 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
43 { GDK_Page_Up
, IDC_SELECT_PREVIOUS_TAB
, GDK_CONTROL_MASK
},
44 { GDK_w
, IDC_CLOSE_TAB
, GDK_CONTROL_MASK
},
45 { GDK_t
, IDC_RESTORE_TAB
,
46 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
47 { GDK_t
, IDC_NEW_TAB
, GDK_CONTROL_MASK
},
48 { GDK_n
, IDC_NEW_WINDOW
, GDK_CONTROL_MASK
},
49 { GDK_n
, IDC_NEW_INCOGNITO_WINDOW
,
50 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
51 { GDK_w
, IDC_CLOSE_WINDOW
,
52 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
54 { GDK_1
, IDC_SELECT_TAB_0
, GDK_CONTROL_MASK
},
55 { GDK_2
, IDC_SELECT_TAB_1
, GDK_CONTROL_MASK
},
56 { GDK_3
, IDC_SELECT_TAB_2
, GDK_CONTROL_MASK
},
57 { GDK_4
, IDC_SELECT_TAB_3
, GDK_CONTROL_MASK
},
58 { GDK_5
, IDC_SELECT_TAB_4
, GDK_CONTROL_MASK
},
59 { GDK_6
, IDC_SELECT_TAB_5
, GDK_CONTROL_MASK
},
60 { GDK_7
, IDC_SELECT_TAB_6
, GDK_CONTROL_MASK
},
61 { GDK_8
, IDC_SELECT_TAB_7
, GDK_CONTROL_MASK
},
62 { GDK_9
, IDC_SELECT_LAST_TAB
, GDK_CONTROL_MASK
},
64 { GDK_1
, IDC_SELECT_TAB_0
, GDK_MOD1_MASK
},
65 { GDK_2
, IDC_SELECT_TAB_1
, GDK_MOD1_MASK
},
66 { GDK_3
, IDC_SELECT_TAB_2
, GDK_MOD1_MASK
},
67 { GDK_4
, IDC_SELECT_TAB_3
, GDK_MOD1_MASK
},
68 { GDK_5
, IDC_SELECT_TAB_4
, GDK_MOD1_MASK
},
69 { GDK_6
, IDC_SELECT_TAB_5
, GDK_MOD1_MASK
},
70 { GDK_7
, IDC_SELECT_TAB_6
, GDK_MOD1_MASK
},
71 { GDK_8
, IDC_SELECT_TAB_7
, GDK_MOD1_MASK
},
72 { GDK_9
, IDC_SELECT_LAST_TAB
, GDK_MOD1_MASK
},
74 { GDK_KP_1
, IDC_SELECT_TAB_0
, GDK_CONTROL_MASK
},
75 { GDK_KP_2
, IDC_SELECT_TAB_1
, GDK_CONTROL_MASK
},
76 { GDK_KP_3
, IDC_SELECT_TAB_2
, GDK_CONTROL_MASK
},
77 { GDK_KP_4
, IDC_SELECT_TAB_3
, GDK_CONTROL_MASK
},
78 { GDK_KP_5
, IDC_SELECT_TAB_4
, GDK_CONTROL_MASK
},
79 { GDK_KP_6
, IDC_SELECT_TAB_5
, GDK_CONTROL_MASK
},
80 { GDK_KP_7
, IDC_SELECT_TAB_6
, GDK_CONTROL_MASK
},
81 { GDK_KP_8
, IDC_SELECT_TAB_7
, GDK_CONTROL_MASK
},
82 { GDK_KP_9
, IDC_SELECT_LAST_TAB
, GDK_CONTROL_MASK
},
84 { GDK_KP_1
, IDC_SELECT_TAB_0
, GDK_MOD1_MASK
},
85 { GDK_KP_2
, IDC_SELECT_TAB_1
, GDK_MOD1_MASK
},
86 { GDK_KP_3
, IDC_SELECT_TAB_2
, GDK_MOD1_MASK
},
87 { GDK_KP_4
, IDC_SELECT_TAB_3
, GDK_MOD1_MASK
},
88 { GDK_KP_5
, IDC_SELECT_TAB_4
, GDK_MOD1_MASK
},
89 { GDK_KP_6
, IDC_SELECT_TAB_5
, GDK_MOD1_MASK
},
90 { GDK_KP_7
, IDC_SELECT_TAB_6
, GDK_MOD1_MASK
},
91 { GDK_KP_8
, IDC_SELECT_TAB_7
, GDK_MOD1_MASK
},
92 { GDK_KP_9
, IDC_SELECT_LAST_TAB
, GDK_MOD1_MASK
},
94 { GDK_F4
, IDC_CLOSE_TAB
, GDK_CONTROL_MASK
},
95 { GDK_F4
, IDC_CLOSE_WINDOW
, GDK_MOD1_MASK
},
98 { GDK_KP_Add
, IDC_ZOOM_PLUS
, GDK_CONTROL_MASK
},
99 { GDK_plus
, IDC_ZOOM_PLUS
,
100 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
101 { GDK_equal
, IDC_ZOOM_PLUS
, GDK_CONTROL_MASK
},
102 { XF86XK_ZoomIn
, IDC_ZOOM_PLUS
, GdkModifierType(0) },
103 { GDK_KP_0
, IDC_ZOOM_NORMAL
, GDK_CONTROL_MASK
},
104 { GDK_0
, IDC_ZOOM_NORMAL
, GDK_CONTROL_MASK
},
105 { GDK_KP_Subtract
, IDC_ZOOM_MINUS
, GDK_CONTROL_MASK
},
106 { GDK_minus
, IDC_ZOOM_MINUS
, GDK_CONTROL_MASK
},
107 { GDK_underscore
, IDC_ZOOM_MINUS
,
108 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
109 { XF86XK_ZoomOut
, IDC_ZOOM_MINUS
, GdkModifierType(0) },
112 { GDK_g
, IDC_FIND_NEXT
, GDK_CONTROL_MASK
},
113 { GDK_F3
, IDC_FIND_NEXT
, GdkModifierType(0) },
114 { GDK_g
, IDC_FIND_PREVIOUS
,
115 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
116 { GDK_F3
, IDC_FIND_PREVIOUS
, GDK_SHIFT_MASK
},
118 // Navigation / toolbar buttons.
119 { GDK_Home
, IDC_HOME
, GDK_MOD1_MASK
},
120 { XF86XK_HomePage
, IDC_HOME
, GdkModifierType(0) },
121 { GDK_Escape
, IDC_STOP
, GdkModifierType(0) },
122 { XF86XK_Stop
, IDC_STOP
, GdkModifierType(0) },
123 { GDK_Left
, IDC_BACK
, GDK_MOD1_MASK
},
124 { XF86XK_Back
, IDC_BACK
, GdkModifierType(0) },
125 { GDK_Right
, IDC_FORWARD
, GDK_MOD1_MASK
},
126 { XF86XK_Forward
, IDC_FORWARD
, GdkModifierType(0) },
127 { GDK_r
, IDC_RELOAD
, GDK_CONTROL_MASK
},
128 { GDK_r
, IDC_RELOAD_IGNORING_CACHE
,
129 GdkModifierType(GDK_CONTROL_MASK
|GDK_SHIFT_MASK
) },
130 { GDK_F5
, IDC_RELOAD
, GdkModifierType(0) },
131 { GDK_F5
, IDC_RELOAD_IGNORING_CACHE
, GDK_CONTROL_MASK
},
132 { GDK_F5
, IDC_RELOAD_IGNORING_CACHE
, GDK_SHIFT_MASK
},
133 { XF86XK_Reload
, IDC_RELOAD
, GdkModifierType(0) },
134 { XF86XK_Refresh
, IDC_RELOAD
, GdkModifierType(0) },
137 { GDK_u
, IDC_VIEW_SOURCE
, GDK_CONTROL_MASK
},
138 { GDK_i
, IDC_DEV_TOOLS
,
139 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
140 { GDK_F12
, IDC_DEV_TOOLS_TOGGLE
, GdkModifierType(0) },
141 { GDK_j
, IDC_DEV_TOOLS_CONSOLE
,
142 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
143 { GDK_c
, IDC_DEV_TOOLS_INSPECT
,
144 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
145 { GDK_Escape
, IDC_TASK_MANAGER
, GDK_SHIFT_MASK
},
148 { GDK_c
, IDC_COPY
, GDK_CONTROL_MASK
},
149 { GDK_x
, IDC_CUT
, GDK_CONTROL_MASK
},
150 { GDK_v
, IDC_PASTE
, GDK_CONTROL_MASK
},
153 { GDK_d
, IDC_BOOKMARK_ALL_TABS
,
154 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
155 { GDK_d
, IDC_BOOKMARK_PAGE
, GDK_CONTROL_MASK
},
156 { GDK_o
, IDC_OPEN_FILE
, GDK_CONTROL_MASK
},
157 { GDK_f
, IDC_FIND
, GDK_CONTROL_MASK
},
158 { GDK_p
, IDC_PRINT
, GDK_CONTROL_MASK
},
159 { GDK_p
, IDC_ADVANCED_PRINT
,
160 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
161 { GDK_b
, IDC_SHOW_BOOKMARK_BAR
,
162 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
163 { GDK_o
, IDC_SHOW_BOOKMARK_MANAGER
,
164 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
165 { GDK_F11
, IDC_FULLSCREEN
, GdkModifierType(0) },
166 { GDK_Delete
, IDC_CLEAR_BROWSING_DATA
,
167 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
168 { GDK_h
, IDC_SHOW_HISTORY
, GDK_CONTROL_MASK
},
169 { GDK_j
, IDC_SHOW_DOWNLOADS
, GDK_CONTROL_MASK
},
170 { GDK_F1
, IDC_HELP_PAGE_VIA_KEYBOARD
, GdkModifierType(0) },
171 { XF86XK_AddFavorite
, IDC_BOOKMARK_PAGE
, GdkModifierType(0) },
172 { XF86XK_Favorites
, IDC_SHOW_BOOKMARK_BAR
, GdkModifierType(0) },
173 { XF86XK_History
, IDC_SHOW_HISTORY
, GdkModifierType(0) },
174 { GDK_q
, IDC_EXIT
, GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
175 { GDK_s
, IDC_SAVE_PAGE
, GDK_CONTROL_MASK
},
176 { GDK_e
, IDC_SHOW_APP_MENU
, GDK_MOD1_MASK
},
177 { GDK_f
, IDC_SHOW_APP_MENU
, GDK_MOD1_MASK
},
178 { GDK_m
, IDC_SHOW_AVATAR_MENU
,
179 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
)},
180 { GDK_greater
, IDC_TOGGLE_SPEECH_INPUT
,
181 GdkModifierType(GDK_CONTROL_MASK
| GDK_SHIFT_MASK
) },
187 AcceleratorsGtk
* AcceleratorsGtk::GetInstance() {
188 return Singleton
<AcceleratorsGtk
>::get();
191 const ui::Accelerator
* AcceleratorsGtk::GetPrimaryAcceleratorForCommand(
193 AcceleratorMap::const_iterator
i(primary_accelerators_
.find(command_id
));
194 return i
!= primary_accelerators_
.end() ? &i
->second
: NULL
;
197 AcceleratorsGtk::AcceleratorsGtk() {
198 for (size_t i
= 0; i
< arraysize(kAcceleratorMap
); ++i
) {
199 const AcceleratorMapping
& entry
= kAcceleratorMap
[i
];
201 ui::Accelerator accelerator
= ui::AcceleratorForGdkKeyCodeAndModifier(
202 entry
.keyval
, entry
.modifier_type
);
204 all_accelerators_
.push_back(std::make_pair(entry
.command_id
, accelerator
));
205 if (primary_accelerators_
.find(entry
.command_id
) ==
206 primary_accelerators_
.end()) {
207 primary_accelerators_
[entry
.command_id
] = accelerator
;
212 AcceleratorsGtk::~AcceleratorsGtk() {}