7145768: [macosx] Regression: failure in b11 of ModalDialogInFocusEventTest
Summary: forward port from 7u4
Reviewed-by: art
--- 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();