7145768: [macosx] Regression: failure in b11 of ModalDialogInFocusEventTest
authorant
Thu, 17 May 2012 22:10:40 +0400
changeset 12662 184d8d3b7fff
parent 12661 6cf8b7116579
child 12663 58d40d4a87b3
7145768: [macosx] Regression: failure in b11 of ModalDialogInFocusEventTest Summary: forward port from 7u4 Reviewed-by: art
jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java
jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java
--- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java	Thu May 17 21:48:57 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java	Thu May 17 22:10:40 2012 +0400
@@ -56,6 +56,8 @@
 import sun.java2d.opengl.OGLRenderQueue;
 import sun.java2d.pipe.Region;
 
+import sun.util.logging.PlatformLogger;
+
 import javax.swing.JComponent;
 import javax.swing.SwingUtilities;
 import javax.swing.RepaintManager;
@@ -65,7 +67,10 @@
 import com.sun.java.swing.SwingUtilities3;
 
 public abstract class LWComponentPeer<T extends Component, D extends JComponent>
-        implements ComponentPeer, DropTargetPeer {
+    implements ComponentPeer, DropTargetPeer
+{
+    private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWComponentPeer");
+
     // State lock is to be used for modifications to this
     // peer's fields (e.g. bounds, background, font, etc.)
     // It should be the last lock in the lock chain
@@ -885,7 +890,13 @@
     @Override
     public boolean requestFocus(Component lightweightChild, boolean temporary,
                                 boolean focusedWindowChangeAllowed, long time,
-                                CausedFocusEvent.Cause cause) {
+                                CausedFocusEvent.Cause cause)
+    {
+        if (focusLog.isLoggable(PlatformLogger.FINEST)) {
+            focusLog.finest("lightweightChild=" + lightweightChild + ", temporary=" + temporary +
+                            ", focusedWindowChangeAllowed=" + focusedWindowChangeAllowed +
+                            ", time= " + time + ", cause=" + cause);
+        }
         if (LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
                 processSynchronousLightweightTransfer(getTarget(), lightweightChild, temporary,
                         focusedWindowChangeAllowed, time)) {
@@ -901,19 +912,44 @@
             case LWKeyboardFocusManagerPeer.SNFH_SUCCESS_PROCEED:
                 Window parentWindow = SunToolkit.getContainingWindow(getTarget());
                 if (parentWindow == null) {
+                    focusLog.fine("request rejected, parentWindow is null");
                     LWKeyboardFocusManagerPeer.removeLastFocusRequest(getTarget());
                     return false;
                 }
                 LWWindowPeer parentPeer = (LWWindowPeer) parentWindow.getPeer();
                 if (parentPeer == null) {
+                    focusLog.fine("request rejected, parentPeer is null");
                     LWKeyboardFocusManagerPeer.removeLastFocusRequest(getTarget());
                     return false;
                 }
 
+                // A fix for 7145768. Ensure the parent window is currently natively focused.
+                // The more evident place to perform this check is in KFM.shouldNativelyFocusHeavyweight,
+                // however that is the shared code and this particular problem's reproducibility has
+                // platform specifics. So, it was decided to narrow down the fix to lwawt (OSX) in
+                // current release. TODO: consider fixing it in the shared code.
+                if (!focusedWindowChangeAllowed) {
+                    LWWindowPeer decoratedPeer = parentPeer.isSimpleWindow() ?
+                        LWWindowPeer.getOwnerFrameDialog(parentPeer) : parentPeer;
+
+                    if (decoratedPeer == null || !decoratedPeer.getPlatformWindow().isActive()) {
+                        if (focusLog.isLoggable(PlatformLogger.FINE)) {
+                            focusLog.fine("request rejected, focusedWindowChangeAllowed==false, " +
+                                          "decoratedPeer is inactive: " + decoratedPeer);
+                        }
+                        LWKeyboardFocusManagerPeer.removeLastFocusRequest(getTarget());
+                        return false;
+                    }
+                }
+
                 boolean res = parentPeer.requestWindowFocus(cause);
                 // If parent window can be made focused and has been made focused (synchronously)
                 // then we can proceed with children, otherwise we retreat
                 if (!res || !parentWindow.isFocused()) {
+                    if (focusLog.isLoggable(PlatformLogger.FINE)) {
+                        focusLog.fine("request rejected, res= " + res + ", parentWindow.isFocused()=" +
+                                      parentWindow.isFocused());
+                    }
                     LWKeyboardFocusManagerPeer.removeLastFocusRequest(getTarget());
                     return false;
                 }
--- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Thu May 17 21:48:57 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Thu May 17 22:10:40 2012 +0400
@@ -50,7 +50,7 @@
         EMBEDDEDFRAME
     }
 
-    private static final sun.util.logging.PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWWindowPeer");
+    private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWWindowPeer");
 
     private PlatformWindow platformWindow;
 
@@ -245,15 +245,17 @@
                         getInstance(getAppContext());
 
                     if (visible) {
-                        updateFocusableWindowState();
-                        changeFocusedWindow(true, true);
-
+                        if (!getTarget().isAutoRequestFocus()) {
+                            return;
+                        } else {
+                            requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION);
+                        }
                     // Focus the owner in case this window is focused.
                     } else if (manager.getCurrentFocusedWindow() == getTarget()) {
+                        // Transfer focus to the owner.
                         LWWindowPeer owner = getOwnerFrameDialog(LWWindowPeer.this);
                         if (owner != null) {
-                            // KFM will do all the rest.
-                            owner.changeFocusedWindow(true, false);
+                            owner.requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION);
                         }
                     }
                 }
