src/macosx/native/sun/awt/AWTWindow.m

Print this page

        

@@ -236,51 +236,63 @@
     [self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];
 
     return self;
 }
 
++ (BOOL) isAWTWindow:(NSWindow *)window {
+    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 {
+    return [self.nsWindow windowNumber] == [AWTWindow getTopmostWindowUnderMouseID];
+}
+
++ (AWTWindow *) getTopmostWindowUnderMouse {    
+    NSEnumerator *windowEnumerator = [[NSApp windows] objectEnumerator];
+    NSWindow *window;
+    
+    int topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
 
-    int currentWinID = [self.nsWindow windowNumber];
+    while ((window = [windowEnumerator nextObject]) != nil) {
+        if ([window windowNumber] == topmostWindowUnderMouseID) {
+            BOOL isAWTWindow = [AWTWindow isAWTWindow: window]; 
+            return isAWTWindow ? (AWTWindow *) [window delegate] : nil;
+        }
+    }     
+    return nil;
+}    
+
+// returns id for the topmost window under mouse
++ (int) getTopmostWindowUnderMouseID {
 
     NSRect screenRect = [[NSScreen mainScreen] frame];
     NSPoint nsMouseLocation = [NSEvent mouseLocation];
     CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y);
 
     NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
 
-
     for (NSDictionary *window in windows) {
         int layer = [[window objectForKey:(id)kCGWindowLayer] intValue];
         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] intValue];
             }
         }
     }
-    return NO;
+    return -1;
 }
 
-- (void) synthesizeMouseEnteredExitedEvents {
+- (void) synthesizeMouseEnteredExitedEvents:(int)topmostWindowUnderMouseID withType:(NSEventType)eventType {
 
-    int eventType = 0;
-    BOOL isUnderMouse = [self isTopmostWindowUnderMouse];
+    BOOL isUnderMouse = (topmostWindowUnderMouseID == [[self nsWindow] windowNumber]);
     BOOL mouseIsOver = [[self.nsWindow contentView] mouseIsOver];
 
-    if (isUnderMouse && !mouseIsOver) {
-        eventType = NSMouseEntered;
-    } else if (!isUnderMouse && mouseIsOver) {
-        eventType = NSMouseExited;
-    } else {
-        return;
-    }
+    if ((isUnderMouse && !mouseIsOver && eventType == NSMouseEntered)
+        || (!isUnderMouse && mouseIsOver && eventType == NSMouseExited)) {
 
     NSPoint screenLocation = [NSEvent mouseLocation];
     NSPoint windowLocation = [self.nsWindow convertScreenToBase: screenLocation];
     int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
 

@@ -294,10 +306,35 @@
                                             trackingNumber: 0
                                                   userData: nil
                             ];
 
     [[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent];
+    }
+}
+
++ (void) synthesizeMouseEnteredExitedEventsForAllWindows {
+    int topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
+
+    NSArray *windows = [NSApp windows];
+    NSEnumerator *windowEnumerator = [windows objectEnumerator];
+    NSWindow *window;
+
+    while ((window = [windowEnumerator nextObject]) != nil) {
+        if ([AWTWindow isAWTWindow: window]) {
+            AWTWindow *awtWindow = (AWTWindow*)[window delegate];
+            [awtWindow synthesizeMouseEnteredExitedEvents: topmostWindowUnderMouseID withType: NSMouseExited];
+        }
+    }
+
+    windowEnumerator = [windows objectEnumerator];
+
+    while ((window = [windowEnumerator nextObject]) != nil) {
+        if ([AWTWindow isAWTWindow: window]) {
+            AWTWindow *awtWindow = (AWTWindow*)[window delegate];
+            [awtWindow synthesizeMouseEnteredExitedEvents: topmostWindowUnderMouseID withType: NSMouseEntered];
+        }
+    }     
 }
 
 - (void) dealloc {
 AWT_ASSERT_APPKIT_THREAD;
 

@@ -823,11 +860,11 @@
 
         // ensure we repaint the whole window after the resize operation
         // (this will also re-enable screen updates, which were disabled above)
         // TODO: send PaintEvent
 
-        [window synthesizeMouseEnteredExitedEvents];
+        [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
     }];
 
 JNF_COCOA_EXIT(env);
 }
 

@@ -1038,10 +1075,34 @@
 JNF_COCOA_EXIT(env);
 }
 
 /*
  * 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)

@@ -1053,11 +1114,11 @@
     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
         AWT_ASSERT_APPKIT_THREAD;
 
         AWTWindow *window = (AWTWindow*)[nsWindow delegate];
 
-        [window synthesizeMouseEnteredExitedEvents];
+        [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
     }];
 
     JNF_COCOA_EXIT(env);
 }