| 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 <AppKit/NSEvent.h> | 5 #include <AppKit/NSEvent.h> |
| 6 #include <Carbon/Carbon.h> | 6 #include <Carbon/Carbon.h> |
| 7 | 7 |
| 8 #include "chrome/browser/global_keyboard_shortcuts_mac.h" | 8 #include "chrome/browser/global_keyboard_shortcuts_mac.h" |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 return CommandForKeyboardShortcut(GetBrowserKeyboardShortcutTable, | 166 return CommandForKeyboardShortcut(GetBrowserKeyboardShortcutTable, |
| 167 command_key, shift_key, | 167 command_key, shift_key, |
| 168 cntrl_key, opt_key, vkey_code, | 168 cntrl_key, opt_key, vkey_code, |
| 169 key_char); | 169 key_char); |
| 170 } | 170 } |
| 171 | 171 |
| 172 unichar KeyCharacterForEvent(NSEvent* event) { | 172 unichar KeyCharacterForEvent(NSEvent* event) { |
| 173 NSString* eventString = [event charactersIgnoringModifiers]; | 173 NSString* eventString = [event charactersIgnoringModifiers]; |
| 174 NSString* characters = [event characters]; | 174 NSString* characters = [event characters]; |
| 175 | 175 |
| 176 // Character pairs that undergo BiDi mirrored. | |
| 177 // There are actually many more such pairs, but these are the ones that | |
| 178 // are likely to show up in keyboard shortcuts. | |
| 179 const struct { | |
| 180 unichar a; | |
| 181 unichar b; | |
| 182 } kMirroredBiDiChars[] = { | |
| 183 {'{', '}'}, | |
| 184 {'[', ']'}, | |
| 185 {'(', ')'}, | |
| 186 }; | |
| 187 | |
| 188 if ([eventString length] != 1) | 176 if ([eventString length] != 1) |
| 189 return 0; | 177 return 0; |
| 190 | 178 |
| 191 if ([characters length] != 1) | 179 if ([characters length] != 1) |
| 192 return [eventString characterAtIndex:0]; | 180 return [eventString characterAtIndex:0]; |
| 193 | 181 |
| 182 // Some characters are BiDi mirrored. The mirroring is different |
| 183 // for different OS versions. Instead of having a mirror table, map |
| 184 // raw/processed pairs to desired outputs. |
| 185 const struct { |
| 186 unichar rawChar; |
| 187 unichar unmodChar; |
| 188 unichar targetChar; |
| 189 } kCharMapping[] = { |
| 190 // OSX 10.8 mirrors certain chars. |
| 191 {'{', '}', '{'}, |
| 192 {'}', '{', '}'}, |
| 193 {'(', ')', '('}, |
| 194 {')', '(', ')'}, |
| 195 |
| 196 // OSX 10.9 has the unshifted raw char. |
| 197 {'[', '}', '{'}, |
| 198 {']', '{', '}'}, |
| 199 {'9', ')', '('}, |
| 200 {'0', '(', ')'}, |
| 201 |
| 202 // These are the same either way. |
| 203 {'[', ']', '['}, |
| 204 {']', '[', ']'}, |
| 205 }; |
| 206 |
| 194 unichar noModifiersChar = [eventString characterAtIndex:0]; | 207 unichar noModifiersChar = [eventString characterAtIndex:0]; |
| 195 unichar rawChar = [characters characterAtIndex:0]; | 208 unichar rawChar = [characters characterAtIndex:0]; |
| 196 // When both |characters| and |charactersIgnoringModifiers| are ascii, | 209 |
| 197 // return the first character of |characters|, if... | 210 // Only apply transformation table for ascii. |
| 198 if (isascii(noModifiersChar) && isascii(rawChar)) { | 211 if (isascii(noModifiersChar) && isascii(rawChar)) { |
| 199 // |characters| is an alphabet (mainly for dvorak-qwerty layout), or | 212 // Alphabetic characters aren't mirrored, go with the raw character. |
| 213 // [A previous partial comment said something about Dvorak?] |
| 200 if (isalpha(rawChar)) | 214 if (isalpha(rawChar)) |
| 201 return rawChar; | 215 return rawChar; |
| 202 | 216 |
| 203 // http://crbug.com/42517 | 217 // http://crbug.com/42517 |
| 218 // http://crbug.com/315379 |
| 204 // In RTL keyboard layouts, Cocoa mirrors characters in the string | 219 // In RTL keyboard layouts, Cocoa mirrors characters in the string |
| 205 // returned by [event charactersIgnoringModifiers]. In this case, return | 220 // returned by [event charactersIgnoringModifiers]. In this case, return |
| 206 // the raw (unmirrored) char. | 221 // the raw (unmirrored) char. |
| 207 // FIXME: If there is a need to add any more characters to the | 222 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kCharMapping); ++i) { |
| 208 // kMirroredBiDiChars table, then it's probably better to use ICU's | 223 if (rawChar == kCharMapping[i].rawChar && |
| 209 // u_charMirror() function to perform this test. | 224 noModifiersChar == kCharMapping[i].unmodChar) { |
| 210 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kMirroredBiDiChars); ++i) { | 225 return kCharMapping[i].targetChar; |
| 211 const unichar& a = kMirroredBiDiChars[i].a; | 226 } |
| 212 const unichar& b = kMirroredBiDiChars[i].b; | |
| 213 if ((rawChar == a && noModifiersChar == b) || | |
| 214 (rawChar == b && noModifiersChar == a)) | |
| 215 return rawChar; | |
| 216 } | 227 } |
| 217 | 228 |
| 218 // opt/alt modifier is set (e.g. on german layout we want '{' for opt-8). | 229 // opt/alt modifier is set (e.g. on german layout we want '{' for opt-8). |
| 219 if ([event modifierFlags] & NSAlternateKeyMask) | 230 if ([event modifierFlags] & NSAlternateKeyMask) |
| 220 return [characters characterAtIndex:0]; | 231 return rawChar; |
| 221 } | 232 } |
| 222 | 233 |
| 223 return [eventString characterAtIndex:0]; | 234 return noModifiersChar; |
| 224 } | 235 } |
| OLD | NEW |