Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(225)

Side by Side Diff: chrome/browser/cocoa/nsmenuitem_additions.mm

Issue 319001: Add a function that can check if a menu item would be fired by a keypress. (Closed)
Patch Set: remove done todo, 80cols Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #import "chrome/browser/cocoa/nsmenuitem_additions.h"
2
3 #include <Carbon/Carbon.h>
4
5 #include "base/logging.h"
6
7 @implementation NSMenuItem(ChromeAdditions)
8
9 - (BOOL)cr_firesForKeyEvent:(NSEvent*)event {
10 DCHECK([event type] == NSKeyDown);
11 if (![self isEnabled])
12 return NO;
13
14 // In System Preferences->Keyboard->Keyboard Shortcuts, it is possible to add
15 // arbitrary keyboard shortcuts to applications. It is not documented how this
16 // works in detail, but |NSMenuItem| has a method |userKeyEquivalent| that
17 // sounds related.
18 // However, it looks like |userKeyEquivalent| is equal to |keyEquivalent| when
19 // a user shortcut is set in system preferences, i.e. Cocoa automatically
20 // sets/overwrites |keyEquivalent| as well. Hence, this method can ignore
21 // |userKeyEquivalent| and check |keyEquivalent| only.
22
23 // Menu item key equivalents are nearly all stored without modifiers. The
24 // exception is shift, which is included in the key and not in the modifiers
25 // for printable characters (but not for stuff like arrow keys etc).
26 NSString* eventString = [event charactersIgnoringModifiers];
27 NSUInteger eventModifiers =
28 [event modifierFlags] & NSDeviceIndependentModifierFlagsMask;
29
30 if ([eventString length] == 0 || [[self keyEquivalent] length] == 0)
31 return NO;
32
33 // Turns out esc never fires unless cmd or ctrl is down.
34 if ([event keyCode] == kVK_Escape &&
35 (eventModifiers & (NSControlKeyMask | NSCommandKeyMask)) == 0)
36 return NO;
37
38 // From the |NSMenuItem setKeyEquivalent:| documentation:
39 //
40 // If you want to specify the Backspace key as the key equivalent for a menu
41 // item, use a single character string with NSBackspaceCharacter (defined in
42 // NSText.h as 0x08) and for the Forward Delete key, use NSDeleteCharacter
43 // (defined in NSText.h as 0x7F). Note that these are not the same characters
44 // you get from an NSEvent key-down event when pressing those keys.
45 if ([[self keyEquivalent] characterAtIndex:0] == NSBackspaceCharacter
46 && [eventString characterAtIndex:0] == NSDeleteCharacter) {
47 unichar chr = NSBackspaceCharacter;
48 eventString = [NSString stringWithCharacters:&chr length:1];
49
50 // Make sure "shift" is not removed from modifiers below.
51 eventModifiers |= NSFunctionKeyMask;
52 }
53 if ([[self keyEquivalent] characterAtIndex:0] == NSDeleteCharacter &&
54 [eventString characterAtIndex:0] == NSDeleteFunctionKey) {
55 unichar chr = NSDeleteCharacter;
56 eventString = [NSString stringWithCharacters:&chr length:1];
57
58 // Make sure "shift" is not removed from modifiers below.
59 eventModifiers |= NSFunctionKeyMask;
60 }
61
62 // cmd-opt-a gives some weird char as characters and "a" as
63 // charactersWithoutModifiers with an US layout, but an "a" as characters and
64 // a weird char as "charactersWithoutModifiers" with a cyrillic layout. Oh,
65 // Cocoa! Instead of getting the current layout from Text Input Services,
66 // and then requesting the kTISPropertyUnicodeKeyLayoutData and looking in
67 // there, let's try a pragmatic hack.
68 if ([eventString characterAtIndex:0] > 0x7f &&
69 [[event characters] length] > 0 &&
70 [[event characters] characterAtIndex:0] <= 0x7f)
71 eventString = [event characters];
72
73 // When both |characters| and |charactersIgnoringModifiers| are ascii, we
74 // want to use |characters| if it's a character and
75 // |charactersIgnoringModifiers| else (on dvorak, cmd-shift-z should fire
76 // "cmd-:" instead of "cmd-;", but on dvorak-qwerty, cmd-shift-z should fire
77 // cmd-shift-z instead of cmd-:).
78 if ([eventString characterAtIndex:0] <= 0x7f &&
79 [[event characters] length] > 0 &&
80 [[event characters] characterAtIndex:0] <= 0x7f &&
81 isalpha([[event characters] characterAtIndex:0]))
82 eventString = [event characters];
James Su 2009/10/26 03:10:13 Is it possible to make above two if statements eas
Nico 2009/10/26 03:22:14 No, on the dvorak-qwertycmd layout, cmd-z will sen
83
84 // Clear shift key for printable characters.
85 if ((eventModifiers & (NSNumericPadKeyMask | NSFunctionKeyMask)) == 0 &&
86 [[self keyEquivalent] characterAtIndex:0] != '\r')
87 eventModifiers &= ~NSShiftKeyMask;
88
89 // Clear all non-interesting modifiers
90 eventModifiers &= NSCommandKeyMask |
91 NSControlKeyMask |
92 NSAlternateKeyMask |
93 NSShiftKeyMask;
94
95 return [eventString isEqualToString:[self keyEquivalent]]
96 && eventModifiers == [self keyEquivalentModifierMask];
97 }
98
99 @end
100
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/nsmenuitem_additions.h ('k') | chrome/browser/cocoa/nsmenuitem_additions_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698