changeset 518:dd26806bd6df

6578583: Regression: Modality is broken in windows vista home premium from jdk1.7 b02 onwards. Summary: WS_DISABLED style should be used to fix some modality bugs Reviewed-by: art, son
author dcherepanov
date Fri, 14 Mar 2008 22:00:33 +0300
parents 506b35a2f558
children 95ac2f7ddad0
files src/windows/native/sun/windows/awt_Component.cpp src/windows/native/sun/windows/awt_Dialog.cpp src/windows/native/sun/windows/awt_Window.cpp src/windows/native/sun/windows/awt_Window.h test/java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java test/java/awt/Modal/WsDisabledStyle/OverBlocker/OverBlocker.java test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java
diffstat 7 files changed, 1344 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/windows/native/sun/windows/awt_Component.cpp	Wed Jul 06 17:22:25 2011 -0700
+++ b/src/windows/native/sun/windows/awt_Component.cpp	Fri Mar 14 22:00:33 2008 +0300
@@ -5408,7 +5408,13 @@
 void AwtComponent::Enable(BOOL bEnable)
 {
     sm_suppressFocusAndActivation = TRUE;
+
+    if (bEnable && IsTopLevel()) {
+        // we should not enable blocked toplevels
+        bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()));
+    }
     ::EnableWindow(GetHWnd(), bEnable);
+
     sm_suppressFocusAndActivation = FALSE;
     CriticalSection::Lock l(GetLock());
     VerifyState();
--- a/src/windows/native/sun/windows/awt_Dialog.cpp	Wed Jul 06 17:22:25 2011 -0700
+++ b/src/windows/native/sun/windows/awt_Dialog.cpp	Fri Mar 14 22:00:33 2008 +0300
@@ -273,6 +273,10 @@
         {
             HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd));
             HWND topMostBlocker = blocker;
+            HWND prevForegroundWindow = ::GetForegroundWindow();
+            if (::IsWindow(blocker)) {
+                ::BringWindowToTop(hWnd);
+            }
             while (::IsWindow(blocker)) {
                 topMostBlocker = blocker;
                 ::BringWindowToTop(blocker);
@@ -282,7 +286,7 @@
                 // no beep/flash if the mouse was clicked in the taskbar menu
                 // or the dialog is currently inactive
                 if ((::WindowFromPoint(mhs->pt) == hWnd) &&
-                    (::GetForegroundWindow() == topMostBlocker))
+                    (prevForegroundWindow == topMostBlocker))
                 {
                     ::MessageBeep(MB_OK);
                     // some heuristics: 3 times x 64 milliseconds
@@ -292,6 +296,7 @@
                     ::BringWindowToTop(topMostBlocker);
                     ::SetForegroundWindow(topMostBlocker);
                 }
+                return 1;
             }
         }
     }
--- a/src/windows/native/sun/windows/awt_Window.cpp	Wed Jul 06 17:22:25 2011 -0700
+++ b/src/windows/native/sun/windows/awt_Window.cpp	Fri Mar 14 22:00:33 2008 +0300
@@ -185,7 +185,6 @@
     }
 
     ::RemoveProp(GetHWnd(), ModalBlockerProp);
-    ::RemoveProp(GetHWnd(), ModalSaveWSEXProp);
 
     if (m_grabbedWindow == this) {
         Ungrab();
@@ -1467,20 +1466,17 @@
     if (!::IsWindow(window)) {
         return;
     }
-    DWORD exStyle = ::GetWindowLong(window, GWL_EXSTYLE);
+
     if (::IsWindow(blocker)) {
-        // save WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles
-        DWORD saveStyle = exStyle & (AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW);
-        ::SetProp(window, ModalSaveWSEXProp, reinterpret_cast<HANDLE>(saveStyle));
-        ::SetWindowLong(window, GWL_EXSTYLE, (exStyle | AWT_WS_EX_NOACTIVATE) & ~WS_EX_APPWINDOW);
         ::SetProp(window, ModalBlockerProp, reinterpret_cast<HANDLE>(blocker));
+        ::EnableWindow(window, FALSE);
     } else {
-        // restore WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles
-        DWORD saveStyle = reinterpret_cast<DWORD>(::GetProp(window, ModalSaveWSEXProp));
-        ::SetWindowLong(window, GWL_EXSTYLE,
-                        (exStyle & ~(AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW)) | saveStyle);
-        ::RemoveProp(window, ModalSaveWSEXProp);
         ::RemoveProp(window, ModalBlockerProp);
+         AwtComponent *comp = AwtComponent::GetComponent(window);
+         // we don't expect to be called with non-java HWNDs
+         DASSERT(comp && comp->IsTopLevel());
+         // we should not unblock disabled toplevels
+         ::EnableWindow(window, comp->isEnabled());
     }
 }
 
