OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/global_keyboard_shortcuts_mac.h" | 5 #include "chrome/browser/global_keyboard_shortcuts_mac.h" |
6 | 6 |
7 #import <AppKit/AppKit.h> | 7 #import <AppKit/AppKit.h> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
(...skipping 15 matching lines...) Expand all Loading... | |
26 result = item; | 26 result = item; |
27 } | 27 } |
28 | 28 |
29 if (result) | 29 if (result) |
30 break; | 30 break; |
31 } | 31 } |
32 | 32 |
33 return result; | 33 return result; |
34 } | 34 } |
35 | 35 |
36 } // namespace | 36 bool MatchesEventForKeyboardShortcut(const KeyboardShortcutData& shortcut, |
37 | 37 bool command_key, |
38 // Basically, there are two kinds of keyboard shortcuts: Ones that should work | 38 bool shift_key, |
39 // only if the tab contents is focused (BrowserKeyboardShortcut), and ones that | 39 bool cntrl_key, |
40 // should work in all other cases (WindowKeyboardShortcut). In the latter case, | 40 bool opt_key, |
41 // we differentiate between shortcuts that are checked before any other view | 41 int vkey_code, |
42 // gets the chance to handle them (WindowKeyboardShortcut) or after all views | 42 unichar key_char) { |
43 // had a chance but did not handle the keypress event | |
44 // (DelayedWindowKeyboardShortcut). | |
45 | |
46 const KeyboardShortcutData* GetWindowKeyboardShortcutTable( | |
47 size_t* num_entries) { | |
48 static const KeyboardShortcutData keyboard_shortcuts[] = { | |
49 // cmd shift cntrl option | |
50 // --- ----- ----- ------ | |
51 // '{' / '}' characters should be matched earlier than virtual key code | |
52 // (therefore we can match alt-8 as '{' on german keyboards). | |
53 {true, false, false, false, 0, '}', IDC_SELECT_NEXT_TAB}, | |
54 {true, false, false, false, 0, '{', IDC_SELECT_PREVIOUS_TAB}, | |
55 {false, false, true, false, kVK_PageDown, 0, IDC_SELECT_NEXT_TAB}, | |
56 {false, false, true, false, kVK_Tab, 0, IDC_SELECT_NEXT_TAB}, | |
57 {false, false, true, false, kVK_PageUp, 0, IDC_SELECT_PREVIOUS_TAB}, | |
58 {false, true, true, false, kVK_Tab, 0, IDC_SELECT_PREVIOUS_TAB}, | |
59 // Cmd-0..8 select the Nth tab, with cmd-9 being "last tab". | |
60 {true, false, false, false, kVK_ANSI_1, 0, IDC_SELECT_TAB_0}, | |
61 {true, false, false, false, kVK_ANSI_Keypad1, 0, IDC_SELECT_TAB_0}, | |
62 {true, false, false, false, kVK_ANSI_2, 0, IDC_SELECT_TAB_1}, | |
63 {true, false, false, false, kVK_ANSI_Keypad2, 0, IDC_SELECT_TAB_1}, | |
64 {true, false, false, false, kVK_ANSI_3, 0, IDC_SELECT_TAB_2}, | |
65 {true, false, false, false, kVK_ANSI_Keypad3, 0, IDC_SELECT_TAB_2}, | |
66 {true, false, false, false, kVK_ANSI_4, 0, IDC_SELECT_TAB_3}, | |
67 {true, false, false, false, kVK_ANSI_Keypad4, 0, IDC_SELECT_TAB_3}, | |
68 {true, false, false, false, kVK_ANSI_5, 0, IDC_SELECT_TAB_4}, | |
69 {true, false, false, false, kVK_ANSI_Keypad5, 0, IDC_SELECT_TAB_4}, | |
70 {true, false, false, false, kVK_ANSI_6, 0, IDC_SELECT_TAB_5}, | |
71 {true, false, false, false, kVK_ANSI_Keypad6, 0, IDC_SELECT_TAB_5}, | |
72 {true, false, false, false, kVK_ANSI_7, 0, IDC_SELECT_TAB_6}, | |
73 {true, false, false, false, kVK_ANSI_Keypad7, 0, IDC_SELECT_TAB_6}, | |
74 {true, false, false, false, kVK_ANSI_8, 0, IDC_SELECT_TAB_7}, | |
75 {true, false, false, false, kVK_ANSI_Keypad8, 0, IDC_SELECT_TAB_7}, | |
76 {true, false, false, false, kVK_ANSI_9, 0, IDC_SELECT_LAST_TAB}, | |
77 {true, false, false, false, kVK_ANSI_Keypad9, 0, IDC_SELECT_LAST_TAB}, | |
78 {true, true, false, false, kVK_ANSI_M, 0, IDC_SHOW_AVATAR_MENU}, | |
79 {true, false, false, true, kVK_ANSI_L, 0, IDC_SHOW_DOWNLOADS}, | |
80 }; | |
81 | |
82 *num_entries = arraysize(keyboard_shortcuts); | |
83 | |
84 return keyboard_shortcuts; | |
85 } | |
86 | |
87 const KeyboardShortcutData* GetDelayedWindowKeyboardShortcutTable( | |
88 size_t* num_entries) { | |
89 static const KeyboardShortcutData keyboard_shortcuts[] = { | |
90 //cmd shift cntrl option | |
91 //--- ----- ----- ------ | |
92 {false, false, false, false, kVK_Escape, 0, IDC_STOP}, | |
93 }; | |
94 | |
95 *num_entries = arraysize(keyboard_shortcuts); | |
96 | |
97 return keyboard_shortcuts; | |
98 } | |
99 | |
100 const KeyboardShortcutData* GetBrowserKeyboardShortcutTable( | |
101 size_t* num_entries) { | |
102 static const KeyboardShortcutData keyboard_shortcuts[] = { | |
103 //cmd shift cntrl option | |
104 //--- ----- ----- ------ | |
105 {true, false, false, false, kVK_LeftArrow, 0, IDC_BACK}, | |
106 {true, false, false, false, kVK_RightArrow, 0, IDC_FORWARD}, | |
107 {false, false, false, false, kVK_Delete, 0, IDC_BACKSPACE_BACK}, | |
108 {false, true, false, false, kVK_Delete, 0, IDC_BACKSPACE_FORWARD}, | |
109 {true, true, false, false, 0, 'c', IDC_DEV_TOOLS_INSPECT}, | |
110 }; | |
111 | |
112 *num_entries = arraysize(keyboard_shortcuts); | |
113 | |
114 return keyboard_shortcuts; | |
115 } | |
116 | |
117 static bool MatchesEventForKeyboardShortcut( | |
118 const KeyboardShortcutData& shortcut, | |
119 bool command_key, bool shift_key, bool cntrl_key, bool opt_key, | |
120 int vkey_code, unichar key_char) { | |
121 // Expects that one of |key_char| or |vkey_code| is 0. | 43 // Expects that one of |key_char| or |vkey_code| is 0. |
122 DCHECK((shortcut.key_char == 0) ^ (shortcut.vkey_code == 0)); | 44 DCHECK((shortcut.key_char == 0) ^ (shortcut.vkey_code == 0)); |
123 if (shortcut.key_char) { | 45 if (shortcut.key_char) { |
124 // Shortcuts that have a |key_char| and have |opt_key| set are mistakes, | 46 // Shortcuts that have a |key_char| and have |opt_key| set are mistakes, |
125 // since |opt_key| is not checked when there is a |key_char|. | 47 // since |opt_key| is not checked when there is a |key_char|. |
126 DCHECK(!shortcut.opt_key); | 48 DCHECK(!shortcut.opt_key); |
127 // The given shortcut key is to be matched by a keyboard character. | 49 // The given shortcut key is to be matched by a keyboard character. |
128 // In this case we ignore shift and opt (alt) key modifiers, because | 50 // In this case we ignore shift and opt (alt) key modifiers, because |
129 // the character may be generated by a combination with those keys. | 51 // the character may be generated by a combination with those keys. |
130 if (shortcut.command_key == command_key && | 52 if (shortcut.command_key == command_key && |
131 shortcut.cntrl_key == cntrl_key && | 53 shortcut.cntrl_key == cntrl_key && |
132 shortcut.key_char == key_char) | 54 shortcut.key_char == key_char) |
133 return true; | 55 return true; |
134 } else if (shortcut.vkey_code) { | 56 } else if (shortcut.vkey_code) { |
135 // The given shortcut key is to be matched by a virtual key code. | 57 // The given shortcut key is to be matched by a virtual key code. |
136 if (shortcut.command_key == command_key && | 58 if (shortcut.command_key == command_key && |
137 shortcut.shift_key == shift_key && | 59 shortcut.shift_key == shift_key && |
138 shortcut.cntrl_key == cntrl_key && | 60 shortcut.cntrl_key == cntrl_key && |
139 shortcut.opt_key == opt_key && | 61 shortcut.opt_key == opt_key && |
140 shortcut.vkey_code == vkey_code) | 62 shortcut.vkey_code == vkey_code) |
141 return true; | 63 return true; |
142 } else { | 64 } else { |
143 NOTREACHED(); // Shouldn't happen. | 65 NOTREACHED(); // Shouldn't happen. |
144 } | 66 } |
145 return false; | 67 return false; |
146 } | 68 } |
147 | 69 |
148 static int CommandForKeyboardShortcut( | 70 int CommandForKeyboardShortcut(const std::vector<KeyboardShortcutData>& table, |
149 const KeyboardShortcutData* (*get_keyboard_shortcut_table)(size_t*), | 71 bool command_key, |
150 bool command_key, bool shift_key, bool cntrl_key, bool opt_key, | 72 bool shift_key, |
151 int vkey_code, unichar key_char) { | 73 bool cntrl_key, |
152 | 74 bool opt_key, |
75 int vkey_code, | |
76 unichar key_char) { | |
153 // Scan through keycodes and see if it corresponds to one of the global | 77 // Scan through keycodes and see if it corresponds to one of the global |
154 // shortcuts on file. | 78 // shortcuts on file. |
155 // | 79 // |
156 // TODO(jeremy): Change this into a hash table once we get enough | 80 // TODO(jeremy): Change this into a hash table once we get enough |
157 // entries in the array to make a difference. | 81 // entries in the array to make a difference. |
158 // (When turning this into a hash table, note that the current behavior | 82 // (When turning this into a hash table, note that the current behavior |
159 // relies on the order of the table (see the comment for '{' / '}' above). | 83 // relies on the order of the table (see the comment for '{' / '}' above). |
160 size_t num_shortcuts = 0; | 84 for (const auto& shortcut : table) { |
161 const KeyboardShortcutData *it = get_keyboard_shortcut_table(&num_shortcuts); | 85 if (MatchesEventForKeyboardShortcut(shortcut, command_key, shift_key, |
162 for (size_t i = 0; i < num_shortcuts; ++i, ++it) { | 86 cntrl_key, opt_key, vkey_code, |
163 if (MatchesEventForKeyboardShortcut(*it, command_key, shift_key, cntrl_key, | 87 key_char)) |
164 opt_key, vkey_code, key_char)) | 88 return shortcut.chrome_command; |
165 return it->chrome_command; | |
166 } | 89 } |
167 | 90 |
168 return -1; | 91 return -1; |
169 } | 92 } |
170 | 93 |
94 } // namespace | |
95 | |
96 // MacViews: Lists shortcuts that are impossible to migrate to | |
97 // accelerator_table.cc (crbug.com/25946) as well as those that should work when | |
98 // Omnibox is in focus. | |
tapted
2016/11/14 22:44:49
This doesn't sound right.
BrowserView::LoadAccele
themblsha
2016/11/15 11:43:33
No. The Views code doesn't see the event at all.
| |
99 // | |
100 // Cocoa: see comment in global_keyboard_shortcuts_cocoa_mac.mm. | |
101 const std::vector<KeyboardShortcutData>& GetWindowKeyboardShortcutTable() { | |
102 CR_DEFINE_STATIC_LOCAL(std::vector<KeyboardShortcutData>, result, ({ | |
103 // cmd shift cntrl option | |
104 // --- ----- ----- ------ | |
105 // '{' / '}' characters should be matched earlier than virtual key code | |
106 // (therefore we can match alt-8 as '{' on german keyboards). | |
107 {true, false, false, false, 0, '}', IDC_SELECT_NEXT_TAB}, | |
108 {true, false, false, false, 0, '{', IDC_SELECT_PREVIOUS_TAB}, | |
109 {false, false, true, false, kVK_PageDown, 0, IDC_SELECT_NEXT_TAB}, | |
110 {false, false, true, false, kVK_Tab, 0, IDC_SELECT_NEXT_TAB}, | |
111 {false, false, true, false, kVK_PageUp, 0, IDC_SELECT_PREVIOUS_TAB}, | |
112 {false, true, true, false, kVK_Tab, 0, IDC_SELECT_PREVIOUS_TAB}, | |
113 // Cmd-0..8 select the Nth tab, with cmd-9 being "last tab". | |
114 {true, false, false, false, kVK_ANSI_1, 0, IDC_SELECT_TAB_0}, | |
115 {true, false, false, false, kVK_ANSI_Keypad1, 0, IDC_SELECT_TAB_0}, | |
116 {true, false, false, false, kVK_ANSI_2, 0, IDC_SELECT_TAB_1}, | |
117 {true, false, false, false, kVK_ANSI_Keypad2, 0, IDC_SELECT_TAB_1}, | |
118 {true, false, false, false, kVK_ANSI_3, 0, IDC_SELECT_TAB_2}, | |
119 {true, false, false, false, kVK_ANSI_Keypad3, 0, IDC_SELECT_TAB_2}, | |
120 {true, false, false, false, kVK_ANSI_4, 0, IDC_SELECT_TAB_3}, | |
121 {true, false, false, false, kVK_ANSI_Keypad4, 0, IDC_SELECT_TAB_3}, | |
122 {true, false, false, false, kVK_ANSI_5, 0, IDC_SELECT_TAB_4}, | |
123 {true, false, false, false, kVK_ANSI_Keypad5, 0, IDC_SELECT_TAB_4}, | |
124 {true, false, false, false, kVK_ANSI_6, 0, IDC_SELECT_TAB_5}, | |
125 {true, false, false, false, kVK_ANSI_Keypad6, 0, IDC_SELECT_TAB_5}, | |
126 {true, false, false, false, kVK_ANSI_7, 0, IDC_SELECT_TAB_6}, | |
127 {true, false, false, false, kVK_ANSI_Keypad7, 0, IDC_SELECT_TAB_6}, | |
128 {true, false, false, false, kVK_ANSI_8, 0, IDC_SELECT_TAB_7}, | |
129 {true, false, false, false, kVK_ANSI_Keypad8, 0, IDC_SELECT_TAB_7}, | |
130 {true, false, false, false, kVK_ANSI_9, 0, IDC_SELECT_LAST_TAB}, | |
131 {true, false, false, false, kVK_ANSI_Keypad9, 0, IDC_SELECT_LAST_TAB}, | |
132 {true, true, false, false, kVK_ANSI_M, 0, IDC_SHOW_AVATAR_MENU}, | |
133 {true, false, false, true, kVK_ANSI_L, 0, IDC_SHOW_DOWNLOADS}, | |
134 })); | |
135 return result; | |
136 } | |
137 | |
171 int CommandForWindowKeyboardShortcut( | 138 int CommandForWindowKeyboardShortcut( |
172 bool command_key, bool shift_key, bool cntrl_key, bool opt_key, | 139 bool command_key, bool shift_key, bool cntrl_key, bool opt_key, |
173 int vkey_code, unichar key_char) { | 140 int vkey_code, unichar key_char) { |
174 return CommandForKeyboardShortcut(GetWindowKeyboardShortcutTable, | 141 return CommandForKeyboardShortcut(GetWindowKeyboardShortcutTable(), |
175 command_key, shift_key, | 142 command_key, shift_key, |
176 cntrl_key, opt_key, vkey_code, | 143 cntrl_key, opt_key, vkey_code, |
177 key_char); | 144 key_char); |
178 } | 145 } |
179 | 146 |
180 int CommandForDelayedWindowKeyboardShortcut( | 147 int CommandForDelayedWindowKeyboardShortcut( |
181 bool command_key, bool shift_key, bool cntrl_key, bool opt_key, | 148 bool command_key, bool shift_key, bool cntrl_key, bool opt_key, |
182 int vkey_code, unichar key_char) { | 149 int vkey_code, unichar key_char) { |
183 return CommandForKeyboardShortcut(GetDelayedWindowKeyboardShortcutTable, | 150 return CommandForKeyboardShortcut(GetDelayedWindowKeyboardShortcutTable(), |
184 command_key, shift_key, | 151 command_key, shift_key, |
185 cntrl_key, opt_key, vkey_code, | 152 cntrl_key, opt_key, vkey_code, |
186 key_char); | 153 key_char); |
187 } | 154 } |
188 | 155 |
189 int CommandForBrowserKeyboardShortcut( | 156 int CommandForBrowserKeyboardShortcut( |
190 bool command_key, bool shift_key, bool cntrl_key, bool opt_key, | 157 bool command_key, bool shift_key, bool cntrl_key, bool opt_key, |
191 int vkey_code, unichar key_char) { | 158 int vkey_code, unichar key_char) { |
192 return CommandForKeyboardShortcut(GetBrowserKeyboardShortcutTable, | 159 return CommandForKeyboardShortcut(GetBrowserKeyboardShortcutTable(), |
193 command_key, shift_key, | 160 command_key, shift_key, |
194 cntrl_key, opt_key, vkey_code, | 161 cntrl_key, opt_key, vkey_code, |
195 key_char); | 162 key_char); |
196 } | 163 } |
197 | 164 |
198 int CommandForKeyEvent(NSEvent* event) { | 165 int CommandForKeyEvent(NSEvent* event) { |
199 if ([event type] != NSKeyDown) | 166 if ([event type] != NSKeyDown) |
200 return -1; | 167 return -1; |
201 | 168 |
202 // Look in menu. | 169 // Look in menu. |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
294 } | 261 } |
295 } | 262 } |
296 | 263 |
297 // opt/alt modifier is set (e.g. on german layout we want '{' for opt-8). | 264 // opt/alt modifier is set (e.g. on german layout we want '{' for opt-8). |
298 if ([event modifierFlags] & NSAlternateKeyMask) | 265 if ([event modifierFlags] & NSAlternateKeyMask) |
299 return rawChar; | 266 return rawChar; |
300 } | 267 } |
301 | 268 |
302 return noModifiersChar; | 269 return noModifiersChar; |
303 } | 270 } |
OLD | NEW |