diff --git a/ChangeLog b/ChangeLog index 9df006be2..c512b58db 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2010-06-22 Doug Simons + + * Source/NSButton.m: + * Source/NSMatrix.m: + * Source/NSMenu.m: + Further change to performKeyEquivalent: methods to take Shift key + into account for control keys (such as Return and Tab) as well as + function keys, and to honor keyEquivalentModifierMask for cells in + a matrix that implement that method. Also, ignore key events with + zero length (such as the Windows key) which was previously triggering + actions on objects with no keyEquivalent. + 2010-06-22 Wolfgang Lux * Source/NSPopUpButtonCell.m (-initTextCell:pullsDown:, -initWithCoder:, diff --git a/Source/NSButton.m b/Source/NSButton.m index 3fd472bb5..034a4f5da 100644 --- a/Source/NSButton.m +++ b/Source/NSButton.m @@ -515,15 +515,19 @@ static id buttonCellClass = nil; if ([self isEnabled] && (mw == nil || [w worksWhenModal] || mw == w)) { - NSString *key = [self keyEquivalent]; + NSString *keyEquivalent = [self keyEquivalent]; - if (key != nil && [key isEqual: [anEvent charactersIgnoringModifiers]]) + if ([keyEquivalent length] > 0 && [keyEquivalent isEqualToString: [anEvent charactersIgnoringModifiers]]) { - const unsigned int relevantMask = - NSCommandKeyMask | NSAlternateKeyMask | NSControlKeyMask; unsigned int mask = [self keyEquivalentModifierMask]; - - if (([anEvent modifierFlags] & relevantMask) == (mask & relevantMask)) + unsigned int modifiers = [anEvent modifierFlags]; + unsigned int relevantModifiersMask = NSCommandKeyMask | NSAlternateKeyMask | NSControlKeyMask; + /* Take shift key into account only for control keys and arrow and function keys */ + if ((modifiers & NSFunctionKeyMask) + || [[NSCharacterSet controlCharacterSet] characterIsMember:[keyEquivalent characterAtIndex:0]]) + relevantModifiersMask |= NSShiftKeyMask; + + if ((modifiers & relevantModifiersMask) == (mask & relevantModifiersMask)) { [self performClick: self]; return YES; diff --git a/Source/NSMatrix.m b/Source/NSMatrix.m index f4f50e6c9..de7aa27cf 100644 --- a/Source/NSMatrix.m +++ b/Source/NSMatrix.m @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -63,8 +64,8 @@ #include #include -#include "AppKit/NSActionCell.h" #include "AppKit/NSApplication.h" +#include "AppKit/NSButtonCell.h" #include "AppKit/NSColor.h" #include "AppKit/NSCursor.h" #include "AppKit/NSEvent.h" @@ -2580,8 +2581,18 @@ static SEL getSel; */ - (BOOL) performKeyEquivalent: (NSEvent*)theEvent { - NSString *key = [theEvent charactersIgnoringModifiers]; + NSString *keyEquivalent = [theEvent charactersIgnoringModifiers]; + unsigned int modifiers = [theEvent modifierFlags]; int i; + unsigned int relevantModifiersMask = NSCommandKeyMask | NSAlternateKeyMask | NSControlKeyMask; + unichar key = ([keyEquivalent length] > 0 ? [keyEquivalent characterAtIndex:0] : 0); + /* Take shift key into account only for control keys and arrow and function keys */ + if ((modifiers & NSFunctionKeyMask) + || ([keyEquivalent length] > 0 && [[NSCharacterSet controlCharacterSet] characterIsMember:[keyEquivalent characterAtIndex:0]])) + relevantModifiersMask |= NSShiftKeyMask; + + if ([keyEquivalent length] == 0) + return NO; // don't respond to zero-length string (such as the Windows key) for (i = 0; i < _numRows; i++) { @@ -2590,9 +2601,13 @@ static SEL getSel; for (j = 0; j < _numCols; j++) { NSCell *aCell = _cells[i][j];; + unsigned int mask = 0; + if ([aCell respondsToSelector:@selector(keyEquivalentModifierMask)]) + mask = [(NSButtonCell *)aCell keyEquivalentModifierMask]; if ([aCell isEnabled] - && [[aCell keyEquivalent] isEqualToString: key]) + && [[aCell keyEquivalent] isEqualToString: keyEquivalent] + && (mask & relevantModifiersMask) == (modifiers & relevantModifiersMask)) { NSCell *oldSelectedCell = _selectedCell; int oldSelectedRow = _selectedRow; diff --git a/Source/NSMenu.m b/Source/NSMenu.m index 3bf2db8cf..469c4fe4c 100644 --- a/Source/NSMenu.m +++ b/Source/NSMenu.m @@ -1226,10 +1226,15 @@ static BOOL menuBarVisible = YES; unsigned i; unsigned count = [_items count]; NSEventType type = [theEvent type]; - unsigned modifiers = [theEvent modifierFlags]; + unsigned int modifiers = [theEvent modifierFlags]; NSString *keyEquivalent = [theEvent charactersIgnoringModifiers]; + unsigned int relevantModifiersMask = NSCommandKeyMask | NSAlternateKeyMask | NSControlKeyMask; + /* Take shift key into account only for control keys and arrow and function keys */ + if ((modifiers & NSFunctionKeyMask) + || ([keyEquivalent length] > 0 && [[NSCharacterSet controlCharacterSet] characterIsMember:[keyEquivalent characterAtIndex:0]])) + relevantModifiersMask |= NSShiftKeyMask; - if (type != NSKeyDown && type != NSKeyUp) + if ((type != NSKeyDown && type != NSKeyUp) || [keyEquivalent length] == 0) return NO; for (i = 0; i < count; i++) @@ -1239,6 +1244,7 @@ static BOOL menuBarVisible = YES; if ([item hasSubmenu]) { // Recurse through submenus whether active or not. + // Recurse through submenus whether active or not. if ([[item submenu] performKeyEquivalent: theEvent]) { // The event has been handled by an item in the submenu. @@ -1247,16 +1253,10 @@ static BOOL menuBarVisible = YES; } else { - unsigned int relevantMask = - NSCommandKeyMask | NSAlternateKeyMask | NSControlKeyMask; unsigned int mask = [item keyEquivalentModifierMask]; - if (modifiers & NSFunctionKeyMask) - { - relevantMask |= NSShiftKeyMask; - } if ([[item keyEquivalent] isEqualToString: keyEquivalent] - && (modifiers & relevantMask) == (mask & relevantMask)) + && (modifiers & relevantModifiersMask) == (mask & relevantModifiersMask)) { if ([item isEnabled]) {