7124376: [macosx] Modal dialog lost focus
authorleonidr
Thu, 03 May 2012 19:22:38 +0400
changeset 12640 5ea775607d72
parent 12639 c1634bcec0a8
child 12641 40df38d36cb4
7124376: [macosx] Modal dialog lost focus Reviewed-by: anthony
jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java
jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java
jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java
jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
jdk/src/macosx/native/sun/awt/AWTView.m
jdk/src/macosx/native/sun/awt/AWTWindow.h
jdk/src/macosx/native/sun/awt/AWTWindow.m
--- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Thu May 03 18:29:00 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Thu May 03 19:22:38 2012 +0400
@@ -409,6 +409,8 @@
         synchronized (getPeerTreeLock()) {
             this.blocker = blocked ? (LWWindowPeer)blocker.getPeer() : null;
         }
+
+        platformWindow.setModalBlocked(blocked);
     }
 
     @Override
--- a/jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java	Thu May 03 18:29:00 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java	Thu May 03 19:22:38 2012 +0400
@@ -108,6 +108,8 @@
     public void flip(int x1, int y1, int x2, int y2,
                      BufferCapabilities.FlipContents flipAction);
 
+    public void setModalBlocked(boolean blocked);
+
     public void toFront();
 
     public void toBack();
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java	Thu May 03 18:29:00 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java	Thu May 03 19:22:38 2012 +0400
@@ -205,4 +205,7 @@
 
     @Override
     public void setWindowState(int windowState) {}
+
+    @Override
+    public void setModalBlocked(boolean blocked) {}
 }
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Thu May 03 18:29:00 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Thu May 03 19:22:38 2012 +0400
@@ -61,6 +61,7 @@
     private static native void nativeSetNSWindowMinimizedIcon(long nsWindowPtr, long nsImage);
     private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename);
     private static native void nativeSetNSWindowSecurityWarningPositioning(long nsWindowPtr, double x, double y, float biasX, float biasY);
+    private static native void nativeSetEnabled(long nsWindowPtr, boolean isEnabled);
     private static native void nativeSynthesizeMouseEnteredExitedEvents(long nsWindowPtr);
 
     private static native int nativeGetScreenNSWindowIsOn_AppKitThread(long nsWindowPtr);
@@ -800,6 +801,15 @@
         //       value when the native notification comes to us
     }
 
+    @Override
+    public void setModalBlocked(boolean blocked) {
+        if (target.getModalExclusionType() == Dialog.ModalExclusionType.APPLICATION_EXCLUDE) {
+            return;
+        }
+
+        nativeSetEnabled(getNSWindowPtr(), !blocked);
+    }
+
     // ----------------------------------------------------------------------
     //                          UTILITY METHODS
     // ----------------------------------------------------------------------
--- a/jdk/src/macosx/native/sun/awt/AWTView.m	Thu May 03 18:29:00 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/AWTView.m	Thu May 03 19:22:38 2012 +0400
@@ -81,7 +81,7 @@
     fEnablePressAndHold = shouldUsePressAndHold();
     fInPressAndHold = NO;
     fPAHNeedsToSelect = NO;
-    
+
     mouseIsOver = NO;
 
     if (windowLayer != nil) {
@@ -302,16 +302,25 @@
  */
 
 -(void) deliverJavaMouseEvent: (NSEvent *) event {
-    
-    NSEventType type = [event type];    
-    
+    BOOL isEnabled = YES;
+    NSWindow* window = [self window];
+    if ([window isKindOfClass: [AWTWindow class]]) {
+        isEnabled = [(AWTWindow*)window isEnabled];
+    }
+
+    if (!isEnabled) {
+        return;
+    }
+
+    NSEventType type = [event type];
+
     // check synthesized mouse entered/exited events
     if ((type == NSMouseEntered && mouseIsOver) || (type == NSMouseExited && !mouseIsOver)) {
         return;
     }else if ((type == NSMouseEntered && !mouseIsOver) || (type == NSMouseExited && mouseIsOver)) {
         mouseIsOver = !mouseIsOver;
     }
-    
+
     [AWTToolkit eventCountPlusPlus];
 
     JNIEnv *env = [ThreadUtilities getJNIEnv];
--- a/jdk/src/macosx/native/sun/awt/AWTWindow.h	Thu May 03 18:29:00 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/AWTWindow.h	Thu May 03 19:22:38 2012 +0400
@@ -42,6 +42,7 @@
     NSSize javaMinSize;
     NSSize javaMaxSize;
     jint styleBits;
+    BOOL isEnabled;
 }
 
 @property (nonatomic, retain) JNFWeakJObjectWrapper *javaPlatformWindow;
@@ -49,6 +50,7 @@
 @property (nonatomic) NSSize javaMinSize;
 @property (nonatomic) NSSize javaMaxSize;
 @property (nonatomic) jint styleBits;
+@property (nonatomic) BOOL isEnabled;
 
 - (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)javaPlatformWindow
                     styleBits:(jint)styleBits
--- a/jdk/src/macosx/native/sun/awt/AWTWindow.m	Thu May 03 18:29:00 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m	Thu May 03 19:22:38 2012 +0400
@@ -58,6 +58,7 @@
 @synthesize javaMinSize;
 @synthesize javaMaxSize;
 @synthesize styleBits;
+@synthesize isEnabled;
 
 - (void) updateMinMaxSize:(BOOL)resizable {
     if (resizable) {
@@ -157,6 +158,7 @@
 
     if (self == nil) return nil; // no hope
 
+    self.isEnabled = YES;
     self.javaPlatformWindow = platformWindow;
     self.styleBits = bits;
     [self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];
@@ -170,22 +172,22 @@
     return self;
 }
 
-// checks that this window is under the mouse cursor and this point is not overlapped by others windows 
+// checks that this window is under the mouse cursor and this point is not overlapped by others windows
 - (BOOL) isTopmostWindowUnderMouse {
-    
-    int currentWinID = [self windowNumber]; 
-    
-    NSRect screenRect = [[NSScreen mainScreen] frame];    
+
+    int currentWinID = [self windowNumber];
+
+    NSRect screenRect = [[NSScreen mainScreen] frame];
     NSPoint nsMouseLocation = [NSEvent mouseLocation];
-    CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y);    
-    
+    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];            
+            int winID = [[window objectForKey:(id)kCGWindowNumber] intValue];
             CGRect rect;
             CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);
             if (CGRectContainsPoint(rect, cgMouseLocation)) {
@@ -199,23 +201,23 @@
 }
 
 - (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;        
+        eventType = NSMouseExited;
     } else {
         return;
     }
