changeset 4921:25c4d6676efa

Merge
author michaelm
date Wed, 01 Feb 2012 01:37:54 -0800
parents 3802c2440dd2 bdf67b76a4f0
children 5b524b43fdd1
files
diffstat 11 files changed, 148 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/src/macosx/classes/sun/lwawt/LWComponentPeer.java	Wed Feb 01 01:35:46 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/LWComponentPeer.java	Wed Feb 01 01:37:54 2012 -0800
@@ -1108,13 +1108,7 @@
                 handleJavaPaintEvent();
                 break;
             case MouseEvent.MOUSE_PRESSED:
-                Component target = getTarget();
-                if ((e.getSource() == target) && !target.isFocusOwner() &&
-                        LWKeyboardFocusManagerPeer.shouldFocusOnClick(target)) {
-                    LWKeyboardFocusManagerPeer.requestFocusFor(target,
-                            CausedFocusEvent.Cause.MOUSE_EVENT);
-                }
-                break;
+                handleJavaMouseEvent((MouseEvent)e);
         }
 
         sendEventToDelegate(e);
@@ -1182,6 +1176,18 @@
         return delegateEvent;
     }
 
+    protected void handleJavaMouseEvent(MouseEvent e) {
+        Component target = getTarget();
+        assert (e.getSource() == target);
+
+        if (!target.isFocusOwner() && LWKeyboardFocusManagerPeer.shouldFocusOnClick(target)) {
+            LWKeyboardFocusManagerPeer.requestFocusFor(target, CausedFocusEvent.Cause.MOUSE_EVENT);
+        } else {
+            // Anyway request focus to the toplevel.
+            getWindowPeerOrSelf().requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT);
+        }
+    }
+
     /**
      * Handler for FocusEvents.
      */
--- a/src/macosx/classes/sun/lwawt/LWKeyboardFocusManagerPeer.java	Wed Feb 01 01:35:46 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/LWKeyboardFocusManagerPeer.java	Wed Feb 01 01:37:54 2012 -0800
@@ -90,6 +90,12 @@
         }
     }
 
