7171045: [macosx] There are no enter or exit events reported against 8b39 for MouseEventsDuringDrag.
authoralexsch
Wed, 29 Aug 2012 15:54:28 +0400
changeset 13647 de61414bbcf2
parent 13552 5270c932737d
child 13648 90effcfc064f
7171045: [macosx] There are no enter or exit events reported against 8b39 for MouseEventsDuringDrag. Reviewed-by: anthony, serb
jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java
jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java
jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java
jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
jdk/src/macosx/native/sun/awt/AWTView.h
jdk/src/macosx/native/sun/awt/AWTView.m
jdk/src/macosx/native/sun/awt/AWTWindow.m
--- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Tue Aug 28 16:04:27 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Wed Aug 29 15:54:28 2012 +0400
@@ -88,10 +88,16 @@
 
     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
@@ -707,66 +713,65 @@
         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);
                     postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
-                                             MouseEvent.MOUSE_EXITED, when,
-                                             modifiers, lp.x, lp.y, screenX,
-                                             screenY, clickCount, popupTrigger,
-                                             button));
+                            MouseEvent.MOUSE_EXITED, when,
+                            modifiers, lp.x, lp.y, 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 (targetPeer != lastMouseEventPeer) {
-
-                if (id != MouseEvent.MOUSE_DRAGGED || lastMouseEventPeer == null) {
-                    // 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;
-                            postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
-                                                     MouseEvent.MOUSE_EXITED,
-                                                     when, modifiers,
-                                                     oldp.x, oldp.y, screenX, screenY,
-                                                     clickCount, popupTrigger, button));
-                        } else {
-                            Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
-                            postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
-                                                     MouseEvent.MOUSE_EXITED,
-                                                     when, modifiers,
-                                                     oldp.x, oldp.y, screenX, screenY,
-                                                     clickCount, popupTrigger, button));
-                        }
-                    }
-                    if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) {
-                        Point newp = targetPeer.windowToLocal(x, y, curWindowPeer);
+        } else if(id == MouseEvent.MOUSE_ENTERED) {
+            isMouseOver = true;
+            if (targetPeer != null) {
+                if (targetPeer.isEnabled()) {
+                    Point lp = targetPeer.windowToLocal(x, y, this);
                         postEvent(new MouseEvent(targetPeer.getTarget(),
-                                                 MouseEvent.MOUSE_ENTERED,
-                                                 when, modifiers,
-                                                 newp.x, newp.y, screenX, screenY,
-                                                 clickCount, popupTrigger, button));
-                    }
+                            MouseEvent.MOUSE_ENTERED, when,
+                            modifiers, lp.x, lp.y, screenX,
+                            screenY, clickCount, popupTrigger,
+                            button));
                 }
+                lastCommonMouseEventPeer = targetPeer;
                 lastMouseEventPeer = targetPeer;
             }
+        } else {
+            PlatformWindow topmostPlatforWindow =
+                    platformWindow.getTopmostPlatformWindowUnderMouse();
+
+            LWWindowPeer topmostWindowPeer =
+                    topmostPlatforWindow != null ? topmostPlatforWindow.getPeer() : null;
+
+            // topmostWindowPeer == null condition is added for the backward
+            // compatibility with applets. It can be removed when the
+            // getTopmostPlatformWindowUnderMouse() method will be properly
+            // implemented in 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;
@@ -816,19 +821,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()) {
                 MouseEvent event = new MouseEvent(targetPeer.getTarget(), id,
                                                   when, modifiers, lp.x, lp.y,
@@ -852,6 +851,38 @@
         notifyUpdateCursor();
     }
 
+    private void generateMouseEnterExitEventsForComponents(long when,
+            int button, int x, int y, int screenX, int screenY,
+            int modifiers, int clickCount, boolean popupTrigger,
+            LWComponentPeer targetPeer) {
+
+        if (!isMouseOver || targetPeer == lastMouseEventPeer) {
+            return;
+        }
+
+        // Generate Mouse Exit for components
+        if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
+            Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
+            postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
+                    MouseEvent.MOUSE_EXITED,
+                    when, modifiers,
+                    oldp.x, oldp.y, screenX, screenY,
+                    clickCount, popupTrigger, button));
+        }
+        lastCommonMouseEventPeer = targetPeer;
+        lastMouseEventPeer = targetPeer;
+
+        // Generate Mouse Enter for components
+        if (targetPeer != null && targetPeer.isEnabled()) {
+            Point newp = targetPeer.windowToLocal(x, y, this);
+            postEvent(new MouseEvent(targetPeer.getTarget(),
+                    MouseEvent.MOUSE_ENTERED,
+                    when, modifiers,
+                    newp.x, newp.y, screenX, screenY,
+                    clickCount, popupTrigger, button));
+        }
+    }
+
     public void dispatchMouseWheelEvent(long when, int x, int y, int modifiers,
                                         int scrollType, int scrollAmount,
                                         int wheelRotation, double preciseWheelRotation,
@@ -1096,11 +1127,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/jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java	Tue Aug 28 16:04:27 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java	Wed Aug 29 15:54:28 2012 +0400
@@ -118,6 +118,8 @@
 
     public void setAlwaysOnTop(boolean value);
 
+    public PlatformWindow getTopmostPlatformWindowUnderMouse();
+
     public void updateFocusableWindowState();
 
     public boolean rejectFocusRequest(CausedFocusEvent.Cause cause);
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java	Tue Aug 28 16:04:27 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java	Wed Aug 29 15:54:28 2012 +0400
@@ -151,6 +151,10 @@
     @Override
     public void setAlwaysOnTop(boolean value) {}
 
+    // This method should be properly implemented for applets.
+    // It returns null just as a stub.
+    public PlatformWindow getTopmostPlatformWindowUnderMouse() { return null; }
+
     @Override
     public void updateFocusableWindowState() {}
 
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Tue Aug 28 16:04:27 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Wed Aug 29 15:54:28 2012 +0400
@@ -61,8 +61,9 @@
     private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename);
     private static native void nativeSetNSWindowSecurityWarningPositioning(long nsWindowPtr, double x, double y, float biasX, float biasY);
     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();
 
     private static native int nativeGetNSWindowDisplayID_AppKitThread(long nsWindowPtr);
 
