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 // returns id for the topmost window under mouse
246 + (NSInteger) getTopmostWindowUnderMouseID {
247
248 NSRect screenRect = [[NSScreen mainScreen] frame];
249 NSPoint nsMouseLocation = [NSEvent mouseLocation];
250 CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y);
251
252 NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
253
254 for (NSDictionary *window in windows) {
255 NSInteger layer = [[window objectForKey:(id)kCGWindowLayer] integerValue];
256 if (layer == 0) {
257 CGRect rect;
258 CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);
259 if (CGRectContainsPoint(rect, cgMouseLocation)) {
260 return [[window objectForKey:(id)kCGWindowNumber] integerValue];
261 }
262 }
263 }
264 return -1;
265 }
266
267 // checks that this window is under the mouse cursor and this point is not overlapped by others windows
268 - (BOOL) isTopmostWindowUnderMouse {
269 return [self.nsWindow windowNumber] == [AWTWindow getTopmostWindowUnderMouseID];
270 }
271
272 + (AWTWindow *) getTopmostWindowUnderMouse {
273 NSEnumerator *windowEnumerator = [[NSApp windows] objectEnumerator];
274 NSWindow *window;
275
276 NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
277
278 while ((window = [windowEnumerator nextObject]) != nil) {
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:(NSInteger)topmostWindowUnderMouseID withWindow:(NSWindow*)window {
288
289 NSEventType eventType = 0;
290 NSInteger windowID = [window windowNumber];
291 BOOL isUnderMouse = (windowID == topmostWindowUnderMouseID);
292 BOOL mouseIsOver = [[window contentView] mouseIsOver];
293
294 if (isUnderMouse && !mouseIsOver) {
295 eventType = NSMouseEntered;
296 } else if (!isUnderMouse && mouseIsOver) {
297 eventType = NSMouseExited;
298 } else {
299 return;
300 }
301
302 NSPoint screenLocation = [NSEvent mouseLocation];
303 NSPoint windowLocation = [window convertScreenToBase: screenLocation];
304 int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
305
306 NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType
307 location: windowLocation
308 modifierFlags: modifierFlags
309 timestamp: 0
310 windowNumber: windowID
311 context: nil
312 eventNumber: 0
313 trackingNumber: 0
314 userData: nil
315 ];
316
317 [[window contentView] deliverJavaMouseEvent: mouseEvent];
318 }
319
320 + (void) synthesizeMouseEnteredExitedEventsForAllWindows {
321
322 NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
323 NSArray *windows = [NSApp windows];
324 NSWindow *window;
325
326 NSEnumerator *windowEnumerator = [windows objectEnumerator];
327 while ((window = [windowEnumerator nextObject]) != nil) {
328 if ([AWTWindow isAWTWindow: window]) {
329 [AWTWindow synthesizeMouseEnteredExitedEvents: topmostWindowUnderMouseID withWindow: window];
330 }
331 }
332 }
333
334 - (void) dealloc {
335 AWT_ASSERT_APPKIT_THREAD;
336
337 JNIEnv *env = [ThreadUtilities getJNIEnv];
338 [self.javaPlatformWindow setJObject:nil withEnv:env];
339
340 self.nsWindow = nil;
341
342 [super dealloc];
343 }
344
345 // NSWindow overrides
346 - (BOOL) canBecomeKeyWindow {
347 AWT_ASSERT_APPKIT_THREAD;
348 return self.isEnabled && IS(self.styleBits, SHOULD_BECOME_KEY);
349 }
350
351 - (BOOL) canBecomeMainWindow {
841 NSWindow *nsWindow = OBJC(windowPtr);
842 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
843 AWT_ASSERT_APPKIT_THREAD;
844
845 AWTWindow *window = (AWTWindow*)[nsWindow delegate];
846
847 NSRect rect = ConvertNSScreenRect(NULL, jrect);
848 [window constrainSize:&rect.size];
849
850 [nsWindow setFrame:rect display:YES];
851
852 // only start tracking events if pointer is above the toplevel
853 // TODO: should post an Entered event if YES.
854 NSPoint mLocation = [NSEvent mouseLocation];
855 [nsWindow setAcceptsMouseMovedEvents:NSPointInRect(mLocation, rect)];
856
857 // ensure we repaint the whole window after the resize operation
858 // (this will also re-enable screen updates, which were disabled above)
859 // TODO: send PaintEvent
860
861 [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
862 }];
863
864 JNF_COCOA_EXIT(env);
865 }
866
867 /*
868 * Class: sun_lwawt_macosx_CPlatformWindow
869 * Method: nativeSetNSWindowMinMax
870 * Signature: (JDDDD)V
871 */
872 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinMax
873 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble minW, jdouble minH, jdouble maxW, jdouble maxH)
874 {
875 JNF_COCOA_ENTER(env);
876 AWT_ASSERT_NOT_APPKIT_THREAD;
877
878 if (minW < 1) minW = 1;
879 if (minH < 1) minH = 1;
880 if (maxW < 1) maxW = 1;
881 if (maxH < 1) maxH = 1;
1056 }
1057
1058 /*
1059 * Class: sun_lwawt_macosx_CPlatformWindow
1060 * Method: nativeSetNSWindowSecurityWarningPositioning
1061 * Signature: (JDDFF)V
1062 */
1063 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowSecurityWarningPositioning
1064 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble x, jdouble y, jfloat biasX, jfloat biasY)
1065 {
1066 JNF_COCOA_ENTER(env);
1067 AWT_ASSERT_NOT_APPKIT_THREAD;
1068
1069 [JNFException raise:env as:kRuntimeException reason:"unimplemented"];
1070
1071 JNF_COCOA_EXIT(env);
1072 }
1073
1074 /*
1075 * Class: sun_lwawt_macosx_CPlatformWindow
1076 * Method: nativeGetTopmostPlatformWindowUnderMouse
1077 * Signature: (J)V
1078 */
1079 JNIEXPORT jobject
1080 JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetTopmostPlatformWindowUnderMouse
1081 (JNIEnv *env, jclass clazz)
1082 {
1083 jobject topmostWindowUnderMouse = nil;
1084
1085 JNF_COCOA_ENTER(env);
1086 AWT_ASSERT_APPKIT_THREAD;
1087
1088 AWTWindow *awtWindow = [AWTWindow getTopmostWindowUnderMouse];
1089 if (awtWindow != nil) {
1090 topmostWindowUnderMouse = [awtWindow.javaPlatformWindow jObject];
1091 }
1092
1093 JNF_COCOA_EXIT(env);
1094
1095 return topmostWindowUnderMouse;
1096 }
1097
1098 /*
1099 * Class: sun_lwawt_macosx_CPlatformWindow
1100 * Method: nativeSynthesizeMouseEnteredExitedEvents
1101 * Signature: (J)V
1102 */
1103 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents
1104 (JNIEnv *env, jclass clazz)
1105 {
1106 JNF_COCOA_ENTER(env);
1107 AWT_ASSERT_NOT_APPKIT_THREAD;
1108
1109 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
1110 AWT_ASSERT_APPKIT_THREAD;
1111 [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
1112 }];
1113
1114 JNF_COCOA_EXIT(env);
1115 }
1116
1117 /*
1118 * Class: sun_lwawt_macosx_CPlatformWindow
1119 * Method: nativeGetDisplayID_AppKitThread
1120 * Signature: (J)I
1121 */
1122 JNIEXPORT jint JNICALL
1123 Java_sun_lwawt_macosx_CPlatformWindow_nativeGetNSWindowDisplayID_1AppKitThread
1124 (JNIEnv *env, jclass clazz, jlong windowPtr)
1125 {
1126 jint ret; // CGDirectDisplayID
1127
1128 JNF_COCOA_ENTER(env);
1129 AWT_ASSERT_APPKIT_THREAD;
1130
1131 NSWindow *window = OBJC(windowPtr);
|