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 4980161 7158623 8204860
  28   @summary Setting focusable window state to false makes the maximized frame resizable
  29   @compile UnfocusableMaximizedFrameResizablity.java
  30   @run main UnfocusableMaximizedFrameResizablity
  31 */
  32 
  33 import java.awt.Toolkit;
  34 import java.awt.Frame;
  35 import java.awt.Rectangle;
  36 import java.awt.AWTException;
  37 import java.awt.event.InputEvent;
  38 import java.awt.Robot;
  39 import javax.swing.JFrame;
  40 import javax.swing.SwingUtilities;
  41 
  42 public class UnfocusableMaximizedFrameResizablity {
  43 
  44     private static Frame frame;
  45     private static JFrame jframe;
  46     private static Robot robot;
  47     private static boolean isProgInterruption = false;
  48     private static Thread mainThread = null;
  49     private static int sleepTime = 300000;
  50 
  51     private static void createAndShowFrame() throws Exception {
  52 
  53         //The MAXIMIZED_BOTH state is not supported by the toolkit. Nothing to test.
  54         if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH)) {
  55             return;
  56         }
  57 
  58         //Case 1: Setting frame resizable to true followed by focusable to false
  59         frame = createFrame("Resizable Unfocusable frame");
  60         frame.setResizable(true);
  61         frame.setFocusableWindowState(false);
  62         tryToResizeFrame(frame);
  63 
  64         //Case 2: Setting frame focusable to false followed by resizable to true
  65         frame = createFrame("Unfocusable Resizable frame");
  66         frame.setFocusableWindowState(false);
  67         frame.setResizable(true);
  68         tryToResizeFrame(frame);
  69 
  70         //Case 3: Testing JFrame fullscreen behaviour only on Mac OS
  71         if (System.getProperty("os.name").toLowerCase().startsWith("mac")) {
  72             SwingUtilities.invokeAndWait(new Runnable() {
  73 
  74                 Override
  75                 public void run() {
  76                     jframe = createJFrame("Unfocusable Resizable JFrame");
  77                     jframe.setFocusableWindowState(false);
  78                     jframe.setResizable(true);
  79                     Object prop1 = jframe.getRootPane().getClientProperty("apple.awt.fullscreenable");
  80                     jframe.setVisible(false);
  81                     jframe.setVisible(true);
  82                     Object prop2 = jframe.getRootPane().getClientProperty("apple.awt.fullscreenable");
  83 
  84                     if((prop1 != null && prop2 != null) && (!prop1.equals(prop2))) {
  85                         jframe.dispose();
  86                         cleanup();
  87                         throw new RuntimeException("Non-focusable resizable JFrame is fullscreenable!!");
  88                     }
  89                 }
  90             });
  91         }
  92 
  93         cleanup();
  94     }
  95 
  96     private static JFrame createJFrame(String title) {
  97         JFrame jframe = new JFrame(title);
  98         jframe.setMaximizedBounds(new Rectangle(0, 0, 300, 300));
  99         jframe.setSize(200, 200);
 100         jframe.setVisible(true);
 101         jframe.setExtendedState(Frame.MAXIMIZED_BOTH);
 102 
 103         return jframe;
 104     }
 105 
 106     private static Frame createFrame(String title) {
 107         Frame frame = new Frame(title);
 108         frame.setMaximizedBounds(new Rectangle(0, 0, 300, 300));
 109         frame.setSize(200, 200);
 110         frame.setVisible(true);
 111         frame.setExtendedState(Frame.MAXIMIZED_BOTH);
 112 
 113         return frame;
 114     }
 115 
 116     private static void tryToResizeFrame(Frame frame) {
 117         try {
 118             robot = new Robot();
 119         } catch (AWTException e) {
 120             throw new RuntimeException("Robot creation failed");
 121         }
 122         robot.delay(2000);
 123 
 124         // The initial bounds of the frame
 125         final Rectangle bounds = frame.getBounds();
 126 
 127         // Let's move the mouse pointer to the bottom-right coner of the frame (the "size-grip")
 128         robot.mouseMove(bounds.x + bounds.width - 2, bounds.y + bounds.height - 2);
 129         robot.waitForIdle();
 130 
 131         // ... and start resizing
 132         robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
 133         robot.waitForIdle();
 134         robot.mouseMove(bounds.x + bounds.width + 20, bounds.y + bounds.height + 15);
 135         robot.waitForIdle();
 136 
 137         robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
 138         robot.waitForIdle();
 139 
 140         // The bounds of the frame after the attempt of resizing is made
 141         final Rectangle finalBounds = frame.getBounds();
 142 
 143         if (!finalBounds.equals(bounds)) {
 144             cleanup();
 145             throw new RuntimeException("The maximized unfocusable frame can be resized.");
 146         }
 147 
 148         frame.dispose();
 149     }
 150 
 151     private static void cleanup() {
 152         isProgInterruption = true;
 153         mainThread.interrupt();
 154     }
 155 
 156     public static void main(String args[]) throws Exception {
 157 
 158         mainThread = Thread.currentThread();
 159 
 160         try {
 161             createAndShowFrame();
 162             mainThread.sleep(sleepTime);
 163         } catch (InterruptedException e) {
 164             if (!isProgInterruption) {
 165                 throw e;
 166             }
 167         }
 168 
 169         if (!isProgInterruption) {
 170             throw new RuntimeException("Timed out after " + sleepTime / 1000
 171                     + " seconds");
 172         }
 173     }
 174 }
 175