python-mss
python-mss copied to clipboard
SetProcessDpiAwareness Failed to fit High DPI in windows if once called
General information:
- OS name: Windows
- OS version: Windows 10 version 2004
- OS architecture: 64 bits
- Resolutions:
- Monitor 1: 1920x1080, scale 1.25 (Laptop)
- Monitor 2: 1920x1080, scale 1.00 (External, Main)
- Python version: 3.7.5
- MSS version: 6.0.0
Description of the warning/error
Once first time setting DPI awareness is not PROCESS_PER_MONITOR_DPI_AWARE=2
, mss
will not fit DPI scaling for all monitors.
Details
According to Microsoft Docs SetProcessDpiAwareness:
Once API awareness is set for an app, any future calls to this API will fail.
This function will return S_OK=0
only if first time to set DPI awareness, otherwise return E_ACCESSDENIED=0x80070005=-2147024891
. We can print the return value to check it.
Available DPI awareness setting functions including:
-
SetProcessDpiAwareness
-
SetProcessDpiAware
should equals toSetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE=1)
-
SetProcessDpiAwarenessContext
not tested -
SetThreadDpiAwarenessContext
not tested
In this mss
package, we use SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE=2)
inside __init__
. However some other python packages will just call SetProcessDpiAware()
during import process, like mouseinfo
/ pyautogui
/ pyscreeze
. It means that only monitor which startup program has the correct DPI awareness(PROCESS_SYSTEM_DPI_AWARE
) while mostly we need PROCESS_PER_MONITOR_DPI_AWARE
.
Then mss
uses user32.EnumDisplayMonitors
to get monitor RECT and this function is affected by DPI awareness setting.
Solution
Currently I have no idea about how to avoid E_ACCESSDENIED
error, one possible way is to get the real resolution of monitors regardless of DPI awareness.
According to Microsoft Docs of functions with prefix EnumDisplaySettings
, e.g. EnumDisplaySettingsA, EnumDisplaySettingsExA
, EnumDisplaySettingsExW
, EnumDisplaySettingsW
:
This API does not participate in DPI virtualization. The output given is always in terms of physical pixels, and is not related to the calling context.
I think it may be a prefer way to obtain monitor information. But I never learned Windows programming, hope anyone else can help on this problem.
Upvote & Fund
- We're using Polar.sh so you can upvote and help fund this issue.
- We receive the funding once the issue is completed & confirmed by you.
- Thank you in advance for helping prioritize & fund our backlog.