src/macosx/native/sun/awt/AWTWindow.m

Print this page




 221     else
 222     {
 223         // These windows will appear in the window list in the dock icon menu
 224         self.nsWindow = [[AWTWindow_Normal alloc] initWithDelegate:self
 225                             frameRect:contentRect
 226                             styleMask:styleMask
 227                           contentView:view];
 228     }
 229 
 230     if (self.nsWindow == nil) return nil; // no hope either
 231     [self.nsWindow release]; // the property retains the object already
 232 
 233     self.isEnabled = YES;
 234     self.javaPlatformWindow = platformWindow;
 235     self.styleBits = bits;
 236     [self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];
 237 
 238     return self;
 239 }
 240 




 241 // checks that this window is under the mouse cursor and this point is not overlapped by others windows
 242 - (BOOL) isTopmostWindowUnderMouse {








 243 
 244     int currentWinID = [self.nsWindow windowNumber];










 245 
 246     NSRect screenRect = [[NSScreen mainScreen] frame];
 247     NSPoint nsMouseLocation = [NSEvent mouseLocation];
 248     CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y);
 249 
 250     NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
 251 
 252 
 253     for (NSDictionary *window in windows) {
 254         int layer = [[window objectForKey:(id)kCGWindowLayer] intValue];
 255         if (layer == 0) {
 256             int winID = [[window objectForKey:(id)kCGWindowNumber] intValue];
 257             CGRect rect;
 258             CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);
 259             if (CGRectContainsPoint(rect, cgMouseLocation)) {
 260                 return currentWinID == winID;
 261             } else if (currentWinID == winID) {
 262                 return NO;
 263             }
 264         }
 265     }
 266     return NO;
 267 }
 268 
 269 - (void) synthesizeMouseEnteredExitedEvents {
 270 
 271     int eventType = 0;
 272     BOOL isUnderMouse = [self isTopmostWindowUnderMouse];
 273     BOOL mouseIsOver = [[self.nsWindow contentView] mouseIsOver];
 274 
 275     if (isUnderMouse && !mouseIsOver) {
 276         eventType = NSMouseEntered;
 277     } else if (!isUnderMouse && mouseIsOver) {
 278         eventType = NSMouseExited;
 279     } else {
 280         return;
 281     }
 282 
 283     NSPoint screenLocation = [NSEvent mouseLocation];
 284     NSPoint windowLocation = [self.nsWindow convertScreenToBase: screenLocation];
 285     int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
 286 
 287     NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType
 288                                                   location: windowLocation
 289                                              modifierFlags: modifierFlags
 290                                                  timestamp: 0
 291                                               windowNumber: [self.nsWindow windowNumber]
 292                                                    context: nil
 293                                                eventNumber: 0
 294                                             trackingNumber: 0
 295                                                   userData: nil
 296                             ];
 297 
 298     [[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent];

























 299 }
 300 
 301 - (void) dealloc {
 302 AWT_ASSERT_APPKIT_THREAD;
 303 
 304     JNIEnv *env = [ThreadUtilities getJNIEnv];
 305     [self.javaPlatformWindow setJObject:nil withEnv:env];
 306 
 307     self.nsWindow = nil;
 308 
 309     [super dealloc];
 310 }
 311 
 312 // NSWindow overrides
 313 - (BOOL) canBecomeKeyWindow {
 314 AWT_ASSERT_APPKIT_THREAD;
 315     return self.isEnabled && IS(self.styleBits, SHOULD_BECOME_KEY);
 316 }
 317 
 318 - (BOOL) canBecomeMainWindow {


 808     NSWindow *nsWindow = OBJC(windowPtr);
 809     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 810         AWT_ASSERT_APPKIT_THREAD;
 811 
 812         AWTWindow *window = (AWTWindow*)[nsWindow delegate];
 813 
 814         NSRect rect = ConvertNSScreenRect(NULL, jrect);
 815         [window constrainSize:&rect.size];
 816 
 817         [nsWindow setFrame:rect display:YES];
 818 
 819         // only start tracking events if pointer is above the toplevel
 820         // TODO: should post an Entered event if YES.
 821         NSPoint mLocation = [NSEvent mouseLocation];
 822         [nsWindow setAcceptsMouseMovedEvents:NSPointInRect(mLocation, rect)];
 823 
 824         // ensure we repaint the whole window after the resize operation
 825         // (this will also re-enable screen updates, which were disabled above)
 826         // TODO: send PaintEvent
 827 
 828         [window synthesizeMouseEnteredExitedEvents];
 829     }];
 830 
 831 JNF_COCOA_EXIT(env);
 832 }
 833 
 834 /*
 835  * Class:     sun_lwawt_macosx_CPlatformWindow
 836  * Method:    nativeSetNSWindowMinMax
 837  * Signature: (JDDDD)V
 838  */
 839 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinMax
 840 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble minW, jdouble minH, jdouble maxW, jdouble maxH)
 841 {
 842 JNF_COCOA_ENTER(env);
 843 AWT_ASSERT_NOT_APPKIT_THREAD;
 844 
 845     if (minW < 1) minW = 1;
 846     if (minH < 1) minH = 1;
 847     if (maxW < 1) maxW = 1;
 848     if (maxH < 1) maxH = 1;


1023 }
1024 
1025 /*
1026  * Class:     sun_lwawt_macosx_CPlatformWindow
1027  * Method:    nativeSetNSWindowSecurityWarningPositioning
1028  * Signature: (JDDFF)V
1029  */
1030 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowSecurityWarningPositioning
1031 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble x, jdouble y, jfloat biasX, jfloat biasY)
1032 {
1033 JNF_COCOA_ENTER(env);
1034 AWT_ASSERT_NOT_APPKIT_THREAD;
1035 
1036     [JNFException raise:env as:kRuntimeException reason:"unimplemented"];
1037 
1038 JNF_COCOA_EXIT(env);
1039 }
1040 
1041 /*
1042  * Class:     sun_lwawt_macosx_CPlatformWindow
























1043  * Method:    nativeSynthesizeMouseEnteredExitedEvents
1044  * Signature: (J)V
1045  */
1046 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents
1047 (JNIEnv *env, jclass clazz, jlong windowPtr)
1048 {
1049     JNF_COCOA_ENTER(env);
1050     AWT_ASSERT_NOT_APPKIT_THREAD;
1051 
1052     NSWindow *nsWindow = OBJC(windowPtr);
1053     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
1054         AWT_ASSERT_APPKIT_THREAD;
1055 
1056         AWTWindow *window = (AWTWindow*)[nsWindow delegate];
1057 
1058         [window synthesizeMouseEnteredExitedEvents];
1059     }];
1060 
1061     JNF_COCOA_EXIT(env);
1062 }
1063 
1064 /*
1065  * Class:     sun_lwawt_macosx_CPlatformWindow
1066  * Method:    nativeGetDisplayID_AppKitThread
1067  * Signature: (J)I
1068  */
1069 JNIEXPORT jint JNICALL
1070 Java_sun_lwawt_macosx_CPlatformWindow_nativeGetNSWindowDisplayID_1AppKitThread
1071 (JNIEnv *env, jclass clazz, jlong windowPtr)
1072 {
1073     jint ret; // CGDirectDisplayID
1074 
1075 JNF_COCOA_ENTER(env);
1076 AWT_ASSERT_APPKIT_THREAD;
1077 
1078     NSWindow *window = OBJC(windowPtr);




 221     else
 222     {
 223         // These windows will appear in the window list in the dock icon menu
 224         self.nsWindow = [[AWTWindow_Normal alloc] initWithDelegate:self
 225                             frameRect:contentRect
 226                             styleMask:styleMask
 227                           contentView:view];
 228     }
 229 
 230     if (self.nsWindow == nil) return nil; // no hope either
 231     [self.nsWindow release]; // the property retains the object already
 232 
 233     self.isEnabled = YES;
 234     self.javaPlatformWindow = platformWindow;
 235     self.styleBits = bits;
 236     [self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];
 237 
 238     return self;
 239 }
 240 
 241 + (BOOL) isAWTWindow:(NSWindow *)window {
 242     return [window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]];
 243 }
 244 
 245 // checks that this window is under the mouse cursor and this point is not overlapped by others windows
 246 - (BOOL) isTopmostWindowUnderMouse {
 247     return [self.nsWindow windowNumber] == [AWTWindow getTopmostWindowUnderMouseID];
 248 }
 249 
 250 + (AWTWindow *) getTopmostWindowUnderMouse {    
 251     NSEnumerator *windowEnumerator = [[NSApp windows] objectEnumerator];
 252     NSWindow *window;
 253     
 254     int topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
 255     
 256     while ((window = [windowEnumerator nextObject]) != nil) {
 257         if ([window windowNumber] == topmostWindowUnderMouseID) {
 258             BOOL isAWTWindow = [AWTWindow isAWTWindow: window]; 
 259             return isAWTWindow ? (AWTWindow *) [window delegate] : nil;
 260         }
 261     }     
 262     return nil;
 263 }    
 264 
 265 // returns id for the topmost window under mouse
 266 + (int) getTopmostWindowUnderMouseID {
 267     
 268     NSRect screenRect = [[NSScreen mainScreen] frame];
 269     NSPoint nsMouseLocation = [NSEvent mouseLocation];
 270     CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y);
 271     
 272     NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);    
 273     

 274     for (NSDictionary *window in windows) {
 275         int layer = [[window objectForKey:(id)kCGWindowLayer] intValue];
 276         if (layer == 0) {

 277             CGRect rect;
 278             CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);
 279             if (CGRectContainsPoint(rect, cgMouseLocation)) {
 280                 return [[window objectForKey:(id)kCGWindowNumber] intValue];


 281             }
 282         }
 283     }
 284     return -1;
 285 }
 286 
 287 - (void) synthesizeMouseEnteredExitedEvents:(int)topmostWindowUnderMouseID withType:(NSEventType)eventType {
 288     
 289     BOOL isUnderMouse = (topmostWindowUnderMouseID == [[self nsWindow] windowNumber]);

 290     BOOL mouseIsOver = [[self.nsWindow contentView] mouseIsOver];
 291     
 292     if ((isUnderMouse && !mouseIsOver && eventType == NSMouseEntered)
 293         || (!isUnderMouse && mouseIsOver && eventType == NSMouseExited)) {





 294         
 295         NSPoint screenLocation = [NSEvent mouseLocation];
 296         NSPoint windowLocation = [self.nsWindow convertScreenToBase: screenLocation];
 297         int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
 298     
 299         NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType
 300                                                  location: windowLocation
 301                                             modifierFlags: modifierFlags
 302                                                 timestamp: 0
 303                                              windowNumber: [self.nsWindow windowNumber]
 304                                                   context: nil
 305                                               eventNumber: 0
 306                                            trackingNumber: 0
 307                                                  userData: nil
 308                                ];
 309     
 310         [[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent];
 311     }
 312 }
 313 
 314 + (void) synthesizeMouseEnteredExitedEventsForAllWindows {
 315     int topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
 316 
 317     NSArray *windows = [NSApp windows];
 318     NSEnumerator *windowEnumerator = [windows objectEnumerator];
 319     NSWindow *window;
 320 
 321     while ((window = [windowEnumerator nextObject]) != nil) {
 322         if ([AWTWindow isAWTWindow: window]) {
 323             AWTWindow *awtWindow = (AWTWindow*)[window delegate];
 324             [awtWindow synthesizeMouseEnteredExitedEvents: topmostWindowUnderMouseID withType: NSMouseExited];
 325         }
 326     }
 327 
 328     windowEnumerator = [windows objectEnumerator];
 329 
 330     while ((window = [windowEnumerator nextObject]) != nil) {
 331         if ([AWTWindow isAWTWindow: window]) {
 332             AWTWindow *awtWindow = (AWTWindow*)[window delegate];
 333             [awtWindow synthesizeMouseEnteredExitedEvents: topmostWindowUnderMouseID withType: NSMouseEntered];
 334         }
 335     }     
 336 }
 337 
 338 - (void) dealloc {
 339 AWT_ASSERT_APPKIT_THREAD;
 340 
 341     JNIEnv *env = [ThreadUtilities getJNIEnv];
 342     [self.javaPlatformWindow setJObject:nil withEnv:env];
 343 
 344     self.nsWindow = nil;
 345 
 346     [super dealloc];
 347 }
 348 
 349 // NSWindow overrides
 350 - (BOOL) canBecomeKeyWindow {
 351 AWT_ASSERT_APPKIT_THREAD;
 352     return self.isEnabled && IS(self.styleBits, SHOULD_BECOME_KEY);
 353 }
 354 
 355 - (BOOL) canBecomeMainWindow {


 845     NSWindow *nsWindow = OBJC(windowPtr);
 846     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 847         AWT_ASSERT_APPKIT_THREAD;
 848 
 849         AWTWindow *window = (AWTWindow*)[nsWindow delegate];
 850 
 851         NSRect rect = ConvertNSScreenRect(NULL, jrect);
 852         [window constrainSize:&rect.size];
 853 
 854         [nsWindow setFrame:rect display:YES];
 855 
 856         // only start tracking events if pointer is above the toplevel
 857         // TODO: should post an Entered event if YES.
 858         NSPoint mLocation = [NSEvent mouseLocation];
 859         [nsWindow setAcceptsMouseMovedEvents:NSPointInRect(mLocation, rect)];
 860 
 861         // ensure we repaint the whole window after the resize operation
 862         // (this will also re-enable screen updates, which were disabled above)
 863         // TODO: send PaintEvent
 864 
 865         [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
 866     }];
 867 
 868 JNF_COCOA_EXIT(env);
 869 }
 870 
 871 /*
 872  * Class:     sun_lwawt_macosx_CPlatformWindow
 873  * Method:    nativeSetNSWindowMinMax
 874  * Signature: (JDDDD)V
 875  */
 876 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinMax
 877 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble minW, jdouble minH, jdouble maxW, jdouble maxH)
 878 {
 879 JNF_COCOA_ENTER(env);
 880 AWT_ASSERT_NOT_APPKIT_THREAD;
 881 
 882     if (minW < 1) minW = 1;
 883     if (minH < 1) minH = 1;
 884     if (maxW < 1) maxW = 1;
 885     if (maxH < 1) maxH = 1;


1060 }
1061 
1062 /*
1063  * Class:     sun_lwawt_macosx_CPlatformWindow
1064  * Method:    nativeSetNSWindowSecurityWarningPositioning
1065  * Signature: (JDDFF)V
1066  */
1067 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowSecurityWarningPositioning
1068 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble x, jdouble y, jfloat biasX, jfloat biasY)
1069 {
1070 JNF_COCOA_ENTER(env);
1071 AWT_ASSERT_NOT_APPKIT_THREAD;
1072 
1073     [JNFException raise:env as:kRuntimeException reason:"unimplemented"];
1074 
1075 JNF_COCOA_EXIT(env);
1076 }
1077 
1078 /*
1079  * Class:     sun_lwawt_macosx_CPlatformWindow
1080  * Method:    nativeGetTopmostPlatformWindowUnderMouse
1081  * Signature: (J)V
1082  */
1083 JNIEXPORT jobject
1084 JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetTopmostPlatformWindowUnderMouse
1085 (JNIEnv *env, jclass clazz)
1086 {
1087     jobject topmostWindowUnderMouse = nil;
1088 
1089     JNF_COCOA_ENTER(env);
1090     AWT_ASSERT_APPKIT_THREAD;
1091 
1092     AWTWindow *awtWindow = [AWTWindow getTopmostWindowUnderMouse];
1093     if (awtWindow != nil) {
1094         topmostWindowUnderMouse = [awtWindow.javaPlatformWindow jObject];
1095     }
1096     
1097     JNF_COCOA_EXIT(env);
1098     
1099     return topmostWindowUnderMouse;
1100 }
1101 
1102 /*
1103  * Class:     sun_lwawt_macosx_CPlatformWindow
1104  * Method:    nativeSynthesizeMouseEnteredExitedEvents
1105  * Signature: (J)V
1106  */
1107 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents
1108 (JNIEnv *env, jclass clazz, jlong windowPtr)
1109 {
1110     JNF_COCOA_ENTER(env);
1111     AWT_ASSERT_NOT_APPKIT_THREAD;
1112 
1113     NSWindow *nsWindow = OBJC(windowPtr);
1114     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
1115         AWT_ASSERT_APPKIT_THREAD;
1116 
1117         AWTWindow *window = (AWTWindow*)[nsWindow delegate];
1118 
1119         [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
1120     }];
1121 
1122     JNF_COCOA_EXIT(env);
1123 }
1124 
1125 /*
1126  * Class:     sun_lwawt_macosx_CPlatformWindow
1127  * Method:    nativeGetDisplayID_AppKitThread
1128  * Signature: (J)I
1129  */
1130 JNIEXPORT jint JNICALL
1131 Java_sun_lwawt_macosx_CPlatformWindow_nativeGetNSWindowDisplayID_1AppKitThread
1132 (JNIEnv *env, jclass clazz, jlong windowPtr)
1133 {
1134     jint ret; // CGDirectDisplayID
1135 
1136 JNF_COCOA_ENTER(env);
1137 AWT_ASSERT_APPKIT_THREAD;
1138 
1139     NSWindow *window = OBJC(windowPtr);