8279227: Access Bridge: Wrong frame position and hit test result on HiDPI display
Reviewed-by: ant, kizune, aivanov
This commit is contained in:
parent
bd35f9740d
commit
20ef954158
@ -27,6 +27,7 @@ package com.sun.java.accessibility.internal;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.util.*;
|
||||
import java.lang.*;
|
||||
import java.lang.reflect.*;
|
||||
@ -478,6 +479,9 @@ public final class AccessBridge {
|
||||
if (parent == null) {
|
||||
return null;
|
||||
}
|
||||
Point userSpaceXY = AccessibilityGraphicsEnvironment.toUserSpace(x, y);
|
||||
x = userSpaceXY.x;
|
||||
y = userSpaceXY.y;
|
||||
if (windowHandleToContextMap != null &&
|
||||
windowHandleToContextMap.containsValue(getRootAccessibleContext(parent))) {
|
||||
// Path for applications that register their top-level
|
||||
@ -1593,6 +1597,8 @@ public final class AccessBridge {
|
||||
if (p != null) {
|
||||
r.x = p.x;
|
||||
r.y = p.y;
|
||||
|
||||
r = AccessibilityGraphicsEnvironment.toDeviceSpaceAbs(r);
|
||||
return r;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -2257,6 +2263,7 @@ public final class AccessBridge {
|
||||
if (s != null && s.equals("\n")) {
|
||||
rect.width = 0;
|
||||
}
|
||||
rect = AccessibilityGraphicsEnvironment.toDeviceSpaceAbs(rect);
|
||||
return rect;
|
||||
}
|
||||
}
|
||||
@ -7338,4 +7345,182 @@ public final class AccessBridge {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper class to handle coordinate conversion between screen and user spaces.
|
||||
* See {@link sun.java2d.SunGraphicsEnvironment}
|
||||
*/
|
||||
private static abstract class AccessibilityGraphicsEnvironment extends GraphicsEnvironment {
|
||||
/**
|
||||
* Returns the graphics configuration which bounds contain the given point in the user's space.
|
||||
*
|
||||
* See {@link sun.java2d.SunGraphicsEnvironment#getGraphicsConfigurationAtPoint(GraphicsConfiguration, double, double)}
|
||||
*
|
||||
* @param x the x coordinate of the given point in the user's space
|
||||
* @param y the y coordinate of the given point in the user's space
|
||||
* @return the graphics configuration
|
||||
*/
|
||||
public static GraphicsConfiguration getGraphicsConfigurationAtPoint(double x, double y) {
|
||||
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
|
||||
.getDefaultScreenDevice().getDefaultConfiguration();
|
||||
return getGraphicsConfigurationAtPoint(gc, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the graphics configuration which bounds contain the given point in the user's space.
|
||||
*
|
||||
* See {@link sun.java2d.SunGraphicsEnvironment#getGraphicsConfigurationAtPoint(GraphicsConfiguration, double, double)}
|
||||
*
|
||||
* @param current the default configuration which is checked in the first
|
||||
* place
|
||||
* @param x the x coordinate of the given point in the user's space
|
||||
* @param y the y coordinate of the given point in the user's space
|
||||
* @return the graphics configuration
|
||||
*/
|
||||
public static GraphicsConfiguration getGraphicsConfigurationAtPoint(
|
||||
GraphicsConfiguration current, double x, double y) {
|
||||
if (containsUserSpacePoint(current, x, y)) {
|
||||
return current;
|
||||
}
|
||||
GraphicsEnvironment env = getLocalGraphicsEnvironment();
|
||||
for (GraphicsDevice device : env.getScreenDevices()) {
|
||||
GraphicsConfiguration config = device.getDefaultConfiguration();
|
||||
if (containsUserSpacePoint(config, x, y)) {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the graphics configuration which bounds contain the given point in the device space.
|
||||
*
|
||||
* @param x the x coordinate of the given point in the device space
|
||||
* @param y the y coordinate of the given point in the device space
|
||||
* @return the graphics configuration
|
||||
*/
|
||||
public static GraphicsConfiguration getGraphicsConfigurationAtDevicePoint(double x, double y) {
|
||||
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
|
||||
.getDefaultScreenDevice().getDefaultConfiguration();
|
||||
return getGraphicsConfigurationAtDevicePoint(gc, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the graphics configuration which bounds contain the given point in the device space.
|
||||
*
|
||||
* @param current the default configuration which is checked in the first
|
||||
* place
|
||||
* @param x the x coordinate of the given point in the device space
|
||||
* @param y the y coordinate of the given point in the device space
|
||||
* @return the graphics configuration
|
||||
*/
|
||||
public static GraphicsConfiguration getGraphicsConfigurationAtDevicePoint(
|
||||
GraphicsConfiguration current, double x, double y) {
|
||||
if (containsDeviceSpacePoint(current, x, y)) {
|
||||
return current;
|
||||
}
|
||||
GraphicsEnvironment env = getLocalGraphicsEnvironment();
|
||||
for (GraphicsDevice device : env.getScreenDevices()) {
|
||||
GraphicsConfiguration config = device.getDefaultConfiguration();
|
||||
if (containsDeviceSpacePoint(config, x, y)) {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
private static boolean containsDeviceSpacePoint(GraphicsConfiguration config, double x, double y) {
|
||||
Rectangle bounds = config.getBounds();
|
||||
bounds = toDeviceSpaceAbs(config, bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
return bounds.contains(x, y);
|
||||
}
|
||||
|
||||
private static boolean containsUserSpacePoint(GraphicsConfiguration config, double x, double y) {
|
||||
Rectangle bounds = config.getBounds();
|
||||
return bounds.contains(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts absolute coordinates from the device
|
||||
* space to the user's space space using appropriate device transformation.
|
||||
*
|
||||
* @param x absolute x coordinate in the device's space
|
||||
* @param y absolute y coordinate in the device's space
|
||||
* @return the corresponding coordinates in user's space
|
||||
*/
|
||||
public static Point toUserSpace(int x, int y) {
|
||||
GraphicsConfiguration gc = getGraphicsConfigurationAtDevicePoint(x, y);
|
||||
return toUserSpace(gc, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts absolute coordinates from the device
|
||||
* space to the user's space using passed graphics configuration.
|
||||
*
|
||||
* @param gc the graphics configuration to be used for transformation
|
||||
* @param x absolute x coordinate in the device's space
|
||||
* @param y absolute y coordinate in the device's space
|
||||
* @return the corresponding coordinates in user's space
|
||||
*/
|
||||
public static Point toUserSpace(GraphicsConfiguration gc, int x, int y) {
|
||||
AffineTransform tx = gc.getDefaultTransform();
|
||||
Rectangle screen = gc.getBounds();
|
||||
int userX = screen.x + clipRound((x - screen.x) / tx.getScaleX());
|
||||
int userY = screen.y + clipRound((y - screen.y) / tx.getScaleY());
|
||||
return new Point(userX, userY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the rectangle from the user's space to the device space using
|
||||
* appropriate device transformation.
|
||||
*
|
||||
* See {@link sun.java2d.SunGraphicsEnvironment#toDeviceSpaceAbs(Rectangle)}
|
||||
*
|
||||
* @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 = getGraphicsConfigurationAtPoint(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.
|
||||
*
|
||||
* See {@link sun.java2d.SunGraphicsEnvironment#toDeviceSpaceAbs(GraphicsConfiguration, int, int, int, int)}
|
||||
*
|
||||
* @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 + clipRound((x - screen.x) * tx.getScaleX()),
|
||||
screen.y + clipRound((y - screen.y) * tx.getScaleY()),
|
||||
clipRound(w * tx.getScaleX()),
|
||||
clipRound(h * tx.getScaleY())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link sun.java2d.pipe.Region#clipRound}
|
||||
*/
|
||||
private static int clipRound(final double coordinate) {
|
||||
final double newv = coordinate - 0.5;
|
||||
if (newv < Integer.MIN_VALUE) {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
if (newv > Integer.MAX_VALUE) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
return (int) Math.ceil(newv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user