jdk/src/macosx/native/sun/awt/AWTWindow.m
changeset 13647 de61414bbcf2
parent 13233 4d45f7ebc0d7
child 13777 c94cf7e1bac2
--- 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);