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
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp Fri Mar 14 20:40:09 2008 +0300
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp Fri Mar 14 22:00:33 2008 +0300
@@ -5425,7 +5425,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/jdk/src/windows/native/sun/windows/awt_Dialog.cpp Fri Mar 14 20:40:09 2008 +0300
+++ b/jdk/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/jdk/src/windows/native/sun/windows/awt_Window.cpp Fri Mar 14 20:40:09 2008 +0300
+++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp Fri Mar 14 22:00:33 2008 +0300
@@ -180,7 +180,6 @@
}
::RemoveProp(GetHWnd(), ModalBlockerProp);
- ::RemoveProp(GetHWnd(), ModalSaveWSEXProp);
if (m_grabbedWindow == this) {
Ungrab();
@@ -1455,20 +1454,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/jdk/src/windows/native/sun/windows/awt_Window.h Fri Mar 14 20:40:09 2008 +0300
+++ b/jdk/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/jdk/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/jdk/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/jdk/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