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   @author    anton.tarasov: area=awt.focus
30   @library /java/awt/patchlib     ../../regtesthelpers
31   @build java.desktop/java.awt.Helper
32   @build      Util
33   @run       main AutoRequestFocusToFrontTest
34 */
35 
36 import java.awt.*;
37 import java.awt.event.*;
38 import java.applet.Applet;
39 import java.util.concurrent.atomic.AtomicBoolean;
40 import java.lang.reflect.InvocationTargetException;
41 import test.java.awt.regtesthelpers.Util;
42 
43 public class AutoRequestFocusToFrontTest extends Applet {
44     static boolean haveDelays;
45 
46     static Frame auxFrame;
47     static Frame frame;
48     static Button frameButton;
49     static Frame frame2;
50     static Button frameButton2;
51     static Frame frame3;
52     static Button frameButton3;
53     static Window window;
54     static Button winButton;
55     static Dialog dialog;
56     static Button dlgButton;
57     static Window ownedWindow;
58     static Button ownWinButton;
59     static Dialog ownedDialog;
60     static Button ownDlgButton;
61     static Dialog modalDialog;
62     static Button modalDlgButton;
63 
64     static String toolkitClassName;
65     static Robot robot = Util.createRobot();
66 
main(String[] args)67     public static void main(String[] args) {
68 
69         if (args.length != 0) {
70             haveDelays = "delay".equals(args[0]) ? true : false;
71         }
72 
73         AutoRequestFocusToFrontTest app = new AutoRequestFocusToFrontTest();
74         app.init();
75         app.start();
76     }
77 
init()78     public void init() {
79         // Create instructions for the user here, as well as set up
80         // the environment -- set the layout manager, add buttons,
81         // etc.
82         this.setLayout (new BorderLayout ());
83         toolkitClassName = Toolkit.getDefaultToolkit().getClass().getName();
84     }
85 
recreateGUI()86     static void recreateGUI() {
87         if (auxFrame != null) {
88             auxFrame.dispose();
89             frame.dispose();
90             frame2.dispose();
91             frame3.dispose();
92             window.dispose();
93             dialog.dispose();
94             ownedWindow.dispose();
95             ownedDialog.dispose();
96             modalDialog.dispose();
97         }
98 
99         auxFrame = new Frame("Auxiliary Frame");
100 
101         frame = new Frame("Test Frame");
102         frameButton = new Button("button");
103 
104         frame2 = new Frame("Test Frame 2");
105         frameButton2 = new Button("button");
106 
107         frame3 = new Frame("Test Frame 3");
108         frameButton3 = new Button("button");
109 
110         window = new Window(null);
111         winButton = new Button("button");
112         dialog = new Dialog((Frame)null, "Test Dialog");
113         dlgButton = new Button("button");
114 
115         ownedWindow = new Window(frame);
116         ownWinButton = new Button("button");
117 
118         ownedDialog = new Dialog(frame2, "Test Owned Dialog");
119         ownDlgButton = new Button("button");
120 
121         modalDialog = new Dialog(frame3, "Test Modal Dialog");
122         modalDlgButton = new Button("button");
123 
124         auxFrame.setBounds(100, 100, 300, 300);
125 
126         frame.setBounds(120, 120, 260, 260);
127         frame.add(frameButton);
128 
129         frame2.setBounds(120, 120, 260, 260);
130         frame2.add(frameButton2);
131 
132         frame3.setBounds(120, 120, 260, 260);
133         frame3.add(frameButton3);
134 
135         window.setBounds(120, 120, 260, 260);
136         window.add(winButton);
137 
138         dialog.setBounds(120, 120, 260, 260);
139         dialog.add(dlgButton);
140 
141         ownedWindow.setBounds(140, 140, 220, 220);
142         ownedWindow.add(ownWinButton);
143 
144         ownedDialog.setBounds(140, 140, 220, 220);
145         ownedDialog.add(ownDlgButton);
146 
147         modalDialog.setBounds(140, 140, 220, 220);
148         modalDialog.add(modalDlgButton);
149         modalDialog.setModal(true);
150     }
151 
start()152     public void start() {
153         // 1. Simple Frame.
154         //////////////////
155 
156         recreateGUI();
157         Test.setWindows(frame, null, null);
158         Test.test("Test stage 1 in progress", frameButton);
159 
160 
161         // 2. Ownerless Window.
162         //////////////////////
163 
164         recreateGUI();
165         Test.setWindows(window, null, null);
166         Test.test("Test stage 2 in progress", winButton);
167 
168 
169         // 3. Ownerless Dialog.
170         //////////////////////
171 
172         recreateGUI();
173         Test.setWindows(dialog, null, null);
174         Test.test("Test stage 3 in progress", dlgButton);
175 
176 
177         // 4.1. Owner Frame (with owned Window).
178         ///////////////////////////////////////
179 
180         recreateGUI();
181         Test.setWindows(frame, null, new Window[] {ownedWindow, frame});
182         Test.test("Test stage 4.1 in progress", ownWinButton);
183 
184 
185         // 4.2. Owned Window (with owner Frame).
186         ///////////////////////////////////////
187 
188         recreateGUI();
189         Test.setWindows(ownedWindow, null, new Window[] {ownedWindow, frame});
190         Test.test("Test stage 4.2 in progress", ownWinButton);
191 
192 
193         // 5.1. Owner Frame (with owned Dialog).
194         ///////////////////////////////////////
195 
196         recreateGUI();
197         Test.setWindows(frame2, null, new Window[] {ownedDialog, frame2});
198         Test.test("Test stage 5.1 in progress", ownDlgButton);
199 
200 
201         // 5.2. Owned Dialog (with owner Frame).
202         ///////////////////////////////////////
203 
204         recreateGUI();
205         Test.setWindows(ownedDialog, null, new Window[] {ownedDialog, frame2});
206         Test.test("Test stage 5.2 in progress", ownDlgButton);
207 
208 
209         ////////////////////////////////////////////////
210         // 6.1. Owned modal Dialog (with owner Frame).
211         //      Focused frame is excluded from modality.
212         ////////////////////////////////////////////////
213 
214         if (!"sun.awt.motif.MToolkit".equals(toolkitClassName)) {
215             recreateGUI();
216             auxFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
217 
218             Test.setWindows(modalDialog, modalDialog, new Window[] {modalDialog, frame3});
219             Test.test("Test stage 6.1 in progress", modalDlgButton);
220         }
221 
222 
223         // 6.2. Owner Frame (with owned modal Dialog).
224         //      Focused frame is excluded from modality.
225         ////////////////////////////////////////////////
226 
227         if (!"sun.awt.motif.MToolkit".equals(toolkitClassName)) {
228             recreateGUI();
229             auxFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
230 
231             Test.setWindows(frame3, modalDialog, new Window[] {modalDialog, frame3});
232             Test.test("Test stage 6.2 in progress", modalDlgButton, true);
233         }
234 
235         ///////////////////////////////////////////////////
236         // 7. Calling setVisible(true) for the shown Frame.
237         ///////////////////////////////////////////////////
238 
239         recreateGUI();
240         Test.setWindows(frame, null, null);
241         Test.setTestSetVisible();
242         Test.test("Test stage 7 in progress", frameButton);
243 
244 
245         System.out.println("Test passed.");
246     }
247 
248     static class Test {
249         static Window testWindow; // a window to move to front with autoRequestFocus set
250         static Window focusWindow; // a window to gain focus
251         static Window[] showWindows; // windows to show, or null if only testWindow should be shown
252 
253         static boolean testSetVisible;
254 
setWindows(Window _testWindow, Window _focusWindow, Window[] _showWindows)255         static void setWindows(Window _testWindow, Window _focusWindow, Window[] _showWindows) {
256             testWindow = _testWindow;
257             focusWindow = _focusWindow;
258             showWindows = _showWindows;
259         }
setTestSetVisible()260         static void setTestSetVisible() {
261             testSetVisible = true;
262         }
263 
264         /*
265          * @param msg notifies test stage number
266          * @param testButton a button of the window (owner or owned) that is to be on the top of stack order
267          * @param shouldFocusChange true for modal dialogs
268          */
test(String msg, final Button testButton, boolean shouldFocusChange)269         static void test(String msg, final Button testButton, boolean shouldFocusChange) {
270             System.out.println(msg);
271 
272             showWindows(testWindow, showWindows, true);
273 
274             pause(100);
275 
276             /////////////////////////////////////////////////////////
277             // Test that calling toFront() doesn't cause focus change
278             // when 'autoRequestFocus' is false.
279             /////////////////////////////////////////////////////////
280 
281             Runnable action = new Runnable() {
282                     public void run() {
283                         testWindow.setAutoRequestFocus(false);
284                         if (testSetVisible) {
285                             setVisible(testWindow, true);
286                         } else {
287                             toFront(testWindow);
288                         }
289                     }
290                 };
291 
292             if (shouldFocusChange) {
293                 action.run();
294                 Util.waitForIdle(robot);
295                 if (!focusWindow.isFocused()) {
296                     throw new TestFailedException("the window must gain focus on moving to front but it didn't!");
297                 }
298             } else if (TestHelper.trackFocusChangeFor(action, robot)) {
299                 throw new TestFailedException("the window shouldn't gain focus on moving to front but it did!");
300             }
301 
302             pause(100);
303 
304             ///////////////////////////////////////////////////////
305             // Test that the window (or its owned window) is on top.
306             ///////////////////////////////////////////////////////
307 
308             // The latest versions of Metacity (e.g. 2.16) have problems with moving a window to the front.
309             if (Util.getWMID() != Util.METACITY_WM) {
310 
311                 boolean performed = Util.trackActionPerformed(testButton, new Runnable() {
312                         public void run() {
313                             Util.clickOnComp(testButton, robot);
314                         }
315                     }, 1000, false);
316 
317                 if (!performed) {
318                     // For the case when the robot failed to trigger ACTION_EVENT.
319                     System.out.println("(ACTION_EVENT was not generated. One more attemp.)");
320                     performed = Util.trackActionPerformed(testButton, new Runnable() {
321                             public void run() {
322                                 Util.clickOnComp(testButton, robot);
323                             }
324                         }, 1000, false);
325                     if (!performed) {
326                         throw new TestFailedException("the window moved to front is not on the top!");
327                     }
328                 }
329             }
330 
331             showWindows(testWindow, showWindows, false);
332 
333 
334             /////////////////////////////////////////////////
335             // Test that calling toFront() focuses the window
336             // when 'autoRequestFocus' is true.
337             /////////////////////////////////////////////////
338 
339             // Skip this stage for unfocusable window
340             if (!testWindow.isFocusableWindow()) {
341                 return;
342             }
343 
344             showWindows(testWindow, showWindows, true);
345 
346             pause(100);
347 
348             boolean gained = Util.trackWindowGainedFocus(testWindow, new Runnable() {
349                     public void run() {
350                         testWindow.setAutoRequestFocus(true);
351                         if (testSetVisible) {
352                             setVisible(testWindow, true);
353                         } else {
354                             toFront(testWindow);
355                         }
356                     }
357                 }, 1000, false);
358 
359             // Either the window or its owned window must be focused
360             if (!gained && !testButton.hasFocus()) {
361                 throw new TestFailedException("the window should gain focus automatically but it didn't!");
362             }
363 
364             showWindows(testWindow, showWindows, false);
365         }
366 
test(String msg, Button testButton)367         static void test(String msg, Button testButton) {
368             test(msg, testButton, false);
369         }
370 
showWindows(Window win, Window[] wins, final boolean visible)371         private static void showWindows(Window win, Window[] wins, final boolean visible) {
372             pause(100);
373 
374             if (wins == null) {
375                 wins = new Window[] {win}; // operate with 'win'
376             }
377             for (final Window w: wins) {
378                 if (visible) {
379                     if ((w instanceof Dialog) && ((Dialog)w).isModal()) {
380                         TestHelper.invokeLaterAndWait(new Runnable() {
381                                 public void run() {
382                                     w.setVisible(true);
383                                 }
384                             }, robot);
385                     } else {
386                         setVisible(w, true);
387                     }
388                 } else {
389                     w.dispose();
390                 }
391             }
392             setVisible(auxFrame, visible);
393 
394             if (visible) {
395                 if (!auxFrame.isFocused()) {
396                     Util.clickOnTitle(auxFrame, robot);
397                     Util.waitForIdle(robot);
398                     if (!auxFrame.isFocused()) {
399                         throw new Error("Test error: the frame couldn't be focused.");
400                     }
401                 }
402             }
403         }
404     }
405 
setVisible(Window w, boolean b)406     private static void setVisible(Window w, boolean b) {
407         w.setVisible(b);
408         try {
409             Util.waitForIdle(robot);
410         } catch (RuntimeException rte) { // InfiniteLoop
411             rte.printStackTrace();
412         }
413         robot.delay(200);
414     }
415 
toFront(Window w)416     private static void toFront(Window w) {
417         w.toFront();
418         Util.waitForIdle(robot);
419         robot.delay(200);
420     }
421 
pause(int msec)422     private static void pause(int msec) {
423         if (haveDelays) {
424             robot.delay(msec);
425         }
426     }
427 }
428 
429 class TestFailedException extends RuntimeException {
TestFailedException(String msg)430     TestFailedException(String msg) {
431         super("Test failed: " + msg);
432     }
433 }
434 
435