OpenJDK / amber / amber
changeset 14168:5d6486e974ab
Merge
author | lana |
---|---|
date | Tue, 23 Oct 2012 09:40:06 -0700 |
parents | 0f28da8d3c45 e5ddc84321f2 |
children | cd64865d1faf |
files | |
diffstat | 20 files changed, 628 insertions(+), 98 deletions(-) [+] |
line wrap: on
line diff
--- 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>