8211999: Window positioning bugs due to overlapping GraphicsDevice bounds (Windows/HiDPI)
Reviewed-by: kizune, aivanov
This commit is contained in:
parent
0a41ca6b75
commit
be635258fa
@ -43,6 +43,9 @@ import sun.awt.SunToolkit;
|
||||
import sun.awt.image.SunWritableRaster;
|
||||
import sun.java2d.SunGraphicsEnvironment;
|
||||
|
||||
import static sun.java2d.SunGraphicsEnvironment.toDeviceSpace;
|
||||
import static sun.java2d.SunGraphicsEnvironment.toDeviceSpaceAbs;
|
||||
|
||||
/**
|
||||
* This class is used to generate native system input events
|
||||
* for the purposes of test automation, self-running demos, and
|
||||
@ -385,13 +388,9 @@ public class Robot {
|
||||
*/
|
||||
public synchronized Color getPixelColor(int x, int y) {
|
||||
checkScreenCaptureAllowed();
|
||||
AffineTransform tx = GraphicsEnvironment.
|
||||
getLocalGraphicsEnvironment().getDefaultScreenDevice().
|
||||
getDefaultConfiguration().getDefaultTransform();
|
||||
x = (int) (x * tx.getScaleX());
|
||||
y = (int) (y * tx.getScaleY());
|
||||
Color color = new Color(peer.getRGBPixel(x, y));
|
||||
return color;
|
||||
Point point = peer.useAbsoluteCoordinates() ? toDeviceSpaceAbs(x, y)
|
||||
: toDeviceSpace(x, y);
|
||||
return new Color(peer.getRGBPixel(point.x, point.y));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -523,17 +522,16 @@ public class Robot {
|
||||
imageArray[0] = highResolutionImage;
|
||||
|
||||
} else {
|
||||
|
||||
int sX = (int) Math.floor(screenRect.x * uiScaleX);
|
||||
int sY = (int) Math.floor(screenRect.y * uiScaleY);
|
||||
int sWidth = (int) Math.ceil(screenRect.width * uiScaleX);
|
||||
int sHeight = (int) Math.ceil(screenRect.height * uiScaleY);
|
||||
int[] temppixels;
|
||||
Rectangle scaledRect = new Rectangle(sX, sY, sWidth, sHeight);
|
||||
temppixels = peer.getRGBPixels(scaledRect);
|
||||
|
||||
Rectangle scaledRect;
|
||||
if (peer.useAbsoluteCoordinates()) {
|
||||
scaledRect = toDeviceSpaceAbs(gc, screenRect.x,
|
||||
screenRect.y, screenRect.width, screenRect.height);
|
||||
} else {
|
||||
scaledRect = toDeviceSpace(gc, screenRect.x,
|
||||
screenRect.y, screenRect.width, screenRect.height);
|
||||
}
|
||||
// HighResolutionImage
|
||||
pixels = temppixels;
|
||||
pixels = peer.getRGBPixels(scaledRect);
|
||||
buffer = new DataBufferInt(pixels, pixels.length);
|
||||
raster = Raster.createPackedRaster(buffer, scaledRect.width,
|
||||
scaledRect.height, scaledRect.width, bandmasks, null);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -117,4 +117,14 @@ public interface RobotPeer
|
||||
* @see Robot#createScreenCapture(Rectangle)
|
||||
*/
|
||||
int[] getRGBPixels(Rectangle bounds);
|
||||
|
||||
/**
|
||||
* Determines if absolute coordinates should be used by this peer.
|
||||
*
|
||||
* @return {@code true} if absolute coordinates should be used,
|
||||
* {@code false} otherwise
|
||||
*/
|
||||
default boolean useAbsoluteCoordinates() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ package sun.java2d;
|
||||
|
||||
import java.awt.AWTError;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
@ -348,54 +349,125 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounds of the graphics configuration in device space.
|
||||
*
|
||||
* @param config the graphics configuration which bounds are requested
|
||||
* @return the bounds of the area covered by this
|
||||
* {@code GraphicsConfiguration} in device space (pixels)
|
||||
*/
|
||||
public static Rectangle getGCDeviceBounds(GraphicsConfiguration config) {
|
||||
AffineTransform tx = config.getDefaultTransform();
|
||||
Rectangle bounds = config.getBounds();
|
||||
bounds.width *= tx.getScaleX();
|
||||
bounds.height *= tx.getScaleY();
|
||||
return bounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the size (w, h) from the device space to the user's space using
|
||||
* passed graphics configuration.
|
||||
*
|
||||
* @param gc the graphics configuration to be used for transformation
|
||||
* @param w the width in the device space
|
||||
* @param h the height in the device space
|
||||
* @return the size in the user's space
|
||||
*/
|
||||
public static Dimension toUserSpace(GraphicsConfiguration gc,
|
||||
int w, int h) {
|
||||
AffineTransform tx = gc.getDefaultTransform();
|
||||
return new Dimension(
|
||||
Region.clipRound(w / tx.getScaleX()),
|
||||
Region.clipRound(h / tx.getScaleY())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts absolute coordinates from the user's space to the device space
|
||||
* using appropriate device transformation.
|
||||
*
|
||||
* @param x absolute coordinate in the user's space
|
||||
* @param y absolute coordinate in the user's space
|
||||
* @return the point which uses device space (pixels)
|
||||
*/
|
||||
public static Point toDeviceSpaceAbs(int x, int y) {
|
||||
GraphicsConfiguration gc = getLocalGraphicsEnvironment()
|
||||
.getDefaultScreenDevice().getDefaultConfiguration();
|
||||
gc = getGraphicsConfigurationAtPoint(gc, x, y);
|
||||
return toDeviceSpaceAbs(gc, x, y, 0, 0).getLocation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the rectangle from the user's space to the device space using
|
||||
* appropriate device transformation.
|
||||
*
|
||||
* @param rect the rectangle in the user's space
|
||||
* @return the rectangle which uses device space (pixels)
|
||||
*/
|
||||
public static Rectangle toDeviceSpaceAbs(Rectangle rect) {
|
||||
GraphicsConfiguration gc = getLocalGraphicsEnvironment()
|
||||
.getDefaultScreenDevice().getDefaultConfiguration();
|
||||
gc = getGraphicsConfigurationAtPoint(gc, rect.x, rect.y);
|
||||
return toDeviceSpaceAbs(gc, rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts absolute coordinates (x, y) and the size (w, h) from the user's
|
||||
* space to the device space using passed graphics configuration.
|
||||
*
|
||||
* @param gc the graphics configuration to be used for transformation
|
||||
* @param x absolute coordinate in the user's space
|
||||
* @param y absolute coordinate in the user's space
|
||||
* @param w the width in the user's space
|
||||
* @param h the height in the user's space
|
||||
* @return the rectangle which uses device space (pixels)
|
||||
*/
|
||||
public static Rectangle toDeviceSpaceAbs(GraphicsConfiguration gc,
|
||||
int x, int y, int w, int h) {
|
||||
AffineTransform tx = gc.getDefaultTransform();
|
||||
Rectangle screen = gc.getBounds();
|
||||
return new Rectangle(
|
||||
screen.x + Region.clipRound((x - screen.x) * tx.getScaleX()),
|
||||
screen.y + Region.clipRound((y - screen.y) * tx.getScaleY()),
|
||||
Region.clipRound(w * tx.getScaleX()),
|
||||
Region.clipRound(h * tx.getScaleY())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts coordinates from the user's space to the device space using
|
||||
* appropriate device transformation.
|
||||
*
|
||||
* @param x coordinate in the user space
|
||||
* @param y coordinate in the user space
|
||||
* @return the point which uses device space(pixels)
|
||||
* @param x coordinate in the user's space
|
||||
* @param y coordinate in the user's space
|
||||
* @return the point which uses device space (pixels)
|
||||
*/
|
||||
public static Point convertToDeviceSpace(double x, double y) {
|
||||
GraphicsConfiguration gc = getLocalGraphicsEnvironment()
|
||||
.getDefaultScreenDevice().getDefaultConfiguration();
|
||||
gc = getGraphicsConfigurationAtPoint(gc, x, y);
|
||||
|
||||
AffineTransform tx = gc.getDefaultTransform();
|
||||
x = Region.clipRound(x * tx.getScaleX());
|
||||
y = Region.clipRound(y * tx.getScaleY());
|
||||
return new Point((int) x, (int) y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts bounds from the user's space to the device space using
|
||||
* appropriate device transformation.
|
||||
*
|
||||
* @param bounds the rectangle in the user space
|
||||
* @return the rectangle which uses device space(pixels)
|
||||
*/
|
||||
public static Rectangle convertToDeviceSpace(Rectangle bounds) {
|
||||
public static Point toDeviceSpace(int x, int y) {
|
||||
GraphicsConfiguration gc = getLocalGraphicsEnvironment()
|
||||
.getDefaultScreenDevice().getDefaultConfiguration();
|
||||
gc = getGraphicsConfigurationAtPoint(gc, bounds.x, bounds.y);
|
||||
return convertToDeviceSpace(gc, bounds);
|
||||
gc = getGraphicsConfigurationAtPoint(gc, x, y);
|
||||
return toDeviceSpace(gc, x, y, 0, 0).getLocation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts bounds from the user's space to the device space using
|
||||
* appropriate device transformation of the passed graphics configuration.
|
||||
* Converts coordinates (x, y) and the size (w, h) from the user's
|
||||
* space to the device space using passed graphics configuration.
|
||||
*
|
||||
* @param bounds the rectangle in the user space
|
||||
* @return the rectangle which uses device space(pixels)
|
||||
* @param gc the graphics configuration to be used for transformation
|
||||
* @param x coordinate in the user's space
|
||||
* @param y coordinate in the user's space
|
||||
* @param w the width in the user's space
|
||||
* @param h the height in the user's space
|
||||
* @return the rectangle which uses device space (pixels)
|
||||
*/
|
||||
public static Rectangle convertToDeviceSpace(GraphicsConfiguration gc,
|
||||
Rectangle bounds) {
|
||||
public static Rectangle toDeviceSpace(GraphicsConfiguration gc,
|
||||
int x, int y, int w, int h) {
|
||||
AffineTransform tx = gc.getDefaultTransform();
|
||||
return new Rectangle(
|
||||
Region.clipRound(bounds.x * tx.getScaleX()),
|
||||
Region.clipRound(bounds.y * tx.getScaleY()),
|
||||
Region.clipRound(bounds.width * tx.getScaleX()),
|
||||
Region.clipRound(bounds.height * tx.getScaleY())
|
||||
Region.clipRound(x * tx.getScaleX()),
|
||||
Region.clipRound(y * tx.getScaleY()),
|
||||
Region.clipRound(w * tx.getScaleX()),
|
||||
Region.clipRound(h * tx.getScaleY())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -467,7 +467,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
|
||||
// display mode
|
||||
Rectangle screenBounds = getDefaultConfiguration().getBounds();
|
||||
w.setBounds(screenBounds.x, screenBounds.y,
|
||||
dm.getWidth(), dm.getHeight());
|
||||
screenBounds.width, screenBounds.height);
|
||||
// Note: no call to replaceSurfaceData is required here since
|
||||
// replacement will be caused by an upcoming display change event
|
||||
} else {
|
||||
|
@ -533,7 +533,11 @@ public abstract class WComponentPeer extends WObjectPeer
|
||||
|
||||
@Override
|
||||
public boolean updateGraphicsData(GraphicsConfiguration gc) {
|
||||
var old = getGraphicsConfiguration().getDefaultTransform();
|
||||
winGraphicsConfig = (Win32GraphicsConfig)gc;
|
||||
if (gc != null && !old.equals(gc.getDefaultTransform())) {
|
||||
syncBounds(); // the bounds of the peer depend on the DPI
|
||||
}
|
||||
try {
|
||||
replaceSurfaceData();
|
||||
} catch (InvalidPipeException e) {
|
||||
@ -542,6 +546,14 @@ public abstract class WComponentPeer extends WObjectPeer
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that the native peer's coordinates are in sync with the target.
|
||||
*/
|
||||
void syncBounds() {
|
||||
Rectangle r = ((Component) target).getBounds();
|
||||
setBounds(r.x, r.y, r.width, r.height, SET_BOUNDS);
|
||||
}
|
||||
|
||||
//This will return null for Components not yet added to a Container
|
||||
@Override
|
||||
public ColorModel getColorModel() {
|
||||
|
@ -36,6 +36,8 @@ import java.awt.peer.DialogPeer;
|
||||
import sun.awt.AWTAccessor;
|
||||
import sun.awt.im.InputMethodManager;
|
||||
|
||||
import static sun.java2d.SunGraphicsEnvironment.toUserSpace;
|
||||
|
||||
final class WDialogPeer extends WWindowPeer implements DialogPeer {
|
||||
// Toolkit & peer internals
|
||||
|
||||
@ -117,8 +119,8 @@ final class WDialogPeer extends WWindowPeer implements DialogPeer {
|
||||
if (((Dialog)target).isUndecorated()) {
|
||||
return super.getMinimumSize();
|
||||
}
|
||||
return new Dimension(scaleDownX(getSysMinWidth()),
|
||||
scaleDownY(getSysMinHeight()));
|
||||
return toUserSpace(getGraphicsConfiguration(),
|
||||
getSysMinWidth(), getSysMinHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -38,7 +38,9 @@ import sun.awt.AWTAccessor;
|
||||
import sun.awt.im.InputMethodManager;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
import static sun.java2d.SunGraphicsEnvironment.convertToDeviceSpace;
|
||||
import static sun.java2d.SunGraphicsEnvironment.getGCDeviceBounds;
|
||||
import static sun.java2d.SunGraphicsEnvironment.toDeviceSpaceAbs;
|
||||
import static sun.java2d.SunGraphicsEnvironment.toUserSpace;
|
||||
|
||||
class WFramePeer extends WWindowPeer implements FramePeer {
|
||||
|
||||
@ -97,10 +99,9 @@ class WFramePeer extends WWindowPeer implements FramePeer {
|
||||
*/
|
||||
private Rectangle adjustMaximizedBounds(Rectangle bounds) {
|
||||
// All calculations should be done in the device space
|
||||
bounds = convertToDeviceSpace(bounds);
|
||||
|
||||
bounds = toDeviceSpaceAbs(bounds);
|
||||
GraphicsConfiguration gc = getGraphicsConfiguration();
|
||||
Rectangle currentDevBounds = convertToDeviceSpace(gc, gc.getBounds());
|
||||
Rectangle currentDevBounds = getGCDeviceBounds(gc);
|
||||
// Prepare data for WM_GETMINMAXINFO message.
|
||||
// ptMaxPosition should be in coordinate system of the current monitor,
|
||||
// not the main monitor, or monitor on which we maximize the window.
|
||||
@ -148,13 +149,13 @@ class WFramePeer extends WWindowPeer implements FramePeer {
|
||||
|
||||
@Override
|
||||
public final Dimension getMinimumSize() {
|
||||
GraphicsConfiguration gc = getGraphicsConfiguration();
|
||||
Dimension d = new Dimension();
|
||||
if (!((Frame)target).isUndecorated()) {
|
||||
d.setSize(scaleDownX(getSysMinWidth()),
|
||||
scaleDownY(getSysMinHeight()));
|
||||
d.setSize(toUserSpace(gc, getSysMinWidth(), getSysMinHeight()));
|
||||
}
|
||||
if (((Frame)target).getMenuBar() != null) {
|
||||
d.height += scaleDownY(getSysMenuHeight());
|
||||
if (((Frame) target).getMenuBar() != null) {
|
||||
d.height += toUserSpace(gc, 0, getSysMenuHeight()).height;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
@ -29,14 +29,14 @@ import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.peer.RobotPeer;
|
||||
|
||||
import sun.java2d.SunGraphicsEnvironment;
|
||||
import static sun.java2d.SunGraphicsEnvironment.toDeviceSpaceAbs;
|
||||
|
||||
final class WRobotPeer implements RobotPeer {
|
||||
|
||||
public native void mouseMoveImpl(int x, int y);
|
||||
@Override
|
||||
public void mouseMove(int x, int y) {
|
||||
Point point = SunGraphicsEnvironment.convertToDeviceSpace(x, y);
|
||||
Point point = toDeviceSpaceAbs(x, y);
|
||||
mouseMoveImpl(point.x, point.y);
|
||||
}
|
||||
@Override
|
||||
@ -64,5 +64,10 @@ final class WRobotPeer implements RobotPeer {
|
||||
return pixelArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAbsoluteCoordinates() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private native void getRGBPixels(int x, int y, int width, int height, int[] pixelArray);
|
||||
}
|
||||
|
@ -63,10 +63,11 @@ import sun.awt.TimedWindowEvent;
|
||||
import sun.awt.Win32GraphicsConfig;
|
||||
import sun.awt.Win32GraphicsDevice;
|
||||
import sun.awt.Win32GraphicsEnvironment;
|
||||
import sun.java2d.SunGraphicsEnvironment;
|
||||
import sun.java2d.pipe.Region;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
import static sun.java2d.SunGraphicsEnvironment.toUserSpace;
|
||||
|
||||
public class WWindowPeer extends WPanelPeer implements WindowPeer,
|
||||
DisplayChangedListener
|
||||
{
|
||||
@ -108,8 +109,6 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
|
||||
* WindowStateEvent is posted to the EventQueue.
|
||||
*/
|
||||
private WindowListener windowListener;
|
||||
private float scaleX;
|
||||
private float scaleY;
|
||||
|
||||
/**
|
||||
* Initialize JNI field IDs
|
||||
@ -222,8 +221,6 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
|
||||
GraphicsConfiguration gc = getGraphicsConfiguration();
|
||||
Win32GraphicsDevice gd = (Win32GraphicsDevice) gc.getDevice();
|
||||
gd.addDisplayChangedListener(this);
|
||||
scaleX = gd.getDefaultScaleX();
|
||||
scaleY = gd.getDefaultScaleY();
|
||||
|
||||
initActiveWindowsTracking((Window)target);
|
||||
|
||||
@ -310,6 +307,12 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
final void syncBounds() {
|
||||
// Windows will take care of the top-level window/frame/dialog, and
|
||||
// update the location/size when DPI changes.
|
||||
}
|
||||
|
||||
// Synchronize the insets members (here & in helper) with actual window
|
||||
// state.
|
||||
native void updateInsets(Insets i);
|
||||
@ -438,9 +441,10 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
|
||||
minimumSize = ((Component)target).getMinimumSize();
|
||||
}
|
||||
if (minimumSize != null) {
|
||||
int w = Math.max(minimumSize.width, scaleDownX(getSysMinWidth()));
|
||||
int h = Math.max(minimumSize.height, scaleDownY(getSysMinHeight()));
|
||||
setMinSize(w, h);
|
||||
Dimension sysMin = toUserSpace(getGraphicsConfiguration(),
|
||||
getSysMinWidth(), getSysMinHeight());
|
||||
setMinSize(Math.max(minimumSize.width, sysMin.width),
|
||||
Math.max(minimumSize.height, sysMin.height));
|
||||
} else {
|
||||
setMinSize(0, 0);
|
||||
}
|
||||
@ -598,21 +602,6 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
|
||||
|
||||
AWTAccessor.getComponentAccessor().
|
||||
setGraphicsConfiguration((Component)target, winGraphicsConfig);
|
||||
|
||||
checkDPIChange(oldDev, newDev);
|
||||
}
|
||||
|
||||
private void checkDPIChange(Win32GraphicsDevice oldDev,
|
||||
Win32GraphicsDevice newDev) {
|
||||
float newScaleX = newDev.getDefaultScaleX();
|
||||
float newScaleY = newDev.getDefaultScaleY();
|
||||
|
||||
if (scaleX != newScaleX || scaleY != newScaleY) {
|
||||
windowDPIChange(oldDev.getScreen(), scaleX, scaleY,
|
||||
newDev.getScreen(), newScaleX, newScaleY);
|
||||
scaleX = newScaleX;
|
||||
scaleY = newScaleY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -666,77 +655,9 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
|
||||
return true;
|
||||
}
|
||||
|
||||
// These are the peer bounds. They get updated at:
|
||||
// 1. the WWindowPeer.setBounds() method.
|
||||
// 2. the native code (on WM_SIZE/WM_MOVE)
|
||||
private volatile int sysX = 0;
|
||||
private volatile int sysY = 0;
|
||||
private volatile int sysW = 0;
|
||||
private volatile int sysH = 0;
|
||||
|
||||
@Override
|
||||
public native void repositionSecurityWarning();
|
||||
|
||||
@Override
|
||||
public void setBounds(int x, int y, int width, int height, int op) {
|
||||
sysX = x;
|
||||
sysY = y;
|
||||
sysW = width;
|
||||
sysH = height;
|
||||
|
||||
int cx = x + width / 2;
|
||||
int cy = y + height / 2;
|
||||
GraphicsConfiguration current = getGraphicsConfiguration();
|
||||
GraphicsConfiguration other = SunGraphicsEnvironment
|
||||
.getGraphicsConfigurationAtPoint(current, cx, cy);
|
||||
if (!current.equals(other)) {
|
||||
AffineTransform tx = other.getDefaultTransform();
|
||||
double otherScaleX = tx.getScaleX();
|
||||
double otherScaleY = tx.getScaleY();
|
||||
initScales();
|
||||
if (scaleX != otherScaleX || scaleY != otherScaleY) {
|
||||
x = (int) Math.floor(x * otherScaleX / scaleX);
|
||||
y = (int) Math.floor(y * otherScaleY / scaleY);
|
||||
}
|
||||
}
|
||||
|
||||
super.setBounds(x, y, width, height, op);
|
||||
}
|
||||
|
||||
private void initScales() {
|
||||
|
||||
if (scaleX >= 1 && scaleY >= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
GraphicsConfiguration gc = getGraphicsConfiguration();
|
||||
if (gc instanceof Win32GraphicsConfig) {
|
||||
Win32GraphicsDevice gd = ((Win32GraphicsConfig) gc).getDevice();
|
||||
scaleX = gd.getDefaultScaleX();
|
||||
scaleY = gd.getDefaultScaleY();
|
||||
} else {
|
||||
AffineTransform tx = gc.getDefaultTransform();
|
||||
scaleX = (float) tx.getScaleX();
|
||||
scaleY = (float) tx.getScaleY();
|
||||
}
|
||||
}
|
||||
|
||||
final int scaleUpX(int x) {
|
||||
return Region.clipRound(x * scaleX);
|
||||
}
|
||||
|
||||
final int scaleUpY(int y) {
|
||||
return Region.clipRound(y * scaleY);
|
||||
}
|
||||
|
||||
final int scaleDownX(int x) {
|
||||
return Region.clipRound(x / scaleX);
|
||||
}
|
||||
|
||||
final int scaleDownY(int y) {
|
||||
return Region.clipRound(y / scaleY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(Graphics g) {
|
||||
// We assume we print the whole frame,
|
||||
@ -905,9 +826,6 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
|
||||
}
|
||||
}
|
||||
|
||||
native void windowDPIChange(int prevScreen, float prevScaleX, float prevScaleY,
|
||||
int newScreen, float newScaleX, float newScaleY);
|
||||
|
||||
/*
|
||||
* The method maps the list of the active windows to the window's AppContext,
|
||||
* then the method registers ActiveWindowListener, GuiDisposedListener listeners;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -106,8 +106,8 @@ Java_sun_awt_windows_WMouseInfoPeer_fillPointWithCoords(JNIEnv *env, jclass cls,
|
||||
yID = env->GetFieldID(pointClass, "y", "I");
|
||||
CHECK_NULL_RETURN(yID, (jint)0);
|
||||
|
||||
int x = (device == NULL) ? pt.x : device->ScaleDownX(pt.x);
|
||||
int y = (device == NULL) ? pt.y : device->ScaleDownY(pt.y);
|
||||
int x = (device == NULL) ? pt.x : device->ScaleDownAbsX(pt.x);
|
||||
int y = (device == NULL) ? pt.y : device->ScaleDownAbsY(pt.y);
|
||||
|
||||
env->SetIntField(point, xID, x);
|
||||
env->SetIntField(point, yID, y);
|
||||
|
@ -603,7 +603,7 @@ AwtComponent::CreateHWnd(JNIEnv *env, LPCWSTR title,
|
||||
/*
|
||||
* Fix for 4046446.
|
||||
*/
|
||||
SetWindowPos(GetHWnd(), 0, x, y, w, h, SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOACTIVATE);
|
||||
Reshape(x, y, w, h);
|
||||
|
||||
/* Set default colors. */
|
||||
m_colorForeground = colorForeground;
|
||||
@ -1087,6 +1087,7 @@ void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment) {
|
||||
WIN_MSG(WM_DESTROY)
|
||||
WIN_MSG(WM_MOVE)
|
||||
WIN_MSG(WM_SIZE)
|
||||
WIN_MSG(WM_DPICHANGED)
|
||||
WIN_MSG(WM_ACTIVATE)
|
||||
WIN_MSG(WM_SETFOCUS)
|
||||
WIN_MSG(WM_KILLFOCUS)
|
||||
@ -1505,9 +1506,9 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
case WM_SIZE:
|
||||
{
|
||||
RECT r;
|
||||
// fix 4128317 : use GetClientRect for full 32-bit int precision and
|
||||
// fix 4128317 : use GetWindowRect for full 32-bit int precision and
|
||||
// to avoid negative client area dimensions overflowing 16-bit params - robi
|
||||
::GetClientRect( GetHWnd(), &r );
|
||||
::GetWindowRect(GetHWnd(), &r);
|
||||
mr = WmSize(static_cast<UINT>(wParam), r.right - r.left, r.bottom - r.top);
|
||||
//mr = WmSize(wParam, LOWORD(lParam), HIWORD(lParam));
|
||||
SetCompositionWindow(r);
|
||||
@ -3888,8 +3889,8 @@ void AwtComponent::OpenCandidateWindow(int x, int y)
|
||||
}
|
||||
HWND hTop = GetTopLevelParentForWindow(hWnd);
|
||||
::ClientToScreen(hTop, &p);
|
||||
int sx = ScaleUpX(x) - p.x;
|
||||
int sy = ScaleUpY(y) - p.y;
|
||||
int sx = ScaleUpAbsX(x) - p.x;
|
||||
int sy = ScaleUpAbsY(y) - p.y;
|
||||
if (!m_bitsCandType) {
|
||||
SetCandidateWindow(m_bitsCandType, sx, sy);
|
||||
return;
|
||||
@ -4767,34 +4768,71 @@ void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha)
|
||||
}
|
||||
}
|
||||
|
||||
int AwtComponent::GetScreenImOn() {
|
||||
HWND hWindow = GetAncestor(GetHWnd(), GA_ROOT);
|
||||
AwtComponent *comp = AwtComponent::GetComponent(hWindow);
|
||||
if (comp && comp->IsTopLevel()) {
|
||||
return comp->GetScreenImOn();
|
||||
}
|
||||
return AwtWin32GraphicsDevice::DeviceIndexForWindow(hWindow);
|
||||
}
|
||||
|
||||
int AwtComponent::ScaleUpX(int x) {
|
||||
int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
|
||||
int screen = GetScreenImOn();
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
|
||||
return device == NULL ? x : device->ScaleUpX(x);
|
||||
}
|
||||
|
||||
int AwtComponent::ScaleUpAbsX(int x) {
|
||||
int screen = GetScreenImOn();
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
|
||||
return device == NULL ? x : device->ScaleUpAbsX(x);
|
||||
}
|
||||
|
||||
int AwtComponent::ScaleUpY(int y) {
|
||||
int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
|
||||
int screen = GetScreenImOn();
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
|
||||
return device == NULL ? y : device->ScaleUpY(y);
|
||||
}
|
||||
|
||||
int AwtComponent::ScaleUpAbsY(int y) {
|
||||
int screen = GetScreenImOn();
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
|
||||
return device == NULL ? y : device->ScaleUpAbsY(y);
|
||||
}
|
||||
|
||||
int AwtComponent::ScaleDownX(int x) {
|
||||
int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
|
||||
int screen = GetScreenImOn();
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
|
||||
return device == NULL ? x : device->ScaleDownX(x);
|
||||
}
|
||||
|
||||
int AwtComponent::ScaleDownAbsX(int x) {
|
||||
int screen = GetScreenImOn();
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
|
||||
return device == NULL ? x : device->ScaleDownAbsX(x);
|
||||
}
|
||||
|
||||
int AwtComponent::ScaleDownY(int y) {
|
||||
int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
|
||||
int screen = GetScreenImOn();
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
|
||||
return device == NULL ? y : device->ScaleDownY(y);
|
||||
}
|
||||
|
||||
int AwtComponent::ScaleDownAbsY(int y) {
|
||||
int screen = GetScreenImOn();
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
|
||||
return device == NULL ? y : device->ScaleDownAbsY(y);
|
||||
}
|
||||
|
||||
jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size, int alpha) {
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
|
||||
@ -5090,7 +5128,7 @@ void AwtComponent::SendMouseEvent(jint id, jlong when, jint x, jint y,
|
||||
id, when, modifiers,
|
||||
ScaleDownX(x + insets.left),
|
||||
ScaleDownY(y + insets.top),
|
||||
ScaleDownX(xAbs), ScaleDownY(yAbs),
|
||||
ScaleDownAbsX(xAbs), ScaleDownAbsY(yAbs),
|
||||
clickCount, popupTrigger, button);
|
||||
|
||||
if (safe_ExceptionOccurred(env)) {
|
||||
@ -5163,8 +5201,8 @@ AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y,
|
||||
id, when, modifiers,
|
||||
ScaleDownX(x + insets.left),
|
||||
ScaleDownY(y + insets.top),
|
||||
ScaleDownX(xAbs),
|
||||
ScaleDownY(yAbs),
|
||||
ScaleDownAbsX(xAbs),
|
||||
ScaleDownAbsY(yAbs),
|
||||
clickCount, popupTrigger,
|
||||
scrollType, scrollAmount,
|
||||
roundedWheelRotation, preciseWheelRotation);
|
||||
@ -5674,8 +5712,8 @@ jobject AwtComponent::_GetLocationOnScreen(void *param)
|
||||
RECT rect;
|
||||
VERIFY(::GetWindowRect(p->GetHWnd(),&rect));
|
||||
result = JNU_NewObjectByName(env, "java/awt/Point", "(II)V",
|
||||
p->ScaleDownX(rect.left),
|
||||
p->ScaleDownY(rect.top));
|
||||
p->ScaleDownAbsX(rect.left),
|
||||
p->ScaleDownAbsY(rect.top));
|
||||
}
|
||||
ret:
|
||||
env->DeleteGlobalRef(self);
|
||||
|
@ -275,6 +275,7 @@ public:
|
||||
/*
|
||||
* methods on this component
|
||||
*/
|
||||
virtual int GetScreenImOn();
|
||||
virtual void Show();
|
||||
virtual void Hide();
|
||||
virtual void Reshape(int x, int y, int w, int h);
|
||||
@ -755,9 +756,13 @@ protected:
|
||||
virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha);
|
||||
|
||||
int ScaleUpX(int x);
|
||||
int ScaleUpAbsX(int x);
|
||||
int ScaleUpY(int y);
|
||||
int ScaleUpAbsY(int y);
|
||||
int ScaleDownX(int x);
|
||||
int ScaleDownAbsX(int x);
|
||||
int ScaleDownY(int y);
|
||||
int ScaleDownAbsY(int y);
|
||||
|
||||
private:
|
||||
/* A bitmask keeps the button's numbers as MK_LBUTTON, MK_MBUTTON, MK_RBUTTON
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -475,8 +475,8 @@ Java_sun_awt_windows_WGlobalCursorManager_getCursorPos(JNIEnv *env,
|
||||
int screen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(monitor);
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
int x = (device == NULL) ? p.x : device->ScaleDownX(p.x);
|
||||
int y = (device == NULL) ? p.y : device->ScaleDownY(p.y);
|
||||
int x = (device == NULL) ? p.x : device->ScaleDownAbsX(p.x);
|
||||
int y = (device == NULL) ? p.y : device->ScaleDownAbsY(p.y);
|
||||
env->SetIntField(point, AwtCursor::pointXID, x);
|
||||
env->SetIntField(point, AwtCursor::pointYID, y);
|
||||
|
||||
|
@ -1174,14 +1174,14 @@ HRESULT __stdcall AwtDragSource::GetProcessId(FORMATETC __RPC_FAR *pFormatEtc, S
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void ScaleDown(POINT &pt) {
|
||||
static void ScaleDownAbs(POINT &pt) {
|
||||
HMONITOR monitor = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
|
||||
int screen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(monitor);
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
if (device) {
|
||||
pt.x = device->ScaleDownX(pt.x);
|
||||
pt.y = device->ScaleDownY(pt.y);
|
||||
pt.x = device->ScaleDownAbsX(pt.x);
|
||||
pt.y = device->ScaleDownAbsY(pt.y);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1190,7 +1190,7 @@ DECLARE_JAVA_CLASS(dSCClazz, "sun/awt/windows/WDragSourceContextPeer")
|
||||
void
|
||||
AwtDragSource::call_dSCenter(JNIEnv* env, jobject self, jint targetActions,
|
||||
jint modifiers, POINT pt) {
|
||||
ScaleDown(pt);
|
||||
ScaleDownAbs(pt);
|
||||
DECLARE_VOID_JAVA_METHOD(dSCenter, dSCClazz, "dragEnter", "(IIII)V");
|
||||
DASSERT(!JNU_IsNull(env, self));
|
||||
env->CallVoidMethod(self, dSCenter, targetActions, modifiers, pt.x, pt.y);
|
||||
@ -1203,7 +1203,7 @@ AwtDragSource::call_dSCenter(JNIEnv* env, jobject self, jint targetActions,
|
||||
void
|
||||
AwtDragSource::call_dSCmotion(JNIEnv* env, jobject self, jint targetActions,
|
||||
jint modifiers, POINT pt) {
|
||||
ScaleDown(pt);
|
||||
ScaleDownAbs(pt);
|
||||
DECLARE_VOID_JAVA_METHOD(dSCmotion, dSCClazz, "dragMotion", "(IIII)V");
|
||||
DASSERT(!JNU_IsNull(env, self));
|
||||
env->CallVoidMethod(self, dSCmotion, targetActions, modifiers, pt.x, pt.y);
|
||||
@ -1216,7 +1216,7 @@ AwtDragSource::call_dSCmotion(JNIEnv* env, jobject self, jint targetActions,
|
||||
void
|
||||
AwtDragSource::call_dSCchanged(JNIEnv* env, jobject self, jint targetActions,
|
||||
jint modifiers, POINT pt) {
|
||||
ScaleDown(pt);
|
||||
ScaleDownAbs(pt);
|
||||
DECLARE_VOID_JAVA_METHOD(dSCchanged, dSCClazz, "operationChanged",
|
||||
"(IIII)V");
|
||||
DASSERT(!JNU_IsNull(env, self));
|
||||
@ -1229,7 +1229,7 @@ AwtDragSource::call_dSCchanged(JNIEnv* env, jobject self, jint targetActions,
|
||||
|
||||
void
|
||||
AwtDragSource::call_dSCexit(JNIEnv* env, jobject self, POINT pt) {
|
||||
ScaleDown(pt);
|
||||
ScaleDownAbs(pt);
|
||||
DECLARE_VOID_JAVA_METHOD(dSCexit, dSCClazz, "dragExit", "(II)V");
|
||||
DASSERT(!JNU_IsNull(env, self));
|
||||
env->CallVoidMethod(self, dSCexit, pt.x, pt.y);
|
||||
@ -1242,7 +1242,7 @@ AwtDragSource::call_dSCexit(JNIEnv* env, jobject self, POINT pt) {
|
||||
void
|
||||
AwtDragSource::call_dSCddfinished(JNIEnv* env, jobject self, jboolean success,
|
||||
jint operations, POINT pt) {
|
||||
ScaleDown(pt);
|
||||
ScaleDownAbs(pt);
|
||||
DECLARE_VOID_JAVA_METHOD(dSCddfinished, dSCClazz, "dragDropFinished", "(ZIII)V");
|
||||
DASSERT(!JNU_IsNull(env, self));
|
||||
env->CallVoidMethod(self, dSCddfinished, success, operations, pt.x, pt.y);
|
||||
@ -1255,7 +1255,7 @@ AwtDragSource::call_dSCddfinished(JNIEnv* env, jobject self, jboolean success,
|
||||
void
|
||||
AwtDragSource::call_dSCmouseMoved(JNIEnv* env, jobject self, jint targetActions,
|
||||
jint modifiers, POINT pt) {
|
||||
ScaleDown(pt);
|
||||
ScaleDownAbs(pt);
|
||||
DECLARE_VOID_JAVA_METHOD(dSCmouseMoved, dSCClazz, "dragMouseMoved",
|
||||
"(IIII)V");
|
||||
DASSERT(!JNU_IsNull(env, self));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -631,18 +631,18 @@ Java_sun_awt_windows_WFileDialogPeer_toBack(JNIEnv *env, jobject peer)
|
||||
CATCH_BAD_ALLOC;
|
||||
}
|
||||
|
||||
int ScaleDownX(int x, HWND hwnd) {
|
||||
int ScaleDownAbsX(int x, HWND hwnd) {
|
||||
int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(hwnd);
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
|
||||
return device == NULL ? x : device->ScaleDownX(x);
|
||||
return device == NULL ? x : device->ScaleDownAbsX(x);
|
||||
}
|
||||
|
||||
int ScaleDownY(int y, HWND hwnd) {
|
||||
int ScaleDownAbsY(int y, HWND hwnd) {
|
||||
int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(hwnd);
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
|
||||
return device == NULL ? y : device->ScaleDownY(y);
|
||||
return device == NULL ? y : device->ScaleDownAbsY(y);
|
||||
}
|
||||
|
||||
jobject AwtFileDialog::_GetLocationOnScreen(void *param)
|
||||
@ -657,7 +657,8 @@ jobject AwtFileDialog::_GetLocationOnScreen(void *param)
|
||||
RECT rect;
|
||||
VERIFY(::GetWindowRect(hwnd, &rect));
|
||||
result = JNU_NewObjectByName(env, "java/awt/Point", "(II)V",
|
||||
ScaleDownX(rect.left, hwnd), ScaleDownY(rect.top, hwnd));
|
||||
ScaleDownAbsX(rect.left, hwnd),
|
||||
ScaleDownAbsY(rect.top, hwnd));
|
||||
}
|
||||
|
||||
if (result != NULL)
|
||||
|
@ -328,17 +328,13 @@ AwtFrame* AwtFrame::Create(jobject self, jobject parent)
|
||||
frame->CreateHWnd(env, L"",
|
||||
style,
|
||||
exStyle,
|
||||
0, 0, 0, 0,
|
||||
x, y, width, height,
|
||||
hwndParent,
|
||||
NULL,
|
||||
::GetSysColor(COLOR_WINDOWTEXT),
|
||||
::GetSysColor(COLOR_WINDOWFRAME),
|
||||
self);
|
||||
/*
|
||||
* Reshape here instead of during create, so that a
|
||||
* WM_NCCALCSIZE is sent.
|
||||
*/
|
||||
frame->Reshape(x, y, width, height);
|
||||
frame->RecalcNonClient();
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -288,14 +288,17 @@ void AwtList::SetMultiSelect(BOOL ms) {
|
||||
|
||||
UnsubclassHWND();
|
||||
AwtToolkit::DestroyComponentHWND(m_hwnd);
|
||||
CreateHWnd(env, L"", style, exStyle,
|
||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
|
||||
CreateHWnd(env, L"", style, exStyle, 0, 0, 0, 0,
|
||||
parentHWnd,
|
||||
NULL,
|
||||
::GetSysColor(COLOR_WINDOWTEXT),
|
||||
::GetSysColor(COLOR_WINDOW),
|
||||
peer);
|
||||
|
||||
SetWindowPos(GetHWnd(), 0,
|
||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
|
||||
SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOACTIVATE);
|
||||
|
||||
SendListMessage(WM_SETFONT, (WPARAM)font, (LPARAM)FALSE);
|
||||
SendListMessage(LB_SETITEMHEIGHT, 0, MAKELPARAM(itemHeight, 0));
|
||||
SendListMessage(LB_RESETCONTENT);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -99,16 +99,12 @@ JNIEXPORT jobject JNICALL
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
|
||||
if (TRUE == MonitorBounds(AwtWin32GraphicsDevice::GetMonitor(screen), &rRW)) {
|
||||
|
||||
int x = (device == NULL) ? rRW.left : device->ScaleDownX(rRW.left);
|
||||
int y = (device == NULL) ? rRW.top : device->ScaleDownY(rRW.top);
|
||||
int w = (device == NULL) ? rRW.right - rRW.left
|
||||
: device->ScaleDownX(rRW.right - rRW.left);
|
||||
int h = (device == NULL) ? rRW.bottom - rRW.top
|
||||
: device->ScaleDownY(rRW.bottom - rRW.top);
|
||||
|
||||
bounds = env->NewObject(clazz, mid, x, y, w, h);
|
||||
|
||||
bounds = env->NewObject(clazz, mid, rRW.left, rRW.top, w, h);
|
||||
}
|
||||
else {
|
||||
// 4910760 - don't return a null bounds, return the bounds of the
|
||||
|
@ -77,6 +77,7 @@ AwtWin32GraphicsDevice::AwtWin32GraphicsDevice(int screen,
|
||||
this->devicesArray = arr;
|
||||
this->scaleX = 1;
|
||||
this->scaleY = 1;
|
||||
disableScaleAutoRefresh = FALSE;
|
||||
javaDevice = NULL;
|
||||
colorData = new ImgColorData;
|
||||
colorData->grayscale = GS_NOTGRAY;
|
||||
@ -633,21 +634,45 @@ int AwtWin32GraphicsDevice::ScaleUpX(int x)
|
||||
return ClipRound(x * scaleX);
|
||||
}
|
||||
|
||||
int AwtWin32GraphicsDevice::ScaleUpAbsX(int x)
|
||||
{
|
||||
LONG screen = pMonitorInfo->rcMonitor.left;
|
||||
return screen + ClipRound((x - screen) * scaleX);
|
||||
}
|
||||
|
||||
int AwtWin32GraphicsDevice::ScaleUpY(int y)
|
||||
{
|
||||
return ClipRound(y * scaleY);
|
||||
}
|
||||
|
||||
int AwtWin32GraphicsDevice::ScaleUpAbsY(int y)
|
||||
{
|
||||
LONG screen = pMonitorInfo->rcMonitor.top;
|
||||
return screen + ClipRound((y - screen) * scaleY);
|
||||
}
|
||||
|
||||
int AwtWin32GraphicsDevice::ScaleDownX(int x)
|
||||
{
|
||||
return ClipRound(x / scaleX);
|
||||
}
|
||||
|
||||
int AwtWin32GraphicsDevice::ScaleDownAbsX(int x)
|
||||
{
|
||||
LONG screen = pMonitorInfo->rcMonitor.left;
|
||||
return screen + ClipRound((x - screen) / scaleX);
|
||||
}
|
||||
|
||||
int AwtWin32GraphicsDevice::ScaleDownY(int y)
|
||||
{
|
||||
return ClipRound(y / scaleY);
|
||||
}
|
||||
|
||||
int AwtWin32GraphicsDevice::ScaleDownAbsY(int y)
|
||||
{
|
||||
LONG screen = pMonitorInfo->rcMonitor.top;
|
||||
return screen + ClipRound((y - screen) / scaleY);
|
||||
}
|
||||
|
||||
int AwtWin32GraphicsDevice::ClipRound(double value)
|
||||
{
|
||||
value -= 0.5;
|
||||
@ -666,11 +691,13 @@ int AwtWin32GraphicsDevice::ClipRound(double value)
|
||||
|
||||
void AwtWin32GraphicsDevice::InitDesktopScales()
|
||||
{
|
||||
float dpiX = -1.0f;
|
||||
float dpiY = -1.0f;
|
||||
GetScreenDpi(GetMonitor(), &dpiX, &dpiY);
|
||||
if (dpiX > 0 && dpiY > 0) {
|
||||
SetScale(dpiX / 96, dpiY / 96);
|
||||
if (!disableScaleAutoRefresh) {
|
||||
float dpiX = -1.0f;
|
||||
float dpiY = -1.0f;
|
||||
GetScreenDpi(GetMonitor(), &dpiX, &dpiY);
|
||||
if (dpiX > 0 && dpiY > 0) {
|
||||
SetScale(dpiX / 96, dpiY / 96);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -694,6 +721,11 @@ void AwtWin32GraphicsDevice::DisableOffscreenAcceleration()
|
||||
// REMIND: noop for now
|
||||
}
|
||||
|
||||
void AwtWin32GraphicsDevice::DisableScaleAutoRefresh()
|
||||
{
|
||||
disableScaleAutoRefresh = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates the GraphicsDevice object associated with this
|
||||
* device by disabling offscreen acceleration and calling
|
||||
@ -754,6 +786,21 @@ void AwtWin32GraphicsDevice::ResetAllMonitorInfo()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function updates the scale factor for all monitors on the system.
|
||||
*/
|
||||
void AwtWin32GraphicsDevice::ResetAllDesktopScales()
|
||||
{
|
||||
if (!Devices::GetInstance()){
|
||||
return;
|
||||
}
|
||||
Devices::InstanceAccess devices;
|
||||
int devicesNum = devices->GetNumDevices();
|
||||
for (int deviceIndex = 0; deviceIndex < devicesNum; deviceIndex++) {
|
||||
devices->GetDevice(deviceIndex)->InitDesktopScales();
|
||||
}
|
||||
}
|
||||
|
||||
void AwtWin32GraphicsDevice::DisableOffscreenAccelerationForDevice(
|
||||
HMONITOR hMonitor)
|
||||
{
|
||||
@ -1393,6 +1440,7 @@ JNIEXPORT void JNICALL
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
|
||||
if (device != NULL ) {
|
||||
device->DisableScaleAutoRefresh();
|
||||
device->SetScale(scaleX, scaleY);
|
||||
}
|
||||
}
|
||||
@ -1441,4 +1489,3 @@ Java_sun_awt_Win32GraphicsDevice_initNativeScale
|
||||
device->InitDesktopScales();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -65,15 +65,20 @@ public:
|
||||
int GetDeviceIndex() { return screen; }
|
||||
void Release();
|
||||
void DisableOffscreenAcceleration();
|
||||
void DisableScaleAutoRefresh();
|
||||
void Invalidate(JNIEnv *env);
|
||||
void InitDesktopScales();
|
||||
void SetScale(float scaleX, float scaleY);
|
||||
float GetScaleX();
|
||||
float GetScaleY();
|
||||
int ScaleUpX(int x);
|
||||
int ScaleUpAbsX(int x);
|
||||
int ScaleUpY(int y);
|
||||
int ScaleUpAbsY(int x);
|
||||
int ScaleDownX(int x);
|
||||
int ScaleDownAbsX(int x);
|
||||
int ScaleDownY(int y);
|
||||
int ScaleDownAbsY(int y);
|
||||
|
||||
static int DeviceIndexForWindow(HWND hWnd);
|
||||
static jobject GetColorModel(JNIEnv *env, jboolean dynamic,
|
||||
@ -88,6 +93,7 @@ public:
|
||||
static HMONITOR GetMonitor(int deviceIndex);
|
||||
static LPMONITORINFO GetMonitorInfo(int deviceIndex);
|
||||
static void ResetAllMonitorInfo();
|
||||
static void ResetAllDesktopScales();
|
||||
static BOOL IsPrimaryPalettized() { return primaryPalettized; }
|
||||
static int GetDefaultDeviceIndex() { return primaryIndex; }
|
||||
static void DisableOffscreenAccelerationForDevice(HMONITOR hMonitor);
|
||||
@ -117,6 +123,7 @@ private:
|
||||
Devices *devicesArray;
|
||||
float scaleX;
|
||||
float scaleY;
|
||||
BOOL disableScaleAutoRefresh;
|
||||
|
||||
static HDC MakeDCFromMonitor(HMONITOR);
|
||||
static int ClipRound(double value);
|
||||
|
@ -153,17 +153,6 @@ struct SetFullScreenExclusiveModeStateStruct {
|
||||
jboolean isFSEMState;
|
||||
};
|
||||
|
||||
// struct for _WindowDPIChange() method
|
||||
struct ScaleStruct {
|
||||
jobject window;
|
||||
jint prevScreen;
|
||||
jfloat prevScaleX;
|
||||
jfloat prevScaleY;
|
||||
jint screen;
|
||||
jfloat scaleX;
|
||||
jfloat scaleY;
|
||||
};
|
||||
|
||||
struct OverrideHandle {
|
||||
jobject frame;
|
||||
HWND handle;
|
||||
@ -179,10 +168,6 @@ jfieldID AwtWindow::autoRequestFocusID;
|
||||
jfieldID AwtWindow::securityWarningWidthID;
|
||||
jfieldID AwtWindow::securityWarningHeightID;
|
||||
|
||||
jfieldID AwtWindow::sysXID;
|
||||
jfieldID AwtWindow::sysYID;
|
||||
jfieldID AwtWindow::sysWID;
|
||||
jfieldID AwtWindow::sysHID;
|
||||
jfieldID AwtWindow::windowTypeID;
|
||||
jmethodID AwtWindow::notifyWindowStateChangedMID;
|
||||
|
||||
@ -1128,20 +1113,19 @@ AwtWindow* AwtWindow::Create(jobject self, jobject parent)
|
||||
// specify WS_EX_TOOLWINDOW to remove parentless windows from taskbar
|
||||
exStyle |= WS_EX_TOOLWINDOW;
|
||||
}
|
||||
window->CreateHWnd(env, L"",
|
||||
style, exStyle,
|
||||
0, 0, 0, 0,
|
||||
(awtParent != NULL) ? awtParent->GetHWnd() : NULL,
|
||||
NULL,
|
||||
::GetSysColor(COLOR_WINDOWTEXT),
|
||||
::GetSysColor(COLOR_WINDOW),
|
||||
self);
|
||||
|
||||
jint x = env->GetIntField(target, AwtComponent::xID);
|
||||
jint y = env->GetIntField(target, AwtComponent::yID);
|
||||
jint width = env->GetIntField(target, AwtComponent::widthID);
|
||||
jint height = env->GetIntField(target, AwtComponent::heightID);
|
||||
|
||||
window->CreateHWnd(env, L"",
|
||||
style, exStyle,
|
||||
x, y, width, height,
|
||||
(awtParent != NULL) ? awtParent->GetHWnd() : NULL,
|
||||
NULL,
|
||||
::GetSysColor(COLOR_WINDOWTEXT),
|
||||
::GetSysColor(COLOR_WINDOW),
|
||||
self);
|
||||
/*
|
||||
* Initialize icon as inherited from parent if it exists
|
||||
*/
|
||||
@ -1151,13 +1135,7 @@ AwtWindow* AwtWindow::Create(jobject self, jobject parent)
|
||||
window->m_iconInherited = TRUE;
|
||||
}
|
||||
window->DoUpdateIcon();
|
||||
|
||||
|
||||
/*
|
||||
* Reshape here instead of during create, so that a WM_NCCALCSIZE
|
||||
* is sent.
|
||||
*/
|
||||
window->Reshape(x, y, width, height);
|
||||
window->RecalcNonClient();
|
||||
}
|
||||
} catch (...) {
|
||||
env->DeleteLocalRef(target);
|
||||
@ -1215,6 +1193,48 @@ void AwtWindow::moveToDefaultLocation() {
|
||||
VERIFY(::SetWindowPos(GetHWnd(), NULL, defLoc.left, defLoc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER));
|
||||
}
|
||||
|
||||
/**
|
||||
* Override AwtComponent::Reshape() to handle absolute screen coordinates used
|
||||
* by the top-level windows.
|
||||
*/
|
||||
void AwtWindow::Reshape(int x, int y, int w, int h) {
|
||||
if (IsEmbeddedFrame()) {
|
||||
// Not the "real" top level window
|
||||
return AwtComponent::Reshape(x, y, w, h);
|
||||
}
|
||||
// Yes, use x,y in user's space to find the nearest monitor in device space.
|
||||
POINT pt = {x + w / 2, y + h / 2};
|
||||
Devices::InstanceAccess devices;
|
||||
HMONITOR monitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
|
||||
int screen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(monitor);
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
// Try to set the correct size and jump to the correct location, even if it is
|
||||
// on the different monitor. Note that for the "size" we use the current
|
||||
// monitor, so the WM_DPICHANGED will adjust it for the "target" monitor.
|
||||
int scaleUpAbsX = device == NULL ? x : device->ScaleUpAbsX(x);
|
||||
int scaleUpAbsY = device == NULL ? y : device->ScaleUpAbsY(y);
|
||||
ReshapeNoScale(scaleUpAbsX, scaleUpAbsY, ScaleUpX(w), ScaleUpY(h));
|
||||
// The window manager may tweak the size for different reasons, so try
|
||||
// to make sure our window has the correct size in the user's space.
|
||||
// NOOP if the size was changed already or changing is in progress.
|
||||
RECT rc;
|
||||
::GetWindowRect(GetHWnd(), &rc);
|
||||
ReshapeNoScale(rc.left, rc.top, ScaleUpX(w), ScaleUpY(h));
|
||||
// the window manager may ignore our "SetWindowPos" request, in this,
|
||||
// case the WmMove/WmSize will not come and we need to manually resync
|
||||
// the "java.awt.Window" locations, because "java.awt.Window" already
|
||||
// uses location ignored by the window manager.
|
||||
::GetWindowRect(GetHWnd(), &rc);
|
||||
if (x != ScaleDownAbsX(rc.left) || y != ScaleDownAbsY(rc.top)) {
|
||||
WmMove(rc.left, rc.top);
|
||||
}
|
||||
int userW = ScaleDownX(rc.right - rc.left);
|
||||
int userH = ScaleDownY(rc.bottom - rc.top);
|
||||
if (w != userW || h != userH) {
|
||||
WmSize(SIZENORMAL, rc.right - rc.left, rc.bottom - rc.top);
|
||||
}
|
||||
}
|
||||
|
||||
void AwtWindow::Show()
|
||||
{
|
||||
m_visible = true;
|
||||
@ -1774,6 +1794,15 @@ MsgRouting AwtWindow::WmShowWindow(BOOL show, UINT status)
|
||||
return AwtCanvas::WmShowWindow(show, status);
|
||||
}
|
||||
|
||||
void AwtWindow::WmDPIChanged(const LPARAM &lParam) {
|
||||
// need to update the scales now, otherwise the ReshapeNoScale() will
|
||||
// calculate the bounds wrongly
|
||||
AwtWin32GraphicsDevice::ResetAllDesktopScales();
|
||||
RECT *r = (RECT *) lParam;
|
||||
ReshapeNoScale(r->left, r->top, r->right - r->left, r->bottom - r->top);
|
||||
CheckIfOnNewScreen(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Override AwtComponent's move handling to first update the
|
||||
* java AWT target's position fields directly, since Windows
|
||||
@ -1789,30 +1818,21 @@ MsgRouting AwtWindow::WmMove(int x, int y)
|
||||
// NOTE: See also AwtWindow::Reshape
|
||||
return mrDoDefault;
|
||||
}
|
||||
|
||||
if (m_screenNum == -1) {
|
||||
// Set initial value
|
||||
m_screenNum = GetScreenImOn();
|
||||
}
|
||||
else {
|
||||
CheckIfOnNewScreen();
|
||||
}
|
||||
// Check for the new screen and update the java peer
|
||||
CheckIfOnNewScreen(false); // postpone if different DPI
|
||||
|
||||
/* Update the java AWT target component's fields directly */
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
if (env->EnsureLocalCapacity(1) < 0) {
|
||||
return mrConsume;
|
||||
}
|
||||
jobject peer = GetPeer(env);
|
||||
jobject target = env->GetObjectField(peer, AwtObject::targetID);
|
||||
jobject target = GetTarget(env);
|
||||
|
||||
RECT rect;
|
||||
::GetWindowRect(GetHWnd(), &rect);
|
||||
|
||||
(env)->SetIntField(target, AwtComponent::xID, ScaleDownX(rect.left));
|
||||
(env)->SetIntField(target, AwtComponent::yID, ScaleDownY(rect.top));
|
||||
(env)->SetIntField(peer, AwtWindow::sysXID, ScaleDownX(rect.left));
|
||||
(env)->SetIntField(peer, AwtWindow::sysYID, ScaleDownY(rect.top));
|
||||
(env)->SetIntField(target, AwtComponent::xID, ScaleDownAbsX(rect.left));
|
||||
(env)->SetIntField(target, AwtComponent::yID, ScaleDownAbsY(rect.top));
|
||||
SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED);
|
||||
|
||||
env->DeleteLocalRef(target);
|
||||
@ -1857,13 +1877,22 @@ MsgRouting AwtWindow::WmSizing()
|
||||
MsgRouting AwtWindow::WmEnterSizeMove()
|
||||
{
|
||||
m_winSizeMove = TRUE;
|
||||
// Below is a workaround, see CheckWindowDPIChange
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(m_screenNum);
|
||||
if (device) {
|
||||
prevScaleRec.screen = m_screenNum;
|
||||
prevScaleRec.scaleX = device->GetScaleX();
|
||||
prevScaleRec.scaleY = device->GetScaleY();
|
||||
}
|
||||
// Above is a workaround
|
||||
return mrDoDefault;
|
||||
}
|
||||
|
||||
MsgRouting AwtWindow::WmExitSizeMove()
|
||||
{
|
||||
m_winSizeMove = FALSE;
|
||||
CheckWindowDPIChange();
|
||||
CheckWindowDPIChange(); // workaround
|
||||
return mrDoDefault;
|
||||
}
|
||||
|
||||
@ -1880,6 +1909,8 @@ MsgRouting AwtWindow::WmSize(UINT type, int w, int h)
|
||||
UpdateSecurityWarningVisibility();
|
||||
return mrDoDefault;
|
||||
}
|
||||
// Check for the new screen and update the java peer
|
||||
CheckIfOnNewScreen(false); // postpone if different DPI
|
||||
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
if (env->EnsureLocalCapacity(1) < 0)
|
||||
@ -1887,15 +1918,8 @@ MsgRouting AwtWindow::WmSize(UINT type, int w, int h)
|
||||
jobject target = GetTarget(env);
|
||||
// fix 4167248 : ensure the insets are up-to-date before using
|
||||
BOOL insetsChanged = UpdateInsets(NULL);
|
||||
int newWidth = w + m_insets.left + m_insets.right;
|
||||
int newHeight = h + m_insets.top + m_insets.bottom;
|
||||
|
||||
(env)->SetIntField(target, AwtComponent::widthID, ScaleDownX(newWidth));
|
||||
(env)->SetIntField(target, AwtComponent::heightID, ScaleDownY(newHeight));
|
||||
|
||||
jobject peer = GetPeer(env);
|
||||
(env)->SetIntField(peer, AwtWindow::sysWID, ScaleDownX(newWidth));
|
||||
(env)->SetIntField(peer, AwtWindow::sysHID, ScaleDownY(newHeight));
|
||||
(env)->SetIntField(target, AwtComponent::widthID, ScaleDownX(w));
|
||||
(env)->SetIntField(target, AwtComponent::heightID, ScaleDownY(h));
|
||||
|
||||
if (!AwtWindow::IsResizing()) {
|
||||
WindowResized();
|
||||
@ -1977,6 +2001,11 @@ LRESULT AwtWindow::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
LRESULT retValue = 0L;
|
||||
|
||||
switch(message) {
|
||||
case WM_DPICHANGED: {
|
||||
WmDPIChanged(lParam);
|
||||
mr = mrConsume;
|
||||
break;
|
||||
}
|
||||
case WM_GETICON:
|
||||
mr = WmGetIcon(wParam, retValue);
|
||||
break;
|
||||
@ -2120,14 +2149,28 @@ int AwtWindow::GetScreenImOn() {
|
||||
return scrnNum;
|
||||
}
|
||||
|
||||
/* Check to see if we've been moved onto another screen.
|
||||
/*
|
||||
* Check to see if we've been moved onto another screen.
|
||||
* If so, update internal data, surfaces, etc.
|
||||
*/
|
||||
|
||||
void AwtWindow::CheckIfOnNewScreen() {
|
||||
void AwtWindow::CheckIfOnNewScreen(BOOL force) {
|
||||
int curScrn = GetScreenImOn();
|
||||
|
||||
if (curScrn != m_screenNum) { // we've been moved
|
||||
// if moved from one monitor to another with different DPI, we should
|
||||
// update the m_screenNum only if the size was updated as well in the
|
||||
// WM_DPICHANGED.
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* oldDevice = devices->GetDevice(m_screenNum);
|
||||
AwtWin32GraphicsDevice* newDevice = devices->GetDevice(curScrn);
|
||||
if (!force && m_winSizeMove && oldDevice && newDevice) {
|
||||
if (oldDevice->GetScaleX() != newDevice->GetScaleX()
|
||||
|| oldDevice->GetScaleY() != newDevice->GetScaleY()) {
|
||||
// scales are different, wait for WM_DPICHANGED
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
|
||||
jclass peerCls = env->GetObjectClass(m_peerObject);
|
||||
@ -2149,67 +2192,39 @@ void AwtWindow::CheckIfOnNewScreen() {
|
||||
}
|
||||
}
|
||||
|
||||
// The shared code is not ready to the top-level window which crosses a few
|
||||
// monitors with different DPI. Popup windows will start to use wrong screen,
|
||||
// will be placed in the wrong place and will use the wrong size, see 8249164
|
||||
// So we will "JUMP TO" the new screen.
|
||||
void AwtWindow::CheckWindowDPIChange() {
|
||||
|
||||
if (prevScaleRec.screen != -1 ) {
|
||||
float prevScaleX = prevScaleRec.scaleX;
|
||||
float prevScaleY = prevScaleRec.scaleY;
|
||||
|
||||
if (prevScaleX >= 1 && prevScaleY >= 1) {
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(m_screenNum);
|
||||
if (device) {
|
||||
float scaleX = device->GetScaleX();
|
||||
float scaleY = device->GetScaleY();
|
||||
if (prevScaleX != scaleX || prevScaleY != scaleY) {
|
||||
WindowDPIChange(prevScaleRec.screen, prevScaleX, prevScaleY,
|
||||
m_screenNum, scaleX, scaleY);
|
||||
if (prevScaleRec.screen != -1 && prevScaleRec.screen != m_screenNum) {
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(m_screenNum);
|
||||
if (device) {
|
||||
if (prevScaleRec.scaleX != device->GetScaleX()
|
||||
|| prevScaleRec.scaleY != device->GetScaleY()) {
|
||||
RECT rect;
|
||||
::GetWindowRect(GetHWnd(), &rect);
|
||||
int x = rect.left;
|
||||
int y = rect.top;
|
||||
int w = rect.right - rect.left;
|
||||
int h = rect.bottom - rect.top;
|
||||
RECT bounds;
|
||||
if (MonitorBounds(device->GetMonitor(), &bounds)) {
|
||||
x = x < bounds.left ? bounds.left : x;
|
||||
y = y < bounds.top ? bounds.top : y;
|
||||
x = (x + w > bounds.right) ? bounds.right - w : x;
|
||||
y = (y + h > bounds.bottom) ? bounds.bottom - h : y;
|
||||
}
|
||||
ReshapeNoScale(x, y, w, h);
|
||||
}
|
||||
}
|
||||
prevScaleRec.screen = -1;
|
||||
prevScaleRec.scaleX = -1.0f;
|
||||
prevScaleRec.scaleY = -1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void AwtWindow::WindowDPIChange(int prevScreen,
|
||||
float prevScaleX, float prevScaleY,
|
||||
int screen, float scaleX,
|
||||
float scaleY)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
RECT rect;
|
||||
|
||||
if (prevScaleX == scaleX && prevScaleY == scaleY) {
|
||||
return;
|
||||
}
|
||||
|
||||
::GetWindowRect(GetHWnd(), &rect);
|
||||
x = rect.left;
|
||||
y = rect.top;
|
||||
w = (rect.right - rect.left) * scaleX / prevScaleX;
|
||||
h = (rect.bottom - rect.top) * scaleY / prevScaleY;
|
||||
|
||||
if (prevScreen != screen) {
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
|
||||
if (device) {
|
||||
RECT bounds;
|
||||
if (MonitorBounds(device->GetMonitor(), &bounds)) {
|
||||
x = x < bounds.left ? bounds.left : x;
|
||||
y = y < bounds.top ? bounds.top : y;
|
||||
|
||||
x = (x + w > bounds.right) ? bounds.right - w : x;
|
||||
y = (y + h > bounds.bottom) ? bounds.bottom - h : y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReshapeNoScale(x, y, w, h);
|
||||
}
|
||||
|
||||
BOOL AwtWindow::IsFocusableWindow() {
|
||||
/*
|
||||
* For Window/Frame/Dialog to accept focus it should:
|
||||
@ -2582,15 +2597,11 @@ void AwtWindow::_ReshapeFrame(void *param)
|
||||
{
|
||||
env->SetIntField(target, AwtComponent::widthID,
|
||||
w = minWidth);
|
||||
env->SetIntField(peer, AwtWindow::sysWID,
|
||||
w);
|
||||
}
|
||||
if (h < minHeight)
|
||||
{
|
||||
env->SetIntField(target, AwtComponent::heightID,
|
||||
h = minHeight);
|
||||
env->SetIntField(peer, AwtWindow::sysHID,
|
||||
h);
|
||||
}
|
||||
}
|
||||
env->DeleteLocalRef(target);
|
||||
@ -3257,39 +3268,6 @@ void AwtWindow::_GetNativeWindowSize(void* param) {
|
||||
env->DeleteGlobalRef(self);
|
||||
}
|
||||
|
||||
void AwtWindow::_WindowDPIChange(void* param)
|
||||
{
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
|
||||
ScaleStruct *ss = (ScaleStruct *)param;
|
||||
jobject self = ss->window;
|
||||
jint prevScreen = ss->prevScreen;
|
||||
jfloat prevScaleX = ss->prevScaleX;
|
||||
jfloat prevScaleY = ss->prevScaleY;
|
||||
jint screen = ss->screen;
|
||||
jfloat scaleX = ss->scaleX;
|
||||
jfloat scaleY = ss->scaleY;
|
||||
|
||||
PDATA pData;
|
||||
JNI_CHECK_PEER_GOTO(self, ret);
|
||||
AwtWindow *window = (AwtWindow *)pData;
|
||||
|
||||
if (window->m_winSizeMove) {
|
||||
if (window->prevScaleRec.screen == -1) {
|
||||
window->prevScaleRec.screen = prevScreen;
|
||||
window->prevScaleRec.scaleX = prevScaleX;
|
||||
window->prevScaleRec.scaleY = prevScaleY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
window->WindowDPIChange(prevScreen, prevScaleX, prevScaleY,
|
||||
screen, scaleX, scaleY);
|
||||
}
|
||||
|
||||
ret:
|
||||
env->DeleteGlobalRef(self);
|
||||
delete ss;
|
||||
}
|
||||
|
||||
extern "C" int getSystemMetricValue(int msgType);
|
||||
extern "C" {
|
||||
@ -3347,11 +3325,6 @@ Java_sun_awt_windows_WWindowPeer_initIDs(JNIEnv *env, jclass cls)
|
||||
{
|
||||
TRY;
|
||||
|
||||
CHECK_NULL(AwtWindow::sysXID = env->GetFieldID(cls, "sysX", "I"));
|
||||
CHECK_NULL(AwtWindow::sysYID = env->GetFieldID(cls, "sysY", "I"));
|
||||
CHECK_NULL(AwtWindow::sysWID = env->GetFieldID(cls, "sysW", "I"));
|
||||
CHECK_NULL(AwtWindow::sysHID = env->GetFieldID(cls, "sysH", "I"));
|
||||
|
||||
AwtWindow::windowTypeID = env->GetFieldID(cls, "windowType",
|
||||
"Ljava/awt/Window$Type;");
|
||||
|
||||
@ -3991,33 +3964,6 @@ Java_sun_awt_windows_WWindowPeer_repositionSecurityWarning(JNIEnv *env,
|
||||
CATCH_BAD_ALLOC;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_awt_windows_WWindowPeer
|
||||
* Method: windowDPIChange
|
||||
* Signature: (IFFIFF)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_awt_windows_WWindowPeer_windowDPIChange(JNIEnv *env, jobject self,
|
||||
jint prevScreen, jfloat prevScaleX, jfloat prevScaleY,
|
||||
jint screen, jfloat scaleX, jfloat scaleY)
|
||||
{
|
||||
TRY;
|
||||
|
||||
ScaleStruct *ss = new ScaleStruct;
|
||||
ss->window = env->NewGlobalRef(self);
|
||||
ss->prevScreen = prevScreen;
|
||||
ss->prevScaleX = prevScaleX;
|
||||
ss->prevScaleY = prevScaleY;
|
||||
ss->screen = screen;
|
||||
ss->scaleX = scaleX;
|
||||
ss->scaleY = scaleY;
|
||||
|
||||
AwtToolkit::GetInstance().InvokeFunction(AwtWindow::_WindowDPIChange, ss);
|
||||
// global refs and ss are deleted in _WindowDPIChange
|
||||
|
||||
CATCH_BAD_ALLOC;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_awt_windows_WLightweightFramePeer
|
||||
* Method: overrideNativeHandle
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -58,12 +58,6 @@ public:
|
||||
static jfieldID securityWarningHeightID;
|
||||
|
||||
/* sun.awt.windows.WWindowPeer field and method IDs */
|
||||
// The coordinates at the peer.
|
||||
static jfieldID sysXID;
|
||||
static jfieldID sysYID;
|
||||
static jfieldID sysWID;
|
||||
static jfieldID sysHID;
|
||||
|
||||
static jfieldID windowTypeID;
|
||||
static jmethodID notifyWindowStateChangedMID;
|
||||
|
||||
@ -129,6 +123,7 @@ public:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
virtual void Reshape(int x, int y, int w, int h);
|
||||
virtual void Invalidate(RECT* r);
|
||||
virtual void Show();
|
||||
virtual void SetResizable(BOOL isResizable);
|
||||
@ -136,7 +131,7 @@ public:
|
||||
virtual void RecalcNonClient();
|
||||
virtual void RedrawNonClient();
|
||||
virtual int GetScreenImOn();
|
||||
virtual void CheckIfOnNewScreen();
|
||||
virtual void CheckIfOnNewScreen(BOOL force);
|
||||
virtual void Grab();
|
||||
virtual void Ungrab();
|
||||
virtual void Ungrab(BOOL doPost);
|
||||
@ -248,7 +243,6 @@ public:
|
||||
static void _RepositionSecurityWarning(void* param);
|
||||
static void _SetFullScreenExclusiveModeState(void* param);
|
||||
static void _GetNativeWindowSize(void* param);
|
||||
static void _WindowDPIChange(void* param);
|
||||
static void _OverrideHandle(void *param);
|
||||
|
||||
inline static BOOL IsResizing() {
|
||||
@ -409,8 +403,7 @@ private:
|
||||
|
||||
void InitOwner(AwtWindow *owner);
|
||||
void CheckWindowDPIChange();
|
||||
void WindowDPIChange(int prevScreen, float prevScaleX, float prevScaleY,
|
||||
int newScreen, float scaleX, float scaleY);
|
||||
void WmDPIChanged(const LPARAM &lParam);
|
||||
|
||||
Type m_windowType;
|
||||
void InitType(JNIEnv *env, jobject peer);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,6 +41,10 @@ extern const UINT SYSCOMMAND_IMM;
|
||||
* See winuser.h for details.
|
||||
*/
|
||||
|
||||
#ifndef WM_DPICHANGED
|
||||
#define WM_DPICHANGED 0x02E0
|
||||
#endif //WM_DPICHANGED
|
||||
|
||||
#ifndef WM_MOUSEWHEEL
|
||||
#define WM_MOUSEWHEEL 0x020A
|
||||
#endif //WM_MOUSEWHEEL
|
||||
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.Button;
|
||||
import java.awt.Canvas;
|
||||
import java.awt.Checkbox;
|
||||
import java.awt.Choice;
|
||||
import java.awt.Component;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Label;
|
||||
import java.awt.List;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Robot;
|
||||
import java.awt.ScrollPane;
|
||||
import java.awt.Scrollbar;
|
||||
import java.awt.TextArea;
|
||||
import java.awt.TextField;
|
||||
import java.awt.Window;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @bug 8211999
|
||||
* @run main/othervm SetComponentsBounds
|
||||
* @run main/othervm -Dsun.java2d.uiScale=1 SetComponentsBounds
|
||||
* @run main/othervm -Dsun.java2d.uiScale=2.25 SetComponentsBounds
|
||||
*/
|
||||
public final class SetComponentsBounds {
|
||||
|
||||
private static final int X = 111;
|
||||
private static final int Y = 222;
|
||||
private static final int WIDTH = 321;
|
||||
private static final int HEIGHT = 123;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
var ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
for (GraphicsDevice gd : ge.getScreenDevices()) {
|
||||
test(gd.getDefaultConfiguration(), true);
|
||||
test(gd.getDefaultConfiguration(), false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void test(GraphicsConfiguration gc, boolean visible) throws Exception {
|
||||
Rectangle screen = gc.getBounds();
|
||||
Window frame = new Frame();
|
||||
try {
|
||||
frame.setLayout(null); // trigger use the minimum size of
|
||||
// the peer
|
||||
frame.setBounds(screen.x + 100, screen.y + 100, 500, 500);
|
||||
frame.add(new Button());
|
||||
frame.add(new Canvas());
|
||||
frame.add(new Checkbox());
|
||||
frame.add(new Choice());
|
||||
frame.add(new Label());
|
||||
frame.add(new List());
|
||||
frame.add(new Scrollbar());
|
||||
frame.add(new ScrollPane());
|
||||
frame.add(new TextArea());
|
||||
frame.add(new TextField());
|
||||
for (Component comp : frame.getComponents()) {
|
||||
comp.setBounds(X, Y, WIDTH, HEIGHT);
|
||||
}
|
||||
if (visible) {
|
||||
frame.setVisible(true);
|
||||
} else {
|
||||
frame.pack();
|
||||
}
|
||||
Robot robot = new Robot();
|
||||
robot.waitForIdle();
|
||||
checkGC(gc, frame);
|
||||
for (Component comp : frame.getComponents()) {
|
||||
Rectangle bounds = comp.getBounds();
|
||||
if (bounds.x != X || bounds.y != Y || bounds.width != WIDTH) {
|
||||
System.err.println("Screen bounds:" + screen);
|
||||
System.err.println("Component:" + comp);
|
||||
throw new RuntimeException("Wrong bounds:" + bounds);
|
||||
}
|
||||
if (bounds.height > HEIGHT) {
|
||||
// different check for HEIGHT, it depends on the font
|
||||
throw new RuntimeException("Wrong height:" + bounds.height);
|
||||
}
|
||||
checkGC(gc, comp);
|
||||
}
|
||||
} finally {
|
||||
frame.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkGC(GraphicsConfiguration gc, Component comp) {
|
||||
GraphicsConfiguration compGC = comp.getGraphicsConfiguration();
|
||||
if (compGC != gc) {
|
||||
System.err.println("Expected GC:" + gc);
|
||||
System.err.println("Actual GC:" + compGC);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,7 +24,7 @@
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @bug 6345003 8171363
|
||||
* @bug 6345003 8171363 8211999
|
||||
* @summary grab problems with EmbeddedFrame
|
||||
* @requires (os.family == "windows")
|
||||
* @modules java.desktop/java.awt.peer
|
||||
@ -67,6 +67,7 @@ public class EmbeddedFrameGrabTest {
|
||||
final Frame frame = new Frame("AWT Frame");
|
||||
frame.pack();
|
||||
frame.setSize(200, 200);
|
||||
frame.setLocationRelativeTo(null);
|
||||
FramePeer frame_peer = AWTAccessor.getComponentAccessor()
|
||||
.getPeer(frame);
|
||||
Class comp_peer_class
|
||||
@ -88,6 +89,7 @@ public class EmbeddedFrameGrabTest {
|
||||
final Panel p = new Panel();
|
||||
p.setLayout(new BorderLayout());
|
||||
embedded_frame.add(p, BorderLayout.CENTER);
|
||||
embedded_frame.setBounds(0, 0, 150, 150);
|
||||
embedded_frame.validate();
|
||||
p.add(combo);
|
||||
p.validate();
|
||||
|
@ -21,6 +21,7 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
@ -30,7 +31,7 @@ import java.awt.Toolkit;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8176359 8231564
|
||||
* @bug 8176359 8231564 8211999
|
||||
* @key headful
|
||||
* @requires (os.family == "windows" | os.family == "mac")
|
||||
* @summary setMaximizedBounds() should work if set to the screen other than
|
||||
@ -58,15 +59,23 @@ public final class MaximizedToOppositeScreenSmall {
|
||||
Rectangle framAt = gd1.getDefaultConfiguration().getBounds();
|
||||
framAt.grow(-framAt.width / 2 + 100, -framAt.height / 2 + 100);
|
||||
for (GraphicsDevice gd2 : gds) {
|
||||
Rectangle maxTo = gd2.getDefaultConfiguration().getBounds();
|
||||
maxTo.grow(-maxTo.width / 2 + 120, -maxTo.height / 2 + 120);
|
||||
Frame frame = new Frame(gd1.getDefaultConfiguration());
|
||||
try {
|
||||
frame.setLayout(null); // trigger use the minimum size of
|
||||
// the peer
|
||||
frame.setBounds(framAt);
|
||||
|
||||
frame.setVisible(true);
|
||||
robot.waitForIdle();
|
||||
robot.delay(1000);
|
||||
|
||||
Dimension minimumSize = frame.getMinimumSize();
|
||||
minimumSize.width = Math.max(minimumSize.width, 120);
|
||||
minimumSize.height = Math.max(minimumSize.height, 120);
|
||||
Rectangle maxTo = gd2.getDefaultConfiguration().getBounds();
|
||||
maxTo.grow(-maxTo.width / 2 + minimumSize.width,
|
||||
-maxTo.height / 2 + minimumSize.height);
|
||||
|
||||
frame.setMaximizedBounds(maxTo);
|
||||
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
|
||||
robot.waitForIdle();
|
||||
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.DisplayMode;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8211999
|
||||
* @key headful
|
||||
* @summary verifies the full-screen window bounds and graphics configuration
|
||||
*/
|
||||
public final class FullscreenWindowProps {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
var ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
GraphicsDevice gd = ge.getDefaultScreenDevice();
|
||||
|
||||
if (!gd.isFullScreenSupported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Frame frame = new Frame() {
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
g.setColor(Color.GREEN);
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
};
|
||||
try {
|
||||
frame.setBackground(Color.MAGENTA);
|
||||
frame.setVisible(true);
|
||||
gd.setFullScreenWindow(frame);
|
||||
Thread.sleep(4000);
|
||||
|
||||
for (DisplayMode dm : gd.getDisplayModes()) {
|
||||
if (dm.getWidth() == 1024 && dm.getHeight() == 768) {
|
||||
gd.setDisplayMode(dm);
|
||||
Thread.sleep(4000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GraphicsConfiguration frameGC = frame.getGraphicsConfiguration();
|
||||
Rectangle frameBounds = frame.getBounds();
|
||||
|
||||
GraphicsConfiguration screenGC = gd.getDefaultConfiguration();
|
||||
Rectangle screenBounds = screenGC.getBounds();
|
||||
|
||||
if (frameGC != screenGC) {
|
||||
System.err.println("Expected: " + screenGC);
|
||||
System.err.println("Actual: " + frameGC);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
checkSize(frameBounds.x, screenBounds.x, "x");
|
||||
checkSize(frameBounds.y, screenBounds.y, "Y");
|
||||
checkSize(frameBounds.width, screenBounds.width, "width");
|
||||
checkSize(frameBounds.height, screenBounds.height, "height");
|
||||
} finally {
|
||||
gd.setFullScreenWindow(null);
|
||||
frame.dispose();
|
||||
Thread.sleep(10000);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkSize(int actual, int expected, String prop) {
|
||||
if (Math.abs(actual - expected) > 30) { // let's allow size variation,
|
||||
// the bug is reproduced anyway
|
||||
System.err.println("Expected: " + expected);
|
||||
System.err.println("Actual: " + actual);
|
||||
throw new RuntimeException(prop + " is wrong");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Frame;
|
||||
import java.awt.List;
|
||||
import java.awt.Panel;
|
||||
import java.awt.Point;
|
||||
import java.awt.Robot;
|
||||
import java.awt.event.InputEvent;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 4909485 8211999
|
||||
* @key headful
|
||||
*/
|
||||
public final class ListMultipleSelectTest {
|
||||
|
||||
private static List aList;
|
||||
private static Panel panel;
|
||||
private static Point p;
|
||||
private static Robot robot;
|
||||
private static int[] selected;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Frame frame = new Frame();
|
||||
try {
|
||||
panel = new Panel();
|
||||
aList = new List();
|
||||
aList.add("Test item1");
|
||||
aList.add("Test item2");
|
||||
aList.add("Test item3");
|
||||
aList.add("Test item4");
|
||||
|
||||
frame.setLayout(new FlowLayout()); //list should fill whole frame's space
|
||||
panel.add(aList);
|
||||
frame.setSize(200, 200);
|
||||
frame.setLocationRelativeTo(null);
|
||||
panel.setVisible(true);
|
||||
frame.add(panel);
|
||||
frame.setVisible(true);
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(" InterruptedException. Test failed. ");
|
||||
}
|
||||
|
||||
Dimension listSize = aList.getSize();
|
||||
p = aList.getLocationOnScreen();
|
||||
int stepY = listSize.height / aList.getItemCount();
|
||||
|
||||
// System.out.println("itemCount = "+aList.getItemCount());
|
||||
// System.out.println("Size Of aList="+ listSize);
|
||||
// System.out.println("stepY = "+stepY);
|
||||
// System.out.println("Point:" +p);
|
||||
System.out.println("Multiple mode is ON");
|
||||
aList.setMultipleMode(true);
|
||||
//=================================================
|
||||
robot = new Robot();
|
||||
robot.setAutoDelay(0);
|
||||
robot.setAutoWaitForIdle(false);
|
||||
robot.delay(10);
|
||||
robot.waitForIdle();
|
||||
|
||||
//=================================================
|
||||
|
||||
for (int i = 0; i < aList.getItemCount(); i++) {
|
||||
//select all items in the List
|
||||
mousePress(p.x + listSize.width / 2, p.y + stepY / 2 + stepY * i);
|
||||
}
|
||||
|
||||
selected = aList.getSelectedIndexes();
|
||||
System.out.println("Multiple mode is ON");
|
||||
aList.setMultipleMode(true);
|
||||
int[] newSelected = aList.getSelectedIndexes();
|
||||
if (!java.util.Arrays.equals(newSelected, selected)) {
|
||||
throw new RuntimeException(" Incorrect item remains selected " +
|
||||
"after setMultipleMode(true). ");
|
||||
}
|
||||
|
||||
aList.setMultipleMode(false);
|
||||
System.out.println("Multiple mode is OFF");
|
||||
selected = aList.getSelectedIndexes();
|
||||
if (selected[0] != 3 || selected.length != 1) {
|
||||
throw new RuntimeException(" Incorrect item remains selected " +
|
||||
"after setMultipleMode(false) or it is more then one " +
|
||||
"item remaining.Forward. ");
|
||||
}
|
||||
|
||||
System.out.println("Multiple mode is ON");
|
||||
aList.setMultipleMode(true);
|
||||
|
||||
if (selected[0] != 3 || selected.length != 1) {
|
||||
throw new RuntimeException(" Incorrect item remains selected " +
|
||||
"after setMultipleMode(true) or it is more then one " +
|
||||
"item remaining. ");
|
||||
}
|
||||
|
||||
deselectAll();
|
||||
for (int i = aList.getItemCount() - 1; i >= 0; i--) {
|
||||
mousePress(p.x + listSize.width / 2, p.y + stepY / 2 + stepY * i);
|
||||
}
|
||||
|
||||
System.out.println("Multiple mode is OFF");
|
||||
aList.setMultipleMode(false);
|
||||
|
||||
selected = aList.getSelectedIndexes();
|
||||
if (selected[0] != 0 || selected.length != 1) {
|
||||
throw new RuntimeException(" Incorrect item remains selected " +
|
||||
"after setMultipleMode(false) or it is more then one " +
|
||||
"item remaining.Backward. ");
|
||||
}
|
||||
System.out.println("Test succeeded.");
|
||||
} finally {
|
||||
frame.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static void mousePress(int x, int y) {
|
||||
robot.mouseMove(x, y);
|
||||
robot.mousePress(InputEvent.BUTTON1_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_MASK);
|
||||
robot.delay(1000);
|
||||
}
|
||||
|
||||
private static void deselectAll() {
|
||||
for (int i = 0; i < selected.length; i++) {
|
||||
aList.deselect(selected[i]);
|
||||
}
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@
|
||||
/*
|
||||
@test
|
||||
@key headful
|
||||
@bug 8017472
|
||||
@bug 8017472 8211999
|
||||
@summary MouseEvent has wrong coordinates when using multiple monitors
|
||||
@run main MouseEventTest
|
||||
*/
|
||||
|
@ -24,6 +24,8 @@
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Robot;
|
||||
@ -38,7 +40,7 @@ import javax.imageio.ImageIO;
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @bug 8215105
|
||||
* @bug 8215105 8211999
|
||||
* @summary tests that Robot can capture the common colors without artifacts
|
||||
*/
|
||||
public final class CheckCommonColors {
|
||||
@ -48,16 +50,20 @@ public final class CheckCommonColors {
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
robot = new Robot();
|
||||
try {
|
||||
test();
|
||||
} finally {
|
||||
frame.dispose();
|
||||
var ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
for (GraphicsDevice gd : ge.getScreenDevices()) {
|
||||
try {
|
||||
test(gd.getDefaultConfiguration().getBounds());
|
||||
} finally {
|
||||
frame.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void test() {
|
||||
private static void test(Rectangle screen) {
|
||||
frame.setSize(400, 400);
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setLocation((int)screen.getCenterX() - 200,
|
||||
(int)screen.getCenterY() - 200);
|
||||
frame.setUndecorated(true);
|
||||
for (final Color color : List.of(Color.WHITE, Color.LIGHT_GRAY,
|
||||
Color.GRAY, Color.DARK_GRAY,
|
||||
@ -69,16 +75,25 @@ public final class CheckCommonColors {
|
||||
robot.waitForIdle();
|
||||
frame.setBackground(color);
|
||||
frame.setVisible(true);
|
||||
checkPixels(color);
|
||||
checkPixels(color, true);
|
||||
checkPixels(color, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkPixels(final Color color) {
|
||||
private static void checkPixels(final Color color, boolean useRect) {
|
||||
System.out.println("color = " + color + ", useRect = " + useRect);
|
||||
int attempt = 0;
|
||||
while (true) {
|
||||
Point p = frame.getLocationOnScreen();
|
||||
p.translate(frame.getWidth() / 2, frame.getHeight() / 2);
|
||||
Color pixel = robot.getPixelColor(p.x, p.y);
|
||||
Color pixel;
|
||||
Rectangle rect = new Rectangle(p.x, p.y, 1, 1);
|
||||
if (useRect) {
|
||||
BufferedImage bi = robot.createScreenCapture(rect);
|
||||
pixel = new Color(bi.getRGB(0, 0));
|
||||
} else {
|
||||
pixel = robot.getPixelColor(rect.x, rect.y);
|
||||
}
|
||||
if (color.equals(pixel)) {
|
||||
return;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,7 +32,7 @@ import java.awt.Robot;
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @bug 8201364 8232433
|
||||
* @bug 8201364 8232433 8211999
|
||||
* @summary Component.getLocation() should returns correct location if
|
||||
* Component.setBounds() was ignored by the OS
|
||||
*/
|
||||
@ -64,8 +64,11 @@ public final class LocationAtScreenCorner {
|
||||
Rectangle bounds = device.getDefaultConfiguration().getBounds();
|
||||
test(robot, frame, bounds.x, bounds.y);
|
||||
test(robot, frame, bounds.width, bounds.y);
|
||||
test(robot, frame, bounds.x + bounds.width, bounds.y);
|
||||
test(robot, frame, bounds.x, bounds.height);
|
||||
test(robot, frame, bounds.x, bounds.y + bounds.height);
|
||||
test(robot, frame, bounds.width, bounds.height);
|
||||
test(robot, frame, bounds.x + bounds.width, bounds.y + bounds.height);
|
||||
}
|
||||
frame.dispose();
|
||||
}
|
||||
|
95
test/jdk/java/awt/Window/SlowMotion/SlowMotion.java
Normal file
95
test/jdk/java/awt/Window/SlowMotion/SlowMotion.java
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Robot;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @bug 8211999
|
||||
* @run main/timeout=300 SlowMotion
|
||||
* @summary places the window on the screen outside of any insets, and waits to
|
||||
* catch any strange window moving
|
||||
*/
|
||||
public final class SlowMotion {
|
||||
|
||||
// some additional space, if getScreenInsets() does not work, say on Linux
|
||||
private static final int SAFE = 100;
|
||||
private static final int HEIGHT = 350;
|
||||
private static final int WIDTH = 279;
|
||||
private static Robot robot;
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
robot = new Robot();
|
||||
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
GraphicsDevice[] sds = ge.getScreenDevices();
|
||||
|
||||
for (GraphicsDevice sd : sds) {
|
||||
GraphicsConfiguration gc = sd.getDefaultConfiguration();
|
||||
Rectangle bounds = gc.getBounds();
|
||||
bounds.translate(SAFE, SAFE);
|
||||
Point point = new Point(bounds.x, bounds.y);
|
||||
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
|
||||
while (point.y < bounds.y + bounds.height - insets.bottom - HEIGHT - SAFE * 2) {
|
||||
while (point.x < bounds.x + bounds.width - insets.right - WIDTH - SAFE * 2) {
|
||||
test(point, new Frame());
|
||||
test(point, new Window(null));
|
||||
test(point, new Dialog((Dialog) null));
|
||||
point.translate(bounds.width / 6, 0);
|
||||
}
|
||||
point.setLocation(bounds.x, point.y + bounds.height / 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void test(final Point loc, Window window) {
|
||||
try {
|
||||
window.setBounds(loc.x, loc.y, WIDTH, HEIGHT);
|
||||
window.setVisible(true);
|
||||
robot.delay(1000); // intentionally very slow, we try to catch
|
||||
// very very last suspicion event
|
||||
Rectangle bounds = window.getBounds();
|
||||
if (loc.x != bounds.x || loc.y != bounds.y
|
||||
|| bounds.width != WIDTH || bounds.height != HEIGHT) {
|
||||
System.err.println("Component = " + window);
|
||||
System.err.println("Actual bounds = " + bounds);
|
||||
System.err.println("Expected location = " + loc);
|
||||
System.err.println("Expected width = " + WIDTH);
|
||||
System.err.println("Expected height = " + HEIGHT);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
} finally {
|
||||
window.dispose();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Robot;
|
||||
import java.awt.Window;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @bug 8211999
|
||||
* @summary The test creates the packed/unpacked top level components on the
|
||||
* different screens and compares their bounds
|
||||
* @run main/othervm WindowSizeDifferentScreens
|
||||
* @run main/othervm -Dsun.java2d.uiScale=1 WindowSizeDifferentScreens
|
||||
* @run main/othervm -Dsun.java2d.uiScale=1.25 WindowSizeDifferentScreens
|
||||
*/
|
||||
public final class WindowSizeDifferentScreens {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
test("window");
|
||||
test("dialog");
|
||||
test("frame");
|
||||
}
|
||||
|
||||
private static void test(String top) throws Exception {
|
||||
var ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
Robot robot = new Robot();
|
||||
Window main = getTopLevel(top);
|
||||
try {
|
||||
main.setVisible(true);
|
||||
robot.waitForIdle();
|
||||
main.setSize(500, 500);
|
||||
robot.waitForIdle();
|
||||
for (GraphicsDevice gd : ge.getScreenDevices()) {
|
||||
Rectangle bounds = gd.getDefaultConfiguration().getBounds();
|
||||
Point point = bounds.getLocation();
|
||||
point.translate(100, 100);
|
||||
main.setLocation(point);
|
||||
main.setBackground(Color.RED);
|
||||
robot.waitForIdle();
|
||||
|
||||
Window packed = getTopLevel(top);
|
||||
Window unpacked = getTopLevel(top);
|
||||
try {
|
||||
packed.pack();
|
||||
robot.waitForIdle();
|
||||
packed.setBackground(Color.GREEN);
|
||||
unpacked.setBackground(Color.BLUE);
|
||||
packed.setSize(500, 500);
|
||||
unpacked.setSize(500, 500);
|
||||
packed.setLocation(point);
|
||||
unpacked.setLocation(point);
|
||||
robot.waitForIdle();
|
||||
packed.setVisible(true);
|
||||
unpacked.setVisible(true);
|
||||
robot.waitForIdle();
|
||||
Rectangle mBounds = main.getBounds();
|
||||
Rectangle pBounds = packed.getBounds();
|
||||
Rectangle uBounds = unpacked.getBounds();
|
||||
|
||||
if (!mBounds.equals(uBounds) ||
|
||||
!mBounds.equals(pBounds)) {
|
||||
System.err.println("Expected bounds: " + mBounds);
|
||||
System.err.println("Actual unpacked: " + uBounds);
|
||||
System.err.println("Actual packed: " + pBounds);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
} finally {
|
||||
packed.dispose();
|
||||
unpacked.dispose();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
main.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static Window getTopLevel(String top) {
|
||||
return switch (top) {
|
||||
case "window" -> new Window(null);
|
||||
case "dialog" -> new Dialog((Dialog) null);
|
||||
case "frame" -> new Frame();
|
||||
default -> throw new IllegalArgumentException("Unexpected: " + top);
|
||||
};
|
||||
}
|
||||
}
|
@ -23,10 +23,10 @@
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Robot;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.dnd.DnDConstants;
|
||||
@ -47,7 +47,7 @@ import test.java.awt.regtesthelpers.Util;
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @bug 4955110 8238575
|
||||
* @bug 4955110 8238575 8211999
|
||||
* @summary tests that DragSourceDragEvent.getDropAction() accords to its new
|
||||
* spec (does not depend on the user drop action)
|
||||
* @library ../../regtesthelpers
|
||||
@ -57,6 +57,7 @@ import test.java.awt.regtesthelpers.Util;
|
||||
*/
|
||||
public final class Button2DragTest {
|
||||
|
||||
private static final int SIZE = 200;
|
||||
private volatile boolean dropSuccess;
|
||||
private volatile boolean locationValid = true;
|
||||
|
||||
@ -79,8 +80,8 @@ public final class Button2DragTest {
|
||||
final DragSourceListener dragSourceListener = new DragSourceListener() {
|
||||
private void checkLocation(DragSourceEvent dsde) {
|
||||
if (!frame.getBounds().contains(dsde.getLocation())) {
|
||||
System.err.println("Expected in" + frame.getBounds());
|
||||
System.err.println("Actual" + dsde.getLocation());
|
||||
System.err.println("Expected in: " + frame.getBounds());
|
||||
System.err.println("Actual: " + dsde.getLocation());
|
||||
locationValid = false;
|
||||
}
|
||||
}
|
||||
@ -130,8 +131,10 @@ public final class Button2DragTest {
|
||||
|
||||
frame.setBackground(Color.GREEN);
|
||||
frame.setUndecorated(true);
|
||||
frame.setSize(200, 200);
|
||||
frame.setLocationRelativeTo(null);
|
||||
Rectangle screen = frame.getGraphicsConfiguration().getBounds();
|
||||
int x = (int) (screen.getCenterX() - SIZE / 2);
|
||||
int y = (int) (screen.getCenterY() - SIZE / 2);
|
||||
frame.setBounds(x, y, SIZE, SIZE);
|
||||
frame.setVisible(true);
|
||||
|
||||
Robot robot = Util.createRobot();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,7 +24,10 @@
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Robot;
|
||||
import java.awt.event.InputEvent;
|
||||
import javax.swing.JFrame;
|
||||
@ -35,13 +38,15 @@ import javax.swing.SwingUtilities;
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @bug 8149849
|
||||
* @bug 8149849 8211999
|
||||
* @summary [hidpi] DnD issues (cannot DnD from JFileChooser to JEditorPane or
|
||||
* other text component) when scale > 1
|
||||
* @run main/othervm DNDTextToScaledArea
|
||||
* @run main/othervm -Dsun.java2d.uiScale=2 DNDTextToScaledArea
|
||||
*/
|
||||
public class DNDTextToScaledArea {
|
||||
|
||||
private static final int SIZE = 300;
|
||||
private static final String TEXT = "ABCDEFGH";
|
||||
private static JFrame frame;
|
||||
private static JTextArea srcTextArea;
|
||||
@ -51,10 +56,17 @@ public class DNDTextToScaledArea {
|
||||
private static volatile boolean passed = false;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Robot robot = new Robot();
|
||||
robot.setAutoDelay(50);
|
||||
var lge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
for (GraphicsDevice device : lge.getScreenDevices()) {
|
||||
test(device);
|
||||
}
|
||||
}
|
||||
|
||||
SwingUtilities.invokeAndWait(DNDTextToScaledArea::createAndShowGUI);
|
||||
private static void test(GraphicsDevice device) throws Exception {
|
||||
Robot robot = new Robot();
|
||||
robot.setAutoDelay(150);
|
||||
|
||||
SwingUtilities.invokeAndWait(() -> createAndShowGUI(device));
|
||||
robot.waitForIdle();
|
||||
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
@ -62,6 +74,11 @@ public class DNDTextToScaledArea {
|
||||
dstPoint = getPoint(dstTextArea, 0.75);
|
||||
});
|
||||
robot.waitForIdle();
|
||||
// check the destination
|
||||
robot.mouseMove(dstPoint.x, dstPoint.y);
|
||||
robot.mousePress(InputEvent.BUTTON1_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_MASK);
|
||||
robot.waitForIdle();
|
||||
|
||||
dragAndDrop(robot, srcPoint, dstPoint);
|
||||
robot.waitForIdle();
|
||||
@ -77,11 +94,12 @@ public class DNDTextToScaledArea {
|
||||
}
|
||||
}
|
||||
|
||||
private static void createAndShowGUI() {
|
||||
|
||||
frame = new JFrame();
|
||||
frame.setSize(300, 300);
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
private static void createAndShowGUI(GraphicsDevice device) {
|
||||
frame = new JFrame(device.getDefaultConfiguration());
|
||||
Rectangle screen = device.getDefaultConfiguration().getBounds();
|
||||
int x = (int) (screen.getCenterX() - SIZE / 2);
|
||||
int y = (int) (screen.getCenterY() - SIZE / 2);
|
||||
frame.setBounds(x, y, SIZE, SIZE);
|
||||
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user