src/macosx/native/sun/awt/AWTWindow.m
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -312,68 +312,90 @@
+ (BOOL) isAWTWindow:(NSWindow *)window {
return [window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]];
}
-// 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];
+// return 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;
+}
+
+// checks that this window is under the mouse cursor and this point is not overlapped by other 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]
+ windowNumber: [window windowNumber]
context: nil
eventNumber: 0
trackingNumber: 0
userData: nil
];
- [[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent];
+ [[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]) {
+ 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];
+ }
+ }
+ }
}
+ (NSNumber *) getNSWindowDisplayID_AppKitThread:(NSWindow *)window {
AWT_ASSERT_APPKIT_THREAD;
NSScreen *screen = [window screen];
@@ -977,11 +999,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);
}
@@ -1156,23 +1178,44 @@
JNF_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CPlatformWindow
+ * Method: nativeGetTopMostWindowUnderMouse
+ * 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);
- NSWindow *nsWindow = OBJC(windowPtr);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
- AWTWindow *window = (AWTWindow*)[nsWindow delegate];
-
- [window synthesizeMouseEnteredExitedEvents];
+ [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
}];
JNF_COCOA_EXIT(env);
}