[I had to fix the links in the previous e-mail, replaced webrev.4 with
webrev.5, sorry]
Hi,
Please review a fix for the CR:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6981400
Webrev:
http://cr.openjdk.java.net/~ant/6981400/webrev.5
The fix covers a number of issues and is an evaluated version of the
fix originally integrated into jdk6. The scenario which reproduces
the referred problems looks pretty like the following:
A frame with components. The first component is focused. In its
focusLost(..) listener it performs some lengthy operation.
TAB key is pressed, say, 5 times. The first component loses focus, the
lengthy operation begins which freezes EDT for a while.
At the same time, a user switches to some other window by Alt-TAB and
then switches back by another Alt-TAB. When the lengthy
operation is done, the user expects focus to be transferred through
the components in order as if no toplevel switch has happened.
Alternatively, the toplevel switch could be done by a mouse click in a
component of the other java toplevel and then by a click to the
title of the original frame.
This may cause the following unexpected results:
1) Focus doesn't go through all the 5 components (which 5 TABs should
result in) but stops on, say, the 3rd one.
2) Components are being transferred in wrong order, say 2, 3, 2, 4, 5,
6 instead of 2, 3, 4, 5, 6.
3) A menu of the original frame eventually gets activated
(reproducible on MS Windows).
Detailed description of why AWT behaves that way is quite lengthy &
tangled. It can be found in the CR.
Below I'll shortly comment the changes made. (The fix additionally
contains changes not directly related to the 3 problems mentioned
above,
but those changes were introduced based on thorough testing with the
focus regression test base and analysing the failures).
1. Component.requestFocusHelper(..), Component.dispatchEventImpl(..),
Container, Dialog, EventQueue
http://cr.openjdk.java.net/~ant/6981400/webrev.5/src/share/classes/java/awt/Component.java.sdiff.html
http://cr.openjdk.java.net/~ant/6981400/webrev.5/src/share/classes/java/awt/Container.java.sdiff.html
http://cr.openjdk.java.net/~ant/6981400/webrev.5/src/share/classes/java/awt/Dialog.java.sdiff.html
http://cr.openjdk.java.net/~ant/6981400/webrev.5/src/share/classes/java/awt/EventQueue.java.sdiff.html
A focus request, in order to set a type-ahead marker's time, uses the
time stamp of the last dispatched _key_ event.
A time stamp of a key event, which is put into the type-ahead queue,
is not registered until the event is retrieved from the queue for
normal dispatching.
This establishes strong dependence b/w type-ahead markers and the
order in which key events are actually dispatched.
2. Component.requestFocusHelper(..)
http://cr.openjdk.java.net/~ant/6981400/webrev.5/src/share/classes/java/awt/Component.java.sdiff.html
As the comments say, a focus request following a mouse event is forced
to be "in-window" focus requests. This is to make sure it won't
re-activate the window
in case the window is inactive by the time the request takes its turn
for processing. This type of deferred side effect of the mouse event
may not be correctly
processed under "tough" conditions and should be dropped.
3. LWComponentPeer, LWWindowPeer
http://cr.openjdk.java.net/~ant/6981400/webrev.5/src/macosx/classes/sun/lwawt/LWComponentPeer.java.sdiff.html
http://cr.openjdk.java.net/~ant/6981400/webrev.5/src/macosx/classes/sun/lwawt/LWWindowPeer.java.udiff.html
A simple (not Frame/Dialog) window or an active but not focused
Frame/Dialog should request window focus by mouse click right on
dispatching of the mouse event
on the platform side, not after the event made the "platform -> java
-> platform" cycle.
4. LWWindowPeer.dispatchKeyEvent(..)
http://cr.openjdk.java.net/~ant/6981400/webrev.5/src/macosx/classes/sun/lwawt/LWWindowPeer.java.udiff.html
This is actually a fix for 7157015 (which I'll close later). The bug
affects behavior and troubles testing of the whole fix, so I'm
including this code as dependent.
5. XBaseWindow, XComponentPeer
http://cr.openjdk.java.net/~ant/6981400/webrev.5/src/solaris/classes/sun/awt/X11/XBaseWindow.java.sdiff.html
http://cr.openjdk.java.net/~ant/6981400/webrev.5/src/solaris/classes/sun/awt/X11/XComponentPeer.java.sdiff.html
Similarly to (3), but for X11 implementation. Additionally,
"actualFocusedWindow" reference, which is the most recent focused
owned simple window, is reset because
a click in an owned window should deliver focus to that window, not to
the most recently focused one.
6. DefaultKeyboardFocusManager.repostIfFollowsKeyEvents(..)
http://cr.openjdk.java.net/~ant/6981400/webrev.5/src/share/classes/java/awt/DefaultKeyboardFocusManager.java.sdiff.html
(The change originally suggested by Oleg Pekhovskiy) Toplevel window
focus events (WINDOW_GAINED_FOCUS/WINDOW_LOST_FOCUS) should not be
processed
until the type-ahead queue, populated before the event of switching
toplevel windows actually happened, is empty. The only we can do here
is to repost the toplevel focus
events to the end of the EDT queue.
7. KeyboardFocusManagerPeerImpl
http://cr.openjdk.java.net/~ant/6981400/webrev.5/src/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java.sdiff.html
The calls:
SunToolkit.postPriorityEvent(fl);
were originally wrong. This is an artefact of an old fix (5028014)
that has been rolled out, but went into jdk7 (with 6806217) by a
mistake.
The focus events should not be sent in prioritized order here.
8. TimedWindowEvent
http://cr.openjdk.java.net/~ant/6981400/webrev.5/src/share/classes/sun/awt/TimedWindowEvent.java.html
A WindowEvent with a time stamp.
9. SunToolkit
http://cr.openjdk.java.net/~ant/6981400/webrev.5/src/share/classes/sun/awt/SunToolkit.java.sdiff.html
WINDOW_LOST_FOCUS event's time stamp is registered.
10. WindowsRootPaneUI
http://cr.openjdk.java.net/~ant/6981400/webrev.5/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java.sdiff.html
Skip menu activating events which weren't processed in time (while the
containing toplevel window is active).
11. awt_Window.cpp
http://cr.openjdk.java.net/~ant/6981400/webrev.5/src/windows/native/sun/windows/awt_Window.cpp.sdiff.html
Window focus events are supplied with a time stamp.
- - -
Thanks,
Anton.