JDK-8140525 : AwtFrame::WmShowWindow() may steal focus
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 8u60,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_8
  • CPU: x86
  • Submitted: 2015-09-29
  • Updated: 2017-11-29
  • Resolved: 2016-11-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u152Fixed 9 b150Fixed
Description
FULL PRODUCT VERSION :
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Windows 8.1

A DESCRIPTION OF THE PROBLEM :
In AwtFrame::WmShowWindow(), as the fix for 6492970, a window is set foreground under some circumstances, including show==true and another process's window is being foreground at the moment. However, it's possible that an AWT frame received WM_SHOWWINDOW with show==true when the frame was already showing on screen. In this case the frame is set foreground and this unexpectedly steals focus from another app's window.

For instance, with is reproducible with Dragon NaturallySpeaking application, when the latter shows Dictation Box (a dialog with a text field to receive text recognized from speech, or simply typed). When the Dictation Box dialog is activated (either way), the AWT (or Swing) frame receives WM_SHOWWINDOW (I don't clearly understand why), nevertheless it's already showing. The frame then steals focus preventing the Dictation Box to receive any input.

I suppose the visibility of the frame should be taken into account. When the frame is visible it is not expected to become foreground on receiving WM_SHOWWINDOW.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Install Dragon NaturallySpeaking (well, theoretically). Run any AWT/Swing application with a text field (e.g. SwingSet2). Activate the Dragon. Focus the AWT/Swing text field. Start dictating or simply, from the Dragon Bar, open Tools -> Dictation Box. A dialog will appear atop of the AWT/Swing frame. Try to do anything with it. It's irresponsible due to inability to get focus (additionally it blocks mouse events, but this is an expected behavior of it).

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Everything you speak (or type) should go into Dictation Box. Then you're able to transfer the text to the AWT/Swing frame.
ACTUAL -
DictationBox is irresponsible due to inability to get focus. Additionally it blocks mouse events, but this is an expected behavior of it, yet it can't be closed.

REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER SUBMITTED WORKAROUND :
It hardly ever can be worked around.


Comments
Anton , this bug will be deferred soon unless your fix is really in progress, on review phase.
15-11-2016

Victor, thanks for letting me know. I'll try to send the fix (listed above) to review in the nearest time.
29-08-2016

Anton, is this bug fix still in your plans to meet ZBB (Oct 20)? http://openjdk.java.net/projects/jdk9/
23-08-2016

Anton, are you still working on this fix? ZBB is approaching next couple of weeks, so a heads up for you do not delay, but proceed now to avoid last minute confusion
16-08-2016

Hi Stephen, Pardeep, Yes, the issue is reproducible with jdk9. Unfortunately, I can't give you a simple test case, because the problem is specific to how the Dragon app communicates to AWT. It shows a dialog being an owned window of an AWT frame, at the same time belonging to another process. I agree, this may seem exotic, but the problem has a simple fix which will allow apps like Intellij IDEA to work with Dragon. In details, what I see is that AWT frame receives WM_SHOWWINDOW [*] with the following params: wParam == TRUE lParam == 0 The latter means the message is sent because of a call to WmShowWindow (it's not AWT calling it). In which case wParam==TRUE means the window is being shown. However, normally, when a window is being shown its visible state should be FALSE at the moment (::IsVisible() == FALSE), but here it's not the case. So, the idea is simply to check if the window is already visible, and if so - don't make it foreground. Here's a patch: diff -r 19f95dbe30b8 src/windows/native/sun/windows/awt_Frame.cpp --- a/src/windows/native/sun/windows/awt_Frame.cpp Tue Sep 08 11:53:13 2015 -0500 +++ b/src/windows/native/sun/windows/awt_Frame.cpp Thu Nov 12 11:07:08 2015 +0300 @@ -484,7 +484,10 @@ if (fgProcessID != ::GetCurrentProcessId()) { AwtWindow* window = (AwtWindow*)GetComponent(GetHWnd()); - if (window != NULL && window->IsFocusableWindow() && window->IsAutoRequestFocus() && + if (window != NULL && + window->IsFocusableWindow() && + window->IsAutoRequestFocus() && + !::IsWindowVisible(GetHWnd()) && // the window is really showing !::IsWindow(GetModalBlocker(GetHWnd()))) { // When the Java process is not allowed to set the foreground window [*] https://msdn.microsoft.com/en-us/library/windows/desktop/ms632645(v=vs.85).aspx
12-11-2015

Closing this as incomplete since we haven't received additional required information to proceed. If we receive any update in future, may reopen the report.
26-10-2015

JI Team to ask filer if the issue reproduces with JDK 9. https://jdk9.java.net/download/ Also need stand-alone/isolated reproducer, since the test case suggested doesn't appear to be straight forward.
08-10-2015