--- a/src/windows/native/sun/windows/awt_Window.h	Wed Jul 06 17:22:25 2011 -0700
+++ b/src/windows/native/sun/windows/awt_Window.h	Fri Mar 14 22:00:33 2008 +0300
@@ -33,7 +33,6 @@
 
 // property name tagging windows disabled by modality
 static LPCTSTR ModalBlockerProp = TEXT("SunAwtModalBlockerProp");
-static LPCTSTR ModalSaveWSEXProp = TEXT("SunAwtModalSaveWSEXProp");
 static LPCTSTR ModalDialogPeerProp = TEXT("SunAwtModalDialogPeerProp");
 
 #ifndef WH_MOUSE_LL
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java	Fri Mar 14 22:00:33 2008 +0300
@@ -0,0 +1,466 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+  @test %I% %E%
+  @bug 4080029
+  @summary Modal Dialog block input to all frame windows not just its parent.
+  @author dmitry.cherepanov: area=awt.modal
+  @run main/manual CloseBlocker
+*/
+
+/**
+ * ManualMainTest.java
+ *
+ * summary: The test opens and closes blocker dialog, the test verifies
+ *          that active window is correct when the dialog is closed.
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class CloseBlocker
+{
+
+    private static void init()
+    {
+        //*** Create instructions for the user here ***
+
+        String[] instructions =
+        {
+            " the test will be run 6 times, to start next test just close all ",
+            " windows of previous; the instructions are the same for all tests: ",
+            " 1) there are two frames (one the frames has 'show modal' button), ",
+            " 2) press the button to show a dialog, ",
+            " 3) close the dialog (an alternative scenario - activate another",
+            "    native window before closing the dialog), ",
+            " 4) the frame with button should become next active window, ",
+            "    if it's true, then the test passed, otherwise, it failed. ",
+            " Press 'pass' button only after all of the 6 tests are completed, ",
+            " the number of the currently executed test is displayed on the ",
+            " output window. "
+        };
+        Sysout.createDialog( );
+        Sysout.printInstructions( instructions );
+
+        test(true, true, false);
+        test(true, true, true);
+        test(false, true, false); // 3rd parameter has no affect for ownerless
+
+        test(true, false, false);
+        test(true, false, true);
+        test(false, false, false); // 3rd parameter has no affect for ownerless
+
+    }//End  init()
+
+    private static final Object obj = new Object();
+    private static int counter = 0;
+
+    /*
+     * The ownerless parameter indicates whether the blocker dialog
+     * has owner. The usual parameter indicates whether the blocker
+     * dialog is a Java dialog (non-native dialog like file dialog).
+     */
+    private static void test(final boolean ownerless, final boolean usual, final boolean initiallyOwnerIsActive) {
+
+        Sysout.print(" * test #" + (++counter) + " is running ... ");
+
+        final Frame active = new Frame();
+        final Frame nonactive = new Frame();
+        Button button = new Button("show modal");
+        button.addActionListener(new ActionListener() {
+               public void actionPerformed(ActionEvent ae) {
+                    Dialog dialog = null;
+                    Frame parent = ownerless ? null : (initiallyOwnerIsActive? active : nonactive);
+                    if (usual) {
+                        dialog = new Dialog(parent, "Sample", true);
+                    } else {
+                        dialog = new FileDialog(parent, "Sample", FileDialog.LOAD);
+                    }
+                    dialog.addWindowListener(new WindowAdapter(){
+                        public void windowClosing(WindowEvent e){
+                                e.getWindow().dispose();
+                        }
+                    });
+                    dialog.setBounds(200, 200, 200, 200);
+                    dialog.setVisible(true);
+                }
+        });
+
+        active.add(button);
+        active.setBounds(200, 400, 200, 200);
+        WindowAdapter adapter = new WindowAdapter(){
+              public void windowClosing(WindowEvent e){
+                    active.dispose();
+                    nonactive.dispose();
+                    synchronized(obj) {
+                        obj.notify();
+                    }
+                }
+             };
+        active.addWindowListener(adapter);
+        active.setVisible(true);
+
+        nonactive.setBounds(400, 400, 200, 200);
+        nonactive.addWindowListener(adapter);
+        nonactive.setVisible(true);
+
+        synchronized(obj) {
+            try{
+                obj.wait();
+            } catch(Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        Sysout.println(" completed. ");
+
+    }
+
+    /*****************************************************
+     * Standard Test Machinery Section
+     * DO NOT modify anything in this section -- it's a
+     * standard chunk of code which has all of the
+     * synchronisation necessary for the test harness.
+     * By keeping it the same in all tests, it is easier
+     * to read and understand someone else's test, as
+     * well as insuring that all tests behave correctly
+     * with the test harness.
+     * There is a section following this for test-defined
+     * classes
+     ******************************************************/
+    private static boolean theTestPassed = false;
+    private static boolean testGeneratedInterrupt = false;
+    private static String failureMessage = "";
+
+    private static Thread mainThread = null;
+
+    private static int sleepTime = 300000;
+
+    public static void main( String args[] ) throws InterruptedException
+    {
+        mainThread = Thread.currentThread();
+        try
+        {
+            init();
+        }
+        catch( TestPassedException e )
+        {
+            //The test passed, so just return from main and harness will
+            // interepret this return as a pass
+            return;
+        }
+        //At this point, neither test passed nor test failed has been
+        // called -- either would have thrown an exception and ended the
+        // test, so we know we have multiple threads.
+
+        //Test involves other threads, so sleep and wait for them to
+        // called pass() or fail()
+        try
+        {
+            Thread.sleep( sleepTime );
+            //Timed out, so fail the test
+            throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+        }
+        catch (InterruptedException e)
+        {
+            if( ! testGeneratedInterrupt ) throw e;
+
+            //reset flag in case hit this code more than once for some reason (just safety)
+            testGeneratedInterrupt = false;
+            if ( theTestPassed == false )
+            {
+                throw new RuntimeException( failureMessage );
+            }
+        }
+
+    }//main
+
+    public static synchronized void setTimeoutTo( int seconds )
+    {
+        sleepTime = seconds * 1000;
+    }
+
+    public static synchronized void pass()
+    {
+        Sysout.println( "The test passed." );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //first check if this is executing in main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //Still in the main thread, so set the flag just for kicks,
+            // and throw a test passed exception which will be caught
+            // and end the test.
+            theTestPassed = true;
+            throw new TestPassedException();
+        }
+        //pass was called from a different thread, so set the flag and interrupt
+        // the main thead.
+        theTestPassed = true;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }//pass()
+
+    public static synchronized void fail()
+    {
+        //test writer didn't specify why test failed, so give generic
+        fail( "it just plain failed! :-)" );
+    }
+
+    public static synchronized void fail( String whyFailed )
+    {
+        Sysout.println( "The test failed: " + whyFailed );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //check if this called from main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //If main thread, fail now 'cause not sleeping
+            throw new RuntimeException( whyFailed );
+        }
+        theTestPassed = false;
+        testGeneratedInterrupt = true;
+        failureMessage = whyFailed;
+        mainThread.interrupt();
+    }//fail()
+
+}// class ManualMainTest
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+   static int newVar = 0;
+
+   public void eventDispatched(AWTEvent e)
+    {
+      //Counting events to see if we get enough
+      eventCount++;
+
+      if( eventCount == 20 )
+       {
+         //got enough events, so pass
+
+         ManualMainTest.pass();
+       }
+      else if( tries == 20 )
+       {
+         //tried too many times without getting enough events so fail
+
+         ManualMainTest.fail();
+       }
+
+    }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+  chunk of code whose purpose is to make user
+  interaction uniform, and thereby make it simpler
+  to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+  for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+  WithInstructions method.  Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+  with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+  as standalone.
+ */
+
+class Sysout
+{
+    private static TestDialog dialog;
+
+    public static void createDialogWithInstructions( String[] instructions )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        dialog.printInstructions( instructions );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+    public static void createDialog( )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        String[] defInstr = { "Instructions will appear here. ", "" } ;
+        dialog.printInstructions( defInstr );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+
+    public static void printInstructions( String[] instructions )
+    {
+        dialog.printInstructions( instructions );
+    }
+
+
+    public static void println( String messageIn )
+    {
+        dialog.displayMessage( messageIn, true );
+    }
+
+    public static void print( String messageIn )
+    {
+        dialog.displayMessage( messageIn, false );
+    }
+
+}// Sysout  class
+
+/**
+  This is part of the standard test machinery.  It provides a place for the
+   test instructions to be displayed, and a place for interactive messages
+   to the user to be displayed.
+  To have the test instructions displayed, see Sysout.
+  To have a message to the user be displayed, see Sysout.
+  Do not call anything in this dialog directly.
+  */
+class TestDialog extends Dialog implements ActionListener
+{
+
+    TextArea instructionsText;
+    TextArea messageText;
+    int maxStringLength = 80;
+    Panel  buttonP = new Panel();
+    Button passB = new Button( "pass" );
+    Button failB = new Button( "fail" );
+
+    //DO NOT call this directly, go through Sysout
+    public TestDialog( Frame frame, String name )
+    {
+        super( frame, name );
+        int scrollBoth = TextArea.SCROLLBARS_BOTH;
+        instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+        add( "North", instructionsText );
+
+        messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+        add("Center", messageText);
+
+        passB = new Button( "pass" );
+        passB.setActionCommand( "pass" );
+        passB.addActionListener( this );
+        buttonP.add( "East", passB );
+
+        failB = new Button( "fail" );
+        failB.setActionCommand( "fail" );
+        failB.addActionListener( this );
+        buttonP.add( "West", failB );
+
+        add( "South", buttonP );
+        pack();
+
+        setVisible(true);
+    }// TestDialog()
+
+    //DO NOT call this directly, go through Sysout
+    public void printInstructions( String[] instructions )
+    {
+        //Clear out any current instructions
+        instructionsText.setText( "" );
+
+        //Go down array of instruction strings
+
+        String printStr, remainingStr;
+        for( int i=0; i < instructions.length; i++ )
+        {
+            //chop up each into pieces maxSringLength long
+            remainingStr = instructions[ i ];
+            while( remainingStr.length() > 0 )
+            {
+                //if longer than max then chop off first max chars to print
+                if( remainingStr.length() >= maxStringLength )
+                {
+                    //Try to chop on a word boundary
+                    int posOfSpace = remainingStr.
+                        lastIndexOf( ' ', maxStringLength - 1 );
+
+                    if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+                    printStr = remainingStr.substring( 0, posOfSpace + 1 );
+                    remainingStr = remainingStr.substring( posOfSpace + 1 );
+                }
+                //else just print
+                else
+                {
+                    printStr = remainingStr;
+                    remainingStr = "";
+                }
+
+                instructionsText.append( printStr + "\n" );
+
+            }// while
+
+        }// for
+
+    }//printInstructions()
+
+    //DO NOT call this directly, go through Sysout
+    public void displayMessage( String messageIn, boolean nextLine )
+    {
+        messageText.append( messageIn + (nextLine? "\n" : "") );
+        System.out.println(messageIn);
+    }
+
+    //catch presses of the passed and failed buttons.
+    //simply call the standard pass() or fail() static methods of
+    //ManualMainTest
+    public void actionPerformed( ActionEvent e )
+    {
+        if( e.getActionCommand() == "pass" )
+        {
+            CloseBlocker.pass();
+        }
+        else
+        {
+            CloseBlocker.fail();
+        }
+    }
+
+}// TestDialog  class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/Modal/WsDisabledStyle/OverBlocker/OverBlocker.java	Fri Mar 14 22:00:33 2008 +0300
@@ -0,0 +1,456 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+  @test %I% %E%
+  @bug 4080029
+  @summary Modal Dialog block input to all frame windows not just its parent.
+  @author dmitry.cherepanov: area=awt.modal
+  @run main/manual OverBlocker
+*/
+
+/**
+ * OverBlocker.java
+ *
+ * summary: The test verifies that if user tries to activate the blocked dialog
+ *          then the blocker dialog appears over the other windows
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class OverBlocker
+{
+
+    private static void init()
+    {
+        //*** Create instructions for the user here ***
+
+        String[] instructions =
+        {
+            " the test will be run 4 times, to start next test just close all ",
+            " windows of previous; the instructions are the same for all tests: ",
+            " 1) there is a frame with 'show modal' button, ",
+            " 2) press the button to show a dialog, ",
+            " 3) activate any non-Java application, move the app over the dialog, ",
+            " 4) click on the frame by mouse, ",
+            " 5) make sure that the dialog comes up from the application and ",
+            "    now the dialog overlaps the app as well as the frame, ",
+            "    if it's true, then the test passed, otherwise, it failed. ",
+            " Press 'pass' button only after all of the 4 tests are completed, ",
+            " the number of the currently executed test is displayed on the ",
+            " output window. "
+        };
+        Sysout.createDialog( );
+        Sysout.printInstructions( instructions );
+
+        test(false, true);
+        test(true, true);
+        test(true, false);
+        test(false, false);
+
+    }//End  init()
+
+    private static final Object obj = new Object();
+    private static int counter = 0;
+
+    /*
+     * The ownerless parameter indicates whether the blocker dialog
+     * has owner. The usual parameter indicates whether the blocker
+     * dialog is a Java dialog (non-native dialog like file dialog).
+     */
+    private static void test(final boolean ownerless, final boolean usual) {
+
+        Sysout.print(" * test #" + (++counter) + " is running ... ");
+
+        final Frame frame = new Frame();
+        Button button = new Button("show modal");
+        button.addActionListener(new ActionListener() {
+              public void actionPerformed(ActionEvent ae) {
+                    Dialog dialog = null;
+                    Frame parent = ownerless ? null : frame;
+                    if (usual) {
+                        dialog = new Dialog(parent, "Sample", true);
+                    } else {
+                        dialog = new FileDialog(parent, "Sample", FileDialog.LOAD);
+                    }
+                    dialog.addWindowListener(new WindowAdapter(){
+                            public void windowClosing(WindowEvent e){
+                                e.getWindow().dispose();
+                            }
+                       });
+                    dialog.setBounds(200, 200, 200, 200);
+                    dialog.setVisible(true);
+                }
+            });
+        frame.add(button);
+        frame.setBounds(400, 400, 200, 200);
+        frame.addWindowListener(new WindowAdapter(){
+              public void windowClosing(WindowEvent e){
+                    e.getWindow().dispose();
+                    synchronized(obj) {
+                        obj.notify();
+                    }
+                }
+             });
+        frame.setVisible(true);
+
+        synchronized(obj) {
+            try{
+                obj.wait();
+            } catch(Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        Sysout.println(" completed. ");
+
+    }
+
+    /*****************************************************
+     * Standard Test Machinery Section
+     * DO NOT modify anything in this section -- it's a
+     * standard chunk of code which has all of the
+     * synchronisation necessary for the test harness.
+     * By keeping it the same in all tests, it is easier
+     * to read and understand someone else's test, as
+     * well as insuring that all tests behave correctly
+     * with the test harness.
+     * There is a section following this for test-defined
+     * classes
+     ******************************************************/
+    private static boolean theTestPassed = false;
+    private static boolean testGeneratedInterrupt = false;
+    private static String failureMessage = "";
+
+    private static Thread mainThread = null;
+
+    private static int sleepTime = 300000;
+
+    public static void main( String args[] ) throws InterruptedException
+    {
+        mainThread = Thread.currentThread();
+        try
+        {
+            init();
+        }
+        catch( TestPassedException e )
+        {
+            //The test passed, so just return from main and harness will
+            // interepret this return as a pass
+            return;
+        }
+        //At this point, neither test passed nor test failed has been
+        // called -- either would have thrown an exception and ended the
+        // test, so we know we have multiple threads.
+
+        //Test involves other threads, so sleep and wait for them to
+        // called pass() or fail()
+        try
+        {
+            Thread.sleep( sleepTime );
+            //Timed out, so fail the test
+            throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+        }
+        catch (InterruptedException e)
+        {
+            if( ! testGeneratedInterrupt ) throw e;
+
+            //reset flag in case hit this code more than once for some reason (just safety)
+            testGeneratedInterrupt = false;
+            if ( theTestPassed == false )
+            {
+                throw new RuntimeException( failureMessage );
+            }
+        }
+
+    }//main
+
+    public static synchronized void setTimeoutTo( int seconds )
+    {
+        sleepTime = seconds * 1000;
+    }
+
+    public static synchronized void pass()
+    {
+        Sysout.println( "The test passed." );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //first check if this is executing in main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //Still in the main thread, so set the flag just for kicks,
+            // and throw a test passed exception which will be caught
+            // and end the test.
+            theTestPassed = true;
+            throw new TestPassedException();
+        }
+        //pass was called from a different thread, so set the flag and interrupt
+        // the main thead.
+        theTestPassed = true;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }//pass()
+
+    public static synchronized void fail()
+    {
+        //test writer didn't specify why test failed, so give generic
+        fail( "it just plain failed! :-)" );
+    }
+
+    public static synchronized void fail( String whyFailed )
+    {
+        Sysout.println( "The test failed: " + whyFailed );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //check if this called from main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //If main thread, fail now 'cause not sleeping
+            throw new RuntimeException( whyFailed );
+        }
+        theTestPassed = false;
+        testGeneratedInterrupt = true;
+        failureMessage = whyFailed;
+        mainThread.interrupt();
+    }//fail()
+
+}// class ManualMainTest
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+   static int newVar = 0;
+
+   public void eventDispatched(AWTEvent e)
+    {
+      //Counting events to see if we get enough
+      eventCount++;
+
+      if( eventCount == 20 )
+       {
+         //got enough events, so pass
+
+         ManualMainTest.pass();
+       }
+      else if( tries == 20 )
+       {
+         //tried too many times without getting enough events so fail
+
+         ManualMainTest.fail();
+       }
+
+    }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+  chunk of code whose purpose is to make user
+  interaction uniform, and thereby make it simpler
+  to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+  for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+  WithInstructions method.  Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+  with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+  as standalone.
+ */
+
+class Sysout
+{
+    private static TestDialog dialog;
+
+    public static void createDialogWithInstructions( String[] instructions )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        dialog.printInstructions( instructions );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+    public static void createDialog( )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        String[] defInstr = { "Instructions will appear here. ", "" } ;
+        dialog.printInstructions( defInstr );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+
+    public static void printInstructions( String[] instructions )
+    {
+        dialog.printInstructions( instructions );
+    }
+
+
+    public static void println( String messageIn )
+    {
+        dialog.displayMessage( messageIn, true );
+    }
+
+    public static void print( String messageIn )
+    {
+        dialog.displayMessage( messageIn, false );
+    }
+
+}// Sysout  class
+
+/**
+  This is part of the standard test machinery.  It provides a place for the
+   test instructions to be displayed, and a place for interactive messages
+   to the user to be displayed.
+  To have the test instructions displayed, see Sysout.
+  To have a message to the user be displayed, see Sysout.
+  Do not call anything in this dialog directly.
+  */
+class TestDialog extends Dialog implements ActionListener
+{
+
+    TextArea instructionsText;
+    TextArea messageText;
+    int maxStringLength = 80;
+    Panel  buttonP = new Panel();
+    Button passB = new Button( "pass" );
+    Button failB = new Button( "fail" );
+
+    //DO NOT call this directly, go through Sysout
+    public TestDialog( Frame frame, String name )
+    {
+        super( frame, name );
+        int scrollBoth = TextArea.SCROLLBARS_BOTH;
+        instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+        add( "North", instructionsText );
+
+        messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+        add("Center", messageText);
+
+        passB = new Button( "pass" );
+        passB.setActionCommand( "pass" );
+        passB.addActionListener( this );
+        buttonP.add( "East", passB );
+
+        failB = new Button( "fail" );
+        failB.setActionCommand( "fail" );
+        failB.addActionListener( this );
+        buttonP.add( "West", failB );
+
+        add( "South", buttonP );
+        pack();
+
+        setVisible(true);
+    }// TestDialog()
+
+    //DO NOT call this directly, go through Sysout
+    public void printInstructions( String[] instructions )
+    {
+        //Clear out any current instructions
+        instructionsText.setText( "" );
+
+        //Go down array of instruction strings
+
+        String printStr, remainingStr;
+        for( int i=0; i < instructions.length; i++ )
+        {
+            //chop up each into pieces maxSringLength long
+            remainingStr = instructions[ i ];
+            while( remainingStr.length() > 0 )
+            {
+                //if longer than max then chop off first max chars to print
+                if( remainingStr.length() >= maxStringLength )
+                {
+                    //Try to chop on a word boundary
+                    int posOfSpace = remainingStr.
+                        lastIndexOf( ' ', maxStringLength - 1 );
+
+                    if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+                    printStr = remainingStr.substring( 0, posOfSpace + 1 );
+                    remainingStr = remainingStr.substring( posOfSpace + 1 );
+                }
+                //else just print
+                else
+                {
+                    printStr = remainingStr;
+                    remainingStr = "";
+                }
+
+                instructionsText.append( printStr + "\n" );
+
+            }// while
+
+        }// for
+
+    }//printInstructions()
+
+    //DO NOT call this directly, go through Sysout
+    public void displayMessage( String messageIn, boolean nextLine )
+    {
+        messageText.append( messageIn + (nextLine? "\n" : "") );
+        System.out.println(messageIn);
+    }
+
+    //catch presses of the passed and failed buttons.
+    //simply call the standard pass() or fail() static methods of
+    //ManualMainTest
+    public void actionPerformed( ActionEvent e )
+    {
+        if( e.getActionCommand() == "pass" )
+        {
+            OverBlocker.pass();
+        }
+        else
+        {
+            OverBlocker.fail();
+        }
+    }
+
+}// TestDialog  class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java	Fri Mar 14 22:00:33 2008 +0300
@@ -0,0 +1,403 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+  @test %I% %E%
+  @bug 6572263 6571808
+  @summary  PIT:FileDialog minimized to taskbar(through 'Show Desktop')selecting the fileDialog using windowList
+  @author dmitry.cherepanov: area=awt.modal
+  @run main/manual Winkey
+*/
+
+/**
+ * Winkey.java
+ *
+ * summary: the test verifies that pressing combination of Windows key
+ *          and M key to minimize all windows doesn't break AWT modality
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class Winkey
+{
+
+    private static void init()
+    {
+        //*** Create instructions for the user here ***
+
+        String[] instructions =
+        {
+            " 1. there is a frame with a 'show modal' button, ",
+            " 2. press the button to show a modal dialog, ",
+            " 3. the modal dialog will be shown over the frame, ",
+            " 4. please verify that all (5.1, 5.2.1, 5.2.2) the following tests pass: ",
+            " ",
+            " 5.1. press combination Windows Key and M key to minimize all windows, ",
+            " 5.2. press combination Windows Key and D key to show desktop, ",
+            "      5.2.1. restore the dialog by choosing this one in the ALT-TAB list, ",
+            "      5.2.2. restore the dialog by mouse click on taskbar (on java or any other item)",
+            " ",
+            " 6. make sure that the dialog and the frame are visible, ",
+            "    the bounds of the windows should be the same as before, ",
+            "    if it's true, then the test passed; otherwise, it failed. "
+        };
+        Sysout.createDialog( );
+        Sysout.printInstructions( instructions );
+
+        final Frame frame = new Frame();
+        Button button = new Button("show modal");
+        button.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent ae) {
+                    FileDialog dialog = new FileDialog((Frame)null, "Sample", FileDialog.LOAD);
+                    dialog.setVisible(true);
+                }
+            });
+        frame.add(button);
+        frame.setBounds(400, 400, 200, 200);
+        frame.setVisible(true);
+
+    }//End  init()
+
+    /*****************************************************
+     * Standard Test Machinery Section
+     * DO NOT modify anything in this section -- it's a
+     * standard chunk of code which has all of the
+     * synchronisation necessary for the test harness.
+     * By keeping it the same in all tests, it is easier
+     * to read and understand someone else's test, as
+     * well as insuring that all tests behave correctly
+     * with the test harness.
+     * There is a section following this for test-defined
+     * classes
+     ******************************************************/
+    private static boolean theTestPassed = false;
+    private static boolean testGeneratedInterrupt = false;
+    private static String failureMessage = "";
+
+    private static Thread mainThread = null;
+
+    private static int sleepTime = 300000;
+
+    public static void main( String args[] ) throws InterruptedException
+    {
+        mainThread = Thread.currentThread();
+        try
+        {
+            init();
+        }
+        catch( TestPassedException e )
+        {
+            //The test passed, so just return from main and harness will
+            // interepret this return as a pass
+            return;
+        }
+        //At this point, neither test passed nor test failed has been
+        // called -- either would have thrown an exception and ended the
+        // test, so we know we have multiple threads.
+
+        //Test involves other threads, so sleep and wait for them to
+        // called pass() or fail()
+        try
+        {
+            Thread.sleep( sleepTime );
+            //Timed out, so fail the test
+            throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+        }
+        catch (InterruptedException e)
+        {
+            if( ! testGeneratedInterrupt ) throw e;
+
+            //reset flag in case hit this code more than once for some reason (just safety)
+            testGeneratedInterrupt = false;
+            if ( theTestPassed == false )
+            {
+                throw new RuntimeException( failureMessage );
+            }
+        }
+
+    }//main
+
+    public static synchronized void setTimeoutTo( int seconds )
+    {
+        sleepTime = seconds * 1000;
+    }
+
+    public static synchronized void pass()
+    {
+        Sysout.println( "The test passed." );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //first check if this is executing in main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //Still in the main thread, so set the flag just for kicks,
+            // and throw a test passed exception which will be caught
+            // and end the test.
+            theTestPassed = true;
+            throw new TestPassedException();
+        }
+        //pass was called from a different thread, so set the flag and interrupt
+        // the main thead.
+        theTestPassed = true;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }//pass()
+
+    public static synchronized void fail()
+    {
+        //test writer didn't specify why test failed, so give generic
+        fail( "it just plain failed! :-)" );
+    }
+
+    public static synchronized void fail( String whyFailed )
+    {
+        Sysout.println( "The test failed: " + whyFailed );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //check if this called from main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //If main thread, fail now 'cause not sleeping
+            throw new RuntimeException( whyFailed );
+        }
+        theTestPassed = false;
+        testGeneratedInterrupt = true;
+        failureMessage = whyFailed;
+        mainThread.interrupt();
+    }//fail()
+
+}// class ManualMainTest
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+   static int newVar = 0;
+
+   public void eventDispatched(AWTEvent e)
+    {
+      //Counting events to see if we get enough
+      eventCount++;
+
+      if( eventCount == 20 )
+       {
+         //got enough events, so pass
+
+         ManualMainTest.pass();
+       }
+      else if( tries == 20 )
+       {
+         //tried too many times without getting enough events so fail
+
+         ManualMainTest.fail();
+       }
+
+    }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+  chunk of code whose purpose is to make user
+  interaction uniform, and thereby make it simpler
+  to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+  for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+  WithInstructions method.  Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+  with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+  as standalone.
+ */
+
+class Sysout
+{
+    private static TestDialog dialog;
+
+    public static void createDialogWithInstructions( String[] instructions )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        dialog.printInstructions( instructions );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+    public static void createDialog( )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        String[] defInstr = { "Instructions will appear here. ", "" } ;
+        dialog.printInstructions( defInstr );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+
+    public static void printInstructions( String[] instructions )
+    {
+        dialog.printInstructions( instructions );
+    }
+
+
+    public static void println( String messageIn )
+    {
+        dialog.displayMessage( messageIn );
+    }
+
+}// Sysout  class
+
+/**
+  This is part of the standard test machinery.  It provides a place for the
+   test instructions to be displayed, and a place for interactive messages
+   to the user to be displayed.
+  To have the test instructions displayed, see Sysout.
+  To have a message to the user be displayed, see Sysout.
+  Do not call anything in this dialog directly.
+  */
+class TestDialog extends Dialog implements ActionListener
+{
+
+    TextArea instructionsText;
+    TextArea messageText;
+    int maxStringLength = 80;
+    Panel  buttonP = new Panel();
+    Button passB = new Button( "pass" );
+    Button failB = new Button( "fail" );
+
+    //DO NOT call this directly, go through Sysout
+    public TestDialog( Frame frame, String name )
+    {
+        super( frame, name );
+        int scrollBoth = TextArea.SCROLLBARS_BOTH;
+        instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+        add( "North", instructionsText );
+
+        messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+        add("Center", messageText);
+
+        passB = new Button( "pass" );
+        passB.setActionCommand( "pass" );
+        passB.addActionListener( this );
+        buttonP.add( "East", passB );
+
+        failB = new Button( "fail" );
+        failB.setActionCommand( "fail" );
+        failB.addActionListener( this );
+        buttonP.add( "West", failB );
+
+        add( "South", buttonP );
+        pack();
+
+        setVisible(true);
+    }// TestDialog()
+
+    //DO NOT call this directly, go through Sysout
+    public void printInstructions( String[] instructions )
+    {
+        //Clear out any current instructions
+        instructionsText.setText( "" );
+
+        //Go down array of instruction strings
+
+        String printStr, remainingStr;
+        for( int i=0; i < instructions.length; i++ )
+        {
+            //chop up each into pieces maxSringLength long
+            remainingStr = instructions[ i ];
+            while( remainingStr.length() > 0 )
+            {
+                //if longer than max then chop off first max chars to print
+                if( remainingStr.length() >= maxStringLength )
+                {
+                    //Try to chop on a word boundary
+                    int posOfSpace = remainingStr.
+                        lastIndexOf( ' ', maxStringLength - 1 );
+
+                    if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+                    printStr = remainingStr.substring( 0, posOfSpace + 1 );
+                    remainingStr = remainingStr.substring( posOfSpace + 1 );
+                }
+                //else just print
+                else
+                {
+                    printStr = remainingStr;
+                    remainingStr = "";
+                }
+
+                instructionsText.append( printStr + "\n" );
+
+            }// while
+
+        }// for
+
+    }//printInstructions()
+
+    //DO NOT call this directly, go through Sysout
+    public void displayMessage( String messageIn )
+    {
+        messageText.append( messageIn + "\n" );
+        System.out.println(messageIn);
+    }
+
+    //catch presses of the passed and failed buttons.
+    //simply call the standard pass() or fail() static methods of
+    //ManualMainTest
+    public void actionPerformed( ActionEvent e )
+    {
+        if( e.getActionCommand() == "pass" )
+        {
+            Winkey.pass();
+        }
+        else
+        {
+            Winkey.fail();
+        }
+    }
+
+}// TestDialog  class