--- 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();
+ }
+ });
+ }
+}