I have an application in which I’m trying to capture the shift key modifier to perform an action, however when I run the program and press and normal key without the shift key modifier I get a beep and the modifier and key are not sent to my keyDown event. The relevant code is:
NSString* eventChars = [theEvent charactersIgnoringModifiers]; if ([eventChars isEqualTo:@'w']) { newPlayerRow++; direction = eUp; } else if ([eventChars isEqualTo:@'x']) { newPlayerRow--; direction = eDown; } else if ([eventChars isEqualTo:@'a']) { newPlayerCol--; direction = eLeft; } else if ([eventChars isEqualTo:@'d']) { newPlayerCol++; direction = eRight; } else { [super keyDown:theEvent]; return; } // handle the player firing a bullet if (([theEvent modifierFlags] & (NSShiftKeyMask | NSAlphaShiftKeyMask)) != 0) { NSLog(@'Shift key'); [self fireBulletAtColumn:newPlayerCol row:newPlayerRow inDirection:direction]; [self setNeedsDisplay:YES]; } else { ... }
I’m not sure what is causing this, but I’d like to be able to capture shift key presses. Thanks in advance for any help with this problem.
EDIT: Also I’m using a MacBook keyboard if that makes any difference.
EDIT: This is definitely a shift-centric problem as changing (NSShiftKeyMask | NSAlphaShiftKeyMask) to NSControlKeyMask does have the desired effect.
First, -charactersIgnoringModifiers doesn’t ignore the shift key, so you will still get shifted characters (i.e UPPERCASE and !%#$%^&*) returned from it. What’s probably happening in your function is: You press shift-w, your -isEqualTo: returns false because you’re comparing a lowercase ‘w’ and an uppercase ‘W’, and so you return before getting to the shift-detection code at the bottom. The simplest solution is to just check for both.
However, if you want, for example, Arabic keyboardists to be able to easily use your app, you really shouldn’t hardcode characters that may not even appear on the user’s keyboard. The value returned by -keyCode refers to a key’s position on the keyboard, not the represented character. For starters, the constants beginning in ‘kVK_ANSI_’ and ‘kVK_’ in Events.h (you may have to link to Carbon.framework and #include <Carbon/Carbon.h> to use those constants) can be compared to what -keyCode returns, and they refer to the key positions a QWERTY-using USian expects. So you can be (pretty) sure that, regardless of keyboard layout, the keycodes for ‘wasd’ (kVK_ANSI_W, kVK_ANSI_A, etc.) will refer to that triangle in the top left of your user’s keyboard.