+    LWWindowPeer getFocusedWindow() {
+        synchronized (lock) {
+            return focusedWindow;
+        }
+    }
+
     void setFocusOwner(LWComponentPeer peer) {
         synchronized (lock) {
             focusOwner = peer;
--- a/src/macosx/classes/sun/lwawt/LWToolkit.java	Wed Feb 01 01:35:46 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/LWToolkit.java	Wed Feb 01 01:37:54 2012 -0800
@@ -522,6 +522,11 @@
         postEvent(targetToAppContext(event.getSource()), event);
     }
 
+    /*
+     * Returns true if the application (one of its windows) owns keyboard focus.
+     */
+    public abstract boolean isApplicationActive();
+
     // use peer's back buffer to implement non-opaque windows.
     @Override
     public boolean needUpdateWindow() {
--- a/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Wed Feb 01 01:35:46 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Wed Feb 01 01:37:54 2012 -0800
@@ -37,6 +37,7 @@
 import sun.java2d.*;
 import sun.java2d.loops.Blit;
 import sun.java2d.loops.CompositeType;
+import sun.util.logging.PlatformLogger;
 
 public class LWWindowPeer
     extends LWContainerPeer<Window, JComponent>
@@ -49,6 +50,8 @@
         EMBEDDEDFRAME
     }
 
+    private static final sun.util.logging.PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWWindowPeer");
+
     private PlatformWindow platformWindow;
 
     // Window bounds reported by the native system (as opposed to
@@ -111,6 +114,8 @@
 
     private static LWWindowPeer grabbingWindow;
 
+    private volatile boolean skipNextFocusChange;
+
     /**
      * Current modal blocker or null.
      *
@@ -713,8 +718,6 @@
                 {
                     grabbingWindow.ungrab();
                 }
-                changeFocusedWindow(true, false);
-
                 if (otherButtonsPressed == 0) {
                     mouseClickButtons = eventButtonMask;
                 } else {
@@ -1048,10 +1051,64 @@
     }
 
     public boolean requestWindowFocus(CausedFocusEvent.Cause cause) {
+        if (focusLog.isLoggable(PlatformLogger.FINE)) {
+            focusLog.fine("requesting native focus to " + this);
+        }
+
         if (!focusAllowedFor()) {
+            focusLog.fine("focus is not allowed");
             return false;
         }
-        return platformWindow.requestWindowFocus(cause == CausedFocusEvent.Cause.MOUSE_EVENT);
+
+        // Cross-app activation requests are not allowed.
+        if (cause != CausedFocusEvent.Cause.MOUSE_EVENT &&
+            !((LWToolkit)Toolkit.getDefaultToolkit()).isApplicationActive())
+        {
+            focusLog.fine("the app is inactive, so the request is rejected");
+            return false;
+        }
+
+        Window currentActive = KeyboardFocusManager.
+            getCurrentKeyboardFocusManager().getActiveWindow();
+
+        // Make the owner active window.
+        if (isSimpleWindow()) {
+            Window owner = getOwnerFrameDialog(this);
+            LWWindowPeer ownerPeer = (owner != null ? (LWWindowPeer)owner.getPeer() : null);
+
+            // If owner is not natively active, request native
+            // activation on it w/o sending events up to java.
+            if (ownerPeer != null && !ownerPeer.platformWindow.isActive()) {
+                if (focusLog.isLoggable(PlatformLogger.FINE)) {
+                    focusLog.fine("requesting native focus to the owner " + ownerPeer);
+                }
+                LWWindowPeer currentActivePeer = (currentActive != null ?
+                    (LWWindowPeer)currentActive.getPeer() : null);
+
+                // Ensure the opposite is natively active and suppress sending events.
+                if (currentActivePeer != null && currentActivePeer.platformWindow.isActive()) {
+                    if (focusLog.isLoggable(PlatformLogger.FINE)) {
+                        focusLog.fine("the opposite is " + currentActivePeer);
+                    }
+                    currentActivePeer.skipNextFocusChange = true;
+                }
+                ownerPeer.skipNextFocusChange = true;
+
+                ownerPeer.platformWindow.requestWindowFocus();
+            }
+
+            // DKFM will synthesize all the focus/activation events correctly.
+            changeFocusedWindow(true, false);
+            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);
+            return true;
+        }
+        return platformWindow.requestWindowFocus();
     }
 
     private boolean focusAllowedFor() {
@@ -1069,7 +1126,12 @@
      * "Delegates" the responsibility of managing focus to keyboard focus manager.
      */
     private void changeFocusedWindow(boolean becomesFocused, boolean isShowing) {
-        if (isShowing && !getTarget().isAutoRequestFocus()) {
+        if (focusLog.isLoggable(PlatformLogger.FINE)) {
+            focusLog.fine((becomesFocused?"gaining":"loosing") + " focus window: " + this);
+        }
+        if (isShowing && !getTarget().isAutoRequestFocus() || skipNextFocusChange) {
+            focusLog.fine("skipping focus change");
+            skipNextFocusChange = false;
             return;
         }
 
@@ -1079,6 +1141,9 @@
         if (becomesFocused) {
             synchronized (getPeerTreeLock()) {
                 if (blocker != null) {
+                    if (focusLog.isLoggable(PlatformLogger.FINEST)) {
+                        focusLog.finest("the window is blocked by " + blocker);
+                    }
                     return;
                 }
             }
@@ -1095,6 +1160,7 @@
         if (!becomesFocused &&
             (isGrabbing() || getOwnerFrameDialog(grabbingWindow) == getTarget()))
         {
+            focusLog.fine("ungrabbing on " + grabbingWindow);
             // ungrab a simple window if its owner looses activation.
             grabbingWindow.ungrab();
         }
@@ -1161,4 +1227,9 @@
     private boolean isGrabbing() {
         return this == grabbingWindow;
     }
+
+    @Override
+    public String toString() {
+        return super.toString() + " [target is " + getTarget() + "]";
+    }
 }
--- a/src/macosx/classes/sun/lwawt/PlatformWindow.java	Wed Feb 01 01:35:46 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/PlatformWindow.java	Wed Feb 01 01:37:54 2012 -0800
@@ -117,7 +117,12 @@
 
     public void updateFocusableWindowState();
 
-    public boolean requestWindowFocus(boolean isMouseEventCause);
+    public boolean requestWindowFocus();
+
+    /*
+     * Returns true only when called on a frame/dialog when it's natively focused.
+     */
+    public boolean isActive();
 
     public void setResizable(boolean resizable);
 
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java	Wed Feb 01 01:35:46 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java	Wed Feb 01 01:37:54 2012 -0800
@@ -149,7 +149,12 @@
     public void updateFocusableWindowState() {}
 
     @Override
-    public boolean requestWindowFocus(boolean isMouseEventCause) {
+    public boolean requestWindowFocus() {
+        return true;
+    }
+
+    @Override
+    public boolean isActive() {
         return true;
     }
 
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Wed Feb 01 01:35:46 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Wed Feb 01 01:37:54 2012 -0800
@@ -63,11 +63,8 @@
 
     private static native int nativeGetScreenNSWindowIsOn_AppKitThread(long nsWindowPtr);
 
-    private static native boolean nativeIsApplicationActive();
-
     // Loger to report issues happened during execution but that do not affect functionality
     private static final PlatformLogger logger = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformWindow");
-    private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.macosx.focus.CPlatformWindow");
 
     // for client properties
     public static final String WINDOW_BRUSH_METAL_LOOK = "apple.awt.brushMetalLook";
@@ -603,12 +600,7 @@
     }
 
     @Override
-    public boolean requestWindowFocus(boolean isMouseEventCause) {
-        if (!isMouseEventCause && !nativeIsApplicationActive()) {
-            focusLog.fine("the app is inactive, so the window activation is rejected");
-            // Cross-app activation requests are not allowed.
-            return false;
-        }
+    public boolean requestWindowFocus() {
         long ptr = getNSWindowPtr();
         if (CWrapper.NSWindow.canBecomeMainWindow(ptr)) {
             CWrapper.NSWindow.makeMainWindow(ptr);
@@ -618,6 +610,12 @@
     }
 
     @Override
+    public boolean isActive() {
+        long ptr = getNSWindowPtr();
+        return CWrapper.NSWindow.isKeyWindow(ptr);
+    }
+
+    @Override
     public void updateFocusableWindowState() {
         final boolean isFocusable = isNativelyFocusableWindow();
         setStyleBits(SHOULD_BECOME_KEY | SHOULD_BECOME_MAIN, isFocusable); // set both bits at once
--- a/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java	Wed Feb 01 01:35:46 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java	Wed Feb 01 01:37:54 2012 -0800
@@ -672,6 +672,9 @@
         return sunAwtDisableCALayers.booleanValue();
     }
 
+    @Override
+    public native boolean isApplicationActive();
+
     /************************
      * Native methods section
      ************************/
--- a/src/macosx/native/sun/awt/AWTWindow.m	Wed Feb 01 01:35:46 2012 -0800
+++ b/src/macosx/native/sun/awt/AWTWindow.m	Wed Feb 01 01:37:54 2012 -0800
@@ -427,7 +427,7 @@
 
 
 - (void) windowDidBecomeKey: (NSNotification *) notification {
-AWT_ASSERT_APPKIT_THREAD;
+AWT_ASSERT_APPKIT_THREAD;	
     [AWTToolkit eventCountPlusPlus];
     [CMenuBar activate:self.javaMenuBar modallyDisabled:NO];
     [self _deliverWindowFocusEvent:YES];
@@ -994,21 +994,6 @@
 JNF_COCOA_EXIT(env);
 }
 
-/*
- * Class:     sun_lwawt_macosx_CPlatformWindow
- * Method:    isApplicationActive
- * Signature: ()Z
- */
-JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeIsApplicationActive
-(JNIEnv *env, jclass clazz)
-{
-JNF_COCOA_ENTER(env);
-
-    return (jboolean)[NSRunningApplication currentApplication].active;
-
-JNF_COCOA_EXIT(env);
-}
-
 JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CMouseInfoPeer_nativeIsWindowUnderMouse
 (JNIEnv *env, jclass clazz, jlong windowPtr)
 {
--- a/src/macosx/native/sun/awt/CWrapper.m	Wed Feb 01 01:35:46 2012 -0800
+++ b/src/macosx/native/sun/awt/CWrapper.m	Wed Feb 01 01:37:54 2012 -0800
@@ -108,8 +108,8 @@
 JNF_COCOA_ENTER(env);
 
     NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
-    [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
-    canBecomeMainWindow = [window canBecomeMainWindow];
+    [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+        canBecomeMainWindow = [window canBecomeMainWindow];
     }];
 
 JNF_COCOA_EXIT(env);
@@ -131,7 +131,7 @@
 JNF_COCOA_ENTER(env);
 
     NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
-    [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
+    [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
         isKeyWindow = [window isKeyWindow];
     }];
 
--- a/src/macosx/native/sun/awt/LWCToolkit.m	Wed Feb 01 01:35:46 2012 -0800
+++ b/src/macosx/native/sun/awt/LWCToolkit.m	Wed Feb 01 01:37:54 2012 -0800
@@ -369,6 +369,29 @@
 }
 
 /*
+ * Class:     sun_lwawt_macosx_LWCToolkit
+ * Method:    isApplicationActive
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_LWCToolkit_isApplicationActive
+(JNIEnv *env, jclass clazz)
+{
+	__block jboolean active = JNI_FALSE;
+
+AWT_ASSERT_NOT_APPKIT_THREAD;
+JNF_COCOA_ENTER(env);
+	
+	[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^() {
+		active = (jboolean)[NSRunningApplication currentApplication].active;
+	}];
+	
+JNF_COCOA_EXIT(env);
+	
+	return active;
+}
+
+
+/*
  * Class:     sun_awt_SunToolkit
  * Method:    closeSplashScreen
  * Signature: ()V