Mercurial > hg > icedtea7-forest-aarch64 > jdk
changeset 8020:feac9624a1e1 jdk7u60-b31
Merge
author | asaha |
---|---|
date | Fri, 09 May 2014 08:36:37 -0700 |
parents | 510910263b66 (current diff) 114d06877867 (diff) |
children | e012c187d505 3709fc571038 |
files | .hgtags src/macosx/classes/sun/lwawt/macosx/CMouseInfoPeer.java src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java src/macosx/native/sun/awt/AWTWindow.m |
diffstat | 15 files changed, 643 insertions(+), 164 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Fri May 09 07:48:02 2014 -0700 +++ b/.hgtags Fri May 09 08:36:37 2014 -0700 @@ -407,6 +407,8 @@ b83f5194edf23b752fe2c0a9be361455f87196df jdk7u55-b32 01a4cd03a6c85abb62eb5d1c2b5bf7d2f544c04e jdk7u55-b33 3f54f8a387c1a908c07106b685183b19a5fc1064 jdk7u55-b34 +2cdc52ec4813abe38b4e52ae9c9f0ff5dcc87faa jdk7u55-b35 +6845d311ff990d422f9376d37e3e82d5d06bff3f jdk7u55-b36 db5a29c812ee25c34ce9cd97de6e0dae284a4e34 jdk7u60-b00 def34c4a798678c424786a8f0d0508e90185958d jdk7u60-b01 ff67c89658525e8903fb870861ed3645befd6bc5 jdk7u60-b02
--- a/make/sun/lwawt/FILES_export_macosx.gmk Fri May 09 07:48:02 2014 -0700 +++ b/make/sun/lwawt/FILES_export_macosx.gmk Fri May 09 08:36:37 2014 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2014, 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 @@ -141,7 +141,6 @@ sun/lwawt/macosx/CMenuBar.java \ sun/lwawt/macosx/CMenuComponent.java \ sun/lwawt/macosx/CMenuItem.java \ - sun/lwawt/macosx/CMouseInfoPeer.java \ sun/lwawt/macosx/CPlatformView.java \ sun/lwawt/macosx/CPlatformWindow.java \ sun/lwawt/macosx/CPlatformComponent.java \
--- a/src/macosx/classes/sun/lwawt/LWWindowPeer.java Fri May 09 07:48:02 2014 -0700 +++ b/src/macosx/classes/sun/lwawt/LWWindowPeer.java Fri May 09 08:36:37 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -89,10 +89,15 @@ private volatile int windowState = Frame.NORMAL; + // check that the mouse is over the window + private volatile boolean isMouseOver = false; + // A peer where the last mouse event came to. Used by cursor manager to + // find the component under cursor + private static volatile LWComponentPeer lastCommonMouseEventPeer = null; + // A peer where the last mouse event came to. Used to generate - // MOUSE_ENTERED/EXITED notifications and by cursor manager to - // find the component under cursor - private static volatile LWComponentPeer lastMouseEventPeer = null; + // MOUSE_ENTERED/EXITED notifications + private volatile LWComponentPeer lastMouseEventPeer; // Peers where all dragged/released events should come to, // depending on what mouse button is being dragged according to Cocoa @@ -773,59 +778,62 @@ Rectangle r = getBounds(); // findPeerAt() expects parent coordinates LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y); - LWWindowPeer lastWindowPeer = - (lastMouseEventPeer != null) ? lastMouseEventPeer.getWindowPeerOrSelf() : null; - LWWindowPeer curWindowPeer = - (targetPeer != null) ? targetPeer.getWindowPeerOrSelf() : null; if (id == MouseEvent.MOUSE_EXITED) { - // Sometimes we may get MOUSE_EXITED after lastMouseEventPeer is switched - // to a peer from another window. So we must first check if this peer is - // the same as lastWindowPeer - if (lastWindowPeer == this) { - if (isEnabled()) { + isMouseOver = false; + if (lastMouseEventPeer != null) { + if (lastMouseEventPeer.isEnabled()) { Point lp = lastMouseEventPeer.windowToLocal(x, y, - lastWindowPeer); + this); Component target = lastMouseEventPeer.getTarget(); postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED, when, modifiers, lp, screenX, screenY, clickCount, popupTrigger, button); } + + // Sometimes we may get MOUSE_EXITED after lastCommonMouseEventPeer is switched + // to a peer from another window. So we must first check if this peer is + // the same as lastWindowPeer + if (lastCommonMouseEventPeer != null && lastCommonMouseEventPeer.getWindowPeerOrSelf() == this) { + lastCommonMouseEventPeer = null; + } lastMouseEventPeer = null; } + } else if (id == MouseEvent.MOUSE_ENTERED) { + isMouseOver = true; + if (targetPeer != null) { + if (targetPeer.isEnabled()) { + Point lp = targetPeer.windowToLocal(x, y, this); + Component target = targetPeer.getTarget(); + postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_ENTERED, when, modifiers, lp, + screenX, screenY, clickCount, popupTrigger, button); + } + lastCommonMouseEventPeer = targetPeer; + lastMouseEventPeer = targetPeer; + } } else { - if (targetPeer != lastMouseEventPeer) { - // lastMouseEventPeer may be null if mouse was out of Java windows - if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) { - // Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit - // later), in which case lastWindowPeer is another window - if (lastWindowPeer != this) { - Point oldp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer); - // Additionally translate from this to lastWindowPeer coordinates - Rectangle lr = lastWindowPeer.getBounds(); - oldp.x += r.x - lr.x; - oldp.y += r.y - lr.y; - Component target = lastMouseEventPeer.getTarget(); - postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED, - when, modifiers, oldp, - screenX, screenY, clickCount, popupTrigger, button); - } else { - Point oldp = lastMouseEventPeer.windowToLocal(x, y, this); - Component target = lastMouseEventPeer.getTarget(); - postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED, - when, modifiers, oldp, - screenX, screenY, clickCount, popupTrigger, button); - } - } - lastMouseEventPeer = targetPeer; - if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) { - Point newp = targetPeer.windowToLocal(x, y, curWindowPeer); - Component target = targetPeer.getTarget(); - postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_ENTERED, - when, modifiers, newp, - screenX, screenY, clickCount, popupTrigger, button); - } + PlatformWindow topmostPlatformWindow = + platformWindow.getTopmostPlatformWindowUnderMouse(); + + LWWindowPeer topmostWindowPeer = + topmostPlatformWindow != null ? topmostPlatformWindow.getPeer() : null; + + // topmostWindowPeer == null condition is added for the backword + // compatibility with applets. It can be removed when the + // getTopmostPlatformWindowUnderMouse() method will be properly + // implemented i CPlatformEmbeddedFrame class + if (topmostWindowPeer == this || topmostWindowPeer == null) { + generateMouseEnterExitEventsForComponents(when, button, x, y, + screenX, screenY, modifiers, clickCount, popupTrigger, + targetPeer); + } else { + LWComponentPeer topmostTargetPeer = + topmostWindowPeer != null ? topmostWindowPeer.findPeerAt(r.x + x, r.y + y) : null; + topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y, + screenX, screenY, modifiers, clickCount, popupTrigger, + topmostTargetPeer); } + // TODO: fill "bdata" member of AWTEvent int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0; @@ -875,19 +883,13 @@ // mouseClickButtons is updated below, after MOUSE_CLICK is sent } - // check if we receive mouseEvent from outside the window's bounds - // it can be either mouseDragged or mouseReleased - if (curWindowPeer == null) { - //TODO This can happen if this window is invisible. this is correct behavior in this case? - curWindowPeer = this; - } if (targetPeer == null) { //TODO This can happen if this window is invisible. this is correct behavior in this case? targetPeer = this; } - Point lp = targetPeer.windowToLocal(x, y, curWindowPeer); + Point lp = targetPeer.windowToLocal(x, y, this); if (targetPeer.isEnabled()) { if (id == MouseEvent.MOUSE_ENTERED || id == MouseEvent.MOUSE_EXITED) { postMouseEnteredExitedEvent(targetPeer.getTarget(), id, @@ -918,6 +920,33 @@ notifyUpdateCursor(); } + private void generateMouseEnterExitEventsForComponents(long when, + int button, int x, int y, int screenX, int screenY, + int modifiers, int clickCount, boolean popupTriger, + LWComponentPeer targetPeer) { + if (!isMouseOver || targetPeer == lastMouseEventPeer) { + return; + } + + // Generate Mouse Exit for components + if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) { + Point oldp = lastMouseEventPeer.windowToLocal(x, y, this); + Component target = lastMouseEventPeer.getTarget(); + postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED, when, modifiers, + oldp, screenX, screenY, clickCount, popupTriger, button); + } + lastCommonMouseEventPeer = targetPeer; + lastMouseEventPeer = targetPeer; + + // Genrate Mouse Enter for Componetns + if (targetPeer != null && targetPeer.isEnabled()) { + Point newp = targetPeer.windowToLocal(x, y, this); + Component target = targetPeer.getTarget(); + postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_ENTERED, when, modifiers, + newp, screenX, screenY, clickCount, popupTriger, button); + } + } + private void postMouseEnteredExitedEvent( Component target, int id, long when, int modifiers, Point loc, int xAbs, int yAbs, @@ -1198,11 +1227,11 @@ } public static LWWindowPeer getWindowUnderCursor() { - return lastMouseEventPeer != null ? lastMouseEventPeer.getWindowPeerOrSelf() : null; + return lastCommonMouseEventPeer != null ? lastCommonMouseEventPeer.getWindowPeerOrSelf() : null; } public static LWComponentPeer<?, ?> getPeerUnderCursor() { - return lastMouseEventPeer; + return lastCommonMouseEventPeer; } /*
--- a/src/macosx/classes/sun/lwawt/PlatformWindow.java Fri May 09 07:48:02 2014 -0700 +++ b/src/macosx/classes/sun/lwawt/PlatformWindow.java Fri May 09 08:36:37 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -118,6 +118,8 @@ public void setAlwaysOnTop(boolean value); + public PlatformWindow getTopmostPlatformWindowUnderMouse(); + public void updateFocusableWindowState(); public boolean rejectFocusRequest(CausedFocusEvent.Cause cause);
--- a/src/macosx/classes/sun/lwawt/macosx/CMouseInfoPeer.java Fri May 09 07:48:02 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2011, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package sun.lwawt.macosx; - -import java.awt.Window; -import sun.lwawt.LWMouseInfoPeer; -import sun.lwawt.LWWindowPeer; - -public class CMouseInfoPeer extends LWMouseInfoPeer -{ - //If a new window is to appear under the cursor, - //we get wrong window. - //This is a workaround for macosx. - @Override - public boolean isWindowUnderMouse(Window w) { - if (w == null) { - return false; - } - - return ((LWWindowPeer)w.getPeer()).getPlatformWindow().isUnderMouse(); - } -}
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java Fri May 09 07:48:02 2014 -0700 +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java Fri May 09 08:36:37 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -151,6 +151,11 @@ @Override public void setAlwaysOnTop(boolean value) {} + // This method should be properly implemented for applets. + // It returns null just as a stub. + @Override + public PlatformWindow getTopmostPlatformWindowUnderMouse() { return null; } + @Override public void updateFocusableWindowState() {}
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri May 09 07:48:02 2014 -0700 +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri May 09 08:36:37 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -61,8 +61,9 @@ private static native void nativeSetNSWindowMinimizedIcon(long nsWindowPtr, long nsImage); private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename); private static native void nativeSetEnabled(long nsWindowPtr, boolean isEnabled); - private static native void nativeSynthesizeMouseEnteredExitedEvents(long nsWindowPtr); + private static native void nativeSynthesizeMouseEnteredExitedEvents(); private static native void nativeDispose(long nsWindowPtr); + private static native CPlatformWindow nativeGetTopmostPlatformWindowUnderMouse(); // Loger to report issues happened during execution but that do not affect functionality private static final PlatformLogger logger = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformWindow"); @@ -593,7 +594,7 @@ } } - nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr); + nativeSynthesizeMouseEnteredExitedEvents(); // Configure stuff #2 updateFocusabilityForAutoRequestFocus(true); @@ -738,6 +739,9 @@ setStyleBits(ALWAYS_ON_TOP, isAlwaysOnTop); } + public PlatformWindow getTopmostPlatformWindowUnderMouse() { + return CPlatformWindow.nativeGetTopmostPlatformWindowUnderMouse(); + } @Override public void setOpacity(float opacity) { CWrapper.NSWindow.setAlphaValue(getNSWindowPtr(), opacity); @@ -830,7 +834,7 @@ throw new RuntimeException("Unknown window state: " + windowState); } - nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr); + nativeSynthesizeMouseEnteredExitedEvents(); // NOTE: the SWP.windowState field gets updated to the newWindowState // value when the native notification comes to us
--- a/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java Fri May 09 07:48:02 2014 -0700 +++ b/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java Fri May 09 08:36:37 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -148,6 +148,11 @@ } @Override + public PlatformWindow getTopmostPlatformWindowUnderMouse() { + return null; + } + + @Override public void updateFocusableWindowState() { }
--- a/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Fri May 09 07:48:02 2014 -0700 +++ b/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Fri May 09 08:36:37 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -300,11 +300,6 @@ } @Override - protected MouseInfoPeer createMouseInfoPeerImpl() { - return new CMouseInfoPeer(); - } - - @Override protected int getScreenHeight() { return GraphicsEnvironment.getLocalGraphicsEnvironment() .getDefaultScreenDevice().getDefaultConfiguration().getBounds().height;
--- a/src/macosx/native/sun/awt/AWTView.h Fri May 09 07:48:02 2014 -0700 +++ b/src/macosx/native/sun/awt/AWTView.h Fri May 09 08:36:37 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014 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 @@ -33,8 +33,8 @@ @private jobject m_cPlatformView; - // Handler for the tracking rect needed for Enter/Exit events management. - NSTrackingRectTag rolloverTrackingRectTag; + // Handler for the tracking area needed for Enter/Exit events management. + NSTrackingArea* rolloverTrackingArea; // TODO: NSMenu *contextualMenu; @@ -61,7 +61,7 @@ - (id) initWithRect:(NSRect) rect platformView:(jobject)cPlatformView windowLayer:(CALayer*)windowLayer; - (void) deliverJavaMouseEvent: (NSEvent *) event; -- (void) resetTrackingRect; +- (void) resetTrackingArea; - (void) deliverJavaKeyEventHelper: (NSEvent *) event; - (jobject) awtComponent:(JNIEnv *)env;
--- a/src/macosx/native/sun/awt/AWTView.m Fri May 09 07:48:02 2014 -0700 +++ b/src/macosx/native/sun/awt/AWTView.m Fri May 09 08:36:37 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -82,6 +82,7 @@ fPAHNeedsToSelect = NO; mouseIsOver = NO; + [self resetTrackingArea]; if (windowLayer != nil) { self.cglLayer = windowLayer; @@ -149,7 +150,7 @@ [[self window] makeFirstResponder: self]; }]; if ([self window] != NULL) { - [self resetTrackingRect]; + [self resetTrackingArea]; } } @@ -380,30 +381,31 @@ JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent); } - -- (void) clearTrackingRect { - if (rolloverTrackingRectTag > 0) { - [self removeTrackingRect:rolloverTrackingRectTag]; - rolloverTrackingRectTag = 0; +- (void) resetTrackingArea { + if (rolloverTrackingArea != nil) { + [self removeTrackingArea:rolloverTrackingArea]; + [rolloverTrackingArea release]; } -} + + int options = (NSTrackingActiveAlways | NSTrackingMouseEnteredAndExited | + NSTrackingMouseMoved | NSTrackingEnabledDuringMouseDrag); -- (void) resetTrackingRect { - [self clearTrackingRect]; - rolloverTrackingRectTag = [self addTrackingRect:[self visibleRect] - owner:self - userData:NULL - assumeInside:NO]; + rolloverTrackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect] + options:options + owner:self + userInfo:nil + ]; + [self addTrackingArea:rolloverTrackingArea]; } - (void)updateTrackingAreas { [super updateTrackingAreas]; - [self resetTrackingRect]; + [self resetTrackingArea]; } - (void) resetCursorRects { [super resetCursorRects]; - [self resetTrackingRect]; + [self resetTrackingArea]; } -(void) deliverJavaKeyEventHelper: (NSEvent *) event {
--- a/src/macosx/native/sun/awt/AWTWindow.m Fri May 09 07:48:02 2014 -0700 +++ b/src/macosx/native/sun/awt/AWTWindow.m Fri May 09 08:36:37 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -314,10 +314,8 @@ return [window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]]; } -// checks that this window is under the mouse cursor and this point is not overlapped by others windows -- (BOOL) isTopmostWindowUnderMouse { - - int currentWinID = [self.nsWindow windowNumber]; +// return id for the topmost window under mouse ++ (NSInteger) getTopmostWindowUnderMouseID { NSRect screenRect = [[NSScreen mainScreen] frame]; NSPoint nsMouseLocation = [NSEvent mouseLocation]; @@ -327,51 +325,75 @@ for (NSDictionary *window in windows) { - int layer = [[window objectForKey:(id)kCGWindowLayer] intValue]; + NSInteger layer = [[window objectForKey:(id)kCGWindowLayer] integerValue]; if (layer == 0) { - int winID = [[window objectForKey:(id)kCGWindowNumber] intValue]; CGRect rect; CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect); if (CGRectContainsPoint(rect, cgMouseLocation)) { - return currentWinID == winID; - } else if (currentWinID == winID) { - return NO; + return [[window objectForKey:(id)kCGWindowNumber] integerValue]; } } } - return NO; + return -1; +} + +// checks that this window is under the mouse cursor and this point is not overlapped by other windows +- (BOOL) isTopmostWindowUnderMouse { + return [self.nsWindow windowNumber] == [AWTWindow getTopmostWindowUnderMouseID]; } -- (void) synthesizeMouseEnteredExitedEvents { ++ (AWTWindow *) getTopmostWindowUnderMouse { + NSEnumerator *windowEnumerator = [[NSApp windows] objectEnumerator]; + NSWindow *window; - int eventType = 0; - BOOL isUnderMouse = [self isTopmostWindowUnderMouse]; - BOOL mouseIsOver = [[self.nsWindow contentView] mouseIsOver]; + NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID]; - if (isUnderMouse && !mouseIsOver) { - eventType = NSMouseEntered; - } else if (!isUnderMouse && mouseIsOver) { - eventType = NSMouseExited; - } else { - return; + while ((window = [windowEnumerator nextObject]) != nil) { + if ([window windowNumber] == topmostWindowUnderMouseID) { + BOOL isAWTWindow = [AWTWindow isAWTWindow: window]; + return isAWTWindow ? (AWTWindow *) [window delegate] : nil; + } } + return nil; +} + ++ (void) synthesizeMouseEnteredExitedEvents:(NSWindow*)window withType:(NSEventType)eventType { NSPoint screenLocation = [NSEvent mouseLocation]; - NSPoint windowLocation = [self.nsWindow convertScreenToBase: screenLocation]; + NSPoint windowLocation = [window convertScreenToBase: screenLocation]; int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask; NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType location: windowLocation modifierFlags: modifierFlags timestamp: 0 - windowNumber: [self.nsWindow windowNumber] + windowNumber: [window windowNumber] context: nil eventNumber: 0 trackingNumber: 0 userData: nil ]; - [[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent]; + [[window contentView] deliverJavaMouseEvent: mouseEvent]; +} + ++(void) synthesizeMouseEnteredExitedEventsForAllWindows { + NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID]; + NSArray *windows = [NSApp windows]; + NSWindow *window; + + NSEnumerator *windowEnumerator = [windows objectEnumerator]; + while ((window = [windowEnumerator nextObject]) != nil) { + if ([AWTWindow isAWTWindow: window]) { + BOOL isUnderMouse = ([window windowNumber] == topmostWindowUnderMouseID); + BOOL mouseIsOver = [[window contentView] mouseIsOver]; + if (isUnderMouse && !mouseIsOver) { + [AWTWindow synthesizeMouseEnteredExitedEvents: window withType:NSMouseEntered]; + } else if (!isUnderMouse && mouseIsOver) { + [AWTWindow synthesizeMouseEnteredExitedEvents: window withType:NSMouseExited]; + } + } + } } + (NSNumber *) getNSWindowDisplayID_AppKitThread:(NSWindow *)window { @@ -979,7 +1001,7 @@ // (this will also re-enable screen updates, which were disabled above) // TODO: send PaintEvent - [window synthesizeMouseEnteredExitedEvents]; + [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows]; }]; JNF_COCOA_EXIT(env); @@ -1158,19 +1180,40 @@ /* * Class: sun_lwawt_macosx_CPlatformWindow + * Method: nativeGetTopMostWindowUnderMouse + * Signature: (J)V + */ +JNIEXPORT jobject +JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetTopmostPlatformWindowUnderMouse +(JNIEnv *env, jclass clazz) +{ + jobject topmostWindowUnderMouse = nil; + + JNF_COCOA_ENTER(env); + AWT_ASSERT_APPKIT_THREAD; + + AWTWindow *awtWindow = [AWTWindow getTopmostWindowUnderMouse]; + if (awtWindow != nil) { + topmostWindowUnderMouse = [awtWindow.javaPlatformWindow jObject]; + } + + JNF_COCOA_EXIT(env); + + return topmostWindowUnderMouse; +} + +/* + * Class: sun_lwawt_macosx_CPlatformWindow * Method: nativeSynthesizeMouseEnteredExitedEvents * Signature: (J)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents -(JNIEnv *env, jclass clazz, jlong windowPtr) +(JNIEnv *env, jclass clazz) { JNF_COCOA_ENTER(env); - NSWindow *nsWindow = OBJC(windowPtr); [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ - AWTWindow *window = (AWTWindow*)[nsWindow delegate]; - - [window synthesizeMouseEnteredExitedEvents]; + [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows]; }]; JNF_COCOA_EXIT(env);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/Mouse/EnterExitEvents/DragWindowTest.java Fri May 09 08:36:37 2014 -0700 @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2005, 2006, 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 7154048 + * @summary Window created under a mouse does not receive mouse enter event. + * Mouse Entered/Exited events are wrongly generated during dragging the window + * from one component to another + * @library ../../regtesthelpers + * @build Util + * @author alexandr.scherbatiy area=awt.event + * @run main DragWindowTest + */ + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +import java.util.concurrent.*; +import sun.awt.SunToolkit; + +import test.java.awt.regtesthelpers.Util; + +public class DragWindowTest { + + private static volatile int dragWindowMouseEnteredCount = 0; + private static volatile int dragWindowMouseReleasedCount = 0; + private static volatile int buttonMouseEnteredCount = 0; + private static volatile int labelMouseReleasedCount = 0; + private static MyDragWindow dragWindow; + private static JLabel label; + private static JButton button; + + public static void main(String[] args) throws Exception { + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + robot.setAutoDelay(50); + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + createAndShowGUI(); + } + }); + + toolkit.realSync(); + + Point pointToClick = Util.invokeOnEDT(new Callable<Point>() { + + @Override + public Point call() throws Exception { + return getCenterPoint(label); + } + }); + + + robot.mouseMove(pointToClick.x, pointToClick.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + + if (dragWindowMouseEnteredCount != 1) { + throw new RuntimeException("No MouseEntered event on Drag Window!"); + } + + Point pointToDrag = Util.invokeOnEDT(new Callable<Point>() { + + @Override + public Point call() throws Exception { + button.addMouseListener(new ButtonMouseListener()); + return getCenterPoint(button); + } + }); + + robot.mouseMove(pointToDrag.x, pointToDrag.y); + toolkit.realSync(); + + if (buttonMouseEnteredCount != 0) { + throw new RuntimeException("Extra MouseEntered event on button!"); + } + + robot.mouseRelease(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + + if (labelMouseReleasedCount != 1) { + throw new RuntimeException("No MouseReleased event on label!"); + } + + } + + private static Point getCenterPoint(Component comp) { + Point p = comp.getLocationOnScreen(); + Rectangle rect = comp.getBounds(); + return new Point(p.x + rect.width / 2, p.y + rect.height / 2); + } + + private static void createAndShowGUI() { + + JFrame frame = new JFrame("Main Frame"); + frame.setSize(300, 200); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + label = new JLabel("Label"); + + LabelMouseListener listener = new LabelMouseListener(frame); + label.addMouseListener(listener); + label.addMouseMotionListener(listener); + + button = new JButton("Button"); + Panel panel = new Panel(new BorderLayout()); + + panel.add(label, BorderLayout.NORTH); + panel.add(button, BorderLayout.CENTER); + + frame.getContentPane().add(panel); + frame.setVisible(true); + + } + + private static Point getAbsoluteLocation(MouseEvent e) { + return new Point(e.getXOnScreen(), e.getYOnScreen()); + } + + static class MyDragWindow extends Window { + + static int d = 30; + + public MyDragWindow(Window parent, Point location) { + super(parent); + setSize(150, 150); + setVisible(true); + JPanel panel = new JPanel(); + add(panel); + setLocation(location.x - d, location.y - d); + addMouseListener(new DragWindowMouseListener()); + } + + void dragTo(Point point) { + setLocation(point.x - d, point.y - d); + } + } + + static class LabelMouseListener extends MouseAdapter { + + Point origin; + Window parent; + + public LabelMouseListener(Window parent) { + this.parent = parent; + } + + @Override + public void mousePressed(MouseEvent e) { + if (dragWindow == null) { + dragWindow = new MyDragWindow(parent, getAbsoluteLocation(e)); + } else { + dragWindow.setVisible(true); + dragWindow.dragTo(getAbsoluteLocation(e)); + } + } + + @Override + public void mouseReleased(MouseEvent e) { + labelMouseReleasedCount++; + if (dragWindow != null) { + dragWindow.setVisible(false); + } + } + + public void mouseDragged(MouseEvent e) { + if (dragWindow != null) { + dragWindow.dragTo(getAbsoluteLocation(e)); + } + } + } + + static class DragWindowMouseListener extends MouseAdapter { + + @Override + public void mouseEntered(MouseEvent e) { + dragWindowMouseEnteredCount++; + } + + @Override + public void mouseReleased(MouseEvent e) { + dragWindowMouseReleasedCount++; + } + } + + static class ButtonMouseListener extends MouseAdapter { + + @Override + public void mouseEntered(MouseEvent e) { + buttonMouseEnteredCount++; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithOverlay.java Fri May 09 08:36:37 2014 -0700 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2014, 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. + */ + +import test.java.awt.regtesthelpers.Util; + +import javax.swing.*; +import java.awt.*; +import java.util.concurrent.atomic.AtomicReference; + +/** + * @test + * @bug 8012026 + * @summary Component.getMousePosition() does not work in an applet on MacOS + * @author Petr Pchelko + * @library ../../regtesthelpers + * @build Util + * @compile GetMousePositionWithOverlay.java + * @run main/othervm GetMousePositionWithOverlay + */ + +public class GetMousePositionWithOverlay { + + static Frame backFrame; + static Frame frontFrame; + + public static void main(String[] args) throws Throwable { + try { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + constructTestUI(); + } + }); + Util.waitForIdle(null); + + Robot r = new Robot(); + Util.pointOnComp(frontFrame, r); + Util.waitForIdle(null); + + Point pos = getMousePosition(backFrame); + if (pos != null) { + throw new RuntimeException("Test failed. Mouse position should be null but was" + pos); + } + + pos = getMousePosition(frontFrame); + if (pos == null) { + throw new RuntimeException("Test failed. Mouse position should not be null"); + } + + r.mouseMove(189, 189); + Util.waitForIdle(null); + + pos = getMousePosition(backFrame); + if (pos == null) { + throw new RuntimeException("Test failed. Mouse position should not be null"); + } + } finally { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + backFrame.dispose(); + frontFrame.dispose(); + } + }); + } + } + + private static Point getMousePosition(final Component component) throws Exception { + final AtomicReference<Point> pos = new AtomicReference<Point>(); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + pos.set(component.getMousePosition()); + } + }); + return pos.get(); + } + + private static void constructTestUI() { + backFrame = new Frame(); + backFrame.setBounds(100, 100, 100, 100); + backFrame.setVisible(true); + + frontFrame = new Frame(); + frontFrame.setBounds(120, 120, 60, 60); + frontFrame.setVisible(true); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithPopup.java Fri May 09 08:36:37 2014 -0700 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014, 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. + */ + +import test.java.awt.regtesthelpers.Util; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; + +/** + * @test + * @bug 8012026 + * @summary Component.getMousePosition() does not work in an applet on MacOS + * @author Petr Pchelko + * @library ../../regtesthelpers + * @build Util + * @compile GetMousePositionWithPopup.java + * @run main/othervm GetMousePositionWithPopup + */ + +public class GetMousePositionWithPopup { + + private static Frame frame1; + private static Frame frame2; + + public static void main(String[] args) throws Exception { + try { + Robot r = Util.createRobot(); + r.mouseMove(0, 0); + Util.waitForIdle(null); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + constructTestUI(); + } + }); + + Util.waitForIdle(null); + r.mouseMove(149, 149); + Util.waitForIdle(null); + r.mouseMove(150, 150); + Util.waitForIdle(null); + + } finally { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + frame1.dispose(); + frame2.dispose(); + } + }); + } + } + + private static void constructTestUI() { + frame1 = new Frame(); + frame1.setBounds(100, 100, 100, 100); + frame1.addMouseMotionListener(new MouseMotionAdapter() { + + private boolean shown = false; + + @Override + public void mouseMoved(MouseEvent e) { + if (shown) { + return; + } + + shown = true; + + frame2 = new Frame(); + frame2.setBounds(120, 120, 120, 120); + frame2.setVisible(true); + + Point positionInFrame2 = frame2.getMousePosition(); + if (positionInFrame2.x != 30 || positionInFrame2.y != 30) { + throw new RuntimeException("Wrong position reported. Should be [30, 30] but was [" + + positionInFrame2.x + ", " + positionInFrame2.y + "]"); + } + + Point positionInFrame1 = frame1.getMousePosition(); + if (positionInFrame1 != null) { + throw new RuntimeException("Wrong position reported. Should be null"); + } + + } + }); + frame1.setVisible(true); + } +}