8279227: Access Bridge: Wrong frame position and hit test result on HiDPI display#72
8279227: Access Bridge: Wrong frame position and hit test result on HiDPI display#72VeselovAlex wants to merge 4 commits into
Conversation
…iDPI display Perform scaling while converting sizes and coordinates to provide correct positions of accessible elements on HiDPI screen and make hit-test work properly. It uses FontRenderContext to receive display scale without API changes.
|
👋 Welcome back VeselovAlex! A progress list of the required criteria for merging this PR into |
|
@VeselovAlex The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
|
@VeselovAlex This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be: You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 41 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@forantar, @azuev-java, @aivanov-jdk) but any other Committer may sponsor as well. ➡️ To flag this PR as ready for integration with the above commit message, type |
|
@mrserb take a look |
| r.y = (int) Math.floor(r.y * at.getScaleY()); | ||
| r.width = (int) Math.ceil(r.width * at.getScaleX()); | ||
| r.height = (int) Math.ceil(r.height * at.getScaleY()); | ||
| } |
There was a problem hiding this comment.
This logic will not work on the multiscreen configs when the monitors have different DPI, the logic should be similar to the SunGraphicsEnvironment.toDeviceSpace().
and probably the round logic should use Region.clipRound as well.
There was a problem hiding this comment.
If this data will be used in native then we can try to use device->ScaleDownAbsX/Y, etc methods.
| if (acomp != null) { | ||
| FontMetrics fm = acomp.getFontMetrics(acomp.getFont()); | ||
| if (fm != null) { | ||
| return fm.getFontRenderContext().getTransform(); |
There was a problem hiding this comment.
I am not sure do we really update the FRC for the component when the DPI is changed?
There was a problem hiding this comment.
I've checked it - it does not change, which is unexpected... Doesn't it seem like a bug?
Actually, the problem is that AccessibleComponent does not provide the component's GC, which is a missing. Ideally would be to add it to the API and then use - because it already contains actual scales for the component. It's a pity to do all that calculations just because we lack API calls...
Is it worth trying to fix the font metrics update instead and use it until the new API is ready and available?
There was a problem hiding this comment.
I've checked it - it does not change, which is unexpected... Doesn't it seem like a bug?
Yes, I think this is a bug.
Actually, the problem is that AccessibleComponent does not provide the component's GC, which is a missing. Ideally would be to add it to the API and then use - because it already contains actual scales for the component. It's a pity to do all that calculations just because we lack API calls...
But do we actually need the GC where the component is located, or do we need a GC where the a11y frame should be placed? I am not sure that both are always the same. Note that you can find the screen where the "virtual coordinates are located" and then convert them to the device space.
There was a problem hiding this comment.
But do we actually need the GC where the component is located, or do we need a GC where the a11y frame should be placed? I am not sure that both are always the same. Note that you can find the screen where the "virtual coordinates are located" and then convert them to the device space.
Well, in AccessBridge.getAccessibleContextAt_1(int x, int y, AccessibleContext parent) we expect [x, y] within the parent bounds and so we can assume [x, y] has the same scaling. However, AccessBridge.getAccessibleContextAt_2 works with generic [x, y] and there we have to perform generic transformation, indeed...
Ok, if we can't avoid it, then I'm ok with the latest version (taking into account my inline comments). Thanks!
|
Hi, @mrserb, thanks for the review. Your idea is awesome and I've tried to implement it. It contains some copied code from But the issue with different scale factors on multi-display configuration is still present, frame size scaling seems to be stuck at primary display's scale factor. |
| * | ||
| * @param current the default configuration which is checked in the first | ||
| * place | ||
| * @param x the x coordinate of the given point |
There was a problem hiding this comment.
Please specify in which space the coordinates are expected.
There was a problem hiding this comment.
Hi, @mrserb, thanks for the review. Your idea is awesome and I've tried to implement it. It contains some copied code from
sun.java2dbut I can't import necessary methods without adding it to dependencies.
Probably we can export that to the "jdk.accessibility" module? We already export "sun.awt" the same way. @prrace any thoughts?
But it will be good to make sure that it will work on a multiscreen config before doing that. At least need to understand the root cause of that.
| */ | ||
| public static GraphicsConfiguration getGraphicsConfigurationAtPoint( | ||
| GraphicsConfiguration current, double x, double y) { | ||
| if (current.getBounds().contains(x, y)) { |
There was a problem hiding this comment.
Here you do not translate the bounds to device space. Actually, I'd remove this check at all, as below you duplicate it. Also, when you call the method you pass the default GC, so it seems it does not bring much profit...
Also move GraphicsConfiguration search into AccessibilityGraphicsEnvironment
|
Tested your patch with NVDA 2021.3.1 and it worked well for me. |
Seems worth reporting this to NVDA (https://github.com/nvaccess/nvda/#communication-channels). |
azuev-java
left a comment
There was a problem hiding this comment.
Tested on Windows 10 and Windows 11 with dual monitor configuration with different scale factors - last version of the fix seems to be working fine.
|
Based on 3 approves and successful testing this fix can be integrated (we are approaching RDP2 for JDK18). |
|
@forantar Only the author (@VeselovAlex) is allowed to issue the |
|
/integrate |
|
@VeselovAlex |
|
/sponsor |
|
Going to push as commit 20ef954.
Your commit was automatically rebased without conflicts. |
|
@forantar @VeselovAlex Pushed as commit 20ef954. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |

Perform scaling while converting sizes and coordinates to provide correct positions of accessible elements on HiDPI screen and make hit-test work properly. It uses FontRenderContext to receive display scale without API changes.
Progress
Issue
Reviewers
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk18 pull/72/head:pull/72$ git checkout pull/72Update a local copy of the PR:
$ git checkout pull/72$ git pull https://git.openjdk.java.net/jdk18 pull/72/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 72View PR using the GUI difftool:
$ git pr show -t 72Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk18/pull/72.diff