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 
main(String[] args)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 
init()73     public void init() {
74         toolkitClassName = Toolkit.getDefaultToolkit().getClass().getName();
75     }
76 
recreateGUI()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 
start()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 
setWindows(Window _testWindow, Window _focusWindow, Window[] _showWindows)246         static void setWindows(Window _testWindow, Window _focusWindow, Window[] _showWindows) {
247             testWindow = _testWindow;
248             focusWindow = _focusWindow;
249             showWindows = _showWindows;
250         }
setTestSetVisible()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          */
test(String msg, final Button testButton, boolean shouldFocusChange)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 
test(String msg, Button testButton)358         static void test(String msg, Button testButton) {
359             test(msg, testButton, false);
360         }
361 
showWindows(Window win, Window[] wins, final boolean visible)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 
setVisible(Window w, boolean b)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 
toFront(Window w)407     private static void toFront(Window w) {
408         w.toFront();
409         Util.waitForIdle(robot);
410         robot.delay(200);
411     }
412 
pause(int msec)413     private static void pause(int msec) {
414         if (haveDelays) {
415             robot.delay(msec);
416         }
417     }
418 }
419 
420 class TestFailedException extends RuntimeException {
TestFailedException(String msg)421     TestFailedException(String msg) {
422         super("Test failed: " + msg);
423     }
424 }
425 
426