8340870: [WIN] Checkbox is not sized according to uiScale #26221
+11
−20
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
JDK-8294427 introduced code to solve the rendering quality of the graphic portions of checkboxes and radio buttons, by loading the graphics for the desired DPI directly via the native Windows theming system instead of having to resort to scaling.
For that, it uses the
OpenThemeDataForDpi
API, and while I couldn't fault the actual logic it applies when using the API, it unfortunately ignores a significant limitation of this api [1]:"The behavior of the returned theme handle will be undermined if the requested DPI value does not correspond to a currently connected display. The theming system only loads theme assets for the set of DPI values corresponding to the currently connected displays."
In practice, this means that when setting uiScale to a value that results a DPI value not matching any if the connected screens, the api call will always return a graphic asset for the control, but it most likely won't be the one for the requested resolution, which results in the size of the graphic asset not matching the rest of the UI.


Even more confusingly, if you had a switched to that particular display scale recently on any of the connected screen, then the theme may still be loaded and the api call may yet return the right asset, even if there are no longer any screen set to this scale (which made for a fair amount of confusion and frustration while trying to reproduce and understand the issue!)
While I don't believe there is a way to solve this problem in an entirely satisfying way, I nevertheless it's worth considering a different trade off which would result in the controls being rendered at the correct size, at the cost of crispness and image quality just for the boxes (not the whole app). In the absence of a perfect solution, I think that rendering the control in the right size is more valuable than having it looking pixel perfect (but too small), as this might otherwise affect accessibility for users with visual impairments or motor disabilities.

Since the
DrawThemeBackground
used to draw the picture already supports re-scaling to a desired size [2], the PR attempts to achieve this by simply removing the logic that does a first theme look-up to determine the effective size of the control and instead use the computed size, forcingpaintBackground
to re-scaled it if it doesn't match.[1] https://learn.microsoft.com/en-us/windows/win32/api/uxtheme/nf-uxtheme-openthemedatafordpi
[2] https://learn.microsoft.com/en-us/windows/win32/api/uxtheme/nf-uxtheme-drawthemebackground#remarks
Progress
Error
Issue
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/26221/head:pull/26221
$ git checkout pull/26221
Update a local copy of the PR:
$ git checkout pull/26221
$ git pull https://git.openjdk.org/jdk.git pull/26221/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 26221
View PR using the GUI difftool:
$ git pr show -t 26221
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/26221.diff