src/macosx/native/sun/awt/AWTWindow.m
Print this page
*** 236,303 ****
[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 {
! int currentWinID = [self.nsWindow 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.nsWindow contentView] mouseIsOver];
! if (isUnderMouse && !mouseIsOver) {
! eventType = NSMouseEntered;
! } else if (!isUnderMouse && mouseIsOver) {
! eventType = NSMouseExited;
! } else {
! return;
}
! NSPoint screenLocation = [NSEvent mouseLocation];
! NSPoint windowLocation = [self.nsWindow 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];
}
- (void) dealloc {
AWT_ASSERT_APPKIT_THREAD;
--- 236,343 ----
[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]];
! }
! // 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) {
! NSInteger layer = [[window objectForKey:(id)kCGWindowLayer] integerValue];
if (layer == 0) {
CGRect rect;
CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);
if (CGRectContainsPoint(rect, cgMouseLocation)) {
! return [[window objectForKey:(id)kCGWindowNumber] integerValue];
}
}
}
! 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];
! }
! + (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) synthesizeMouseEnteredExitedEventsForAllWindows {
! 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: windowID
context: nil
eventNumber: 0
trackingNumber: 0
userData: nil
];
+ [[window 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,833 ****
// 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);
}
--- 863,873 ----
// ensure we repaint the whole window after the resize operation
// (this will also re-enable screen updates, which were disabled above)
// TODO: send PaintEvent
! [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
}];
JNF_COCOA_EXIT(env);
}
*** 1038,1047 ****
--- 1078,1111 ----
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,1063 ****
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
! [window synthesizeMouseEnteredExitedEvents];
}];
JNF_COCOA_EXIT(env);
}
--- 1117,1127 ----
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
! [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
}];
JNF_COCOA_EXIT(env);
}