--- 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);