--- a/jdk/src/macosx/native/sun/awt/AWTWindow.m Wed May 02 13:53:06 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m Wed May 02 17:54:18 2012 +0400
@@ -170,6 +170,66 @@
return self;
}
+// checks that this window is under the mouse cursor and this point is not overlapped by others windows
+- (BOOL) isTopmostWindowUnderMouse {
+
+ int currentWinID = [self windowNumber];
+
+ 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 NO;
+}
+
+- (void) synthesizeMouseEnteredExitedEvents {
+
+ int eventType = 0;
+ BOOL isUnderMouse = [self isTopmostWindowUnderMouse];
+ BOOL mouseIsOver = [[self contentView] mouseIsOver];
+
+ if (isUnderMouse && !mouseIsOver) {
+ eventType = NSMouseEntered;
+ } else if (!isUnderMouse && mouseIsOver) {
+ eventType = NSMouseExited;
+ } else {
+ return;
+ }
+
+ NSPoint screenLocation = [NSEvent mouseLocation];
+ NSPoint windowLocation = [self convertScreenToBase: screenLocation];
+ int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
+
+ NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType
+ location: windowLocation
+ modifierFlags: modifierFlags
+ timestamp: 0
+ windowNumber: [self windowNumber]
+ context: nil
+ eventNumber: 0
+ trackingNumber: 0
+ userData: nil
+ ];
+
+ [[self contentView] deliverJavaMouseEvent: mouseEvent];
+}
+
- (void) dealloc {
AWT_ASSERT_APPKIT_THREAD;
@@ -669,6 +729,8 @@
// 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];
}];
JNF_COCOA_EXIT(env);
@@ -899,6 +961,27 @@
/*
* 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)
+{
+ JNF_COCOA_ENTER(env);
+ AWT_ASSERT_NOT_APPKIT_THREAD;
+
+ AWTWindow *window = OBJC(windowPtr);
+ [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
+ AWT_ASSERT_APPKIT_THREAD;
+
+ [window synthesizeMouseEnteredExitedEvents];
+ }];
+
+ JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeGetScreenNSWindowIsOn_AppKitThread
* Signature: (J)I
*/