-    
-    NSPoint screenLocation = [NSEvent mouseLocation];        
-    NSPoint windowLocation = [self convertScreenToBase: screenLocation];        
+
+    NSPoint screenLocation = [NSEvent mouseLocation];
+    NSPoint windowLocation = [self convertScreenToBase: screenLocation];
     int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
-    
+
     NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType
                                                   location: windowLocation
                                              modifierFlags: modifierFlags
@@ -226,7 +228,7 @@
                                             trackingNumber: 0
                                                   userData: nil
                             ];
-    
+
     [[self contentView] deliverJavaMouseEvent: mouseEvent];
 }
 
@@ -239,16 +241,15 @@
     [super dealloc];
 }
 
-
 // NSWindow overrides
 - (BOOL) canBecomeKeyWindow {
 AWT_ASSERT_APPKIT_THREAD;
-    return IS(self.styleBits, SHOULD_BECOME_KEY);
+    return self.isEnabled && IS(self.styleBits, SHOULD_BECOME_KEY);
 }
 
 - (BOOL) canBecomeMainWindow {
 AWT_ASSERT_APPKIT_THREAD;
-    return IS(self.styleBits, SHOULD_BECOME_MAIN);
+    return self.isEnabled && IS(self.styleBits, SHOULD_BECOME_MAIN);
 }
 
 - (BOOL) worksWhenModal {
@@ -562,6 +563,27 @@
     size->height = MAX(size->height, minHeight);
 }
 
+- (void) setEnabled: (BOOL)flag {
+    self.isEnabled = flag;
+
+    if (IS(self.styleBits, CLOSEABLE)) {
+        [[self standardWindowButton:NSWindowCloseButton] setEnabled: flag];
+    }
+
+    if (IS(self.styleBits, MINIMIZABLE)) {
+        [[self standardWindowButton:NSWindowMiniaturizeButton] setEnabled: flag];
+    }
+
+    if (IS(self.styleBits, ZOOMABLE)) {
+        [[self standardWindowButton:NSWindowZoomButton] setEnabled: flag];
+    }
+
+    if (IS(self.styleBits, RESIZABLE)) {
+        [self updateMinMaxSize:flag];
+        [self setShowsResizeIndicator:flag];
+    }
+}
+
 @end // AWTWindow
 
 
@@ -729,7 +751,7 @@
         // 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];
     }];
 
@@ -969,14 +991,14 @@
 {
     JNF_COCOA_ENTER(env);
     AWT_ASSERT_NOT_APPKIT_THREAD;
-    
+
     AWTWindow *window = OBJC(windowPtr);
     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
         AWT_ASSERT_APPKIT_THREAD;
-        
+
         [window synthesizeMouseEnteredExitedEvents];
     }];
-    
+
     JNF_COCOA_EXIT(env);
 }
 
@@ -1056,3 +1078,17 @@
 
     return underMouse;
 }
+
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetEnabled
+(JNIEnv *env, jclass clazz, jlong windowPtr, jboolean isEnabled)
+{
+JNF_COCOA_ENTER(env);
+
+    AWTWindow *window = OBJC(windowPtr);
+    [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
+        [window setEnabled: isEnabled];
+    }];
+
+JNF_COCOA_EXIT(env);
+}
+