@@ -619,7 +621,7 @@
     }
 
     public void notifyActivation(boolean activation) {
-        changeFocusedWindow(activation, false);
+        changeFocusedWindow(activation);
     }
 
     // MouseDown in non-client area
@@ -1065,6 +1067,10 @@
         return lastMouseEventPeer;
     }
 
+    /*
+     * Requests platform to set native focus on a frame/dialog.
+     * In case of a simple window, triggers appropriate java focus change.
+     */
     public boolean requestWindowFocus(CausedFocusEvent.Cause cause) {
         if (focusLog.isLoggable(PlatformLogger.FINE)) {
             focusLog.fine("requesting native focus to " + this);
@@ -1108,14 +1114,14 @@
             }
 
             // DKFM will synthesize all the focus/activation events correctly.
-            changeFocusedWindow(true, false);
+            changeFocusedWindow(true);
             return true;
 
         // In case the toplevel is active but not focused, change focus directly,
         // as requesting native focus on it will not have effect.
         } else if (getTarget() == currentActive && !getTarget().hasFocus()) {
 
-            changeFocusedWindow(true, false);
+            changeFocusedWindow(true);
             return true;
         }
         return platformWindow.requestWindowFocus();
@@ -1133,13 +1139,13 @@
     }
 
     /*
-     * "Delegates" the responsibility of managing focus to keyboard focus manager.
+     * Changes focused window on java level.
      */
-    private void changeFocusedWindow(boolean becomesFocused, boolean isShowing) {
+    private void changeFocusedWindow(boolean becomesFocused) {
         if (focusLog.isLoggable(PlatformLogger.FINE)) {
             focusLog.fine((becomesFocused?"gaining":"loosing") + " focus window: " + this);
         }
-        if (isShowing && !getTarget().isAutoRequestFocus() || skipNextFocusChange) {
+        if (skipNextFocusChange) {
             focusLog.fine("skipping focus change");
             skipNextFocusChange = false;
             return;
@@ -1184,7 +1190,7 @@
         postEvent(windowEvent);
     }
 
-    private static LWWindowPeer getOwnerFrameDialog(LWWindowPeer peer) {
+    static LWWindowPeer getOwnerFrameDialog(LWWindowPeer peer) {
         Window owner = (peer != null ? peer.getTarget().getOwner() : null);
         while (owner != null && !(owner instanceof Frame || owner instanceof Dialog)) {
             owner = owner.getOwner();