On Thu, 28 Jul 2022 15:01:34 GMT, Kevin Rushforth <k...@openjdk.org> wrote:

> When using the Windows Narrator screen reader on a Hi-DPI screen, the visible 
> focus is drawn in the wrong location and with the wrong size. This happens 
> because the the JavaFX Windows accessibility code that returns the screen 
> bounds of the requested UI element does not take the screen scale into 
> account.
> 
> The fix is to adjust the bounds by the screen scale before returning it.
> 
> You can test it on a Windows machine with scaling set to >= 125% as follows:
> 1. Turn on Windows Narrator
> 2. Run any JavaFX program with at least UI controls, for example, 
> `hello.HelloTextField` in `apps/toys/Hello`
> 3. TAB between the controls
> 
> Without the fix, Narrator shows the focus indicator in the wrong position and 
> is too small. With the fix, it is correct. While testing this, I discovered 
> an unrelated (and preexisting) bug where the focus indicator for a TextField 
> or TextArea whose content is larger that the control (and is displayed with 
> scroll bars) is not clipped to the visible area. This happens regardless of 
> screen scale. I will file a follow-up bug for this.
> 
> Note that this bug is specific to Windows. It does not occur on macOS, which 
> works correctly on a retina or non-retina display.

Getting back to this, I discovered what the problem was with some multi-screens 
layouts when two screens have a different scale. Computing the platform x and y 
by simply multiplying by the scale is not right, and only work for a screen 
that touches the origin of the virtual screen space (in both X and Y). When the 
secondary screen is to the left or above the primary screen, the simple (but 
incorrect) calculation gives the same result as the correct calculation. For a 
secondary screen below or to the right of the primary screen, it doesn't. 
Simply scaling the coordinate about the origin produces a value that is either 
too small or too large when the two screens have a different scale.

The right fix is to use the `Screen.toPlatformX` and `Screen.toPlatformY` 
methods, which take this into account, and translates the coordinate to the 
right origin, scales it, and then translates it back. In order to do that, I 
needed to get the `Window` from which I could get the `Screen`, which required 
making the quantum `WindowStage` class public along with its `getWindow` 
method. This is an internal implementation class, so is not a concern.

I've tested this updated version in various combinations of layout and screen 
scales, and everything now works as expected.

-------------

PR: https://git.openjdk.org/jfx/pull/853

Reply via email to