--- a/jdk/src/macosx/classes/com/apple/laf/AquaFileChooserUI.java Tue Oct 23 09:38:38 2012 -0700
+++ b/jdk/src/macosx/classes/com/apple/laf/AquaFileChooserUI.java Tue Oct 23 09:40:06 2012 -0700
@@ -379,6 +379,19 @@
}
}
updateButtonState(getFileChooser());
+ } else if (prop.equals(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY)) {
+ JFileChooser fileChooser = getFileChooser();
+ if (!fileChooser.isDirectorySelectionEnabled()) {
+ final File[] files = (File[]) e.getNewValue();
+ if (files != null) {
+ for (int selectedRow : fFileList.getSelectedRows()) {
+ File file = (File) fFileList.getValueAt(selectedRow, 0);
+ if (fileChooser.isTraversable(file)) {
+ fFileList.removeSelectedIndex(selectedRow);
+ }
+ }
+ }
+ }
} else if (prop.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) {
fFileList.clearSelection();
final File currentDirectory = getFileChooser().getCurrentDirectory();
--- a/jdk/src/macosx/classes/sun/awt/CGraphicsDevice.java Tue Oct 23 09:38:38 2012 -0700
+++ b/jdk/src/macosx/classes/sun/awt/CGraphicsDevice.java Tue Oct 23 09:40:06 2012 -0700
@@ -33,9 +33,7 @@
import sun.java2d.opengl.CGLGraphicsConfig;
-import sun.awt.FullScreenCapable;
-
-public class CGraphicsDevice extends GraphicsDevice {
+public final class CGraphicsDevice extends GraphicsDevice {
// CoreGraphics display ID
private final int displayID;
@@ -108,11 +106,6 @@
return nativeGetYResolution(displayID);
}
- public int getScreenResolution() {
- // TODO: report non-72 value when HiDPI is turned on
- return 72;
- }
-
private static native double nativeGetXResolution(int displayID);
private static native double nativeGetYResolution(int displayID);
@@ -194,6 +187,9 @@
@Override
public void setDisplayMode(DisplayMode dm) {
+ if (dm == null) {
+ throw new IllegalArgumentException("Invalid display mode");
+ }
nativeSetDisplayMode(displayID, dm.getWidth(), dm.getHeight(), dm.getBitDepth(), dm.getRefreshRate());
if (isFullScreenSupported() && getFullScreenWindow() != null) {
getFullScreenWindow().setSize(dm.getWidth(), dm.getHeight());
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Tue Oct 23 09:38:38 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Tue Oct 23 09:40:06 2012 -0700
@@ -65,7 +65,7 @@
private static native void nativeDispose(long nsWindowPtr);
private static native CPlatformWindow nativeGetTopmostPlatformWindowUnderMouse();
- private static native int nativeGetNSWindowDisplayID_AppKitThread(long nsWindowPtr);
+ private static native int nativeGetNSWindowDisplayID(long nsWindowPtr);
// Loger to report issues happened during execution but that do not affect functionality
private static final PlatformLogger logger = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformWindow");
@@ -444,7 +444,7 @@
public GraphicsDevice getGraphicsDevice() {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
CGraphicsEnvironment cge = (CGraphicsEnvironment)ge;
- int displayID = nativeGetNSWindowDisplayID_AppKitThread(getNSWindowPtr());
+ int displayID = nativeGetNSWindowDisplayID(getNSWindowPtr());
GraphicsDevice gd = cge.getScreenDevice(displayID);
if (gd == null) {
// this could possibly happen during device removal
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CTrayIcon.java Tue Oct 23 09:38:38 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CTrayIcon.java Tue Oct 23 09:40:06 2012 -0700
@@ -26,6 +26,7 @@
package sun.lwawt.macosx;
import sun.awt.SunToolkit;
+import sun.lwawt.macosx.event.NSEvent;
import javax.swing.*;
import java.awt.*;
@@ -42,6 +43,16 @@
private JDialog messageDialog;
private DialogEventHandler handler;
+ // In order to construct MouseEvent object, we need to specify a
+ // Component target. Because TrayIcon isn't Component's subclass,
+ // we use this dummy frame instead
+ private final Frame dummyFrame;
+
+ // A bitmask that indicates what mouse buttons produce MOUSE_CLICKED events
+ // on MOUSE_RELEASE. Click events are only generated if there were no drag
+ // events between MOUSE_PRESSED and MOUSE_RELEASED for particular button
+ private static int mouseClickButtons = 0;
+
CTrayIcon(TrayIcon target) {
super(0, true);
@@ -49,6 +60,7 @@
this.handler = null;
this.target = target;
this.popup = target.getPopupMenu();
+ this.dummyFrame = new Frame();
setPtr(createModel());
//if no one else is creating the peer.
@@ -119,6 +131,8 @@
disposeMessageDialog();
}
+ dummyFrame.dispose();
+
LWCToolkit.targetDisposedPeer(target, this);
target = null;
@@ -161,17 +175,78 @@
private native void setNativeImage(final long model, final long nsimage, final boolean autosize);
- //invocation from the AWTTrayIcon.m
- public void performAction() {
+ private void postEvent(final AWTEvent event) {
SunToolkit.executeOnEventHandlerThread(target, new Runnable() {
public void run() {
- final String cmd = target.getActionCommand();
- final ActionEvent event = new ActionEvent(target, ActionEvent.ACTION_PERFORMED, cmd);
SunToolkit.postEvent(SunToolkit.targetToAppContext(target), event);
}
});
}
+ //invocation from the AWTTrayIcon.m
+ private void handleMouseEvent(NSEvent nsEvent) {
+ int buttonNumber = nsEvent.getButtonNumber();
+ final SunToolkit tk = (SunToolkit)Toolkit.getDefaultToolkit();
+ if ((buttonNumber > 2 && !tk.areExtraMouseButtonsEnabled())
+ || buttonNumber > tk.getNumberOfButtons() - 1) {
+ return;
+ }
+
+ int jeventType = NSEvent.nsToJavaEventType(nsEvent.getType());
+
+ int jbuttonNumber = MouseEvent.NOBUTTON;
+ int jclickCount = 0;
+ if (jeventType != MouseEvent.MOUSE_MOVED) {
+ jbuttonNumber = NSEvent.nsToJavaButton(buttonNumber);
+ jclickCount = nsEvent.getClickCount();
+ }
+
+ int jmodifiers = NSEvent.nsToJavaMouseModifiers(buttonNumber,
+ nsEvent.getModifierFlags());
+ boolean isPopupTrigger = NSEvent.isPopupTrigger(jmodifiers);
+
+ int eventButtonMask = (jbuttonNumber > 0)?
+ MouseEvent.getMaskForButton(jbuttonNumber) : 0;
+ long when = System.currentTimeMillis();
+
+ if (jeventType == MouseEvent.MOUSE_PRESSED) {
+ mouseClickButtons |= eventButtonMask;
+ } else if (jeventType == MouseEvent.MOUSE_DRAGGED) {
+ mouseClickButtons = 0;
+ }
+
+ // The MouseEvent's coordinates are relative to screen
+ int absX = nsEvent.getAbsX();
+ int absY = nsEvent.getAbsY();
+
+ MouseEvent mouseEvent = new MouseEvent(dummyFrame, jeventType, when,
+ jmodifiers, absX, absY, absX, absY, jclickCount, isPopupTrigger,
+ jbuttonNumber);
+ mouseEvent.setSource(target);
+ postEvent(mouseEvent);
+
+ // fire ACTION event
+ if (jeventType == MouseEvent.MOUSE_PRESSED && isPopupTrigger) {
+ final String cmd = target.getActionCommand();
+ final ActionEvent event = new ActionEvent(target,
+ ActionEvent.ACTION_PERFORMED, cmd);
+ postEvent(event);
+ }
+
+ // synthesize CLICKED event
+ if (jeventType == MouseEvent.MOUSE_RELEASED) {
+ if ((mouseClickButtons & eventButtonMask) != 0) {
+ MouseEvent clickEvent = new MouseEvent(dummyFrame,
+ MouseEvent.MOUSE_CLICKED, when, jmodifiers, absX, absY,
+ absX, absY, jclickCount, isPopupTrigger, jbuttonNumber);
+ clickEvent.setSource(target);
+ postEvent(clickEvent);
+ }
+
+ mouseClickButtons &= ~eventButtonMask;
+ }
+ }
+
private native Point2D nativeGetIconLocation(long trayIconModel);
public void displayMessageOnEDT(String caption, String text,
@@ -256,6 +331,9 @@
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.setModal(false);
+ dialog.setModalExclusionType(Dialog.ModalExclusionType.TOOLKIT_EXCLUDE);
+ dialog.setAlwaysOnTop(true);
+ dialog.setAutoRequestFocus(false);
dialog.setResizable(false);
dialog.setContentPane(op);
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Tue Oct 23 09:38:38 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Tue Oct 23 09:40:06 2012 -0700
@@ -53,7 +53,7 @@
/**
* Mac OS X Cocoa-based AWT Toolkit.
*/
-public class LWCToolkit extends LWToolkit {
+public final class LWCToolkit extends LWToolkit {
// While it is possible to enumerate all mouse devices
// and query them for the number of buttons, the code
// that does it is rather complex. Instead, we opt for
@@ -278,7 +278,6 @@
return new CMouseInfoPeer();
}
-
@Override
protected int getScreenHeight() {
return GraphicsEnvironment.getLocalGraphicsEnvironment()
@@ -333,8 +332,9 @@
@Override
public int getScreenResolution() throws HeadlessException {
- return ((CGraphicsDevice) GraphicsEnvironment
- .getLocalGraphicsEnvironment().getDefaultScreenDevice()).getScreenResolution();
+ return (int) ((CGraphicsDevice) GraphicsEnvironment
+ .getLocalGraphicsEnvironment().getDefaultScreenDevice())
+ .getXResolution();
}
@Override
--- a/jdk/src/macosx/native/sun/awt/AWTWindow.m Tue Oct 23 09:38:38 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m Tue Oct 23 09:40:06 2012 -0700
@@ -324,6 +324,13 @@
}
}
++ (NSNumber *) getNSWindowDisplayID_AppKitThread:(NSWindow *)window {
+ AWT_ASSERT_APPKIT_THREAD;
+ NSScreen *screen = [window screen];
+ NSDictionary *deviceDescription = [screen deviceDescription];
+ return [deviceDescription objectForKey:@"NSScreenNumber"];
+}
+
- (void) dealloc {
AWT_ASSERT_APPKIT_THREAD;
@@ -1113,19 +1120,22 @@
* Signature: (J)I
*/
JNIEXPORT jint JNICALL
-Java_sun_lwawt_macosx_CPlatformWindow_nativeGetNSWindowDisplayID_1AppKitThread
+Java_sun_lwawt_macosx_CPlatformWindow_nativeGetNSWindowDisplayID
(JNIEnv *env, jclass clazz, jlong windowPtr)
{
- jint ret; // CGDirectDisplayID
+ __block jint ret; // CGDirectDisplayID
JNF_COCOA_ENTER(env);
-AWT_ASSERT_APPKIT_THREAD;
NSWindow *window = OBJC(windowPtr);
- NSScreen *screen = [window screen];
- NSDictionary *deviceDescription = [screen deviceDescription];
- NSNumber *displayID = [deviceDescription objectForKey:@"NSScreenNumber"];
- ret = (jint)[displayID intValue];
+
+ if ([NSThread isMainThread]) {
+ ret = (jint)[[AWTWindow getNSWindowDisplayID_AppKitThread: window] intValue];
+ } else {
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ ret = (jint)[[AWTWindow getNSWindowDisplayID_AppKitThread: window] intValue];
+ }];
+ }
JNF_COCOA_EXIT(env);
--- a/jdk/src/macosx/native/sun/awt/CTrayIcon.h Tue Oct 23 09:38:38 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/CTrayIcon.h Tue Oct 23 09:40:06 2012 -0700
@@ -53,6 +53,7 @@
- (jobject) peer;
- (void) setImage:(NSImage *) imagePtr sizing:(BOOL)autosize;
- (NSPoint) getLocationOnScreen;
+- (void) deliverJavaMouseEvent:(NSEvent*) event;
@end //AWTTrayIcon
@@ -68,6 +69,7 @@
-(id)initWithTrayIcon:(AWTTrayIcon *)theTrayIcon;
-(void)setHighlighted:(BOOL)aFlag;
-(void)setImage:(NSImage*)anImage;
+-(void)setTrayIcon:(AWTTrayIcon*)theTrayIcon;
@end //AWTTrayIconView
--- a/jdk/src/macosx/native/sun/awt/CTrayIcon.m Tue Oct 23 09:38:38 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/CTrayIcon.m Tue Oct 23 09:40:06 2012 -0700
@@ -29,6 +29,7 @@
#import "CTrayIcon.h"
#import "ThreadUtilities.h"
#include "GeomUtilities.h"
+#import "LWCToolkit.h"
#define kImageInset 4.0
@@ -76,8 +77,9 @@
// Its a bad idea to force the item to release our view by setting
// the item's view to nil: it can lead to a crash in some scenarios.
// The item will release the view later on, so just set the view's image
- // to nil since we are done with it.
+ // and tray icon to nil since we are done with it.
[view setImage: nil];
+ [view setTrayIcon: nil];
[view release];
[theItem release];
@@ -115,6 +117,45 @@
return [[view window] convertBaseToScreen: NSZeroPoint];
}
+-(void) deliverJavaMouseEvent: (NSEvent *) event {
+ [AWTToolkit eventCountPlusPlus];
+
+ JNIEnv *env = [ThreadUtilities getJNIEnv];
+
+ NSPoint eventLocation = [event locationInWindow];
+ NSPoint localPoint = [view convertPoint: eventLocation fromView: nil];
+ localPoint.y = [view bounds].size.height - localPoint.y;
+
+ NSPoint absP = [NSEvent mouseLocation];
+ NSEventType type = [event type];
+
+ NSRect screenRect = [[NSScreen mainScreen] frame];
+ absP.y = screenRect.size.height - absP.y;
+ jint clickCount;
+
+ clickCount = [event clickCount];
+
+ static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/event/NSEvent");
+ static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDD)V");
+ jobject jEvent = JNFNewObject(env, jctor_NSEvent,
+ [event type],
+ [event modifierFlags],
+ clickCount,
+ [event buttonNumber],
+ (jint)localPoint.x, (jint)localPoint.y,
+ (jint)absP.x, (jint)absP.y,
+ [event deltaY],
+ [event deltaX]);
+ if (jEvent == nil) {
+ // Unable to create event by some reason.
+ return;
+ }
+
+ static JNF_CLASS_CACHE(jc_TrayIcon, "sun/lwawt/macosx/CTrayIcon");
+ static JNF_MEMBER_CACHE(jm_handleMouseEvent, jc_TrayIcon, "handleMouseEvent", "(Lsun/lwawt/macosx/event/NSEvent;)V");
+ JNFCallVoidMethod(env, peer, jm_handleMouseEvent, jEvent);
+}
+
@end //AWTTrayIcon
//================================================
@@ -123,7 +164,7 @@
-(id)initWithTrayIcon:(AWTTrayIcon *)theTrayIcon {
self = [super initWithFrame:NSMakeRect(0, 0, 1, 1)];
- trayIcon = theTrayIcon;
+ [self setTrayIcon: theTrayIcon];
isHighlighted = NO;
image = nil;
@@ -153,6 +194,10 @@
}
}
+-(void)setTrayIcon:(AWTTrayIcon*)theTrayIcon {
+ trayIcon = theTrayIcon;
+}
+
- (void)menuWillOpen:(NSMenu *)menu
{
[self setHighlighted:YES];
@@ -191,30 +236,57 @@
];
}
-- (void) mouseDown:(NSEvent *)e {
- //find CTrayIcon.getPopupMenuModel method and call it to get popup menu ptr.
- JNIEnv *env = [ThreadUtilities getJNIEnv];
- static JNF_CLASS_CACHE(jc_CTrayIcon, "sun/lwawt/macosx/CTrayIcon");
- static JNF_MEMBER_CACHE(jm_getPopupMenuModel, jc_CTrayIcon, "getPopupMenuModel", "()J");
- static JNF_MEMBER_CACHE(jm_performAction, jc_CTrayIcon, "performAction", "()V");
- jlong res = JNFCallLongMethod(env, trayIcon.peer, jm_getPopupMenuModel);
- if (res != 0) {
- CPopupMenu *cmenu = jlong_to_ptr(res);
- NSMenu* menu = [cmenu menu];
- [menu setDelegate:self];
- [trayIcon.theItem popUpStatusItemMenu:menu];
- [self setNeedsDisplay:YES];
- } else {
- JNFCallVoidMethod(env, trayIcon.peer, jm_performAction);
+- (void)mouseDown:(NSEvent *)event {
+ [trayIcon deliverJavaMouseEvent: event];
+
+ // don't show the menu on ctrl+click: it triggers ACTION event, like right click
+ if (([event modifierFlags] & NSControlKeyMask) == 0) {
+ //find CTrayIcon.getPopupMenuModel method and call it to get popup menu ptr.
+ JNIEnv *env = [ThreadUtilities getJNIEnv];
+ static JNF_CLASS_CACHE(jc_CTrayIcon, "sun/lwawt/macosx/CTrayIcon");
+ static JNF_MEMBER_CACHE(jm_getPopupMenuModel, jc_CTrayIcon, "getPopupMenuModel", "()J");
+ jlong res = JNFCallLongMethod(env, trayIcon.peer, jm_getPopupMenuModel);
+
+ if (res != 0) {
+ CPopupMenu *cmenu = jlong_to_ptr(res);
+ NSMenu* menu = [cmenu menu];
+ [menu setDelegate:self];
+ [trayIcon.theItem popUpStatusItemMenu:menu];
+ [self setNeedsDisplay:YES];
+ }
}
}
-- (void) rightMouseDown:(NSEvent *)e {
- // Call CTrayIcon.performAction() method on right mouse press
- JNIEnv *env = [ThreadUtilities getJNIEnv];
- static JNF_CLASS_CACHE(jc_CTrayIcon, "sun/lwawt/macosx/CTrayIcon");
- static JNF_MEMBER_CACHE(jm_performAction, jc_CTrayIcon, "performAction", "()V");
- JNFCallVoidMethod(env, trayIcon.peer, jm_performAction);
+- (void) mouseUp:(NSEvent *)event {
+ [trayIcon deliverJavaMouseEvent: event];
+}
+
+- (void) mouseDragged:(NSEvent *)event {
+ [trayIcon deliverJavaMouseEvent: event];
+}
+
+- (void) rightMouseDown:(NSEvent *)event {
+ [trayIcon deliverJavaMouseEvent: event];
+}
+
+- (void) rightMouseUp:(NSEvent *)event {
+ [trayIcon deliverJavaMouseEvent: event];
+}
+
+- (void) rightMouseDragged:(NSEvent *)event {
+ [trayIcon deliverJavaMouseEvent: event];
+}
+
+- (void) otherMouseDown:(NSEvent *)event {
+ [trayIcon deliverJavaMouseEvent: event];
+}
+
+- (void) otherMouseUp:(NSEvent *)event {
+ [trayIcon deliverJavaMouseEvent: event];
+}
+
+- (void) otherMouseDragged:(NSEvent *)event {
+ [trayIcon deliverJavaMouseEvent: event];
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XKeysym.java Tue Oct 23 09:38:38 2012 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XKeysym.java Tue Oct 23 09:40:06 2012 -0700
@@ -379,6 +379,25 @@
keysym2UCSHash.put( (long)0xFFB8, (char)0x0038); // XK_KP_8 --> DIGIT EIGHT
keysym2UCSHash.put( (long)0xFFB9, (char)0x0039); // XK_KP_9 --> DIGIT NINE
keysym2UCSHash.put( (long)0xFE20, (char)0x0009); // XK_ISO_Left_Tab --> <control>
+ keysym2UCSHash.put( (long)0xFE50, (char)0x02CB); // XK_dead_grave --> MODIFIER LETTER GRAVE ACCENT
+ keysym2UCSHash.put( (long)0xFE51, (char)0x02CA); // XK_dead_acute --> MODIFIER LETTER ACUTE ACCENT
+ keysym2UCSHash.put( (long)0xFE52, (char)0x02C6); // XK_dead_circumflex --> MODIFIER LETTER CIRCUMFLEX ACCENT
+ keysym2UCSHash.put( (long)0xFE53, (char)0x02DC); // XK_dead_tilde --> SMALL TILDE
+ keysym2UCSHash.put( (long)0xFE54, (char)0x02C9); // XK_dead_macron --> MODIFIER LETTER MACRON
+ keysym2UCSHash.put( (long)0xFE55, (char)0x02D8); // XK_dead_breve --> BREVE
+ keysym2UCSHash.put( (long)0xFE56, (char)0x02D9); // XK_dead_abovedot --> DOT ABOVE
+ keysym2UCSHash.put( (long)0xFE57, (char)0x00A8); // XK_dead_diaeresis --> DIAERESIS
+ keysym2UCSHash.put( (long)0xFE58, (char)0x02DA); // XK_dead_abovering --> RING ABOVE
+ keysym2UCSHash.put( (long)0xFE59, (char)0x02DD); // XK_dead_doubleacute --> DOUBLE ACUTE ACCENT
+ keysym2UCSHash.put( (long)0xFE5A, (char)0x02C7); // XK_dead_caron --> CARON
+ keysym2UCSHash.put( (long)0xFE5B, (char)0x00B8); // XK_dead_cedilla --> CEDILLA
+ keysym2UCSHash.put( (long)0xFE5C, (char)0x02DB); // XK_dead_ogonek --> OGONEK
+ keysym2UCSHash.put( (long)0xFE5D, (char)0x0269); // XK_dead_iota --> LATIN SMALL LETTER IOTA
+ keysym2UCSHash.put( (long)0xFE5E, (char)0x3099); // XK_dead_voiced_sound --> COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK
+ keysym2UCSHash.put( (long)0xFE5F, (char)0x309A); // XK_dead_semivoiced_sound --> COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+ keysym2UCSHash.put( (long)0xFE60, (char)0x0323); // XK_dead_belowdot --> COMBINING DOT BELOW
+ keysym2UCSHash.put( (long)0xFE61, (char)0x0321); // XK_dead_hook --> COMBINING PALATALIZED HOOK BELOW
+ keysym2UCSHash.put( (long)0xFE62, (char)0x031B); // XK_dead_horn --> COMBINING HORN
keysym2UCSHash.put( (long)0x1a1, (char)0x0104); // XK_Aogonek --> LATIN CAPITAL LETTER A WITH OGONEK
keysym2UCSHash.put( (long)0x1a2, (char)0x02d8); // XK_breve --> BREVE
keysym2UCSHash.put( (long)0x1a3, (char)0x0141); // XK_Lstroke --> LATIN CAPITAL LETTER L WITH STROKE
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java Tue Oct 23 09:38:38 2012 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java Tue Oct 23 09:40:06 2012 -0700
@@ -1115,7 +1115,10 @@
// (1) either XIM could not handle it or
// (2) it was Latin 1:1 mapping.
//
- XKeysym.Keysym2JavaKeycode jkc = XKeysym.getJavaKeycode(ev);
+ // Preserve modifiers to get Java key code for dead keys
+ boolean isDeadKey = isDeadKey(keysym[0]);
+ XKeysym.Keysym2JavaKeycode jkc = isDeadKey ? XKeysym.getJavaKeycode(keysym[0])
+ : XKeysym.getJavaKeycode(ev);
if( jkc == null ) {
jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
}
@@ -1141,7 +1144,7 @@
jkc.getJavaKeycode();
postKeyEvent( java.awt.event.KeyEvent.KEY_PRESSED,
ev.get_time(),
- jkeyToReturn,
+ isDeadKey ? jkeyExtended : jkeyToReturn,
(unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
jkc.getKeyLocation(),
ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()),
@@ -1149,7 +1152,7 @@
jkeyExtended);
- if( unicodeKey > 0 ) {
+ if (unicodeKey > 0 && !isDeadKey) {
keyEventLog.fine("fire _TYPED on "+unicodeKey);
postKeyEvent( java.awt.event.KeyEvent.KEY_TYPED,
ev.get_time(),
@@ -1176,9 +1179,7 @@
}
// un-private it if you need to call it from elsewhere
private void handleKeyRelease(XKeyEvent ev) {
- long keysym[] = new long[2];
int unicodeKey = 0;
- keysym[0] = XConstants.NoSymbol;
if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
logIncomingKeyEvent( ev );
@@ -1187,7 +1188,11 @@
// and Java KeyEvent keycode should be calculated.
// For release we should post released event.
//
- XKeysym.Keysym2JavaKeycode jkc = XKeysym.getJavaKeycode(ev);
+ // Preserve modifiers to get Java key code for dead keys
+ long keysym = xkeycodeToKeysym(ev);
+ boolean isDeadKey = isDeadKey(keysym);
+ XKeysym.Keysym2JavaKeycode jkc = isDeadKey ? XKeysym.getJavaKeycode(keysym)
+ : XKeysym.getJavaKeycode(ev);
if( jkc == null ) {
jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
}
@@ -1219,7 +1224,7 @@
jkc.getJavaKeycode();
postKeyEvent( java.awt.event.KeyEvent.KEY_RELEASED,
ev.get_time(),
- jkeyToReturn,
+ isDeadKey ? jkeyExtended : jkeyToReturn,
(unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
jkc.getKeyLocation(),
ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()),
@@ -1229,6 +1234,11 @@
}
+
+ private boolean isDeadKey(long keysym){
+ return XKeySymConstants.XK_dead_grave <= keysym && keysym <= XKeySymConstants.XK_dead_semivoiced_sound;
+ }
+
/*
* XmNiconic and Map/UnmapNotify (that XmNiconic relies on) are
* unreliable, since mapping changes can happen for a virtual desktop
--- a/jdk/src/solaris/classes/sun/awt/X11/keysym2ucs.h Tue Oct 23 09:38:38 2012 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/keysym2ucs.h Tue Oct 23 09:40:06 2012 -0700
@@ -695,25 +695,25 @@
0x0000 #define XK_ISO_Center_Object 0xFE33
0x0000 #define XK_ISO_Enter 0xFE34
-0x0000 #define XK_dead_grave 0xFE50
-0x0000 #define XK_dead_acute 0xFE51
-0x0000 #define XK_dead_circumflex 0xFE52
-0x0000 #define XK_dead_tilde 0xFE53
-0x0000 #define XK_dead_macron 0xFE54
-0x0000 #define XK_dead_breve 0xFE55
-0x0000 #define XK_dead_abovedot 0xFE56
-0x0000 #define XK_dead_diaeresis 0xFE57
-0x0000 #define XK_dead_abovering 0xFE58
-0x0000 #define XK_dead_doubleacute 0xFE59
-0x0000 #define XK_dead_caron 0xFE5A
-0x0000 #define XK_dead_cedilla 0xFE5B
-0x0000 #define XK_dead_ogonek 0xFE5C
-0x0000 #define XK_dead_iota 0xFE5D
-0x0000 #define XK_dead_voiced_sound 0xFE5E
-0x0000 #define XK_dead_semivoiced_sound 0xFE5F
-0x0000 #define XK_dead_belowdot 0xFE60
-0x0000 #define XK_dead_hook 0xFE61
-0x0000 #define XK_dead_horn 0xFE62
+0x02CB #define XK_dead_grave 0xFE50
+0x02CA #define XK_dead_acute 0xFE51
+0x02C6 #define XK_dead_circumflex 0xFE52
+0x02DC #define XK_dead_tilde 0xFE53
+0x02C9 #define XK_dead_macron 0xFE54
+0x02D8 #define XK_dead_breve 0xFE55
+0x02D9 #define XK_dead_abovedot 0xFE56
+0x00A8 #define XK_dead_diaeresis 0xFE57
+0x02DA #define XK_dead_abovering 0xFE58
+0x02DD #define XK_dead_doubleacute 0xFE59
+0x02C7 #define XK_dead_caron 0xFE5A
+0x00B8 #define XK_dead_cedilla 0xFE5B
+0x02DB #define XK_dead_ogonek 0xFE5C
+0x0269 #define XK_dead_iota 0xFE5D
+0x3099 #define XK_dead_voiced_sound 0xFE5E
+0x309A #define XK_dead_semivoiced_sound 0xFE5F
+0x0323 #define XK_dead_belowdot 0xFE60
+0x0321 #define XK_dead_hook 0xFE61
+0x031B #define XK_dead_horn 0xFE62
0x0000 #define XK_First_Virtual_Screen 0xFED0
0x0000 #define XK_Prev_Virtual_Screen 0xFED1
@@ -2466,6 +2466,7 @@
tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Meta_L), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_META, java.awt.event.KeyEvent.KEY_LOCATION_LEFT));
tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Meta_R), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_META, java.awt.event.KeyEvent.KEY_LOCATION_RIGHT));
tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Caps_Lock), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_CAPS_LOCK, java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
+tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Shift_Lock), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_CAPS_LOCK, java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
tojava
tojava /* Misc Functions */
tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Print), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_PRINTSCREEN, java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
@@ -2640,6 +2641,21 @@
tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Kanji), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_CONVERT, java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
tojava /* Type 5c Japanese keyboard: nihongo */
tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Henkan_Mode), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_INPUT_METHOD_ON_OFF, java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
+tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Eisu_Shift ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_ALPHANUMERIC , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
+tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Eisu_toggle ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_ALPHANUMERIC , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
+tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Zenkaku ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_FULL_WIDTH , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
+tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Hankaku ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_HALF_WIDTH , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
+tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Hiragana ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_HIRAGANA , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
+tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Katakana ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_KATAKANA , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
+tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Romaji ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_JAPANESE_ROMAN , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
+tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Kana_Shift ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_KANA , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
+tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Kana_Lock ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_KANA_LOCK , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
+tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Muhenkan ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_NONCONVERT , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
+tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Zen_Koho ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_ALL_CANDIDATES , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
+tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Kanji_Bangou ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_CODE_INPUT , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
+tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Mae_Koho ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_PREVIOUS_CANDIDATE , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
+tojava
+tojava
tojava /* VK_KANA_LOCK is handled separately because it generates the
tojava * same keysym as ALT_GRAPH in spite of its different behavior.
tojava */
--- a/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c Tue Oct 23 09:38:38 2012 -0700
+++ b/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c Tue Oct 23 09:40:06 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -753,7 +753,7 @@
sizeof(errmsg),
"Can't connect to X11 window server using '%s' as the value of the DISPLAY variable.",
(getenv("DISPLAY") == NULL) ? ":0.0" : getenv("DISPLAY"));
- JNU_ThrowInternalError(env, errmsg);
+ JNU_ThrowByName(env, "java/awt/AWTError", errmsg);
return NULL;
}
--- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java Tue Oct 23 09:38:38 2012 -0700
+++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java Tue Oct 23 09:40:06 2012 -0700
@@ -1099,7 +1099,7 @@
? SwingConstants.CENTER
: SwingConstants.LEADING);
- column.setComparator(new ColumnComparator(getIShellFolder(), i));
+ column.setComparator(new ColumnComparator(Win32ShellFolder2.this, i));
notNullColumns.add(column);
}
@@ -1135,7 +1135,7 @@
// synchronize the whole code of the sort method once
invoke(new Callable<Void>() {
public Void call() {
- Collections.sort(files, new ColumnComparator(getIShellFolder(), 0));
+ Collections.sort(files, new ColumnComparator(Win32ShellFolder2.this, 0));
return null;
}
@@ -1143,12 +1143,12 @@
}
private static class ColumnComparator implements Comparator<File> {
- private final long parentIShellFolder;
+ private final Win32ShellFolder2 shellFolder;
private final int columnIdx;
- public ColumnComparator(long parentIShellFolder, int columnIdx) {
- this.parentIShellFolder = parentIShellFolder;
+ public ColumnComparator(Win32ShellFolder2 shellFolder, int columnIdx) {
+ this.shellFolder = shellFolder;
this.columnIdx = columnIdx;
}
@@ -1159,7 +1159,7 @@
if (o instanceof Win32ShellFolder2
&& o1 instanceof Win32ShellFolder2) {
// delegates comparison to native method
- return compareIDsByColumn(parentIShellFolder,
+ return compareIDsByColumn(shellFolder.getIShellFolder(),
((Win32ShellFolder2) o).getRelativePIDL(),
((Win32ShellFolder2) o1).getRelativePIDL(),
columnIdx);
--- a/jdk/src/windows/native/sun/windows/awt_Window.cpp Tue Oct 23 09:38:38 2012 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp Tue Oct 23 09:40:06 2012 -0700
@@ -1559,21 +1559,8 @@
BOOL AwtWindow::AwtSetActiveWindow(BOOL isMouseEventCause, UINT hittest)
{
- // Fix for 6458497.
- // Retreat if current foreground window is out of both our and embedder process.
- // The exception is when activation is requested due to a mouse event.
- if (!isMouseEventCause) {
- HWND fgWindow = ::GetForegroundWindow();
- if (NULL != fgWindow) {
- DWORD fgProcessID;
- ::GetWindowThreadProcessId(fgWindow, &fgProcessID);
- if (fgProcessID != ::GetCurrentProcessId()
- && !AwtToolkit::GetInstance().IsEmbedderProcessId(fgProcessID))
- {
- return FALSE;
- }
- }
- }
+ // We used to reject non mouse window activation if our app wasn't active.
+ // This code since has been removed as the fix for 7185280
HWND proxyContainerHWnd = GetProxyToplevelContainer();
HWND proxyHWnd = GetProxyFocusOwner();
--- a/jdk/test/java/awt/Frame/7024749/bug7024749.java Tue Oct 23 09:38:38 2012 -0700
+++ b/jdk/test/java/awt/Frame/7024749/bug7024749.java Tue Oct 23 09:40:06 2012 -0700
@@ -25,7 +25,7 @@
* @test
* @bug 7024749
* @summary JDK7 b131---a crash in: Java_sun_awt_windows_ThemeReader_isGetThemeTransitionDurationDefined+0x75
- * @library ../../../regtesthelpers
+ * @library ../../regtesthelpers
* @build Util
* @author Oleg Pekhovskiy: area=awt.toplevel
@run main bug7024749
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/GraphicsConfiguration/NormalizingTransformTest/NormalizingTransformTest.java Tue Oct 23 09:40:06 2012 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, 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 6373505
+ * @summary Tests that the result of Toolkit.getScreenResolution() is
+ * consistent with GraphicsConfiguration.getNormalizingTransform().
+ * @author Dmitri.Trembovetski@Sun.COM: area=GraphicsConfiguration
+ * @run main NormalizingTransformTest
+ */
+
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Toolkit;
+import java.awt.geom.AffineTransform;
+
+public class NormalizingTransformTest {
+
+ public static void main(String[] args) {
+ GraphicsConfiguration gc =
+ GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getDefaultConfiguration();
+ AffineTransform normTransform = gc.getNormalizingTransform();
+ int dpiX = Toolkit.getDefaultToolkit().getScreenResolution();
+ int normDpiX = (int)(normTransform.getScaleX() * 72.0);
+ if (dpiX != normDpiX) {
+ throw new RuntimeException(
+ "Test FAILED. Toolkit.getScreenResolution()=" + dpiX +
+ " GraphicsConfiguration.getNormalizingTransform()="+normDpiX);
+ }
+ System.out.println("Test PASSED. DPI="+normDpiX);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/BadDisplayTest/BadDisplayTest.java Tue Oct 23 09:40:06 2012 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 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
+ * @summary Test that Toolkit.getDefaultToolkit throws AWTError exception if bad DISPLAY variable was set
+ * @bug 6818083
+ *
+ * @run shell/timeout=240 BadDisplayTest.sh
+ */
+
+import java.awt.*;
+
+public class BadDisplayTest{
+ public static void main(String[] args) {
+
+ Throwable th = null;
+ try {
+ Toolkit.getDefaultToolkit();
+ } catch (Throwable x) {
+ th = x;
+ }
+ if ( !(th instanceof AWTError)) {
+ System.exit(1);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/BadDisplayTest/BadDisplayTest.sh Tue Oct 23 09:40:06 2012 -0700
@@ -0,0 +1,42 @@
+# Copyright (c) 2012, 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.
+
+${TESTJAVA}/bin/javac -cp ${TESTSRC} -d . ${TESTSRC}/BadDisplayTest.java
+
+
+export DISPLAY=
+
+OS=`uname -s`
+case "$OS" in
+ SunOS )
+ ${TESTJAVA}/bin/java BadDisplayTest
+ ;;
+ Linux )
+ ${TESTJAVA}/bin/java BadDisplayTest
+ ;;
+ * )
+ echo "Unsupported System: ${OS}"
+ exit 0;
+ ;;
+esac
+
+exit $?
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JMenuItem/4654927/bug4654927.java Tue Oct 23 09:40:06 2012 -0700
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2012, 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 4654927
+ * @summary Clicking on Greyed Menuitems closes the Menubar Dropdown
+ * @author Alexander Potochkin
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main bug4654927
+ */
+
+import javax.swing.*;
+
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.util.concurrent.Callable;
+import sun.awt.SunToolkit;
+
+public class bug4654927 {
+
+ private static volatile JMenu menu;
+ private static volatile JMenuItem menuItem;
+
+ public static void main(String[] args) throws Exception {
+ String systemLAF = UIManager.getSystemLookAndFeelClassName();
+ // the test is not applicable to Motif L&F
+ if(systemLAF.endsWith("MotifLookAndFeel")){
+ return;
+ }
+
+ UIManager.setLookAndFeel(systemLAF);
+ SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+ Robot robot = new Robot();
+ robot.setAutoDelay(10);
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+
+ public void run() {
+ createAndShowUI();
+ }
+ });
+ toolkit.realSync();
+
+ // test mouse press
+ Point point = Util.getCenterPoint(menu);
+ robot.mouseMove(point.x, point.y);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ toolkit.realSync();
+
+ point = Util.getCenterPoint(menuItem);
+ robot.mouseMove(point.x, point.y);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ toolkit.realSync();
+
+ if (!isMenuItemShowing()) {
+ throw new RuntimeException("Popup is unexpectedly closed");
+ }
+
+ // test mouse drag
+ point = Util.getCenterPoint(menu);
+ robot.mouseMove(point.x, point.y);
+ Point menuLocation = Util.invokeOnEDT(new Callable<Point>() {
+
+ @Override
+ public Point call() throws Exception {
+ return menu.getLocationOnScreen();
+ }
+ });
+
+ Point itemLocation = Util.invokeOnEDT(new Callable<Point>() {
+
+ @Override
+ public Point call() throws Exception {
+ return menuItem.getLocationOnScreen();
+ }
+ });
+
+ int x0 = menuLocation.x + 10;
+ int y0 = menuLocation.y + 10;
+ int x1 = itemLocation.x + 10;
+ int y1 = itemLocation.y + 10;
+
+ // close menu
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ toolkit.realSync();
+
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ Util.glide(robot, x0, y0, x1, y1);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ toolkit.realSync();
+
+ if (!isMenuItemShowing()) {
+ throw new RuntimeException("Popup is unexpectedly closed");
+ }
+ }
+
+ private static boolean isMenuItemShowing() throws Exception {
+ return Util.invokeOnEDT(new Callable<Boolean>() {
+
+ @Override
+ public Boolean call() throws Exception {
+ return menuItem.isShowing();
+ }
+ });
+ }
+
+ private static void createAndShowUI() {
+ JFrame frame = new JFrame();
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ menu = new JMenu("Menu");
+ menu.add(new JMenuItem("menuItem"));
+ menuItem = new JMenuItem("menuItem");
+ menuItem.setEnabled(false);
+ menu.add(menuItem);
+ menu.add(new JMenuItem("menuItem"));
+
+ JMenuBar bar = new JMenuBar();
+ bar.add(menu);
+ frame.setJMenuBar(bar);
+
+ frame.setSize(200, 200);
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+
+ }
+}
--- a/jdk/test/javax/swing/regtesthelpers/Util.java Tue Oct 23 09:38:38 2012 -0700
+++ b/jdk/test/javax/swing/regtesthelpers/Util.java Tue Oct 23 09:40:06 2012 -0700
@@ -157,6 +157,36 @@
}
/**
+ * Moves mouse smoothly from (x0, y0) to (x1, y1).
+ */
+ public static void glide(Robot robot, int x0, int y0, int x1, int y1) throws AWTException {
+ float dmax = (float) Math.max(Math.abs(x1 - x0), Math.abs(y1 - y0));
+ float dx = (x1 - x0) / dmax;
+ float dy = (y1 - y0) / dmax;
+
+ for (int i = 0; i <= dmax; i += 10) {
+ robot.mouseMove((int) (x0 + dx * i), (int) (y0 + dy * i));
+ }
+ }
+
+ /**
+ * Gets component center point
+ *
+ * @return center point of the <code>component</code>
+ */
+ public static Point getCenterPoint(final Component component) throws Exception {
+ return Util.invokeOnEDT(new Callable<Point>() {
+
+ @Override
+ public Point call() throws Exception {
+ Point p = component.getLocationOnScreen();
+ Dimension size = component.getSize();
+ return new Point(p.x + size.width / 2, p.y + size.height / 2);
+ }
+ });
+ }
+
+ /**
* Invokes the <code>task</code> on the EDT thread.
*
* @return result of the <code>task</code>