< prev index next >

src/java.desktop/share/classes/java/awt/DefaultKeyboardFocusManager.java

Print this page

        

@@ -73,10 +73,11 @@
     private WeakReference<Component> realOppositeComponentWR = NULL_COMPONENT_WR;
     private int inSendMessage;
     private LinkedList<KeyEvent> enqueuedKeyEvents = new LinkedList<KeyEvent>();
     private LinkedList<TypeAheadMarker> typeAheadMarkers = new LinkedList<TypeAheadMarker>();
     private boolean consumeNextKeyTyped;
+    private Component restoreFocusTo;
 
     static {
         AWTAccessor.setDefaultKeyboardFocusManagerAccessor(
             new AWTAccessor.DefaultKeyboardFocusManagerAccessor() {
                 public void consumeNextKeyTyped(DefaultKeyboardFocusManager dkfm, KeyEvent e) {

@@ -143,23 +144,28 @@
             clearGlobalFocusOwnerPriv();
         }
     }
     private boolean restoreFocus(Window aWindow, Component vetoedComponent,
                                  boolean clearOnFailure) {
+        restoreFocusTo = null;
         Component toFocus =
             KeyboardFocusManager.getMostRecentFocusOwner(aWindow);
 
         if (toFocus != null && toFocus != vetoedComponent) {
-            Component heavyweight = getHeavyweight(aWindow);
-            if (heavyweight != null) {
-                setNativeFocusOwner(heavyweight);
-                Toolkit.getEventQueue().createSecondaryLoop(
-                        () -> getGlobalFocusedWindow() != aWindow, null, 50)
-                        .enter();
+            if (getHeavyweight(aWindow) != getNativeFocusOwner()) {
+                // cannot restore focus synchronously
+                if (!toFocus.isShowing() || !toFocus.canBeFocusOwner()) {
+                    toFocus = toFocus.getNextFocusCandidate();
             }
-            if (getGlobalFocusedWindow() == aWindow &&
-                              doRestoreFocus(toFocus, vetoedComponent, false)) {
+                if (toFocus != null && toFocus != vetoedComponent) {
+                    if (!toFocus.requestFocus(false,
+                                                   FocusEvent.Cause.ROLLBACK)) {
+                        restoreFocusTo = toFocus;
+                    }
+                    return true;
+                }
+            } else if (doRestoreFocus(toFocus, vetoedComponent, false)) {
                 return true;
             }
         }
         if (clearOnFailure) {
             clearGlobalFocusOwnerPriv();

@@ -421,10 +427,12 @@
                     // focus between calculation and our request.
                     // But if focus transfer is synchronous, this synchronization
                     // may cause deadlock, thus we don't synchronize this block.
                     Component toFocus = KeyboardFocusManager.
                         getMostRecentFocusOwner(newFocusedWindow);
+                    boolean isFocusRestore = restoreFocusTo != null &&
+                                                      toFocus == restoreFocusTo;
                     if ((toFocus == null) &&
                         newFocusedWindow.isFocusableWindow())
                     {
                         toFocus = newFocusedWindow.getFocusTraversalPolicy().
                             getInitialComponent(newFocusedWindow);

@@ -439,19 +447,22 @@
                     if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
                         focusLog.finer("tempLost {0}, toFocus {1}",
                                        tempLost, toFocus);
                     }
                     if (tempLost != null) {
-                        tempLost.requestFocusInWindow(FocusEvent.Cause.ACTIVATION);
+                        tempLost.requestFocusInWindow(isFocusRestore ?
+                                                FocusEvent.Cause.ROLLBACK :
+                                                FocusEvent.Cause.ACTIVATION);
                     }
 
                     if (toFocus != null && toFocus != tempLost) {
                         // If there is a component which requested focus when this window
                         // was inactive it expects to receive focus after activation.
                         toFocus.requestFocusInWindow(FocusEvent.Cause.ACTIVATION);
                     }
                 }
+                restoreFocusTo = null;
 
                 Window realOppositeWindow = this.realOppositeWindowWR.get();
                 if (realOppositeWindow != we.getOppositeWindow()) {
                     we = new WindowEvent(newFocusedWindow,
                                          WindowEvent.WINDOW_GAINED_FOCUS,

@@ -497,10 +508,11 @@
 
                 return typeAheadAssertions(newActiveWindow, we);
             }
 
             case FocusEvent.FOCUS_GAINED: {
+                restoreFocusTo = null;
                 FocusEvent fe = (FocusEvent)e;
                 Component oldFocusOwner = getGlobalFocusOwner();
                 Component newFocusOwner = fe.getComponent();
                 if (oldFocusOwner == newFocusOwner) {
                     if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
< prev index next >