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 |
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 |