1 /*
   2  * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25   @test
  26   @key headful
  27   @bug       6187066
  28   @summary   Tests the Window.autoRequestFocus property for the Window.toFront() method.
  29   @library /java/awt/patchlib     ../../regtesthelpers
  30   @build java.desktop/java.awt.Helper
  31   @build      Util
  32   @run       main AutoRequestFocusToFrontTest
  33 */
  34 
  35 import java.awt.*;
  36 import test.java.awt.regtesthelpers.Util;
  37 
  38 public class AutoRequestFocusToFrontTest {
  39     static boolean haveDelays;
  40 
  41     static Frame auxFrame;
  42     static Frame frame;
  43     static Button frameButton;
  44     static Frame frame2;
  45     static Button frameButton2;
  46     static Frame frame3;
  47     static Button frameButton3;
  48     static Window window;
  49     static Button winButton;
  50     static Dialog dialog;
  51     static Button dlgButton;
  52     static Window ownedWindow;
  53     static Button ownWinButton;
  54     static Dialog ownedDialog;
  55     static Button ownDlgButton;
  56     static Dialog modalDialog;
  57     static Button modalDlgButton;
  58 
  59     static String toolkitClassName;
  60     static Robot robot = Util.createRobot();
  61 
  62     public static void main(String[] args) {
  63 
  64         if (args.length != 0) {
  65             haveDelays = "delay".equals(args[0]) ? true : false;
  66         }
  67 
  68         AutoRequestFocusToFrontTest app = new AutoRequestFocusToFrontTest();
  69         app.init();
  70         app.start();
  71     }
  72 
  73     public void init() {
  74         toolkitClassName = Toolkit.getDefaultToolkit().getClass().getName();
  75     }
  76 
  77     static void recreateGUI() {
  78         if (auxFrame != null) {
  79             auxFrame.dispose();
  80             frame.dispose();
  81             frame2.dispose();
  82             frame3.dispose();
  83             window.dispose();
  84             dialog.dispose();
  85             ownedWindow.dispose();
  86             ownedDialog.dispose();
  87             modalDialog.dispose();
  88         }
  89 
  90         auxFrame = new Frame("Auxiliary Frame");
  91 
  92         frame = new Frame("Test Frame");
  93         frameButton = new Button("button");
  94 
  95         frame2 = new Frame("Test Frame 2");
  96         frameButton2 = new Button("button");
  97 
  98         frame3 = new Frame("Test Frame 3");
  99         frameButton3 = new Button("button");
 100 
 101         window = new Window(null);
 102         winButton = new Button("button");
 103         dialog = new Dialog((Frame)null, "Test Dialog");
 104         dlgButton = new Button("button");
 105 
 106         ownedWindow = new Window(frame);
 107         ownWinButton = new Button("button");
 108 
 109         ownedDialog = new Dialog(frame2, "Test Owned Dialog");
 110         ownDlgButton = new Button("button");
 111 
 112         modalDialog = new Dialog(frame3, "Test Modal Dialog");
 113         modalDlgButton = new Button("button");
 114 
 115         auxFrame.setBounds(100, 100, 300, 300);
 116 
 117         frame.setBounds(120, 120, 260, 260);
 118         frame.add(frameButton);
 119 
 120         frame2.setBounds(120, 120, 260, 260);
 121         frame2.add(frameButton2);
 122 
 123         frame3.setBounds(120, 120, 260, 260);
 124         frame3.add(frameButton3);
 125 
 126         window.setBounds(120, 120, 260, 260);
 127         window.add(winButton);
 128 
 129         dialog.setBounds(120, 120, 260, 260);
 130         dialog.add(dlgButton);
 131 
 132         ownedWindow.setBounds(140, 140, 220, 220);
 133         ownedWindow.add(ownWinButton);
 134 
 135         ownedDialog.setBounds(140, 140, 220, 220);
 136         ownedDialog.add(ownDlgButton);
 137 
 138         modalDialog.setBounds(140, 140, 220, 220);
 139         modalDialog.add(modalDlgButton);
 140         modalDialog.setModal(true);
 141     }
 142 
 143     public void start() {
 144         // 1. Simple Frame.
 145         //////////////////
 146 
 147         recreateGUI();
 148         Test.setWindows(frame, null, null);
 149         Test.test("Test stage 1 in progress", frameButton);
 150 
 151 
 152         // 2. Ownerless Window.
 153         //////////////////////
 154 
 155         recreateGUI();
 156         Test.setWindows(window, null, null);
 157         Test.test("Test stage 2 in progress", winButton);
 158 
 159 
 160         // 3. Ownerless Dialog.
 161         //////////////////////
 162 
 163         recreateGUI();
 164         Test.setWindows(dialog, null, null);
 165         Test.test("Test stage 3 in progress", dlgButton);
 166 
 167 
 168         // 4.1. Owner Frame (with owned Window).
 169         ///////////////////////////////////////
 170 
 171         recreateGUI();
 172         Test.setWindows(frame, null, new Window[] {ownedWindow, frame});
 173         Test.test("Test stage 4.1 in progress", ownWinButton);
 174 
 175 
 176         // 4.2. Owned Window (with owner Frame).
 177         ///////////////////////////////////////
 178 
 179         recreateGUI();
 180         Test.setWindows(ownedWindow, null, new Window[] {ownedWindow, frame});
 181         Test.test("Test stage 4.2 in progress", ownWinButton);
 182 
 183 
 184         // 5.1. Owner Frame (with owned Dialog).
 185         ///////////////////////////////////////
 186 
 187         recreateGUI();
 188         Test.setWindows(frame2, null, new Window[] {ownedDialog, frame2});
 189         Test.test("Test stage 5.1 in progress", ownDlgButton);
 190 
 191 
 192         // 5.2. Owned Dialog (with owner Frame).
 193         ///////////////////////////////////////
 194 
 195         recreateGUI();
 196         Test.setWindows(ownedDialog, null, new Window[] {ownedDialog, frame2});
 197         Test.test("Test stage 5.2 in progress", ownDlgButton);
 198 
 199 
 200         ////////////////////////////////////////////////
 201         // 6.1. Owned modal Dialog (with owner Frame).
 202         //      Focused frame is excluded from modality.
 203         ////////////////////////////////////////////////
 204 
 205         if (!"sun.awt.motif.MToolkit".equals(toolkitClassName)) {
 206             recreateGUI();
 207             auxFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
 208 
 209             Test.setWindows(modalDialog, modalDialog, new Window[] {modalDialog, frame3});
 210             Test.test("Test stage 6.1 in progress", modalDlgButton);
 211         }
 212 
 213 
 214         // 6.2. Owner Frame (with owned modal Dialog).
 215         //      Focused frame is excluded from modality.
 216         ////////////////////////////////////////////////
 217 
 218         if (!"sun.awt.motif.MToolkit".equals(toolkitClassName)) {
 219             recreateGUI();
 220             auxFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
 221 
 222             Test.setWindows(frame3, modalDialog, new Window[] {modalDialog, frame3});
 223             Test.test("Test stage 6.2 in progress", modalDlgButton, true);
 224         }
 225 
 226         ///////////////////////////////////////////////////
 227         // 7. Calling setVisible(true) for the shown Frame.
 228         ///////////////////////////////////////////////////
 229 
 230         recreateGUI();
 231         Test.setWindows(frame, null, null);
 232         Test.setTestSetVisible();
 233         Test.test("Test stage 7 in progress", frameButton);
 234 
 235 
 236         System.out.println("Test passed.");
 237     }
 238 
 239     static class Test {
 240         static Window testWindow; // a window to move to front with autoRequestFocus set
 241         static Window focusWindow; // a window to gain focus
 242         static Window[] showWindows; // windows to show, or null if only testWindow should be shown
 243 
 244         static boolean testSetVisible;
 245 
 246         static void setWindows(Window _testWindow, Window _focusWindow, Window[] _showWindows) {
 247             testWindow = _testWindow;
 248             focusWindow = _focusWindow;
 249             showWindows = _showWindows;
 250         }
 251         static void setTestSetVisible() {
 252             testSetVisible = true;
 253         }
 254 
 255         /*
 256          * @param msg notifies test stage number
 257          * @param testButton a button of the window (owner or owned) that is to be on the top of stack order
 258          * @param shouldFocusChange true for modal dialogs
 259          */
 260         static void test(String msg, final Button testButton, boolean shouldFocusChange) {
 261             System.out.println(msg);
 262 
 263             showWindows(testWindow, showWindows, true);
 264 
 265             pause(100);
 266 
 267             /////////////////////////////////////////////////////////
 268             // Test that calling toFront() doesn't cause focus change
 269             // when 'autoRequestFocus' is false.
 270             /////////////////////////////////////////////////////////
 271 
 272             Runnable action = new Runnable() {
 273                     public void run() {
 274                         testWindow.setAutoRequestFocus(false);
 275                         if (testSetVisible) {
 276                             setVisible(testWindow, true);
 277                         } else {
 278                             toFront(testWindow);
 279                         }
 280                     }
 281                 };
 282 
 283             if (shouldFocusChange) {
 284                 action.run();
 285                 Util.waitForIdle(robot);
 286                 if (!focusWindow.isFocused()) {
 287                     throw new TestFailedException("the window must gain focus on moving to front but it didn't!");
 288                 }
 289             } else if (TestHelper.trackFocusChangeFor(action, robot)) {
 290                 throw new TestFailedException("the window shouldn't gain focus on moving to front but it did!");
 291             }
 292 
 293             pause(100);
 294 
 295             ///////////////////////////////////////////////////////
 296             // Test that the window (or its owned window) is on top.
 297             ///////////////////////////////////////////////////////
 298 
 299             // The latest versions of Metacity (e.g. 2.16) have problems with moving a window to the front.
 300             if (Util.getWMID() != Util.METACITY_WM) {
 301 
 302                 boolean performed = Util.trackActionPerformed(testButton, new Runnable() {
 303                         public void run() {
 304                             Util.clickOnComp(testButton, robot);
 305                         }
 306                     }, 1000, false);
 307 
 308                 if (!performed) {
 309                     // For the case when the robot failed to trigger ACTION_EVENT.
 310                     System.out.println("(ACTION_EVENT was not generated. One more attemp.)");
 311                     performed = Util.trackActionPerformed(testButton, new Runnable() {
 312                             public void run() {
 313                                 Util.clickOnComp(testButton, robot);
 314                             }
 315                         }, 1000, false);
 316                     if (!performed) {
 317                         throw new TestFailedException("the window moved to front is not on the top!");
 318                     }
 319                 }
 320             }
 321 
 322             showWindows(testWindow, showWindows, false);
 323 
 324 
 325             /////////////////////////////////////////////////
 326             // Test that calling toFront() focuses the window
 327             // when 'autoRequestFocus' is true.
 328             /////////////////////////////////////////////////
 329 
 330             // Skip this stage for unfocusable window
 331             if (!testWindow.isFocusableWindow()) {
 332                 return;
 333             }
 334 
 335             showWindows(testWindow, showWindows, true);
 336 
 337             pause(100);
 338 
 339             boolean gained = Util.trackWindowGainedFocus(testWindow, new Runnable() {
 340                     public void run() {
 341                         testWindow.setAutoRequestFocus(true);
 342                         if (testSetVisible) {
 343                             setVisible(testWindow, true);
 344                         } else {
 345                             toFront(testWindow);
 346                         }
 347                     }
 348                 }, 1000, false);
 349 
 350             // Either the window or its owned window must be focused
 351             if (!gained && !testButton.hasFocus()) {
 352                 throw new TestFailedException("the window should gain focus automatically but it didn't!");
 353             }
 354 
 355             showWindows(testWindow, showWindows, false);
 356         }
 357 
 358         static void test(String msg, Button testButton) {
 359             test(msg, testButton, false);
 360         }
 361 
 362         private static void showWindows(Window win, Window[] wins, final boolean visible) {
 363             pause(100);
 364 
 365             if (wins == null) {
 366                 wins = new Window[] {win}; // operate with 'win'
 367             }
 368             for (final Window w: wins) {
 369                 if (visible) {
 370                     if ((w instanceof Dialog) && ((Dialog)w).isModal()) {
 371                         TestHelper.invokeLaterAndWait(new Runnable() {
 372                                 public void run() {
 373                                     w.setVisible(true);
 374                                 }
 375                             }, robot);
 376                     } else {
 377                         setVisible(w, true);
 378                     }
 379                 } else {
 380                     w.dispose();
 381                 }
 382             }
 383             setVisible(auxFrame, visible);
 384 
 385             if (visible) {
 386                 if (!auxFrame.isFocused()) {
 387                     Util.clickOnTitle(auxFrame, robot);
 388                     Util.waitForIdle(robot);
 389                     if (!auxFrame.isFocused()) {
 390                         throw new Error("Test error: the frame couldn't be focused.");
 391                     }
 392                 }
 393             }
 394         }
 395     }
 396 
 397     private static void setVisible(Window w, boolean b) {
 398         w.setVisible(b);
 399         try {
 400             Util.waitForIdle(robot);
 401         } catch (RuntimeException rte) { // InfiniteLoop
 402             rte.printStackTrace();
 403         }
 404         robot.delay(200);
 405     }
 406 
 407     private static void toFront(Window w) {
 408         w.toFront();
 409         Util.waitForIdle(robot);
 410         robot.delay(200);
 411     }
 412 
 413     private static void pause(int msec) {
 414         if (haveDelays) {
 415             robot.delay(msec);
 416         }
 417     }
 418 }
 419 
 420 class TestFailedException extends RuntimeException {
 421     TestFailedException(String msg) {
 422         super("Test failed: " + msg);
 423     }
 424 }
 425