< 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 >