3

I was wondering if NSEvent responds to the "Shift" key on the keyboard. I am logging the keyCodes when debugging my app and I don't get a keyCode value for the shift key.

Thanks,

Kevin

EDIT: This is the code I am using from a user response.

-(void)keyDown:(NSEvent*)event
{   

    if ([event modifierFlags] == NSShiftKeyMask) {
        NSLog(@"Shift key pressed");
    }
}

The Shift key is still not being recognized...

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
lab12
  • 6,400
  • 21
  • 68
  • 106
  • This code seems to work only when you press shift a a modifier to _another_ key (e.g., shift + A). It is not triggered when you press the shift key all by itself. – Nicolas Miari Mar 25 '16 at 06:46

5 Answers5

16

Take a look at the flagsChanged: method of NSResponder.

Something like this:

- (void) flagsChanged:(NSEvent *) event {
    if ([event modifierFlags] & NSShiftKeyMask) {
        //Do something
    }
}
Richard
  • 3,316
  • 30
  • 41
9

Your code sample isn't working because -modifierFlags is a bitmask and so testing whether the mask is equal to NSShiftKeyMask won't work. You need to use the bitwise AND operator to test if the flag is set:

if ([event modifierFlags] & NSShiftKeyMask) {
    NSLog(@"Shift key pressed");
}

Also as an aside if you want to store this result in a BOOL you need to check that it is not equal to 0, such as:

BOOL shiftKeyPressed = ([event modifierFlags] & NSShiftKeyMask) != 0;

If you leave it out then the BOOL will evaluate to NO (unless the value you pull out of the bitmask is 1 which is defined as YES; for -modifierFlags this won't happen as the masks start at 1 << 16).

Alex Rozanski
  • 37,815
  • 10
  • 68
  • 69
3

Here is my solution to detecting modifier key changes:

- (void)keyboard:(AMKeyboardView *)keyboard flagsChanged:(NSEvent *)event {
    if ((event.modifierFlags & NSShiftKeyMask) && !lastShiftState) {
        lastShiftState = true;
        //Shift pressed - do something
    }
    else if (!(event.modifierFlags & NSShiftKeyMask) && lastShiftState) {
        lastShiftState = false;
        //Shift released - do something
    }

    else if ((event.modifierFlags & NSFunctionKeyMask) && !lastFnState) {
        lastFnState = true;
        //Fn pressed - do something
    }
    else if (!(event.modifierFlags & NSFunctionKeyMask) && lastFnState) {
        lastFnState = false;
        //Fn released - do something
    }

    else if ((event.modifierFlags & NSControlKeyMask) && !lastControlState) {
        lastControlState = true;
        //Control pressed - do something
    }
    else if (!(event.modifierFlags & NSControlKeyMask) && lastControlState) {
        lastControlState = false;
        //Control released - do something
    }


    else if ((event.modifierFlags & NSAlternateKeyMask) && !lastOptionState) {
        lastOptionState = true;
        //Option pressed - do something
    }
    else if (!(event.modifierFlags & NSAlternateKeyMask) && lastOptionState) {
        lastOptionState = false;
        //Option released - do something
    }

    else if ((event.modifierFlags & NSCommandKeyMask) && !lastCommandState) {
        lastCommandState = true;
        //Command pressed - do something
    }
    else if (!(event.modifierFlags & NSCommandKeyMask) && lastCommandState) {
        lastCommandState = false;
        //Command released - do something
    }

    else NSLog(@"Other");
}

It requires 4 instance variables to store previous states, but can detect the press and release of every modifier key.

Alexander
  • 59,041
  • 12
  • 98
  • 151
  • Something like this is unfortunately necessary as, when a modifier key is released, it doesn't issue it's flag, so in order to track when each modifier is released you need to check both if a flag changes and if a flag was previously set. – Doc Jul 31 '14 at 14:31
  • 1
    Unfortunately, it's possible to desynchronize your variables from reality. For example, when focus is lost on your app whilst a modifier was held down, then release while your app isn't the foreground window. It'd be better to use flagsChanged to call a method which directly samples the keyboard. – Alexander Aug 31 '15 at 20:12
3

Use this to capture changed flags :

- (void)flagsChanged:(NSEvent *)event
{

}
CharlesB
  • 86,532
  • 28
  • 194
  • 218
HappyGL
  • 31
  • 1
2

The Shift key doesn't have a key code, since it's a key modifier. When you get a key event, the presence of the Shift key will be in the modifierFlags field.

Dave DeLong
  • 242,470
  • 58
  • 448
  • 498