Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8276058: Some swing test fails on specific CI macos system #6140

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion test/jdk/ProblemList.txt
Expand Up @@ -192,7 +192,7 @@ java/awt/Toolkit/RealSync/Test.java 6849383 linux-all
java/awt/LightweightComponent/LightweightEventTest/LightweightEventTest.java 8159252 windows-all
java/awt/EventDispatchThread/HandleExceptionOnEDT/HandleExceptionOnEDT.java 8203047 macosx-all
java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.java 8073636 macosx-all
java/awt/FullScreen/FullScreenInsets/FullScreenInsets.java 7019055,8266245 windows-all,linux-all,macosx-aarch64
java/awt/FullScreen/FullScreenInsets/FullScreenInsets.java 7019055,8266245 windows-all,linux-all,macosx-all
java/awt/Focus/8013611/JDK8013611.java 8175366 windows-all,macosx-all
java/awt/Focus/6981400/Test1.java 8029675 windows-all,macosx-all
java/awt/Focus/6981400/Test3.java 8173264 generic-all
Expand Down
Expand Up @@ -46,6 +46,10 @@ public class MakeWindowAlwaysOnTop
private static Frame f;
private static Dialog d;

// move away from cursor
private final static int OFFSET_X = -20;
private final static int OFFSET_Y = -20;

