--- old/src/macosx/native/sun/awt/AWTWindow.m 2012-08-24 17:11:21.000000000 +0400 +++ new/src/macosx/native/sun/awt/AWTWindow.m 2012-08-24 17:11:20.000000000 +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,84 @@ 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; + + 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; +} ++ (void) synthesizeMouseEnteredExitedEvents:(NSInteger)topmostWindowUnderMouseID withWindow:(NSWindow*)window { + + NSEventType eventType = 0; + NSInteger windowID = [window windowNumber]; + BOOL isUnderMouse = (windowID == topmostWindowUnderMouseID); + BOOL mouseIsOver = [[window contentView] mouseIsOver]; + if (isUnderMouse && !mouseIsOver) { eventType = NSMouseEntered; } else if (!isUnderMouse && mouseIsOver) { - eventType = NSMouseExited; + eventType = NSMouseExited; } else { return; } - - NSPoint screenLocation = [NSEvent mouseLocation]; - NSPoint windowLocation = [self.nsWindow convertScreenToBase: screenLocation]; + + NSPoint screenLocation = [NSEvent mouseLocation]; + 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 - ]; - - [[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent]; + location: windowLocation + modifierFlags: modifierFlags + timestamp: 0 + windowNumber: windowID + context: nil + eventNumber: 0 + trackingNumber: 0 + userData: nil + ]; + + [[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]) { + [AWTWindow synthesizeMouseEnteredExitedEvents: topmostWindowUnderMouseID withWindow: window]; + } + } } - (void) dealloc { @@ -825,7 +858,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 +1073,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);