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.*;
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.lang.*;
|
import java.lang.*;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
@ -478,6 +479,9 @@ public final class AccessBridge {
|
|||||||
if (parent == null) {
|
if (parent == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
Point userSpaceXY = AccessibilityGraphicsEnvironment.toUserSpace(x, y);
|
||||||
|
x = userSpaceXY.x;
|
||||||
|
y = userSpaceXY.y;
|
||||||
if (windowHandleToContextMap != null &&
|
if (windowHandleToContextMap != null &&
|
||||||
windowHandleToContextMap.containsValue(getRootAccessibleContext(parent))) {
|
windowHandleToContextMap.containsValue(getRootAccessibleContext(parent))) {
|
||||||
// Path for applications that register their top-level
|
// Path for applications that register their top-level
|
||||||
@ -1593,6 +1597,8 @@ public final class AccessBridge {
|
|||||||
if (p != null) {
|
if (p != null) {
|
||||||
r.x = p.x;
|
r.x = p.x;
|
||||||
r.y = p.y;
|
r.y = p.y;
|
||||||
|
|
||||||
|
r = AccessibilityGraphicsEnvironment.toDeviceSpaceAbs(r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -2257,6 +2263,7 @@ public final class AccessBridge {
|
|||||||
if (s != null && s.equals("\n")) {
|
if (s != null && s.equals("\n")) {
|
||||||
rect.width = 0;
|
rect.width = 0;
|
||||||
}
|
}
|
||||||
|
rect = AccessibilityGraphicsEnvironment.toDeviceSpaceAbs(rect);
|
||||||
return 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