public static void main(String[] args) throws Exception
{
Robot r = Util.createRobot();
Expand Down Expand Up @@ -101,7 +105,7 @@ public static void main(String[] args) throws Exception
Util.waitForIdle(r);


Color c = r.getPixelColor(p.x + f.getWidth() / 2, p.y + f.getHeight() / 2);
Color c = r.getPixelColor(p.x + f.getWidth() / 2 - OFFSET_X, p.y + f.getHeight() / 2 - OFFSET_Y);
System.out.println("Color = " + c);

String exceptionMessage = null;
Expand Down
41 changes: 32 additions & 9 deletions test/jdk/javax/swing/JButton/8151303/PressedIconTest.java
Expand Up @@ -26,7 +26,9 @@
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.InputEvent;
import java.awt.image.BaseMultiResolutionImage;
import java.awt.image.BufferedImage;
Expand Down Expand Up @@ -56,37 +58,56 @@ public class PressedIconTest {
private static volatile double scale = -1;
private static volatile int centerX;
private static volatile int centerY;
private static volatile Point location;
// move away from cursor
private final static int OFFSET_X = -20;
private final static int OFFSET_Y = -20;

public static void main(String[] args) throws Exception {
Robot robot = new Robot();
robot.setAutoDelay(50);
robot.setAutoDelay(100);

SwingUtilities.invokeAndWait(() -> createAndShowGUI());
robot.waitForIdle();
robot.delay(1000);

SwingUtilities.invokeAndWait(() -> {
scale = frame.getGraphicsConfiguration().getDefaultTransform()
.getScaleX();
Point location = frame.getLocation();
location = frame.getLocation();
Dimension size = frame.getSize();
centerX = location.x + size.width / 2;
centerY = location.y + size.height / 2;
});
robot.waitForIdle();

System.out.println("scale " + scale);

robot.mouseMove(centerX, centerY);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.waitForIdle();
Thread.sleep(100);
Color color = robot.getPixelColor(centerX, centerY);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.waitForIdle();
Color color = robot.getPixelColor(centerX - OFFSET_X, centerY - OFFSET_Y);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the problematic pattern is a mouse move to the location from which you subsequently capture a pixel?
I can see how on a compositing window manager that might be an issue as the cursor is part of the window
whereas on old X11 it isn't part of the root window .. but why isn't this ALWAYS an issue on macOS ?

I wonder how many other tests have the same issue ?

And is an offset of 10 enough ? Its a bit arbitrary and cursors could be a larger shape or different orientation ..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robot doesn't capture a cursor, we have a Robot#createScreenCapture spec which clearly says that:

Creates an image containing pixels read from the screen.
This image does not include the mouse cursor.

Both Robot#createScreenCapture and Robot#getPixelColor are using the same CRobot#nativeGetScreenPixels method for getting pixel data.

So the mouse cursor should not affect `Robot#getPixelColor`, this is easy to check on practice
import javax.imageio.ImageIO;
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class CursorTest {
    public static void main(String[] args) throws AWTException, IOException {
        Robot robot = new Robot();

        Frame frame = new Frame();
        frame.setBackground(Color.red);
        frame.setUndecorated(true);

        Rectangle rectangle = new Rectangle(100,100,50,50);
        frame.setBounds(rectangle);
        frame.setVisible(true);

        robot.waitForIdle();
        robot.delay(1000);
        robot.mouseMove(rectangle.x + 5, rectangle.y + 5);
        robot.waitForIdle();

        System.err.println("Moved");
        robot.waitForIdle();
        robot.delay(3000);

        System.err.println("Starting");

        BufferedImage screenCapture = robot.createScreenCapture(rectangle);
        ImageIO.write(screenCapture, "png", new File("/tmp/out.png"));

        for (int i = rectangle.x; i < rectangle.x + rectangle.width; i++) {
            for (int j = rectangle.y; j < rectangle.y + rectangle.height; j++) {
                Color pixelColor = robot.getPixelColor(i, j);
                if (!pixelColor.equals(Color.red)) {
                    System.err.println(pixelColor);
                    frame.dispose();
                    throw new RuntimeException("Unexpected pixel color " + pixelColor);
                }
            }
        }

        System.err.println("Finished");
        frame.dispose();
    }
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok .. yet Prasanta said it did ..
"The png image generated at failure also did not reveal anything abnormal apart from presence of mouse cursor around the same area where the getPixelColor location is pointing to."

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle screen = new Rectangle(0, 0, (int) screenSize.getWidth(), (int) screenSize.getHeight());
BufferedImage img = robot.createScreenCapture(screen);
javax.imageio.ImageIO.write(img, "png", new java.io.File("image.png"));

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we writing the image or any other type of file in the CWD in other tests ?
Shouldn't this use TESTCLASSES or something like that ?

robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);


SwingUtilities.invokeAndWait(() -> frame.dispose());

if ((scale == 1 && !similar(color, COLOR_1X))
|| (scale == 2 && !similar(color, COLOR_2X))) {
throw new RuntimeException("Colors are different!");
if (scale == 1 && !similar(color, COLOR_1X)) {
System.out.println("color " + color + " COLOR_1X " + COLOR_1X);
throw new RuntimeException("Colors is different for scale=1!");
}
if (scale == 2 && !similar(color, COLOR_2X)) {
System.out.println("color " + color + " COLOR_2X " + COLOR_2X);
throw new RuntimeException("Colors is different for scale=2!");
}
System.out.println("Test Passed");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm .. the test tags are

  • @run main/othervm PressedIconTest
  • @run main/othervm -Dsun.java2d.uiScale=2 PressedIconTest

What if the default scale is 2 ?
Or on Windows it could be 1.25 ?
I don't see anything that restricts this test to macOS.

If you are going to explicitly test for 1 and 2 here, shouldn't we explicitly set it ?

And if you aren't then the test here needs to do something based on the actual scale.

}

private static void createAndShowGUI() {
Expand All @@ -108,6 +129,8 @@ private static void createAndShowGUI() {
panel.add(button, BorderLayout.CENTER);

frame.getContentPane().add(panel);
frame.setUndecorated(true);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

Expand Down
38 changes: 31 additions & 7 deletions test/jdk/javax/swing/JInternalFrame/8069348/bug8069348.java
Expand Up @@ -23,9 +23,12 @@

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.event.InputEvent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
Expand All @@ -52,6 +55,10 @@ public class bug8069348 {
private static final Color DESKTOPPANE_COLOR = Color.YELLOW;
private static final Color FRAME_COLOR = Color.ORANGE;

// move away from cursor
private final static int OFFSET_X = -20;
private final static int OFFSET_Y = -20;

private static JFrame frame;
private static JInternalFrame internalFrame;

Expand All @@ -66,7 +73,7 @@ public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(bug8069348::createAndShowGUI);

Robot robot = new Robot();
robot.setAutoDelay(50);
robot.setAutoDelay(100);
robot.waitForIdle();

Rectangle screenBounds = getInternalFrameScreenBounds();
Expand All @@ -79,27 +86,43 @@ public static void main(String[] args) throws Exception {
robot.mouseMove(x, y);
robot.waitForIdle();

robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseMove(x + dx, y + dy);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
robot.waitForIdle();

int cx = screenBounds.x + screenBounds.width + dx / 2;
int cy = screenBounds.y + screenBounds.height + dy / 2;

robot.mouseMove(cx, cy);
if (!FRAME_COLOR.equals(robot.getPixelColor(cx, cy))) {
robot.waitForIdle();
Color color = robot.getPixelColor(cx - OFFSET_X, cy - OFFSET_Y);

if (!FRAME_COLOR.equals(color)) {
System.out.println("cx " + cx + " cy " + cy);
System.err.println("FRAME_COLOR Red: " + FRAME_COLOR.getRed() + "; Green: " + FRAME_COLOR.getGreen() + "; Blue: " + FRAME_COLOR.getBlue());
System.err.println("Pixel color Red: " + color.getRed() + "; Green: " + color.getGreen() + "; Blue: " + color.getBlue());

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle screen = new Rectangle(0, 0, (int) screenSize.getWidth(), (int) screenSize.getHeight());
BufferedImage img = robot.createScreenCapture(screen);
javax.imageio.ImageIO.write(img, "png", new java.io.File("image.png"));

throw new RuntimeException("Internal frame is not correctly dragged!");
}
} finally {
if (frame != null) {
frame.dispose();
}
SwingUtilities.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
System.out.println("Test Passed");
}

private static boolean isSupported() {
String d3d = System.getProperty("sun.java2d.d3d");
System.out.println("d3d " + d3d);
return !Boolean.getBoolean(d3d) || getOSType() == OSType.WINDOWS;
}

Expand Down Expand Up @@ -138,6 +161,7 @@ public void paint(Graphics g) {
panel.add(desktopPane, BorderLayout.CENTER);
frame.add(panel);
frame.setSize(WIN_WIDTH, WIN_HEIGHT);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.requestFocus();
}
Expand Down
Expand Up @@ -37,46 +37,67 @@
import javax.swing.*;
import javax.swing.plaf.synth.*;

public class bug6276188 extends JFrame {
public class bug6276188 {

private static JButton button;
private static Point p;
private static JFrame testFrame;

// move away from cursor
private final static int OFFSET_X = -20;
private final static int OFFSET_Y = -20;

public static void main(String[] args) throws Throwable {
SynthLookAndFeel lookAndFeel = new SynthLookAndFeel();
lookAndFeel.load(bug6276188.class.getResourceAsStream("bug6276188.xml"), bug6276188.class);
try {
Robot robot = new Robot();
robot.setAutoDelay(100);

UIManager.setLookAndFeel(lookAndFeel);
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
JFrame testFrame = new JFrame();
testFrame.setLayout(new BorderLayout());
testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
testFrame.add(BorderLayout.CENTER, button = new JButton());
SynthLookAndFeel lookAndFeel = new SynthLookAndFeel();
lookAndFeel.load(bug6276188.class.getResourceAsStream("bug6276188.xml"), bug6276188.class);
UIManager.setLookAndFeel(lookAndFeel);

testFrame.setSize(new Dimension(320, 200));
testFrame.setVisible(true);
}
});
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
testFrame = new JFrame();
testFrame.setLayout(new BorderLayout());
testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
testFrame.add(BorderLayout.CENTER, button = new JButton());

Robot robot = new Robot();
robot.setAutoDelay(50);
robot.waitForIdle();
robot.delay(200);
testFrame.setSize(new Dimension(320, 200));
testFrame.setLocationRelativeTo(null);
testFrame.setVisible(true);
}
});

p = Util.getCenterPoint(button);
robot.waitForIdle();
robot.delay(1000);

robot.mouseMove(p.x , p.y);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.waitForIdle();
robot.delay(1000);
p = Util.getCenterPoint(button);
System.out.println("Button center point: " + p);

Color color = robot.getPixelColor(p.x, p.y);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
boolean red = color.getRed() > 0 && color.getGreen() == 0 && color.getBlue() == 0;
if (!red) {
System.err.println("Red: " + color.getRed() + "; Green: " + color.getGreen() + "; Blue: " + color.getBlue());
throw new RuntimeException("Synth ButtonUI does not handle PRESSED & MOUSE_OVER state");
robot.mouseMove(p.x , p.y);
robot.waitForIdle();
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.waitForIdle();

Color color = robot.getPixelColor(p.x - OFFSET_X, p.y - OFFSET_y);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
robot.waitForIdle();
boolean red = color.getRed() > 0 && color.getGreen() == 0 && color.getBlue() == 0;
if (!red) {
System.err.println("Red: " + color.getRed() + "; Green: " + color.getGreen() + "; Blue: " + color.getBlue());
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle screen = new Rectangle(0, 0, (int) screenSize.getWidth(), (int) screenSize.getHeight());
BufferedImage img = robot.createScreenCapture(screen);
javax.imageio.ImageIO.write(img, "png", new java.io.File("image.png"));
throw new RuntimeException("Synth ButtonUI does not handle PRESSED & MOUSE_OVER state");
}
} finally {
SwingUtilities.invokeAndWait(() -> {
if (testFrame != null) {
testFrame.dispose();
}
});
}
}
}