--- old/src/share/classes/java/awt/DefaultKeyboardFocusManager.java 2013-05-30 16:30:45.000000000 +0400 +++ new/src/share/classes/java/awt/DefaultKeyboardFocusManager.java 2013-05-30 16:30:45.000000000 +0400 @@ -269,7 +269,7 @@ } return se.dispatched; } - + /* * Checks if the focus window event follows key events waiting in the type-ahead * queue (if any). This may happen when a user types ahead in the window, the client @@ -283,10 +283,20 @@ return false; } TimedWindowEvent we = (TimedWindowEvent)e; + if (we.isReposted()) { + // It is expected that the key events waiting in the type-ahead queue + // get dispatched during the first repost cycle. If they don't, there's + // likely a dependency b/w the key events and the focus window event + // (a type-ahead marker may be targeted at a component belonging to the + // window awaiting activation and focus). So, to avoid the risk of endless + // repost cycle, a focus window event is not reposted repeatedely. See 8015454. + return false; + } long time = we.getWhen(); synchronized (this) { for (KeyEvent ke: enqueuedKeyEvents) { if (time >= ke.getWhen()) { + we.setReposted(); SunToolkit.postEvent(AppContext.getAppContext(), new SequencedEvent(e)); return true; } @@ -482,7 +492,7 @@ } case FocusEvent.FOCUS_GAINED: { - FocusEvent fe = (FocusEvent)e; + FocusEvent fe = (FocusEvent)e; CausedFocusEvent.Cause cause = (fe instanceof CausedFocusEvent) ? ((CausedFocusEvent)fe).getCause() : CausedFocusEvent.Cause.UNKNOWN; Component oldFocusOwner = getGlobalFocusOwner(); --- old/src/share/classes/sun/awt/TimedWindowEvent.java 2013-05-30 16:30:46.000000000 +0400 +++ new/src/share/classes/sun/awt/TimedWindowEvent.java 2013-05-30 16:30:46.000000000 +0400 @@ -31,11 +31,12 @@ public class TimedWindowEvent extends WindowEvent { private long time; + private transient boolean isReposted; public long getWhen() { return time; } - + public TimedWindowEvent(Window source, int id, Window opposite, long time) { super(source, id, opposite); this.time = time; @@ -47,5 +48,13 @@ super(source, id, opposite, oldState, newState); this.time = time; } + + public void setReposted() { + isReposted = true; + } + + public boolean isReposted() { + return isReposted; + } } --- old/test/java/awt/Focus/TypeAhead/TestFocusFreeze.java 2013-05-30 16:30:47.000000000 +0400 +++ new/test/java/awt/Focus/TypeAhead/TestFocusFreeze.java 2013-05-30 16:30:47.000000000 +0400 @@ -132,6 +132,7 @@ } protected synchronized void enqueueKeyEvents(long after, Component untilFocused) { super.enqueueKeyEvents(after, untilFocused); + robot.delay(1); robot.keyPress(KeyEvent.VK_SPACE); robot.delay(50); robot.keyRelease(KeyEvent.VK_SPACE);