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