@@ -588,7 +589,7 @@
             }
         }
 
-        nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr);
+        nativeSynthesizeMouseEnteredExitedEvents();
 
         // Configure stuff #2
         updateFocusabilityForAutoRequestFocus(true);
@@ -729,6 +730,10 @@
         setStyleBits(ALWAYS_ON_TOP, isAlwaysOnTop);
     }
 
+    public PlatformWindow getTopmostPlatformWindowUnderMouse(){
+        return CPlatformWindow.nativeGetTopmostPlatformWindowUnderMouse();
+    }
+
     @Override
     public void setOpacity(float opacity) {
         CWrapper.NSWindow.setAlphaValue(getNSWindowPtr(), opacity);
@@ -803,7 +808,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/jdk/src/macosx/native/sun/awt/AWTView.h	Tue Aug 28 16:04:27 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/AWTView.h	Wed Aug 29 15:54:28 2012 +0400
@@ -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/jdk/src/macosx/native/sun/awt/AWTView.m	Tue Aug 28 16:04:27 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/AWTView.m	Wed Aug 29 15:54:28 2012 +0400
@@ -82,6 +82,7 @@
     fPAHNeedsToSelect = NO;
 
     mouseIsOver = NO;
+    [self resetTrackingArea];
 
     if (windowLayer != nil) {
         self.cglLayer = windowLayer;
@@ -146,7 +147,7 @@
         [[self window] makeFirstResponder: self];
     }];
     if ([self window] != NULL) {
-        [self resetTrackingRect];
+        [self resetTrackingArea];
     }
 }
 
@@ -368,30 +369,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 = (NSTrackingActiveInActiveApp | 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 {
@@ -402,7 +404,7 @@
     }
     [sLastKeyEvent release];
     sLastKeyEvent = [event retain];
-	
+
     [AWTToolkit eventCountPlusPlus];
     JNIEnv *env = [ThreadUtilities getJNIEnv];
 
--- a/jdk/src/macosx/native/sun/awt/AWTWindow.m	Tue Aug 28 16:04:27 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m	Wed Aug 29 15:54:28 2012 +0400
@@ -238,10 +238,12 @@
     return self;
 }
 
-// checks that this window is under the mouse cursor and this point is not overlapped by others windows
-- (BOOL) isTopmostWindowUnderMouse {
++ (BOOL) isAWTWindow:(NSWindow *)window {
+    return [window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]];
+}
 
-    int currentWinID = [self.nsWindow windowNumber];
+// returns id for the topmost window under mouse
++ (NSInteger) getTopmostWindowUnderMouseID {
 
     NSRect screenRect = [[NSScreen mainScreen] frame];
     NSPoint nsMouseLocation = [NSEvent mouseLocation];
@@ -249,53 +251,77 @@
 
     NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
 
-
     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 others 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]
-                                                   context: nil
-                                               eventNumber: 0
-                                            trackingNumber: 0
-                                                  userData: nil
-                            ];
+                                                 location: windowLocation
+                                            modifierFlags: modifierFlags
+                                                timestamp: 0
+                                             windowNumber: [window windowNumber]
+                                                  context: nil
+                                              eventNumber: 0
+                                           trackingNumber: 0
+                                                 userData: nil
+                           ];
+
+    [[window contentView] deliverJavaMouseEvent: mouseEvent];
+}
+
++ (void) synthesizeMouseEnteredExitedEventsForAllWindows {
 
-    [[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent];
+    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];
+            }
+        }
+    }
 }
 
 - (void) dealloc {
@@ -825,7 +851,7 @@
         // (this will also re-enable screen updates, which were disabled above)
         // TODO: send PaintEvent
 
-        [window synthesizeMouseEnteredExitedEvents];
+        [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
     }];
 
 JNF_COCOA_EXIT(env);
@@ -1040,22 +1066,42 @@
 
 /*
  * Class:     sun_lwawt_macosx_CPlatformWindow
+ * Method:    nativeGetTopmostPlatformWindowUnderMouse
+ * 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);
     AWT_ASSERT_NOT_APPKIT_THREAD;
 
-    NSWindow *nsWindow = OBJC(windowPtr);
     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
         AWT_ASSERT_APPKIT_THREAD;
-
-        AWTWindow *window = (AWTWindow*)[nsWindow delegate];
-
-        [window synthesizeMouseEnteredExitedEvents];
+        [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
     }];
 
     JNF_COCOA_EXIT(env);