United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6867293 switching TAB in a browser doesn't deactivate EmbeddedFrame
JDK-6867293 : switching TAB in a browser doesn't deactivate EmbeddedFrame

Details
Type:
Bug
Submit Date:
2009-07-31
Status:
Closed
Updated Date:
2011-01-19
Project Name:
JDK
Resolved Date:
2010-01-13
Component:
client-libs
OS:
windows
Sub-Component:
java.awt
CPU:
x86
Priority:
P2
Resolution:
Fixed
Affected Versions:
6u18
Fixed Versions:
6u18 (b02)

Related Reports
Backport:

Sub Tasks

Description
When an applet is launched and focused in a browser and then another TAB is selected in the browser
the EmbeddedFrame doesn't receive WM_ACTIVATE(WA_INACTIVE) native message. On returning back to
the applet and clicking, say, some textfield in the applet the textfield will not be able to
receive key events. The latter is reproducible with JavaFX applets (see Comments), but is not
reproducible with Java applets.

                                    

Comments
SUGGESTED FIX

------- awt_Frame.cpp -------
*** /tmp/sccs.7Mdxmm    2009-07-31 13:42:02.000000000 +0400
--- awt_Frame.cpp       2009-07-31 13:40:05.494253000 +0400
***************
*** 1100,1111 ****
  /*
   * Execute on Toolkit only.
   */
  void AwtFrame::SynthesizeWmActivate(BOOL doActivate, HWND opposite)
  {
!     if (!::IsWindowVisible(GetHWnd()) ||
!         (doActivate && ::IsIconic(::GetAncestor(GetHWnd(), GA_ROOT))))
      {
          // The activation is rejected if either:
          // - EmbeddedFrame is not visible or
          // - its topmost ancestor window is in minimized state.
          return;
--- 1100,1111 ----
  /*
   * Execute on Toolkit only.
   */
  void AwtFrame::SynthesizeWmActivate(BOOL doActivate, HWND opposite)
  {
!     if (doActivate &&
!         (!::IsWindowVisible(GetHWnd()) || ::IsIconic(::GetAncestor(GetHWnd(), GA_ROOT))))
      {
          // The activation is rejected if either:
          // - EmbeddedFrame is not visible or
          // - its topmost ancestor window is in minimized state.
          return;
                                     
2009-07-31
EVALUATION

When another TAB is selected the focused HW component in the applet receives WM_KILLFOCUS. Then the EmbeddedFrame should be synthetically deactivated. Here's the code that should do that:

void AwtFrame::SynthesizeWmActivate(BOOL doActivate, HWND opposite)
{
    if (!::IsWindowVisible(GetHWnd()) ||
        (doActivate && ::IsIconic(::GetAncestor(GetHWnd(), GA_ROOT))))
    {
        // The activation is rejected if either:
        // - EmbeddedFrame is not visible or
        // - its topmost ancestor window is in minimized state.
        return;
    }
    m_isEmbeddedFrameActivationRequest = TRUE;
    ::SendMessage(GetHWnd(), WM_ACTIVATE, MAKEWPARAM(doActivate ? WA_ACTIVE : WA_INACTIVE, FALSE), (LPARAM) opposite);
}

However it returns before ::SendMessage gets executed because EmbeddedFrame is not already visible (on switching to another TAB), that is !::IsWindowVisible(GetHWnd()) condition is true.

So, the EmbeddedFrame remains active. Then, after returning to the applet it is not re-activated.
However, Java applet receives WM_SETFOCUS triggered by WM_LBUTTONDOWN that restores focus to correct state.
But in case of JavaFX applet, WM_SETFOCUS is not generated by the native system (the reason is unknown for me).
On re-activating EmbeddedFrame, WM_SETFOCUS is generated in both the cases.

The fix is to check for invisibility only for ACTIVATING message (WA_ACTIVE), deactivation should happen anyway.
                                     
2009-07-31



Hardware and Software, Engineered to Work Together