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

Print this page

        

@@ -236,68 +236,108 @@
     [self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];
 
     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];
     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];
+        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;
 }
 
-- (void) synthesizeMouseEnteredExitedEvents {
+// 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];
+}
 
-    int eventType = 0;
-    BOOL isUnderMouse = [self isTopmostWindowUnderMouse];
-    BOOL mouseIsOver = [[self.nsWindow contentView] mouseIsOver];
++ (AWTWindow *) getTopmostWindowUnderMouse {    
+    NSEnumerator *windowEnumerator = [[NSApp windows] objectEnumerator];
+    NSWindow *window;
 
-    if (isUnderMouse && !mouseIsOver) {
-        eventType = NSMouseEntered;
-    } else if (!isUnderMouse && mouseIsOver) {
-        eventType = NSMouseExited;
-    } else {
-        return;
+    NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
+    
+    while ((window = [windowEnumerator nextObject]) != nil) {
+        if ([window windowNumber] == topmostWindowUnderMouseID) {
+            BOOL isAWTWindow = [AWTWindow isAWTWindow: window]; 
+            return isAWTWindow ? (AWTWindow *) [window delegate] : nil;
+        }
     }
+    return nil;
+}
 
-    NSPoint screenLocation = [NSEvent mouseLocation];
-    NSPoint windowLocation = [self.nsWindow convertScreenToBase: screenLocation];
-    int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
++ (void) synthesizeMouseEnteredExitedEventsForAllWindows {
 
-    NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType
-                                                  location: windowLocation
-                                             modifierFlags: modifierFlags
+    NSPoint screenLocation = [NSEvent mouseLocation];
+    NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];    
+    NSArray *windows = [NSApp windows];
+    NSWindow *window;
+
+    // synthesize mouse exited event
+    NSEnumerator *windowEnumerator = [windows objectEnumerator];
+    while ((window = [windowEnumerator nextObject]) != nil) {
+        if ([AWTWindow isAWTWindow: window]) {
+            NSInteger windowID = [window windowNumber];
+            BOOL isUnderMouse = (windowID == topmostWindowUnderMouseID);
+            BOOL mouseIsOver = [[window contentView] mouseIsOver];
+            if (!isUnderMouse && mouseIsOver) {
+                NSEvent *mouseEvent = [NSEvent enterExitEventWithType: NSMouseExited
+                                                             location: [window convertScreenToBase: screenLocation]
+                                                        modifierFlags: NSMouseExitedMask
                                                  timestamp: 0
-                                              windowNumber: [self.nsWindow windowNumber]
+                                                         windowNumber: windowID
                                                    context: nil
                                                eventNumber: 0
                                             trackingNumber: 0
                                                   userData: nil
                             ];
+                [[window contentView] deliverJavaMouseEvent: mouseEvent];                
+            }
+        }
+    }
 
-    [[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent];
+    // synthesize mouse entered event
+    windowEnumerator = [windows objectEnumerator];
+    while ((window = [windowEnumerator nextObject]) != nil) {
+        if ([AWTWindow isAWTWindow: window]) {
+            NSInteger windowID = [window windowNumber];
+            BOOL isUnderMouse = (windowID == topmostWindowUnderMouseID);
+            BOOL mouseIsOver = [[window contentView] mouseIsOver];
+            if (isUnderMouse && !mouseIsOver) {
+                NSEvent *mouseEvent = [NSEvent enterExitEventWithType: NSMouseEntered
+                                                             location: [window convertScreenToBase: screenLocation]
+                                                        modifierFlags: NSMouseEnteredMask
+                                                            timestamp: 0
+                                                         windowNumber: windowID
+                                                              context: nil
+                                                          eventNumber: 0
+                                                       trackingNumber: 0
+                                                             userData: nil
+                                       ];
+                [[window contentView] deliverJavaMouseEvent: mouseEvent];                
+            }
+        }
+    }
 }
 
 - (void) dealloc {
 AWT_ASSERT_APPKIT_THREAD;
 

@@ -823,11 +863,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 +1078,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 +1117,11 @@
     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
         AWT_ASSERT_APPKIT_THREAD;
 
         AWTWindow *window = (AWTWindow*)[nsWindow delegate];
 
-        [window synthesizeMouseEnteredExitedEvents];
+        [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
     }];
 
     JNF_COCOA_EXIT(env);
 }