New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use modern DPI awareness settings #13254
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
Hi @VeselovAlex, welcome to the NVDA project! Thanks for your contribution. This looks like a good change, however it would help if there was more information about the cause. To help with this we use a pull request template which outlines the information that we require. Would you be able to fill this out for us? I can confirm this rectifies the visual highlighting in the case outlined in the description on my machine.
There is a call to This seems to depend on DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2, from the docs:
Can you update the description to cover what will happen for Windows versions before the "Creators Update" ( Just an FYI for future contributions, the contributing guidelines recommend creating an issue / commenting on an issue before you start. The intention is to
You may have done this, but there is no link to an issue (requested in the PR template). |
Further action is required on this PR, converting it to a draft until this is resolved:
|
Hi @feerrenrut, thanks for the feedback and sorry for the delay. I've update PR description, added PerMonitor as a fallback and removed explicit BTW, there is a fixed issue JDK-8279227 with HiDPI support in JDK and the fix will be released soon (OpenJDK 18 or 17.4). This fix will affect NVDA too |
This comment was marked as outdated.
This comment was marked as outdated.
Hi @VeselovAlex, thanks for the updates. Do you know why the manifest approach is preferred? I'm guessing the manifest approach is helpful for supporting older versions of Windows? It would be good if we could support developers (who will mostly run from the script), but not at the cost of users. |
Reading the docs again, I think we should do both (use the manifest, and set in code). Setting from code should only be active for source copies, and will need to take into account the Windows version. This may seem pointless, but the value is in supporting developers. It's easy to imagine a situation where a developer is trying to track down a breakage in 'picking' (getting the UI element at screen coords) that only occurs with the source copy. Keeping the manifest approach for executable versions lowers the risk that we get Windows capabilities wrong for end users. |
@VeselovAlex If you don't mind, I'm going to look into this myself. I may push several commits to get this PR moving again. |
Test if this also fixes: #6722 |
This change makes NVDA DPI-aware to fix wrong size and position of accessible elements on the second display if its DPI differs from the first one's
See test results for failed build of commit 513e340e56 |
97dece1
to
ea9e1e3
Compare
See test results for failed build of commit 8cf134e323 |
I've added a DPI awareness setup when NVDA is running as a script. Also #6722 seems to be fixed with this PR |
See test results for failed build of commit 83193c2148 |
This PR has now been tested and is ready for review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work here, looks solid. Can you clarify whether items in the description under "testing" are tested but not fixed, or not yet tested. I have assumed the former.
source/core.py
Outdated
@@ -427,8 +427,9 @@ def main(): | |||
Finally, it starts the wx main loop. | |||
""" | |||
log.debug("Core starting") | |||
|
|||
ctypes.windll.user32.SetProcessDPIAware() | |||
if globalVars.runningAsSource: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment here to highlight that this is handled via the manifest for packaged versions.
@feerrenrut - correct, these are things tested but not fixed fully |
…PI awareness (#14161) fix-up of #13254 Summary of the issue: After #13254 got merged NVDA failed to start from sources on Windows 7 with the following exception: CRITICAL - __main__ (16:59:34.992) - MainThread (6908): core failure Traceback (most recent call last): File "nvda.pyw", line 393, in <module> core.main() File "core.py", line 436, in main setDPIAwareness() File "winAPI\dpiAwareness.py", line 67, in setDPIAwareness hResult = ctypes.windll.shcore.SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE) File "C:\Python37\lib\ctypes\__init__.py", line 434, in __getattr__ dll = self._dlltype(name) File "C:\Python37\lib\ctypes\__init__.py", line 364, in __init__ self._handle = _dlopen(self._name, mode) OSError: [WinError 126] The specified module cannot be found While we handle different versions of Windows by catching AttributeError if the given function for setting DPI awareness is not present on Windows 7 shcore is missing and ctypes raises a different error for missing libraries. Description of user facing changes NVDA can once again start from sources when running on Windows 7. Description of development approach In addition to catching AttributeError we also catch WindowsError and inspect its error code. If it is caused by the missing library appropriate info is logged and the function continues to use legacy method of setting DPI awareness. Note that AttributeError has to be handled as well to allow NVDA to start on Windows 8/Server 2012.
Link to issue number:
Fixes #13370
Fixes #6722
Fixes #3875
Fixes #12070
Fixes #7083
Likely fixes #9531, otherwise close as stale/can't reproduce
Summary of the issue:
When DPI for a monitor is not set to 100%, or when using multiple monitors with different DPI settings,
NVDA would:
NVDA currently sets the DPI awareness via a Windows API call introduced in Windows Vista.
It is recommended to set DPI through the app manifest, rather than Windows API calls where possible.
Newer settings for DPI awareness have been introduced since Windows Vista.
Windows 8 introduced multiple monitor DPI awareness.
Windows 10 introduced a richer version of multiple monitor DPI awareness.
Description of how this pull request fixes the issue:
Background docs: https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows#per-monitor-and-per-monitor-v2-dpi-awareness
When running as an executable, NVDA sets DPI awareness via the app manifest.
When running through source, NVDA sets DPI awareness via Windows API calls.
The most modern method available is used to set DPI awareness.
Testing strategy:
Manual testing
Using
Test mouse tracking with
Test visual highlight with
Test touch screen with
Known issues with pull request:
#7915, #13440 and #8076 are still remaining issues.
Change log entries:
Code Review Checklist: