--- old/src/macosx/native/sun/awt/AWTView.m 2013-09-09 15:15:10.000000000 +0400 +++ new/src/macosx/native/sun/awt/AWTView.m 2013-09-09 15:15:10.000000000 +0400 @@ -307,10 +307,16 @@ } - (BOOL) performKeyEquivalent: (NSEvent *) event { - [self deliverJavaKeyEventHelper: event]; return NO; } +// This is a SPI that AppKit apparently calls after performKeyEquivalent: +// returned NO. Overriding it to return YES gives us key down events for +// Ctrl-Tab and Ctrl-Esc (which we wouldn't have gotten otherwise). +- (BOOL) _wantsKeyDownForEvent:(NSEvent *)event { + return YES; +} + /** * Utility methods and accessors */ @@ -409,14 +415,6 @@ } -(void) deliverJavaKeyEventHelper: (NSEvent *) event { - static NSEvent* sLastKeyEvent = nil; - if (event == sLastKeyEvent) { - // The event is repeatedly delivered by keyDown: after performKeyEquivalent: - return; - } - [sLastKeyEvent release]; - sLastKeyEvent = [event retain]; - [AWTToolkit eventCountPlusPlus]; JNIEnv *env = [ThreadUtilities getJNIEnv]; --- old/src/macosx/native/sun/awt/CMenuItem.m 2013-09-09 15:15:11.000000000 +0400 +++ new/src/macosx/native/sun/awt/CMenuItem.m 2013-09-09 15:15:11.000000000 +0400 @@ -70,38 +70,7 @@ JNIEnv *env = [ThreadUtilities getJNIEnv]; JNF_COCOA_ENTER(env); - // If we are called as a result of user pressing a shortcut, do nothing, - // because AVTView has already sent corresponding key event to the Java - // layer from performKeyEquivalent. - // There is an exception from the rule above, though: if a window with - // a menu gets minimized by user and there are no other windows to take - // focus, the window's menu won't be removed from the global menu bar. - // However, the Java layer won't handle invocation by a shortcut coming - // from this "frameless" menu, because there are no active windows. This - // means we have to handle it here. NSEvent *currEvent = [[NSApplication sharedApplication] currentEvent]; - if ([currEvent type] == NSKeyDown) { - NSString *menuKey = [sender keyEquivalent]; - NSString *eventKey = [currEvent charactersIgnoringModifiers]; - - // Apple uses characters from private Unicode range for some of the - // keys, so we need to do the same translation here that we do - // for the regular key down events - if ([eventKey length] == 1) { - unichar origChar = [eventKey characterAtIndex:0]; - unichar newChar = NsCharToJavaChar(origChar, 0); - if (newChar == java_awt_event_KeyEvent_CHAR_UNDEFINED) { - newChar = origChar; - } - - eventKey = [NSString stringWithCharacters: &newChar length: 1]; - } - - NSWindow *keyWindow = [NSApp keyWindow]; - if ([menuKey isEqualToString:eventKey] && keyWindow != nil) { - return; - } - } if (fIsCheckbox) { static JNF_CLASS_CACHE(jc_CCheckboxMenuItem, "sun/lwawt/macosx/CCheckboxMenuItem"); --- old/src/macosx/native/sun/osxapp/NSApplicationAWT.m 2013-09-09 15:15:11.000000000 +0400 +++ new/src/macosx/native/sun/osxapp/NSApplicationAWT.m 2013-09-09 15:15:11.000000000 +0400 @@ -341,6 +341,10 @@ if ([event type] == NSApplicationDefined && TS_EQUAL([event timestamp], dummyEventTimestamp)) { [seenDummyEventLock lockWhenCondition:NO]; [seenDummyEventLock unlockWithCondition:YES]; + } else if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask)) { + // Cocoa won't send us key up event when releasing a key while Cmd is down, + // so we have to do it ourselves. + [[self keyWindow] sendEvent:event]; } else { [super sendEvent:event]; }