src/macosx/native/sun/awt/AWTWindow.m
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2011, 2013, 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
--- 1,7 ----
/*
! * 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,379 ****
+ (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];
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];
}
+ (NSNumber *) getNSWindowDisplayID_AppKitThread:(NSWindow *)window {
AWT_ASSERT_APPKIT_THREAD;
NSScreen *screen = [window screen];
--- 312,401 ----
+ (BOOL) isAWTWindow:(NSWindow *)window {
return [window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]];
}
! // 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) {
! 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 other 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) synthesizeMouseEnteredExitedEvents:(NSWindow*)window withType:(NSEventType)eventType {
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: [window windowNumber]
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]) {
! 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,987 ****
// 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);
}
--- 999,1009 ----
// 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);
}
*** 1156,1178 ****
JNF_COCOA_EXIT(env);
}
/*
* 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);
- NSWindow *nsWindow = OBJC(windowPtr);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
! AWTWindow *window = (AWTWindow*)[nsWindow delegate];
!
! [window synthesizeMouseEnteredExitedEvents];
}];
JNF_COCOA_EXIT(env);
}
--- 1178,1221 ----
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)
{
JNF_COCOA_ENTER(env);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
! [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
}];
JNF_COCOA_EXIT(env);
}