8139169: [macosx] Action registered for keyboard shortcut is called twice
authoraniyogi
Thu, 10 Dec 2015 14:21:44 +0300
changeset 34809 cfc824c24939
parent 34808 68d9a9175f9e
child 34810 73f1464a9612
8139169: [macosx] Action registered for keyboard shortcut is called twice Reviewed-by: serb, alexsch
jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.m
jdk/test/javax/swing/JMenuItem/8139169/ScreenMenuBarInputTwice.java
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.m	Wed Dec 09 15:20:39 2015 -0800
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.m	Thu Dec 10 14:21:44 2015 +0300
@@ -24,6 +24,7 @@
  */
 
 #import <JavaNativeFoundation/JavaNativeFoundation.h>
+#include <Carbon/Carbon.h>
 
 #import "CMenuItem.h"
 #import "CMenu.h"
@@ -40,7 +41,7 @@
 @implementation CMenuItem
 
 - (id) initWithPeer:(jobject)peer asSeparator: (NSNumber *) asSeparator{
-AWT_ASSERT_APPKIT_THREAD;
+    AWT_ASSERT_APPKIT_THREAD;
     self = [super initWithPeer:peer];
     if (self) {
         if ([asSeparator boolValue]) {
@@ -63,13 +64,48 @@
 - (BOOL) worksWhenModal {
     return YES;
 }
+// This is a method written using Carbon framework methods to remove
+// All modifiers including "Shift" modifier.
+// Example 1: Shortcut set is "Command Shift m" returns "m"
+// Example 2: Shortcut set is "Command m" returns "m"
+// Example 3: Shortcut set is "Alt Shift ," returns ","
+
+CFStringRef createStringForKey(CGKeyCode keyCode)
+{
+    TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
+//  currentKeyboard now contains the current input source
+    CFDataRef layoutData =
+    TISGetInputSourceProperty(currentKeyboard,
+                              kTISPropertyUnicodeKeyLayoutData);
+//  the UNICODE keyLayout is fetched from currentKeyboard in layoutData
+    const UCKeyboardLayout *keyboardLayout =
+    (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
+//  A read-only data pointer is fetched from layoutData
+    UInt32 keysDown = 0;
+    UniChar chars[4];
+    UniCharCount realLength;
+    
+    UCKeyTranslate(keyboardLayout,
+                   keyCode,
+                   kUCKeyActionDisplay,
+                   0,
+                   LMGetKbdType(),
+                   kUCKeyTranslateNoDeadKeysBit,
+                   &keysDown,
+                   sizeof(chars) / sizeof(chars[0]),
+                   &realLength,
+                   chars);
+    CFRelease(currentKeyboard);
+//  Converts keyCode, modifier and dead-key state into UNICODE characters
+    return CFStringCreateWithCharacters(kCFAllocatorDefault, chars, 1);
+}
 
 // Events
 - (void)handleAction:(NSMenuItem *)sender {
-AWT_ASSERT_APPKIT_THREAD;
+    AWT_ASSERT_APPKIT_THREAD;
     JNIEnv *env = [ThreadUtilities getJNIEnv];
-JNF_COCOA_ENTER(env);
-
+    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.
@@ -82,31 +118,37 @@
     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];
-        }
-
+//      If shortcut is "Command Shift ," the menuKey gets the value ","
+//      But [currEvent charactersIgnoringModifiers]; returns "<" and not ","
+//      because the charactersIgnoreingModifiers does not ignore "Shift"
+//      So a shortcut like "Command Shift m" will return "M" where as the
+//      MenuKey will have the value "m". To remove this issue the below
+//      createStringForKey is used.
+        NSString *eventKey = createStringForKey([currEvent keyCode]);
+        
+//      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");
         static JNF_MEMBER_CACHE(jm_ckHandleAction, jc_CCheckboxMenuItem, "handleAction", "(Z)V");
-
+        
         // Send the opposite of what's currently checked -- the action
         // indicates what state we're going to.
         NSInteger state = [sender state];
@@ -115,26 +157,26 @@
     } else {
         static JNF_CLASS_CACHE(jc_CMenuItem, "sun/lwawt/macosx/CMenuItem");
         static JNF_MEMBER_CACHE(jm_handleAction, jc_CMenuItem, "handleAction", "(JI)V"); // AWT_THREADING Safe (event)
-
+        
         NSUInteger modifiers = [currEvent modifierFlags];
         jint javaModifiers = NsKeyModifiersToJavaModifiers(modifiers, NO);
-
+        
         JNFCallVoidMethod(env, fPeer, jm_handleAction, UTC(currEvent), javaModifiers); // AWT_THREADING Safe (event)
     }
-JNF_COCOA_EXIT(env);
+    JNF_COCOA_EXIT(env);
 }
 
 - (void) setJavaLabel:(NSString *)theLabel shortcut:(NSString *)theKeyEquivalent modifierMask:(jint)modifiers {
-
+    
     NSUInteger modifierMask = 0;
-
+    
     if (![theKeyEquivalent isEqualToString:@""]) {
         // Force the key equivalent to lower case if not using the shift key.
         // Otherwise AppKit will draw a Shift glyph in the menu.
         if ((modifiers & java_awt_event_KeyEvent_SHIFT_MASK) == 0) {
             theKeyEquivalent = [theKeyEquivalent lowercaseString];
         }
-
+        
         // Hack for the question mark -- SHIFT and / means use the question mark.
         if ((modifiers & java_awt_event_KeyEvent_SHIFT_MASK) != 0 &&
             [theKeyEquivalent isEqualToString:@"/"])
@@ -142,10 +184,10 @@
             theKeyEquivalent = @"?";
             modifiers &= ~java_awt_event_KeyEvent_SHIFT_MASK;
         }
-
+        
         modifierMask = JavaModifiersToNsKeyModifiers(modifiers, NO);
     }
-
+    
     [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
         [fMenuItem setKeyEquivalent:theKeyEquivalent];
         [fMenuItem setKeyEquivalentModifierMask:modifierMask];
@@ -154,14 +196,14 @@
 }
 
 - (void) setJavaImage:(NSImage *)theImage {
-
+    
     [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
         [fMenuItem setImage:theImage];
     }];
 }
 
 - (void) setJavaToolTipText:(NSString *)theText {
-
+    
     [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
         [fMenuItem setToolTip:theText];
     }];
