asweigart / pyautogui

A cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard.
BSD 3-Clause "New" or "Revised" License
10.22k stars 1.24k forks source link

importing pyautogui affects pywin32's coordinate system #697

Closed SY-LG closed 2 years ago

SY-LG commented 2 years ago

Description

Windows has two sets of coordinate system: Client and Screen. Importing pyautogui affects pywin32's coordinate system.

Environment

How to Reproduce

code:

import win32api
print(f"x={win32api.GetSystemMetrics(0)} y={win32api.GetSystemMetrics(1)}")
import pyautogui
print(f"x={win32api.GetSystemMetrics(0)} y={win32api.GetSystemMetrics(1)}")

result:

x=1493 y=933
x=2240 y=1400
asweigart commented 2 years ago

This is intended behavior. PyAutoGUI automatically calls the win32 system call SetProcessDPIAware() on Windows so that the Python interpreter is aware of any scaling for the monitor. PyWin32 doesn't do this. Your main monitor's true resolution is 2240x1400, but the scaling is set to 150%. (This is a feature that prevents the application windows and ui from appearing too small to read comfortably.) This is why initially PyWin32 reports it as 1493x933 (because 2240 / 1.5 = 1493 and 1400 / 1.5 = 933).

I'm going to close this issue, since PyAutoGUI needs to be aware of the true monitor resolution to work correctly.

SY-LG commented 2 years ago

Well, I was thinking that there could be a way to limit the scale of SetProcessDPIAware(), for example doing the 1.5 multiplication every time. But then I tried and found that this would somehow affect the accuracy because the coordinates are integer and would omit the .5 part brought by the multiplication. I believe there are more reasons that support using SetProcessDPIAware(), but I suggest putting a note inside README.

In my case, I use win32gui.MoveWindow() to adjust the window size. First I tried that in a test file (which I didn't import pyautogui) and then implied it in my work file(which, pyautogui is imported by other files). The difference of the effect of MoveWindow() really confused me and took me a lot of time to debug. I guess putting a note may be helpful :)