Get window position & size with python
Question:
How can I get and set the window (any windows program) position and size with python?
Answers:
Assuming you’re on Windows, try using pywin32
‘s win32gui
module with its EnumWindows
and GetWindowRect
functions.
If you’re using Mac OS X, you could try using appscript
.
For Linux, you can try one of the many interfaces to X11.
Edit: Example for Windows (not tested):
import win32gui
def callback(hwnd, extra):
rect = win32gui.GetWindowRect(hwnd)
x = rect[0]
y = rect[1]
w = rect[2] - x
h = rect[3] - y
print("Window %s:" % win32gui.GetWindowText(hwnd))
print("tLocation: (%d, %d)" % (x, y))
print("t Size: (%d, %d)" % (w, h))
def main():
win32gui.EnumWindows(callback, None)
if __name__ == '__main__':
main()
You can get the window coordinates using the GetWindowRect
function. For this, you need a handle to the window, which you can get using FindWindow
, assuming you know something about the window (such as its title).
To call Win32 API functions from Python, use pywin32
.
For Linux you can use the tool I made here. The tool was meant for a slightly different use but you can use the API directly for your needs.
Install tool
sudo apt-get install xdotool xprop xwininfo
git clone https://github.com/Pithikos/winlaunch.git && cd winlaunch
In terminal
>>> from winlaunch import *
>>> wid, pid = launch('firefox')
>>> win_pos(wid)
[3210, 726]
wid
and pid
stand for window id and process id respectively.
This code will work on windows. It return the position and size of the active window.
from win32gui import GetWindowText, GetForegroundWindow
print(GetWindowRect(GetForegroundWindow()))
this can return window rect from window title
Code
def GetWindowRectFromName(name:str)-> tuple:
hwnd = ctypes.windll.user32.FindWindowW(0, name)
rect = ctypes.wintypes.RECT()
ctypes.windll.user32.GetWindowRect(hwnd, ctypes.pointer(rect))
# print(hwnd)
# print(rect)
return (rect.left, rect.top, rect.right, rect.bottom)
if __name__ == "__main__":
print(GetWindowRectFromName('CALC'))
pass
Environment
Python 3.8.2 | packaged by conda-forge | (default, Apr 24 2020, 07:34:03) [MSC v.1916 64 bit (AMD64)] on win32
Windows 10 Pro 1909
As Greg Hewgill mentioned, if you know the name of the window, you can simply use win32gui‘s FindWindow, and GetWindowRect. This is perhaps a little cleaner and efficient than previous methods.
from win32gui import FindWindow, GetWindowRect
# FindWindow takes the Window Class name (can be None if unknown), and the window's display text.
window_handle = FindWindow(None, "Diablo II")
window_rect = GetWindowRect(window_handle)
print(window_rect)
#(0, 0, 800, 600)
For future reference: PyWin32GUI has now moved to Github
Something not mentioned in any of the other responses is that in newer Windows (Vista and up), "the Window Rect now includes the area occupied by the drop shadow.", which is what win32gui.GetWindowRect
and ctypes.windll.user32.GetWindowRect
are interfacing with.
If you want to get the positions and sizes without the dropshadow, you can:
- Manually remove them. In my case there were 10 pixels on the left, bottom and right which had to be pruned.
- Use the
dwmapi
to extract the DWMWA_EXTENDED_FRAME_BOUNDS
as mentioned in the article
On using the dwmapi.DwmGetWindowAttribute
(see here):
This function takes four arguments: The hwnd, the identifier for the attribute we are interested in, a pointer for the data structure in which to write the attribute, the size of this data structure. The identifier we get by checking this enum. In our case, the attribute DWMWA_EXTENDED_FRAME_BOUNDS
is on position 9.
import ctypes
from ctypes.wintypes import HWND, DWORD, RECT
dwmapi = ctypes.WinDLL("dwmapi")
hwnd = 133116 # refer to the other answers on how to find the hwnd of your window
rect = RECT()
DMWA_EXTENDED_FRAME_BOUNDS = 9
dwmapi.DwmGetWindowAttribute(HWND(hwnd), DWORD(DMWA_EXTENDED_FRAME_BOUNDS),
ctypes.byref(rect), ctypes.sizeof(rect))
print(rect.left, rect.top, rect.right, rect.bottom)
Lastly: "Note that unlike the Window Rect, the DWM Extended Frame Bounds are not adjusted for DPI".
How can I get and set the window (any windows program) position and size with python?
Assuming you’re on Windows, try using pywin32
‘s win32gui
module with its EnumWindows
and GetWindowRect
functions.
If you’re using Mac OS X, you could try using appscript
.
For Linux, you can try one of the many interfaces to X11.
Edit: Example for Windows (not tested):
import win32gui
def callback(hwnd, extra):
rect = win32gui.GetWindowRect(hwnd)
x = rect[0]
y = rect[1]
w = rect[2] - x
h = rect[3] - y
print("Window %s:" % win32gui.GetWindowText(hwnd))
print("tLocation: (%d, %d)" % (x, y))
print("t Size: (%d, %d)" % (w, h))
def main():
win32gui.EnumWindows(callback, None)
if __name__ == '__main__':
main()
You can get the window coordinates using the GetWindowRect
function. For this, you need a handle to the window, which you can get using FindWindow
, assuming you know something about the window (such as its title).
To call Win32 API functions from Python, use pywin32
.
For Linux you can use the tool I made here. The tool was meant for a slightly different use but you can use the API directly for your needs.
Install tool
sudo apt-get install xdotool xprop xwininfo
git clone https://github.com/Pithikos/winlaunch.git && cd winlaunch
In terminal
>>> from winlaunch import *
>>> wid, pid = launch('firefox')
>>> win_pos(wid)
[3210, 726]
wid
and pid
stand for window id and process id respectively.
This code will work on windows. It return the position and size of the active window.
from win32gui import GetWindowText, GetForegroundWindow
print(GetWindowRect(GetForegroundWindow()))
this can return window rect from window title
Code
def GetWindowRectFromName(name:str)-> tuple:
hwnd = ctypes.windll.user32.FindWindowW(0, name)
rect = ctypes.wintypes.RECT()
ctypes.windll.user32.GetWindowRect(hwnd, ctypes.pointer(rect))
# print(hwnd)
# print(rect)
return (rect.left, rect.top, rect.right, rect.bottom)
if __name__ == "__main__":
print(GetWindowRectFromName('CALC'))
pass
Environment
Python 3.8.2 | packaged by conda-forge | (default, Apr 24 2020, 07:34:03) [MSC v.1916 64 bit (AMD64)] on win32
Windows 10 Pro 1909
As Greg Hewgill mentioned, if you know the name of the window, you can simply use win32gui‘s FindWindow, and GetWindowRect. This is perhaps a little cleaner and efficient than previous methods.
from win32gui import FindWindow, GetWindowRect
# FindWindow takes the Window Class name (can be None if unknown), and the window's display text.
window_handle = FindWindow(None, "Diablo II")
window_rect = GetWindowRect(window_handle)
print(window_rect)
#(0, 0, 800, 600)
For future reference: PyWin32GUI has now moved to Github
Something not mentioned in any of the other responses is that in newer Windows (Vista and up), "the Window Rect now includes the area occupied by the drop shadow.", which is what win32gui.GetWindowRect
and ctypes.windll.user32.GetWindowRect
are interfacing with.
If you want to get the positions and sizes without the dropshadow, you can:
- Manually remove them. In my case there were 10 pixels on the left, bottom and right which had to be pruned.
- Use the
dwmapi
to extract theDWMWA_EXTENDED_FRAME_BOUNDS
as mentioned in the article
On using the dwmapi.DwmGetWindowAttribute
(see here):
This function takes four arguments: The hwnd, the identifier for the attribute we are interested in, a pointer for the data structure in which to write the attribute, the size of this data structure. The identifier we get by checking this enum. In our case, the attribute DWMWA_EXTENDED_FRAME_BOUNDS
is on position 9.
import ctypes
from ctypes.wintypes import HWND, DWORD, RECT
dwmapi = ctypes.WinDLL("dwmapi")
hwnd = 133116 # refer to the other answers on how to find the hwnd of your window
rect = RECT()
DMWA_EXTENDED_FRAME_BOUNDS = 9
dwmapi.DwmGetWindowAttribute(HWND(hwnd), DWORD(DMWA_EXTENDED_FRAME_BOUNDS),
ctypes.byref(rect), ctypes.sizeof(rect))
print(rect.left, rect.top, rect.right, rect.bottom)
Lastly: "Note that unlike the Window Rect, the DWM Extended Frame Bounds are not adjusted for DPI".