@@ -169,11 +211,11 @@
 
 
 - (void)setJavaEnabled:(BOOL) enabled {
-
+    
     [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
         @synchronized(self) {
             fIsEnabled = enabled;
-
+            
             // Warning:  This won't work if the parent menu is disabled.
             // See [CMenu syncFromJava]. We still need to call it here so
             // the NSMenuItem itself gets properly updated.
@@ -183,7 +225,7 @@
 }
 
 - (BOOL)isEnabled {
-
+    
     BOOL enabled = NO;
     @synchronized(self) {
         enabled = fIsEnabled;
@@ -193,7 +235,7 @@
 
 
 - (void)setJavaState:(BOOL)newState {
-
+    
     [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
         [fMenuItem setState:(newState ? NSOnState : NSOffState)];
     }];
@@ -207,7 +249,7 @@
 - (void)dealloc {
     [fMenuItem release];
     fMenuItem = nil;
-
+    
     [super dealloc];
 }
 
@@ -240,7 +282,7 @@
 /** Convert a Java keycode for SetMenuItemCmd */
 static unichar AWTKeyToMacShortcut(jint awtKey, BOOL doShift) {
     unichar macKey = 0;
-
+    
     if ((awtKey >= java_awt_event_KeyEvent_VK_0 && awtKey <= java_awt_event_KeyEvent_VK_9) ||
         (awtKey >= java_awt_event_KeyEvent_VK_A && awtKey <= java_awt_event_KeyEvent_VK_Z))
     {
@@ -255,68 +297,68 @@
     } else {
         // Special characters
         switch (awtKey) {
-        case java_awt_event_KeyEvent_VK_BACK_QUOTE      : macKey = '`'; break;
-        case java_awt_event_KeyEvent_VK_QUOTE           : macKey = '\''; break;
-
-        case java_awt_event_KeyEvent_VK_ESCAPE          : macKey = 0x1B; break;
-        case java_awt_event_KeyEvent_VK_SPACE           : macKey = ' '; break;
-        case java_awt_event_KeyEvent_VK_PAGE_UP         : macKey = NSPageUpFunctionKey; break;
-        case java_awt_event_KeyEvent_VK_PAGE_DOWN       : macKey = NSPageDownFunctionKey; break;
-        case java_awt_event_KeyEvent_VK_END             : macKey = NSEndFunctionKey; break;
-        case java_awt_event_KeyEvent_VK_HOME            : macKey = NSHomeFunctionKey; break;
-
-        case java_awt_event_KeyEvent_VK_LEFT            : macKey = NSLeftArrowFunctionKey; break;
-        case java_awt_event_KeyEvent_VK_UP              : macKey = NSUpArrowFunctionKey; break;
-        case java_awt_event_KeyEvent_VK_RIGHT           : macKey = NSRightArrowFunctionKey; break;
-        case java_awt_event_KeyEvent_VK_DOWN            : macKey = NSDownArrowFunctionKey; break;
-
-        case java_awt_event_KeyEvent_VK_COMMA           : macKey = ','; break;
-
-        // Mac OS doesn't distinguish between the two '-' keys...
-        case java_awt_event_KeyEvent_VK_MINUS           :
-        case java_awt_event_KeyEvent_VK_SUBTRACT        : macKey = '-'; break;
-
-        // or the two '.' keys...
-        case java_awt_event_KeyEvent_VK_DECIMAL         :
-        case java_awt_event_KeyEvent_VK_PERIOD          : macKey = '.'; break;
-
-        // or the two '/' keys.
-        case java_awt_event_KeyEvent_VK_DIVIDE          :
-        case java_awt_event_KeyEvent_VK_SLASH           : macKey = '/'; break;
-
-        case java_awt_event_KeyEvent_VK_SEMICOLON       : macKey = ';'; break;
-        case java_awt_event_KeyEvent_VK_EQUALS          : macKey = '='; break;
-
-        case java_awt_event_KeyEvent_VK_OPEN_BRACKET    : macKey = '['; break;
-        case java_awt_event_KeyEvent_VK_BACK_SLASH      : macKey = '\\'; break;
-        case java_awt_event_KeyEvent_VK_CLOSE_BRACKET   : macKey = ']'; break;
-
-        case java_awt_event_KeyEvent_VK_MULTIPLY        : macKey = '*'; break;
-        case java_awt_event_KeyEvent_VK_ADD             : macKey = '+'; break;
-
-        case java_awt_event_KeyEvent_VK_HELP            : macKey = NSHelpFunctionKey; break;
-        case java_awt_event_KeyEvent_VK_TAB             : macKey = NSTabCharacter; break;
-        case java_awt_event_KeyEvent_VK_ENTER           : macKey = NSNewlineCharacter; break;
-        case java_awt_event_KeyEvent_VK_BACK_SPACE      : macKey = NSBackspaceCharacter; break;
-        case java_awt_event_KeyEvent_VK_DELETE          : macKey = NSDeleteCharacter; break;
-        case java_awt_event_KeyEvent_VK_CLEAR           : macKey = NSClearDisplayFunctionKey; break;
-        case java_awt_event_KeyEvent_VK_AMPERSAND       : macKey = '&'; break;
-        case java_awt_event_KeyEvent_VK_ASTERISK        : macKey = '*'; break;
-        case java_awt_event_KeyEvent_VK_QUOTEDBL        : macKey = '\"'; break;
-        case java_awt_event_KeyEvent_VK_LESS            : macKey = '<'; break;
-        case java_awt_event_KeyEvent_VK_GREATER         : macKey = '>'; break;
-        case java_awt_event_KeyEvent_VK_BRACELEFT       : macKey = '{'; break;
-        case java_awt_event_KeyEvent_VK_BRACERIGHT      : macKey = '}'; break;
-        case java_awt_event_KeyEvent_VK_AT              : macKey = '@'; break;
-        case java_awt_event_KeyEvent_VK_COLON           : macKey = ':'; break;
-        case java_awt_event_KeyEvent_VK_CIRCUMFLEX      : macKey = '^'; break;
-        case java_awt_event_KeyEvent_VK_DOLLAR          : macKey = '$'; break;
-        case java_awt_event_KeyEvent_VK_EXCLAMATION_MARK : macKey = '!'; break;
-        case java_awt_event_KeyEvent_VK_LEFT_PARENTHESIS : macKey = '('; break;
-        case java_awt_event_KeyEvent_VK_NUMBER_SIGN     : macKey = '#'; break;
-        case java_awt_event_KeyEvent_VK_PLUS            : macKey = '+'; break;
-        case java_awt_event_KeyEvent_VK_RIGHT_PARENTHESIS: macKey = ')'; break;
-        case java_awt_event_KeyEvent_VK_UNDERSCORE      : macKey = '_'; break;
+            case java_awt_event_KeyEvent_VK_BACK_QUOTE      : macKey = '`'; break;
+            case java_awt_event_KeyEvent_VK_QUOTE           : macKey = '\''; break;
+                
+            case java_awt_event_KeyEvent_VK_ESCAPE          : macKey = 0x1B; break;
+            case java_awt_event_KeyEvent_VK_SPACE           : macKey = ' '; break;
+            case java_awt_event_KeyEvent_VK_PAGE_UP         : macKey = NSPageUpFunctionKey; break;
+            case java_awt_event_KeyEvent_VK_PAGE_DOWN       : macKey = NSPageDownFunctionKey; break;
+            case java_awt_event_KeyEvent_VK_END             : macKey = NSEndFunctionKey; break;
+            case java_awt_event_KeyEvent_VK_HOME            : macKey = NSHomeFunctionKey; break;
+                
+            case java_awt_event_KeyEvent_VK_LEFT            : macKey = NSLeftArrowFunctionKey; break;
+            case java_awt_event_KeyEvent_VK_UP              : macKey = NSUpArrowFunctionKey; break;
+            case java_awt_event_KeyEvent_VK_RIGHT           : macKey = NSRightArrowFunctionKey; break;
+            case java_awt_event_KeyEvent_VK_DOWN            : macKey = NSDownArrowFunctionKey; break;
+                
+            case java_awt_event_KeyEvent_VK_COMMA           : macKey = ','; break;
+                
+                // Mac OS doesn't distinguish between the two '-' keys...
+            case java_awt_event_KeyEvent_VK_MINUS           :
+            case java_awt_event_KeyEvent_VK_SUBTRACT        : macKey = '-'; break;
+                
+                // or the two '.' keys...
+            case java_awt_event_KeyEvent_VK_DECIMAL         :
+            case java_awt_event_KeyEvent_VK_PERIOD          : macKey = '.'; break;
+                
+                // or the two '/' keys.
+            case java_awt_event_KeyEvent_VK_DIVIDE          :
+            case java_awt_event_KeyEvent_VK_SLASH           : macKey = '/'; break;
+                
+            case java_awt_event_KeyEvent_VK_SEMICOLON       : macKey = ';'; break;
+            case java_awt_event_KeyEvent_VK_EQUALS          : macKey = '='; break;
+                
+            case java_awt_event_KeyEvent_VK_OPEN_BRACKET    : macKey = '['; break;
+            case java_awt_event_KeyEvent_VK_BACK_SLASH      : macKey = '\\'; break;
+            case java_awt_event_KeyEvent_VK_CLOSE_BRACKET   : macKey = ']'; break;
+                
+            case java_awt_event_KeyEvent_VK_MULTIPLY        : macKey = '*'; break;
+            case java_awt_event_KeyEvent_VK_ADD             : macKey = '+'; break;
+                
+            case java_awt_event_KeyEvent_VK_HELP            : macKey = NSHelpFunctionKey; break;
+            case java_awt_event_KeyEvent_VK_TAB             : macKey = NSTabCharacter; break;
+            case java_awt_event_KeyEvent_VK_ENTER           : macKey = NSNewlineCharacter; break;
+            case java_awt_event_KeyEvent_VK_BACK_SPACE      : macKey = NSBackspaceCharacter; break;
+            case java_awt_event_KeyEvent_VK_DELETE          : macKey = NSDeleteCharacter; break;
+            case java_awt_event_KeyEvent_VK_CLEAR           : macKey = NSClearDisplayFunctionKey; break;
+            case java_awt_event_KeyEvent_VK_AMPERSAND       : macKey = '&'; break;
+            case java_awt_event_KeyEvent_VK_ASTERISK        : macKey = '*'; break;
+            case java_awt_event_KeyEvent_VK_QUOTEDBL        : macKey = '\"'; break;
+            case java_awt_event_KeyEvent_VK_LESS            : macKey = '<'; break;
+            case java_awt_event_KeyEvent_VK_GREATER         : macKey = '>'; break;
+            case java_awt_event_KeyEvent_VK_BRACELEFT       : macKey = '{'; break;
+            case java_awt_event_KeyEvent_VK_BRACERIGHT      : macKey = '}'; break;
+            case java_awt_event_KeyEvent_VK_AT              : macKey = '@'; break;
+            case java_awt_event_KeyEvent_VK_COLON           : macKey = ':'; break;
+            case java_awt_event_KeyEvent_VK_CIRCUMFLEX      : macKey = '^'; break;
+            case java_awt_event_KeyEvent_VK_DOLLAR          : macKey = '$'; break;
+            case java_awt_event_KeyEvent_VK_EXCLAMATION_MARK : macKey = '!'; break;
+            case java_awt_event_KeyEvent_VK_LEFT_PARENTHESIS : macKey = '('; break;
+            case java_awt_event_KeyEvent_VK_NUMBER_SIGN     : macKey = '#'; break;
+            case java_awt_event_KeyEvent_VK_PLUS            : macKey = '+'; break;
+            case java_awt_event_KeyEvent_VK_RIGHT_PARENTHESIS: macKey = ')'; break;
+            case java_awt_event_KeyEvent_VK_UNDERSCORE      : macKey = '_'; break;
         }
     }
     return macKey;
@@ -330,27 +372,27 @@
 JNIEXPORT void JNICALL
 Java_sun_lwawt_macosx_CMenuItem_nativeSetLabel
 (JNIEnv *env, jobject peer,
-     jlong menuItemObj, jstring label,
-     jchar shortcutKey, jint shortcutKeyCode, jint mods)
+ jlong menuItemObj, jstring label,
+ jchar shortcutKey, jint shortcutKeyCode, jint mods)
 {
-JNF_COCOA_ENTER(env);
+    JNF_COCOA_ENTER(env);
     NSString *theLabel = JNFJavaToNSString(env, label);
     NSString *theKeyEquivalent = nil;
     unichar macKey = shortcutKey;
-
+    
     if (macKey == 0) {
         macKey = AWTKeyToMacShortcut(shortcutKeyCode, (mods & java_awt_event_KeyEvent_SHIFT_MASK) != 0);
     }
-
+    
     if (macKey != 0) {
         unichar equivalent[1] = {macKey};
         theKeyEquivalent = [NSString stringWithCharacters:equivalent length:1];
     } else {
         theKeyEquivalent = @"";
     }
-
+    
     [((CMenuItem *)jlong_to_ptr(menuItemObj)) setJavaLabel:theLabel shortcut:theKeyEquivalent modifierMask:mods];
-JNF_COCOA_EXIT(env);
+    JNF_COCOA_EXIT(env);
 }
 
 /*
@@ -362,10 +404,10 @@
 Java_sun_lwawt_macosx_CMenuItem_nativeSetTooltip
 (JNIEnv *env, jobject peer, jlong menuItemObj, jstring tooltip)
 {
-JNF_COCOA_ENTER(env);
+    JNF_COCOA_ENTER(env);
     NSString *theTooltip = JNFJavaToNSString(env, tooltip);
     [((CMenuItem *)jlong_to_ptr(menuItemObj)) setJavaToolTipText:theTooltip];
-JNF_COCOA_EXIT(env);
+    JNF_COCOA_EXIT(env);
 }
 
 /*
@@ -377,9 +419,9 @@
 Java_sun_lwawt_macosx_CMenuItem_nativeSetImage
 (JNIEnv *env, jobject peer, jlong menuItemObj, jlong image)
 {
-JNF_COCOA_ENTER(env);
+    JNF_COCOA_ENTER(env);
     [((CMenuItem *)jlong_to_ptr(menuItemObj)) setJavaImage:(NSImage*)jlong_to_ptr(image)];
-JNF_COCOA_EXIT(env);
+    JNF_COCOA_EXIT(env);
 }
 
 /*
@@ -389,38 +431,38 @@
  */
 JNIEXPORT jlong JNICALL
 Java_sun_lwawt_macosx_CMenuItem_nativeCreate
-    (JNIEnv *env, jobject peer, jlong parentCMenuObj, jboolean isSeparator)
+(JNIEnv *env, jobject peer, jlong parentCMenuObj, jboolean isSeparator)
 {
-
+    
     CMenuItem *aCMenuItem = nil;
     CMenu *parentCMenu = (CMenu *)jlong_to_ptr(parentCMenuObj);
-JNF_COCOA_ENTER(env);
-
+    JNF_COCOA_ENTER(env);
+    
     jobject cPeerObjGlobal = (*env)->NewGlobalRef(env, peer);
-
+    
     NSMutableArray *args = nil;
-
+    
     // Create a new item....
     if (isSeparator == JNI_TRUE) {
         args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], [NSNumber numberWithBool:YES],  nil];
     } else {
         args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], [NSNumber numberWithBool:NO],  nil];
     }
-
+    
     [ThreadUtilities performOnMainThread:@selector(_createMenuItem_OnAppKitThread:) on:[CMenuItem alloc] withObject:args waitUntilDone:YES];
-
+    
     aCMenuItem = (CMenuItem *)[args objectAtIndex: 0];
-
+    
     if (aCMenuItem == nil) {
         return 0L;
     }
-
+    
     // and add it to the parent item.
     [parentCMenu addJavaMenuItem: aCMenuItem];
-
+    
     // setLabel will be called after creation completes.
-
-JNF_COCOA_EXIT(env);
+    
+    JNF_COCOA_EXIT(env);
     return ptr_to_jlong(aCMenuItem);
 }
 
