Skip to content

Commit 06c79d4

Browse files
committed
JBR-7919 add tests for Wayland popups
1 parent c50f9ec commit 06c79d4

File tree

7 files changed

+511
-10
lines changed

7 files changed

+511
-10
lines changed

test/jdk/TEST.groups

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,9 @@ jdk_swing_wayland= \
10601060
jb/javax/swing/Popup/WLPopupAsParent.java \
10611061
jb/javax/swing/Popup/WLPopupMinSize.java \
10621062
jb/javax/swing/Popup/WLPopupResize.java \
1063+
jb/javax/swing/Popup/WLPopupLocation.java \
1064+
jb/javax/swing/Popup/WLPopupMoves.java \
1065+
jb/javax/swing/Popup/WLPopupVisibility.java \
10631066
-com/sun/java/swing/plaf/gtk/TestBackSpaceAction.java \
10641067
-com/sun/java/swing/plaf/gtk/TestFileChooserCtrlASelection.java \
10651068
-com/sun/java/swing/plaf/gtk/TestFileChooserSingleDirectorySelection.java \

test/jdk/jb/javax/swing/Popup/WLPopupAsParent.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@
4141
* @key headful
4242
* @modules java.desktop/sun.awt
4343
* @run main WLPopupAsParent
44+
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.0 WLPopupAsParent
45+
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.25 WLPopupAsParent
46+
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.5 WLPopupAsParent
47+
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=2.0 WLPopupAsParent
4448
*/
4549
public class WLPopupAsParent {
4650
private static JFrame frame;
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* Copyright 2024 JetBrains s.r.o.
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+
import javax.swing.*;
25+
import java.awt.*;
26+
27+
import static javax.swing.WindowConstants.EXIT_ON_CLOSE;
28+
29+
/**
30+
* @test
31+
* @summary Verifies that the popup-style window can change it's size and location
32+
* @requires os.family == "linux"
33+
* @key headful
34+
* @modules java.desktop/sun.awt
35+
* @run main/othervm WLPopupLocation
36+
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.0 WLPopupLocation
37+
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.25 WLPopupLocation
38+
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.5 WLPopupLocation
39+
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=2.0 WLPopupLocation
40+
*/
41+
public class WLPopupLocation {
42+
43+
private static JFrame frame;
44+
private static JWindow popup;
45+
46+
private static void createAndShowUI() {
47+
frame = new JFrame("WLPopupLocation Test");
48+
frame.setSize(300, 200);
49+
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
50+
frame.setVisible(true);
51+
}
52+
53+
private static void initPopup() {
54+
JPanel popupContents = new JPanel();
55+
popupContents.add(new JLabel("test popup"));
56+
popup = new JWindow(frame);
57+
popup.setType(Window.Type.POPUP);
58+
sun.awt.AWTAccessor.getWindowAccessor().setPopupParent(popup, frame);
59+
popup.add(popupContents);
60+
}
61+
62+
public static void main(String[] args) throws Exception {
63+
Toolkit toolkit = Toolkit.getDefaultToolkit();
64+
if (!toolkit.getClass().getName().equals("sun.awt.wl.WLToolkit")) {
65+
System.out.println("The test makes sense only for WLToolkit. Exiting...");
66+
return;
67+
}
68+
69+
Robot robot = new Robot();
70+
71+
SwingUtilities.invokeAndWait(WLPopupLocation::createAndShowUI);
72+
pause(robot);
73+
74+
SwingUtilities.invokeAndWait(WLPopupLocation::initPopup);
75+
pause(robot);
76+
77+
int w1 = 150, h1 = 200;
78+
int x1 = 100, y1 = 100;
79+
System.out.printf("Action: locate to (%d, %d), set size (%d, %d)\n", x1, y1, w1, h1);
80+
SwingUtilities.invokeAndWait(() -> {
81+
popup.setVisible(true);
82+
popup.setSize(w1, h1);
83+
popup.setLocation(x1, y1);
84+
});
85+
if (popup.getSize().width != w1 || popup.getSize().height != h1) {
86+
throw new RuntimeException(String.format("Incorrect size (%d, %d), expected (%d, %d)", popup.getSize().width, popup.getSize().height, w1, h1));
87+
}
88+
if (popup.getBounds().x != x1 || popup.getBounds().y != y1) {
89+
throw new RuntimeException(String.format("Wrong location (via getBounds()): (%d, %d). Expected: (%d, %d)", popup.getBounds().x, popup.getBounds().y, x1, y1));
90+
}
91+
pause(robot);
92+
if (popup.getSize().width != h1 || popup.getSize().height != h1) {
93+
throw new RuntimeException(String.format("Incorrect size (%d, %d) after robot's wait for idle, expected (%d, %d)", popup.getSize().width, popup.getSize().height, w1, h1));
94+
}
95+
if (popup.getBounds().x != x1 || popup.getBounds().y != y1) {
96+
throw new RuntimeException(String.format("Wrong location (via getBounds()) after robot's wait for idle: (%d, %d). Expected: (%d, %d)", popup.getBounds().x, popup.getBounds().y, x1, y1));
97+
}
98+
99+
int x2 = 200, y2 = 200;
100+
System.out.printf("Action: set popup size to (%d, %d)\n", x2, y2);
101+
SwingUtilities.invokeAndWait(() -> {
102+
popup.setLocation(x2, y2);
103+
});
104+
if (popup.getSize().width != w1 || popup.getSize().height != h1) {
105+
throw new RuntimeException(String.format("Incorrect size (%d, %d), expected (%d, %d)", popup.getSize().width, popup.getSize().height, w1, h1));
106+
}
107+
if (popup.getBounds().x != x2 || popup.getBounds().y != y2) {
108+
throw new RuntimeException(String.format("Wrong location (via getBounds()): (%d, %d). Expected: (%x, %d)", popup.getBounds().x, popup.getBounds().y, x2, y2));
109+
}
110+
pause(robot);
111+
if (popup.getSize().width != w1 || popup.getSize().height != h1) {
112+
throw new RuntimeException(String.format("Incorrect size (%d, %d) after robot's wait for idle, expected (%d, %d)", popup.getSize().width, popup.getSize().height, w1, h1));
113+
}
114+
if (popup.getBounds().x != x2 || popup.getBounds().y != y2) {
115+
throw new RuntimeException(String.format("Wrong location (via getBounds()) after robot's wait for idle: (%d, %d). Expected: (%d, %d)", popup.getBounds().x, popup.getBounds().y, x2, y2));
116+
}
117+
SwingUtilities.invokeAndWait(frame::dispose);
118+
}
119+
120+
private static void pause(Robot robot) {
121+
robot.waitForIdle();
122+
robot.delay(500);
123+
}
124+
125+
}

test/jdk/jb/javax/swing/Popup/WLPopupMinSize.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@
3838
* @requires os.family == "linux"
3939
* @key headful
4040
* @modules java.desktop/sun.awt
41-
* @run main WLPopupMinSize
41+
* @run main/othervm WLPopupMinSize
42+
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.0 WLPopupMinSize
43+
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.25 WLPopupMinSize
44+
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.5 WLPopupMinSize
45+
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=2.0 WLPopupMinSize
4246
*/
4347
public class WLPopupMinSize {
4448
private static JFrame frame;
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
/*
2+
* Copyright 2024 JetBrains s.r.o.
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+
import javax.swing.*;
25+
import java.awt.*;
26+
import java.awt.geom.AffineTransform;
27+
28+
import static javax.swing.WindowConstants.EXIT_ON_CLOSE;
29+
30+
/**
31+
* @test
32+
* @summary Verifies that the popup-style window can move under Wayland
33+
* @requires os.family == "linux"
34+
* @key headful
35+
* @modules java.desktop/sun.awt
36+
* @run main/othervm WLPopupMoves
37+
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.0 WLPopupMoves
38+
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.25 WLPopupMoves
39+
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.5 WLPopupMoves
40+
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=2.0 WLPopupMoves
41+
*/
42+
public class WLPopupMoves {
43+
44+
private static JFrame frame;
45+
private static JWindow popup;
46+
47+
private static void createAndShowUI() {
48+
frame = new JFrame("WLPopupMoves Test");
49+
frame.setSize(300, 200);
50+
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
51+
frame.setVisible(true);
52+
}
53+
54+
private static void initPopup() {
55+
JPanel popupContents = new JPanel();
56+
popupContents.add(new JLabel("test popup"));
57+
popup = new JWindow(frame);
58+
popup.setType(Window.Type.POPUP);
59+
sun.awt.AWTAccessor.getWindowAccessor().setPopupParent(popup, frame);
60+
popup.add(popupContents);
61+
}
62+
63+
public static void main(String... args) throws Exception {
64+
Toolkit toolkit = Toolkit.getDefaultToolkit();
65+
if (!toolkit.getClass().getName().equals("sun.awt.wl.WLToolkit")) {
66+
System.out.println("The test makes sense only for WLToolkit. Exiting...");
67+
return;
68+
}
69+
70+
Robot robot = new Robot();
71+
72+
SwingUtilities.invokeAndWait(WLPopupMoves::createAndShowUI);
73+
pause(robot);
74+
75+
SwingUtilities.invokeAndWait(WLPopupMoves::initPopup);
76+
pause(robot);
77+
78+
double uiScale = getUiScale();
79+
System.out.printf("UI scale: %.2f.\n", uiScale);
80+
int pixelThreshold = uiScale == 1.0 ? 0 : (int) Math.ceil(uiScale);
81+
System.out.printf("Pixel threshold for verifications: %d\n", pixelThreshold);
82+
83+
int w = 120, h = 200;
84+
System.out.println("Set popup to (50, 50)");
85+
SwingUtilities.invokeAndWait(() -> {
86+
popup.setBounds(50, 50, w, h);
87+
popup.setVisible(true);
88+
});
89+
verifyBounds("Popup position after setting to (50, 50)\n", 50, 50, w, h, pixelThreshold);
90+
pause(robot);
91+
verifyBounds("Popup position (50, 50) after robot's pause\n", 50, 50, w, h, pixelThreshold);
92+
93+
System.out.println("Set popup to (100, 100)");
94+
SwingUtilities.invokeAndWait(() -> {
95+
popup.setBounds(100, 100, w, h);
96+
});
97+
verifyBounds("Popup position after setting to (100, 100)\n", 100, 100, w, h, pixelThreshold);
98+
pause(robot);
99+
verifyBounds("Popup position (100, 100) after robot's pause\n", 100, 100, w, h, pixelThreshold);
100+
101+
int x1 = (int) (toolkit.getScreenSize().width / (2 * uiScale));
102+
int y1 = (int) (toolkit.getScreenSize().height / (2 * uiScale));
103+
System.out.printf("Set popup to (%d, %d)\n", x1, y1);
104+
SwingUtilities.invokeAndWait(() -> {
105+
popup.setBounds(x1, y1, w, h);
106+
});
107+
verifyBounds(String.format("Popup position after setting to (%d, %d)\n", x1, y1), x1, y1, w, h, pixelThreshold);
108+
pause(robot);
109+
verifyBounds(String.format("Popup position (%d, %d) after robot's pause\n", x1, y1), x1, y1, w, h, pixelThreshold);
110+
111+
int x2 = (int) (toolkit.getScreenSize().width / uiScale - 10 - w);
112+
int y2 = (int) (toolkit.getScreenSize().height / uiScale - 10 - h);
113+
System.out.printf("Set popup to (%d, %d). (to the bottom right corner) \n", x2, y2);
114+
SwingUtilities.invokeAndWait(() -> {
115+
popup.setBounds(x2, y2, w, h);
116+
});
117+
verifyBounds(String.format("Popup position after setting to (%d, %d)\n", x2, y2), x2, y2, w, h, pixelThreshold);
118+
pause(robot);
119+
verifyBounds(String.format("Popup position (%d, %d) after robot's pause\n", x2, y2), x2, y2, w, h, pixelThreshold);
120+
121+
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
122+
GraphicsDevice device = ge.getDefaultScreenDevice();
123+
GraphicsConfiguration gc = device.getDefaultConfiguration();
124+
Insets insets = toolkit.getScreenInsets(gc);
125+
int x3 = (int) (toolkit.getScreenSize().width / uiScale - 10 - insets.right);
126+
int y3 = (int) (toolkit.getScreenSize().height / uiScale - 10 - insets.bottom);
127+
System.out.printf("Set popup to (%d, %d). (to the bottom right corner) \n", x3, y3);
128+
SwingUtilities.invokeAndWait(() -> {
129+
popup.setBounds(x2, y2, w, h);
130+
});
131+
int x3Relocated = x3 - w;
132+
int y3Relocated = y3 - h;
133+
verifyBounds(String.format("Popup position after setting to (%d, %d)\n", x3, y3), x3Relocated, y3Relocated, w, h, pixelThreshold);
134+
pause(robot);
135+
verifyBounds(String.format("Popup position (%d, %d) after robot's pause\n", x3, y3), x3Relocated, y3Relocated, w, h, pixelThreshold);
136+
137+
SwingUtilities.invokeAndWait(frame::dispose);
138+
}
139+
140+
private static Double getUiScale() {
141+
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
142+
GraphicsDevice device = ge.getDefaultScreenDevice();
143+
GraphicsConfiguration gc = device.getDefaultConfiguration();
144+
AffineTransform transform = gc.getDefaultTransform();
145+
double scaleX = transform.getScaleX();
146+
double scaleY = transform.getScaleY();
147+
if (scaleX != scaleY) {
148+
System.out.println("Skip test due to non-uniform display scale");
149+
System.exit(0);
150+
}
151+
return scaleX;
152+
}
153+
154+
private static void verifyBounds(String message, int x, int y, int w, int h, int pixelThreshold) {
155+
Rectangle bounds = popup.getBounds();
156+
System.out.printf("Check %s for bounds: %s\n", message, bounds);
157+
boolean isCorrectPosition = x - pixelThreshold <= bounds.x && bounds.x <= x + pixelThreshold &&
158+
y - pixelThreshold <= bounds.y && bounds.y <= y + pixelThreshold;
159+
if (!isCorrectPosition) {
160+
throw new RuntimeException(String.format("%s has wrong position. Expected: (%d, %d). Actual: (%d, %d)", message, x, y, bounds.x, bounds.y));
161+
}
162+
if (bounds.width != w || bounds.height != h) {
163+
throw new RuntimeException(String.format("%s has wrong size. Expected: (%d, %d). Actual: (%d, %d)", message, w, h, bounds.width, bounds.height));
164+
}
165+
}
166+
167+
private static void pause(Robot robot) {
168+
robot.waitForIdle();
169+
robot.delay(500);
170+
}
171+
}

0 commit comments

Comments
 (0)