Hi,
The check you've added also affects lightweight frames (because of line
382). Is it OK?
On 6/13/2013 6:52 PM, Anton V. Tarasov wrote:
Hello,
Please, review the fix.
jira: https://jbs.oracle.com/bugs/browse/JDK-8016555
webrev: http://cr.openjdk.java.net/~ant/JDK-8014821/webrev.0
It's reproducible in the applet mode only, on Windows. When an applet
is focused and then a new frame pops up, it doesn't get focus.
The reason of the focus loss is the following. When a toplevel is
shown while another toplevel is focused, native focus messages should
be generated strictly in the following order:
WM_ACTIVATE(WA_INACTIVE), WM_ACTIVATE(WA_ACTIVE), appropriately. The
case with applet is special due to the EmbeddedFrame is not a toplevel
from native platform perspective, the toplevel is the browser window.
Moreover, the EmbeddedFrame window belongs to another process, other
than the browser's process. It doesn't receive WM_ACTIVATE messages,
these messages are generated (synthesized) for it when it should be
activated/deactivated as an AWT toplevel. When EmbeddedFrame loses
focus it receives WM_KILLFOCUS (which is triggered by the plugin).
However, in case when a new frame pops up, the EmbeddedFrame receives
WM_KILLFOCUS after the frame receives WM_ACTIVATE(WA_ACTIVE). So the
order is not correct. The reason is the specific of IPC: browser ->
plugin -> applet (another process).
When EmbeddedFrame receives WM_KILLFOCUS it synthesizes
WM_ACTIVATE(WA_INACTIVE) for itself. On processing of this message,
AwtComponent::SetFocusedWindow() static method is called which resets
the native pointer to the focused window. The point is that as the
message is received after WM_ACTIVATE(WA_ACTIVE) (which is sent to the
new frame), the new focused window is set to NULL. Later, when focus
is requested to the frame's default component, it gets rejected
because of the null native focused window value.
Before the regression, there was a check for opposite toplevel being
set focused in processing of WM_KILLFOCUS for EmbeddedFrame. In case
the opposite toplevel is already set focused (which means it already
received WM_ACTIVATE(WA_ACTIVE)), no WM_ACTIVATE(WA_INACTIVE) message
was synthesized. DKFM in that case created a peer WINDOW_LOST_FOCUS
event on java level for the toplevel losing focus (EmbeddedFrame in
our case). This code was lost in the process of refactoring and I'm
simply bring it back.
I've tested it manually with the applet provided in the bugreport
(with IE and FF).
As the fix simply makes the code spot look like it was before the
regression, I consider it low risk.
Thanks,
Anton.
P.S.
I'm going to push it to 7u40 as well.