|
1 | 1 | /* |
2 | | - * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | 4 | * |
5 | 5 | * This code is free software; you can redistribute it and/or modify it |
|
22 | 22 | */ |
23 | 23 |
|
24 | 24 | /* |
25 | | - @test |
26 | | - @key headful |
27 | | - @bug 4737732 |
28 | | - @summary Tests that Toolkit.getScreenInsets() returns correct insets |
29 | | - @author artem.ananiev: area=awt.toplevel |
30 | | - @library ../../regtesthelpers |
31 | | - @build Util |
32 | | - @run main ScreenInsetsTest |
33 | | -*/ |
| 25 | + * @test |
| 26 | + * @key headful |
| 27 | + * @bug 8020443 6899304 4737732 |
| 28 | + * @summary Tests that Toolkit.getScreenInsets() returns correct insets |
| 29 | + * @library /test/lib |
| 30 | + * @build jdk.test.lib.Platform |
| 31 | + * @run main ScreenInsetsTest |
| 32 | + */ |
34 | 33 |
|
35 | 34 | import java.awt.Frame; |
36 | 35 | import java.awt.GraphicsConfiguration; |
|
40 | 39 | import java.awt.Rectangle; |
41 | 40 | import java.awt.Toolkit; |
42 | 41 |
|
43 | | -import test.java.awt.regtesthelpers.Util; |
| 42 | +import jdk.test.lib.Platform; |
44 | 43 |
|
45 | | -public class ScreenInsetsTest |
46 | | -{ |
47 | | - public static void main(String[] args) |
48 | | - { |
49 | | - boolean passed = true; |
| 44 | +public class ScreenInsetsTest { |
| 45 | + private static final int SIZE = 100; |
| 46 | + // Allow a margin tolerance of 1 pixel due to scaling |
| 47 | + private static final int MARGIN_TOLERANCE = 1; |
50 | 48 |
|
| 49 | + public static void main(String[] args) throws InterruptedException { |
51 | 50 | GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); |
52 | 51 | GraphicsDevice[] gds = ge.getScreenDevices(); |
53 | | - for (GraphicsDevice gd : gds) { |
| 52 | + |
| 53 | + for (int screen = 0; screen < gds.length; ++screen) { |
| 54 | + GraphicsDevice gd = gds[screen]; |
54 | 55 | GraphicsConfiguration gc = gd.getDefaultConfiguration(); |
55 | | - Rectangle gcBounds = gc.getBounds(); |
56 | | - Insets gcInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc); |
57 | | - int left = gcInsets.left; |
58 | | - int right = gcInsets.right; |
59 | | - int bottom = gcInsets.bottom; |
60 | | - int top = gcInsets.top; |
61 | | - if (left < 0 || right < 0 || bottom < 0 || top < 0) { |
62 | | - throw new RuntimeException("Negative value: " + gcInsets); |
63 | | - } |
64 | | - int maxW = gcBounds.width / 3; |
65 | | - int maxH = gcBounds.height / 3; |
66 | | - if (left > maxW || right > maxW || bottom > maxH || top > maxH) { |
67 | | - throw new RuntimeException("Big value: " + gcInsets); |
68 | | - } |
| 56 | + Rectangle bounds = gc.getBounds(); |
| 57 | + Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc); |
| 58 | + int workAreaWidth = bounds.width - insets.left - insets.right; |
| 59 | + int workAreaHeight = bounds.height - insets.top - insets.bottom; |
| 60 | + System.out.println("Screen #" + screen); |
| 61 | + System.out.println("Screen Bounds: " + bounds); |
| 62 | + System.out.println("Insets: " + insets); |
| 63 | + |
| 64 | + Frame frame = new Frame(gc); |
| 65 | + frame.setLocation(bounds.x + (bounds.width - SIZE) / 2, |
| 66 | + bounds.y + (bounds.height - SIZE) / 2); |
| 67 | + frame.setSize(SIZE, SIZE); |
69 | 68 |
|
70 | | - if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH)) |
71 | | - { |
72 | | - // this state is used in the test - sorry |
73 | | - continue; |
| 69 | + /* |
| 70 | + * On Windows, undecorated maximized frames are placed over the taskbar. |
| 71 | + * Use a decorated frame instead. |
| 72 | + */ |
| 73 | + if (Platform.isWindows()) { |
| 74 | + frame.setUndecorated(false); |
| 75 | + } else { |
| 76 | + frame.setUndecorated(true); |
74 | 77 | } |
75 | 78 |
|
76 | | - Frame f = new Frame("Test", gc); |
77 | | - f.setUndecorated(true); |
78 | | - f.setBounds(gcBounds.x + 100, gcBounds.y + 100, 320, 240); |
79 | | - f.setVisible(true); |
80 | | - Util.waitForIdle(null); |
| 79 | + frame.setVisible(true); |
81 | 80 |
|
82 | | - f.setExtendedState(Frame.MAXIMIZED_BOTH); |
83 | | - Util.waitForIdle(null); |
| 81 | + // Maximize Frame to reach the struts |
| 82 | + frame.setExtendedState(java.awt.Frame.MAXIMIZED_BOTH); |
| 83 | + Thread.sleep(2000); |
84 | 84 |
|
85 | | - Rectangle fBounds = f.getBounds(); |
86 | | - // workaround: on Windows maximized windows have negative coordinates |
87 | | - if (fBounds.x < gcBounds.x) |
88 | | - { |
89 | | - fBounds.width -= (gcBounds.x - fBounds.x) * 2; // width is decreased |
90 | | - fBounds.x = gcBounds.x; |
| 85 | + Rectangle frameBounds = frame.getBounds(); |
| 86 | + System.out.println("Frame bounds: " + frameBounds); |
| 87 | + |
| 88 | + frame.dispose(); |
| 89 | + |
| 90 | + /* |
| 91 | + * On Windows, the top-left corner of an undecorated maximized frame |
| 92 | + * may have negative coordinates (x, y). |
| 93 | + * Adjust the frame bounds accordingly. |
| 94 | + */ |
| 95 | + if (frameBounds.x < bounds.x) { |
| 96 | + frameBounds.width -= (bounds.x - frameBounds.x) * 2; |
| 97 | + frameBounds.x = bounds.x; |
91 | 98 | } |
92 | | - if (fBounds.y < gcBounds.y) |
93 | | - { |
94 | | - fBounds.height -= (gcBounds.y - fBounds.y) * 2; // height is decreased |
95 | | - fBounds.y = gcBounds.y; |
| 99 | + if (frameBounds.y < bounds.y) { |
| 100 | + frameBounds.height -= (bounds.y - frameBounds.y) * 2; |
| 101 | + frameBounds.y = bounds.y; |
96 | 102 | } |
97 | | - Insets expected = new Insets(fBounds.y - gcBounds.y, |
98 | | - fBounds.x - gcBounds.x, |
99 | | - gcBounds.y + gcBounds.height - fBounds.y - fBounds.height, |
100 | | - gcBounds.x + gcBounds.width - fBounds.x - fBounds.width); |
| 103 | + System.out.println("Adjusted Frame bounds: " + frameBounds); |
101 | 104 |
|
102 | | - // On Windows 10 and up system allows undecorated maximized windows |
103 | | - // to be placed over the taskbar so calculated insets might |
104 | | - // be smaller than reported ones depending on the taskbar position |
105 | | - if (gcInsets.top < expected.top |
106 | | - || gcInsets.bottom < expected.bottom |
107 | | - || gcInsets.left < expected.left |
108 | | - || gcInsets.right < expected.right) |
109 | | - { |
110 | | - passed = false; |
111 | | - System.err.println("Wrong insets for GraphicsConfig: " + gc); |
112 | | - System.err.println("\tExpected: " + expected); |
113 | | - System.err.println("\tActual: " + gcInsets); |
| 105 | + if (bounds.x + insets.left != frameBounds.x |
| 106 | + || bounds.y + insets.top != frameBounds.y |
| 107 | + || Math.abs(workAreaWidth - frameBounds.width) > MARGIN_TOLERANCE |
| 108 | + || Math.abs(workAreaHeight - frameBounds.height) > MARGIN_TOLERANCE) { |
| 109 | + throw new RuntimeException("Test FAILED! Wrong screen #" + |
| 110 | + screen + " insets: " + insets); |
114 | 111 | } |
115 | | - |
116 | | - f.dispose(); |
117 | | - } |
118 | | - |
119 | | - if (!passed) |
120 | | - { |
121 | | - throw new RuntimeException("TEST FAILED: Toolkit.getScreenInsets() returns wrong value for some screens"); |
122 | 112 | } |
| 113 | + System.out.println("Test PASSED!"); |
123 | 114 | } |
124 | 115 | } |
0 commit comments