@@ -433,10 +475,10 @@
 Java_sun_lwawt_macosx_CMenuItem_nativeSetEnabled
 (JNIEnv *env, jobject peer, jlong menuItemObj, jboolean enable)
 {
-JNF_COCOA_ENTER(env);
+    JNF_COCOA_ENTER(env);
     CMenuItem *item = (CMenuItem *)jlong_to_ptr(menuItemObj);
     [item setJavaEnabled: (enable == JNI_TRUE)];
-JNF_COCOA_EXIT(env);
+    JNF_COCOA_EXIT(env);
 }
 
 /*
@@ -448,10 +490,10 @@
 Java_sun_lwawt_macosx_CCheckboxMenuItem_nativeSetState
 (JNIEnv *env, jobject peer, jlong menuItemObj, jboolean state)
 {
-JNF_COCOA_ENTER(env);
+    JNF_COCOA_ENTER(env);
     CMenuItem *item = (CMenuItem *)jlong_to_ptr(menuItemObj);
     [item setJavaState: (state == JNI_TRUE)];
-JNF_COCOA_EXIT(env);
+    JNF_COCOA_EXIT(env);
 }
 
 /*
@@ -463,8 +505,8 @@
 Java_sun_lwawt_macosx_CCheckboxMenuItem_nativeSetIsCheckbox
 (JNIEnv *env, jobject peer, jlong menuItemObj)
 {
-JNF_COCOA_ENTER(env);
+    JNF_COCOA_ENTER(env);
     CMenuItem *item = (CMenuItem *)jlong_to_ptr(menuItemObj);
     [item setIsCheckbox];
-JNF_COCOA_EXIT(env);
+    JNF_COCOA_EXIT(env);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JMenuItem/8139169/ScreenMenuBarInputTwice.java	Thu Dec 10 14:21:44 2015 +0300
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8139169
+ * @summary verifies if TextArea gets input twice due to Apple's Screen Menubar
+ * @requires (os.family=="mac")
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main ScreenMenuBarInputTwice
+ */
+import java.awt.BorderLayout;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import static java.awt.event.KeyEvent.VK_COMMA;
+import static java.awt.event.KeyEvent.VK_META;
+import static java.awt.event.KeyEvent.VK_SHIFT;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.KeyStroke;
+import javax.swing.SwingUtilities;
+import javax.swing.text.BadLocationException;
+
+public class ScreenMenuBarInputTwice {
+
+    public static final String TEST_STRING = "Check string";
+
+    private static Robot robot;
+    private static JFrame frame;
+    private static JPanel content;
+    private static JTextArea textArea;
+    private static JMenuBar menuBar;
+    private static JMenu menu;
+    private static JMenuItem menuItem;
+
+    public static void main(String[] args) throws Exception {
+        robot = new Robot();
+        createUIWithSeperateMenuBar();
+        robot.delay(2000);
+        shortcutTestCase();
+        robot.delay(2000);
+        cleanUp();
+        createUIWithIntegratedMenuBar();
+        robot.delay(2000);
+        menuTestCase();
+        robot.delay(2000);
+        cleanUp();
+    }
+
+    private static void createUIWithSeperateMenuBar() throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                System.setProperty(
+                        "com.apple.mrj.application.apple.menu.about.name",
+                        "A test frame");
+                System.setProperty("apple.laf.useScreenMenuBar", "true");
+                frame = new JFrame("Text input twice check");
+                content = new JPanel(new BorderLayout());
+                textArea = new JTextArea();
+                content.add(new JScrollPane(textArea,
+                        JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+                        JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED),
+                        BorderLayout.CENTER);
+                menuBar = new JMenuBar();
+                frame.setJMenuBar(menuBar);
+                Action a = new AbstractAction("Insert some text") {
+                    @Override
+                    public void actionPerformed(ActionEvent arg0) {
+                        try {
+
+                            textArea.getDocument()
+                                    .insertString(0, TEST_STRING, null);
+                        } catch (BadLocationException e) {
+                            frame.dispose();
+                            throw new RuntimeException("Bad location: ", e);
+                        }
+                    }
+                };
+                KeyStroke keyStroke = KeyStroke.getKeyStroke(
+                        "meta shift COMMA");
+                a.putValue(Action.ACCELERATOR_KEY, keyStroke);
+                textArea.getInputMap().put(keyStroke, "myAction");
+                textArea.getActionMap().put("myAction", a);
+                menu = new JMenu("The Menu");
+                menuItem = new JMenuItem(a);
+                menuItem.setAccelerator((KeyStroke) a.getValue(
+                        Action.ACCELERATOR_KEY));
+                menu.add(menuItem);
+                menuBar.add(menu);
+                frame.getContentPane().add(content);
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+                frame.setLocationRelativeTo(null);
+                frame.setSize(500, 500);
+                frame.setVisible(true);
+                frame.toFront();
+            }
+        });
+    }
+
+    private static void createUIWithIntegratedMenuBar() throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                System.setProperty(
+                        "com.apple.mrj.application.apple.menu.about.name",
+                        "A test frame");
+                System.setProperty("apple.laf.useScreenMenuBar", "false");
+                frame = new JFrame("Text input twice check");
+                content = new JPanel(new BorderLayout());
+                textArea = new JTextArea();
+                content.add(new JScrollPane(textArea,
+                        JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+                        JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED),
+                        BorderLayout.CENTER);
+                menuBar = new JMenuBar();
+                frame.setJMenuBar(menuBar);
+                Action a = new AbstractAction("Insert some text") {
+                    @Override
+                    public void actionPerformed(ActionEvent arg0) {
+                        try {
+
+                            textArea.getDocument()
+                                    .insertString(0, TEST_STRING, null);
+                        } catch (BadLocationException e) {
+                            frame.dispose();
+                            throw new RuntimeException("Bad location: ", e);
+                        }
+                    }
+                };
+                KeyStroke keyStroke = KeyStroke.getKeyStroke(
+                        "meta shift COMMA");
+                a.putValue(Action.ACCELERATOR_KEY, keyStroke);
+                textArea.getInputMap().put(keyStroke, "myAction");
+                textArea.getActionMap().put("myAction", a);
+                menu = new JMenu("The Menu");
+                menuItem = new JMenuItem(a);
+                menuItem.setAccelerator((KeyStroke) a.getValue(
+                        Action.ACCELERATOR_KEY));
+                menu.add(menuItem);
+                menuBar.add(menu);
+                frame.getContentPane().add(content);
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+                frame.setSize(500, 500);
+                frame.setLocationRelativeTo(null);
+                frame.setVisible(true);
+                frame.toFront();
+            }
+        });
+    }
+
+    private static void shortcutTestCase() throws Exception {
+        robot.keyPress(KeyEvent.VK_META);
+        robot.keyPress(KeyEvent.VK_SHIFT);
+        robot.keyPress(KeyEvent.VK_COMMA);
+        robot.keyRelease(VK_COMMA);
+        robot.keyRelease(VK_SHIFT);
+        robot.keyRelease(VK_META);
+        robot.delay(2000);
+        checkText(textArea.getText());
+    }
+
+    private static void menuTestCase() throws Exception {
+        Point mousePoint;
+        mousePoint = Util.getCenterPoint(menu);
+        robot.mouseMove(mousePoint.x, mousePoint.y);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        robot.delay(2000);
+        mousePoint = Util.getCenterPoint(menuItem);
+        robot.mouseMove(mousePoint.x, mousePoint.y);
+        robot.delay(2000);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        robot.delay(2000);
+        checkText(textArea.getText());
+    }
+
+    private static void checkText(String text) throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                if (TEST_STRING.equals(text)) {
+                    textArea.setText("");
+                } else {
+                    frame.dispose();
+                    throw new RuntimeException("Failed. "
+                            + " Menu item shortcut invoked twice");
+                }
+            }
+        });
+    }
+
+    private static void cleanUp() throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame.dispose();
+            }
+        });
+    }
+}