JDK-6589536 : Application modal dialog displayed over many windows in Linux is very slow
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2007-08-06
  • Updated: 2011-02-16
  • Resolved: 2007-08-07
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_01"
Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Linux gigabyte 2.6.18 i686 GNU/Linux

EXTRA RELEVANT SYSTEM CONFIGURATION :
KDE 3.5.7
Xorg info:
X Window System Version 1.3.0
X Protocol Version 11, Revision 0, Release 1.3

A DESCRIPTION OF THE PROBLEM :
The attached test case enables the user to open 25 JFrames at a time.  Click the exit button and an application modal dialog popus up asking the user if he really wants to exit the application.

In Debian Etch the more JFrames have been opened, the longer the exit dialog takes to pop up (at least 5 seconds for 50 windows).  This problem does not occur in Windows XP.

I ran the application through the NetBeans profiler and the bottleneck begins in sun.awt.X11.XWindowPeer.collectJavaTopLevels().

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached test case in Linux.
Click the "open 25 windows" button 1 or more times.
Click the "exit" button.  The more windows have been opened, the longer the dialog takes to pop up.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When the exit button is clicked, the dialog should pop up immediately regardless of how many windows are opened.
ACTUAL -
The more windows have been opened using the "open 25 windows" button, the longer the exit confirmation dialog takes to pop up.  Windows XP does not exhibit this behavior.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class LinuxModalDialogTest {

    private JDialog exitDialog;
    private JFrame parentFrame = new JFrame("parent frame");
    private int counter = 0;
    
    public LinuxModalDialogTest() {
        initializeExitDialog();
        
        JPanel contentPane = new JPanel(new FlowLayout());
        parentFrame.setContentPane(contentPane);
        
        JButton openButton = new JButton("Open 25 windows");
        contentPane.add(openButton);
        openButton.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                for (int i = 0; i < 25; i++) {
                    JFrame frame = new JFrame("Number " + ++counter);
                    JLabel label = new JLabel("Number " + counter);
                    frame.add(label);
                    frame.pack();
                    frame.setVisible(true);
                }
            }
        });
        
        JButton exitFrameButton = new JButton("Exit");
        contentPane.add(exitFrameButton);
        exitFrameButton.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (exitDialog == null ){
                    initializeExitDialog();
                }
                exitDialog.setSize(500,100);
                exitDialog.setVisible(true);
            }
        });
        
        parentFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        parentFrame.setSize(300,300);
        parentFrame.setVisible(true);
    }
    
    private void initializeExitDialog(){
        exitDialog = new JDialog(parentFrame, "Exit", JDialog.ModalityType.APPLICATION_MODAL);
        JPanel contentPane = new JPanel(new FlowLayout());
        exitDialog.setContentPane(contentPane);
        
        JButton exitDialogButton = new JButton("Click this button to actually exit the application.");
        exitDialogButton.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                System.exit(0);
            }
        });
        contentPane.add(exitDialogButton);
        
        JButton cancelButton = new JButton("Do not exit");
        contentPane.add(cancelButton);
        cancelButton.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                exitDialog.dispose();
                exitDialog = null;
            }
        });
    }
    
    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new LinuxModalDialogTest();
            }
        });
    }
    
}
---------- END SOURCE ----------