JDK-6829546 : Modal dialog causes underlying parent JFrame to be set to "Always on top".
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6u10
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2009-04-13
  • Updated: 2014-10-24
  • Resolved: 2011-03-07
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 7
7 b116Fixed
Description
FULL PRODUCT VERSION :
JRE 6 update 12_b04

ADDITIONAL OS VERSION INFORMATION :
Windows XP PRofessional
Version 2002
Service Pack 3

A DESCRIPTION OF THE PROBLEM :
I'm having issue with the jre 6 update 12 with our Swing application. It works fine with update 11. The issue is that my JFrame is somehow getting set to be "always on top" once I've opened an closed a modal dialog from that JFrame.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Here is the steps:

1) Open a JFrame (note the "alwaysOnTop" is not set to true).
2) Click on a button which will open a modal dialog.
3) While the dialog is open click on the underlying JFrame (nothing happens as modal dialog is blocking it).
4) Now close the dialog and suddenly the parent JFrame is now set to be always on top. This won't happen if I didn't click on the parent JFrame while the dialog was open.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expect the underlying parent JFrame to not be set to be "always on top".
ACTUAL -
The parent JFrame is set to be "always on top"/

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class TestTool {

    /**
     * Main.
     *
     * @param args Input arguments.
     */
    public static void main(String[] args) {
        final JFrame f = new JFrame();
        
        JButton open = new JButton("Open Dialog");
               
        JLabel lb1 = new JLabel(
        		"<html>" +
                "<ul> " +
                "Recreate always on top bug" +
        		"<li>Click on \"Open Dialog\" button</li>" +
        		"<li>Click on parent frame while the dialog is open</li>" +
        		"<li>Close the dialog</li>" +
        		"<li>Frame is now set to be always on top</li>" +
        		"</ul>" +
        		"</html>");
        lb1.setAlignmentX(JLabel.CENTER_ALIGNMENT);
                        
        JPanel bp = new JPanel(new FlowLayout());
        bp.add(open);
        
        Box vBox = Box.createVerticalBox();
        vBox.add(lb1);
        
        open.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                JOptionPane dp = new JOptionPane("Here I am.. ");
                JDialog jdg = dp.createDialog(f, "Dialog");
                jdg.setAlwaysOnTop(true);
                jdg.setLocationRelativeTo(f);
                jdg.setVisible(true);
                
                jdg.dispose();
            }
        });
        
        Container cont = f.getContentPane();
        cont.setLayout(new BorderLayout());
        cont.add(vBox, BorderLayout.CENTER);
        cont.add(bp, BorderLayout.SOUTH);
        SwingUtilities.invokeLater(new Runnable() {
           public void run() {
               f.pack();
               f.setSize(new Dimension(300, 300));
               f.setLocationByPlatform(true);
               f.setVisible(true);
           }
        });
    }

}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
There is no workaround.

Release Regression From : 6u11
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.

Comments
SUGGESTED FIX diff -r 8afd49c55619 src/windows/native/sun/windows/awt_Dialog.cpp --- a/src/windows/native/sun/windows/awt_Dialog.cpp Thu Sep 30 21:06:53 2010 +0400 +++ b/src/windows/native/sun/windows/awt_Dialog.cpp Fri Oct 01 20:00:29 2010 +0400 @@ -304,7 +304,13 @@ UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE; if (isBlocked) { - ::SetWindowPos(dialog, blocker, 0, 0, 0, 0, flags); + BOOL isBlockerTopmost = (::GetWindowLong(blocker, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0; + BOOL isDialogTopmost = (::GetWindowLong(dialog, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0; + if (!isBlockerTopmost || isDialogTopmost) { + ::SetWindowPos(dialog, blocker, 0, 0, 0, 0, flags); + } else { + ::SetWindowPos(dialog, HWND_TOP, 0, 0, 0, 0, flags); + } } else { ::SetWindowPos(dialog, HWND_TOP, 0, 0, 0, 0, flags); // no beep/flash if the mouse was clicked in the taskbar menu
01-10-2010

EVALUATION The problem is caused by the code in awt_Dialog.cpp, in AwtDialog::PopupOneDialog() method which is for example called from ModalFilterProc() and MouseHookProc(): ... if (isBlocked) { * ::SetWindowPos(dialog, blocker, 0, 0, 0, 0, flags); } else { ::SetWindowPos(dialog, HWND_TOP, 0, 0, 0, 0, flags); ... In the line marked with (*) we bring the blocked window to the top and use 'blocker' as hWndInsertAfter parameter for ::SetWindowPos. MSDN says nothing about this case, but I found that if 'blocker' is a top-most window and 'dialog' is not, then calling ::SetWindowPos(dialog, blocker, ...) makes 'dialog' top-most as well.
01-10-2010

EVALUATION I reproduced this bug, assigned to AWT team
23-06-2009