changeset 5404:3d459273c61b

8012330: [macosx] Sometimes the applet showing the modal dialog itself loses the ability to gain focus Reviewed-by: serb, ant
author alexsch
date Mon, 29 Apr 2013 16:46:18 +0400
parents 5d5752746305
children 0895957e8e00
files src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java
diffstat 1 files changed, 26 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java	Wed May 01 00:49:21 2013 +0200
+++ b/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java	Mon Apr 29 16:46:18 2013 +0400
@@ -38,7 +38,8 @@
 public class CEmbeddedFrame extends EmbeddedFrame {
 
     private CPlatformResponder responder;
-    private boolean focused = true;
+    private static final Object classLock = new Object();
+    private static volatile CEmbeddedFrame focusedWindow;
     private boolean parentWindowActive = true;
 
     public CEmbeddedFrame() {
@@ -98,18 +99,38 @@
         responder.handleInputEvent(text);
     }
 
+    // handleFocusEvent is called when the applet becames focused/unfocused.
+    // This method can be called from different threads.
     public void handleFocusEvent(boolean focused) {
-        this.focused = focused;
-        if (parentWindowActive) {
+
+        boolean handleWindowFocusEvent;
+        synchronized (classLock) {
+            // In some cases an applet may not receive the focus lost event
+            // from the parent window (see 8012330)
+            focusedWindow = (focused) ? this
+                    : ((focusedWindow == this) ? null : focusedWindow);
+            handleWindowFocusEvent = parentWindowActive;
+        }
+
+        if (handleWindowFocusEvent) {
             responder.handleWindowFocusEvent(focused);
         }
     }
 
+    // handleWindowFocusEvent is called for all applets, when the browser
+    // becames active/inactive. This event should be filtered out for
+    // non-focused applet. This method can be called from different threads.
     public void handleWindowFocusEvent(boolean parentWindowActive) {
-        this.parentWindowActive = parentWindowActive;
+
+        boolean handleWindowFocusEvent;
+        synchronized (classLock) {
+            this.parentWindowActive = parentWindowActive;
+            handleWindowFocusEvent = focusedWindow == this && parentWindowActive;
+        }
+
         // ignore focus "lost" native request as it may mistakenly
         // deactivate active window (see 8001161)
-        if (focused && parentWindowActive) {
+        if (handleWindowFocusEvent) {
             responder.handleWindowFocusEvent(parentWindowActive);
         }
     }