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

Print this page

        

@@ -228,10 +228,70 @@
     } else growBoxWindow = nil;
 
     return self;
 }
 
+-(BOOL)  isTopmostWindowUnderMouse{
+    
+    int currentWinID = [self 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 contentView] mouseIsOver];
+    
+    if(isUnderMouse && !mouseIsOver){
+        eventType = NSMouseEntered;
+    }else if(!isUnderMouse && mouseIsOver){
+        eventType = NSMouseExited;        
+    }else{
+        return;
+    }
+    
+    NSPoint screenLocation = [NSEvent mouseLocation];        
+    NSPoint windowLocation = [self convertScreenToBase: screenLocation];        
+    int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
+    
+    NSEvent * mouseEvent = [NSEvent 
+                            enterExitEventWithType: eventType
+                            location: windowLocation
+                            modifierFlags: modifierFlags
+                            timestamp: 0
+                            windowNumber: [self windowNumber]
+                            context: nil
+                            eventNumber: 0
+                            trackingNumber: 0
+                            userData: nil
+                            ];
+    
+    [[self contentView] deliverJavaMouseEvent: mouseEvent];
+}
+
 - (void) dealloc {
 AWT_ASSERT_APPKIT_THREAD;
 
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     [self.javaPlatformWindow setJObject:nil withEnv:env];

@@ -711,10 +771,12 @@
         [window setAcceptsMouseMovedEvents:NSPointInRect(mLocation, rect)];
 
         // 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);
 }
 

@@ -763,10 +825,11 @@
     AWTWindow *window = OBJC(windowPtr);
     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
         AWT_ASSERT_APPKIT_THREAD;
 
         [window orderBack:nil];
+        [window synthesizeMouseEnteredExitedEvents];
     }];
 
 JNF_COCOA_EXIT(env);
 }
 

@@ -788,10 +851,12 @@
         if (![window isKeyWindow]) {
             [window makeKeyAndOrderFront:window];
         } else {
             [window orderFront:window];
         }
+        
+        [window synthesizeMouseEnteredExitedEvents];
     }];
 
 JNF_COCOA_EXIT(env);
 }