jdk/src/macosx/native/sun/awt/AWTWindow.m
changeset 13647 de61414bbcf2
parent 13233 4d45f7ebc0d7
child 13777 c94cf7e1bac2
equal deleted inserted replaced
13552:5270c932737d 13647:de61414bbcf2
   236     [self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];
   236     [self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];
   237 
   237 
   238     return self;
   238     return self;
   239 }
   239 }
   240 
   240 
   241 // checks that this window is under the mouse cursor and this point is not overlapped by others windows
   241 + (BOOL) isAWTWindow:(NSWindow *)window {
   242 - (BOOL) isTopmostWindowUnderMouse {
   242     return [window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]];
   243 
   243 }
   244     int currentWinID = [self.nsWindow windowNumber];
   244 
       
   245 // returns id for the topmost window under mouse
       
   246 + (NSInteger) getTopmostWindowUnderMouseID {
   245 
   247 
   246     NSRect screenRect = [[NSScreen mainScreen] frame];
   248     NSRect screenRect = [[NSScreen mainScreen] frame];
   247     NSPoint nsMouseLocation = [NSEvent mouseLocation];
   249     NSPoint nsMouseLocation = [NSEvent mouseLocation];
   248     CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y);
   250     CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y);
   249 
   251 
   250     NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
   252     NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
   251 
   253 
   252 
       
   253     for (NSDictionary *window in windows) {
   254     for (NSDictionary *window in windows) {
   254         int layer = [[window objectForKey:(id)kCGWindowLayer] intValue];
   255         NSInteger layer = [[window objectForKey:(id)kCGWindowLayer] integerValue];
   255         if (layer == 0) {
   256         if (layer == 0) {
   256             int winID = [[window objectForKey:(id)kCGWindowNumber] intValue];
       
   257             CGRect rect;
   257             CGRect rect;
   258             CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);
   258             CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);
   259             if (CGRectContainsPoint(rect, cgMouseLocation)) {
   259             if (CGRectContainsPoint(rect, cgMouseLocation)) {
   260                 return currentWinID == winID;
   260                 return [[window objectForKey:(id)kCGWindowNumber] integerValue];
   261             } else if (currentWinID == winID) {
       
   262                 return NO;
       
   263             }
   261             }
   264         }
   262         }
   265     }
   263     }
   266     return NO;
   264     return -1;
   267 }
   265 }
   268 
   266 
   269 - (void) synthesizeMouseEnteredExitedEvents {
   267 // checks that this window is under the mouse cursor and this point is not overlapped by others windows
   270 
   268 - (BOOL) isTopmostWindowUnderMouse {
   271     int eventType = 0;
   269     return [self.nsWindow windowNumber] == [AWTWindow getTopmostWindowUnderMouseID];
   272     BOOL isUnderMouse = [self isTopmostWindowUnderMouse];
   270 }
   273     BOOL mouseIsOver = [[self.nsWindow contentView] mouseIsOver];
   271 
   274 
   272 + (AWTWindow *) getTopmostWindowUnderMouse {
   275     if (isUnderMouse && !mouseIsOver) {
   273     NSEnumerator *windowEnumerator = [[NSApp windows] objectEnumerator];
   276         eventType = NSMouseEntered;
   274     NSWindow *window;
   277     } else if (!isUnderMouse && mouseIsOver) {
   275 
   278         eventType = NSMouseExited;
   276     NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
   279     } else {
   277 
   280         return;
   278     while ((window = [windowEnumerator nextObject]) != nil) {
   281     }
   279         if ([window windowNumber] == topmostWindowUnderMouseID) {
       
   280             BOOL isAWTWindow = [AWTWindow isAWTWindow: window];
       
   281             return isAWTWindow ? (AWTWindow *) [window delegate] : nil;
       
   282         }
       
   283     }
       
   284     return nil;
       
   285 }
       
   286 
       
   287 + (void) synthesizeMouseEnteredExitedEvents:(NSWindow*)window withType:(NSEventType)eventType {
   282 
   288 
   283     NSPoint screenLocation = [NSEvent mouseLocation];
   289     NSPoint screenLocation = [NSEvent mouseLocation];
   284     NSPoint windowLocation = [self.nsWindow convertScreenToBase: screenLocation];
   290     NSPoint windowLocation = [window convertScreenToBase: screenLocation];
   285     int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
   291     int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
   286 
   292 
   287     NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType
   293     NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType
   288                                                   location: windowLocation
   294                                                  location: windowLocation
   289                                              modifierFlags: modifierFlags
   295                                             modifierFlags: modifierFlags
   290                                                  timestamp: 0
   296                                                 timestamp: 0
   291                                               windowNumber: [self.nsWindow windowNumber]
   297                                              windowNumber: [window windowNumber]
   292                                                    context: nil
   298                                                   context: nil
   293                                                eventNumber: 0
   299                                               eventNumber: 0
   294                                             trackingNumber: 0
   300                                            trackingNumber: 0
   295                                                   userData: nil
   301                                                  userData: nil
   296                             ];
   302                            ];
   297 
   303 
   298     [[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent];
   304     [[window contentView] deliverJavaMouseEvent: mouseEvent];
       
   305 }
       
   306 
       
   307 + (void) synthesizeMouseEnteredExitedEventsForAllWindows {
       
   308 
       
   309     NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
       
   310     NSArray *windows = [NSApp windows];
       
   311     NSWindow *window;
       
   312 
       
   313     NSEnumerator *windowEnumerator = [windows objectEnumerator];
       
   314     while ((window = [windowEnumerator nextObject]) != nil) {
       
   315         if ([AWTWindow isAWTWindow: window]) {
       
   316             BOOL isUnderMouse = ([window windowNumber] == topmostWindowUnderMouseID);
       
   317             BOOL mouseIsOver = [[window contentView] mouseIsOver];
       
   318             if (isUnderMouse && !mouseIsOver) {
       
   319                 [AWTWindow synthesizeMouseEnteredExitedEvents:window withType:NSMouseEntered];
       
   320             } else if (!isUnderMouse && mouseIsOver) {
       
   321                 [AWTWindow synthesizeMouseEnteredExitedEvents:window withType:NSMouseExited];
       
   322             }
       
   323         }
       
   324     }
   299 }
   325 }
   300 
   326 
   301 - (void) dealloc {
   327 - (void) dealloc {
   302 AWT_ASSERT_APPKIT_THREAD;
   328 AWT_ASSERT_APPKIT_THREAD;
   303 
   329 
   823 
   849 
   824         // ensure we repaint the whole window after the resize operation
   850         // ensure we repaint the whole window after the resize operation
   825         // (this will also re-enable screen updates, which were disabled above)
   851         // (this will also re-enable screen updates, which were disabled above)
   826         // TODO: send PaintEvent
   852         // TODO: send PaintEvent
   827 
   853 
   828         [window synthesizeMouseEnteredExitedEvents];
   854         [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
   829     }];
   855     }];
   830 
   856 
   831 JNF_COCOA_EXIT(env);
   857 JNF_COCOA_EXIT(env);
   832 }
   858 }
   833 
   859 
  1038 JNF_COCOA_EXIT(env);
  1064 JNF_COCOA_EXIT(env);
  1039 }
  1065 }
  1040 
  1066 
  1041 /*
  1067 /*
  1042  * Class:     sun_lwawt_macosx_CPlatformWindow
  1068  * Class:     sun_lwawt_macosx_CPlatformWindow
       
  1069  * Method:    nativeGetTopmostPlatformWindowUnderMouse
       
  1070  * Signature: (J)V
       
  1071  */
       
  1072 JNIEXPORT jobject
       
  1073 JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetTopmostPlatformWindowUnderMouse
       
  1074 (JNIEnv *env, jclass clazz)
       
  1075 {
       
  1076     jobject topmostWindowUnderMouse = nil;
       
  1077 
       
  1078     JNF_COCOA_ENTER(env);
       
  1079     AWT_ASSERT_APPKIT_THREAD;
       
  1080 
       
  1081     AWTWindow *awtWindow = [AWTWindow getTopmostWindowUnderMouse];
       
  1082     if (awtWindow != nil) {
       
  1083         topmostWindowUnderMouse = [awtWindow.javaPlatformWindow jObject];
       
  1084     }
       
  1085 
       
  1086     JNF_COCOA_EXIT(env);
       
  1087 
       
  1088     return topmostWindowUnderMouse;
       
  1089 }
       
  1090 
       
  1091 /*
       
  1092  * Class:     sun_lwawt_macosx_CPlatformWindow
  1043  * Method:    nativeSynthesizeMouseEnteredExitedEvents
  1093  * Method:    nativeSynthesizeMouseEnteredExitedEvents
  1044  * Signature: (J)V
  1094  * Signature: (J)V
  1045  */
  1095  */
  1046 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents
  1096 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents
  1047 (JNIEnv *env, jclass clazz, jlong windowPtr)
  1097 (JNIEnv *env, jclass clazz)
  1048 {
  1098 {
  1049     JNF_COCOA_ENTER(env);
  1099     JNF_COCOA_ENTER(env);
  1050     AWT_ASSERT_NOT_APPKIT_THREAD;
  1100     AWT_ASSERT_NOT_APPKIT_THREAD;
  1051 
  1101 
  1052     NSWindow *nsWindow = OBJC(windowPtr);
       
  1053     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
  1102     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
  1054         AWT_ASSERT_APPKIT_THREAD;
  1103         AWT_ASSERT_APPKIT_THREAD;
  1055 
  1104         [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
  1056         AWTWindow *window = (AWTWindow*)[nsWindow delegate];
       
  1057 
       
  1058         [window synthesizeMouseEnteredExitedEvents];
       
  1059     }];
  1105     }];
  1060 
  1106 
  1061     JNF_COCOA_EXIT(env);
  1107     JNF_COCOA_EXIT(env);
  1062 }
  1108 }
  1063 
  1109