| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- # PyGetWindow
- # A cross-platform module to find information about the windows on the screen.
- # Work in progress
- # Useful info:
- # https://stackoverflow.com/questions/373020/finding-the-current-active-window-in-mac-os-x-using-python
- # https://stackoverflow.com/questions/7142342/get-window-position-size-with-python
- # win32 api and ctypes on Windows
- # cocoa api and pyobjc on Mac
- # Xlib on linux
- # Possible Future Features:
- # get/click menu (win32: GetMenuItemCount, GetMenuItemInfo, GetMenuItemID, GetMenu, GetMenuItemRect)
- __version__ = "0.0.9"
- import sys, collections, pyrect
- class PyGetWindowException(Exception):
- """
- Base class for exceptions raised when PyGetWindow functions
- encounter a problem. If PyGetWindow raises an exception that isn't
- this class, that indicates a bug in the module.
- """
- pass
- def pointInRect(x, y, left, top, width, height):
- """Returns ``True`` if the ``(x, y)`` point is within the box described
- by ``(left, top, width, height)``."""
- return left < x < left + width and top < y < top + height
- # NOTE: `Rect` is a named tuple for use in Python, while structs.RECT represents
- # the win32 RECT struct. PyRect's Rect class is used for handling changing
- # geometry of rectangular areas.
- Rect = collections.namedtuple("Rect", "left top right bottom")
- Point = collections.namedtuple("Point", "x y")
- Size = collections.namedtuple("Size", "width height")
- class BaseWindow:
- def __init__(self):
- pass
- def _setupRectProperties(self):
- def _onRead(attrName):
- r = self._getWindowRect()
- self._rect._left = r.left # Setting _left directly to skip the onRead.
- self._rect._top = r.top # Setting _top directly to skip the onRead.
- self._rect._width = r.right - r.left # Setting _width directly to skip the onRead.
- self._rect._height = r.bottom - r.top # Setting _height directly to skip the onRead.
- def _onChange(oldBox, newBox):
- self.moveTo(newBox.left, newBox.top)
- self.resizeTo(newBox.width, newBox.height)
- r = self._getWindowRect()
- self._rect = pyrect.Rect(r.left, r.top, r.right - r.left, r.bottom - r.top, onChange=_onChange, onRead=_onRead)
- def _getWindowRect(self):
- raise NotImplementedError
- def __str__(self):
- r = self._getWindowRect()
- width = r.right - r.left
- height = r.bottom - r.top
- return '<%s left="%s", top="%s", width="%s", height="%s", title="%s">' % (
- self.__class__.__qualname__,
- r.left,
- r.top,
- width,
- height,
- self.title,
- )
- def close(self):
- """Closes this window. This may trigger "Are you sure you want to
- quit?" dialogs or other actions that prevent the window from
- actually closing. This is identical to clicking the X button on the
- window."""
- raise NotImplementedError
- def minimize(self):
- """Minimizes this window."""
- raise NotImplementedError
- def maximize(self):
- """Maximizes this window."""
- raise NotImplementedError
- def restore(self):
- """If maximized or minimized, restores the window to it's normal size."""
- raise NotImplementedError
- def activate(self):
- """Activate this window and make it the foreground window."""
- raise NotImplementedError
- def resizeRel(self, widthOffset, heightOffset):
- """Resizes the window relative to its current size."""
- raise NotImplementedError
- def resizeTo(self, newWidth, newHeight):
- """Resizes the window to a new width and height."""
- raise NotImplementedError
- def moveRel(self, xOffset, yOffset):
- """Moves the window relative to its current position."""
- raise NotImplementedError
- def moveTo(self, newLeft, newTop):
- """Moves the window to new coordinates on the screen."""
- raise NotImplementedError
- @property
- def isMinimized(self):
- """Returns True if the window is currently minimized."""
- raise NotImplementedError
- @property
- def isMaximized(self):
- """Returns True if the window is currently maximized."""
- raise NotImplementedError
- @property
- def isActive(self):
- """Returns True if the window is currently the active, foreground window."""
- raise NotImplementedError
- @property
- def title(self):
- """Returns the window title as a string."""
- raise NotImplementedError
- @property
- def visible(self):
- raise NotImplementedError
- # Wrappers for pyrect.Rect object's properties:
- @property
- def left(self):
- return self._rect.left
- @left.setter
- def left(self, value):
- # import pdb; pdb.set_trace()
- self._rect.left # Run rect's onRead to update the Rect object.
- self._rect.left = value
- @property
- def right(self):
- return self._rect.right
- @right.setter
- def right(self, value):
- self._rect.right # Run rect's onRead to update the Rect object.
- self._rect.right = value
- @property
- def top(self):
- return self._rect.top
- @top.setter
- def top(self, value):
- self._rect.top # Run rect's onRead to update the Rect object.
- self._rect.top = value
- @property
- def bottom(self):
- return self._rect.bottom
- @bottom.setter
- def bottom(self, value):
- self._rect.bottom # Run rect's onRead to update the Rect object.
- self._rect.bottom = value
- @property
- def topleft(self):
- return self._rect.topleft
- @topleft.setter
- def topleft(self, value):
- self._rect.topleft # Run rect's onRead to update the Rect object.
- self._rect.topleft = value
- @property
- def topright(self):
- return self._rect.topright
- @topright.setter
- def topright(self, value):
- self._rect.topright # Run rect's onRead to update the Rect object.
- self._rect.topright = value
- @property
- def bottomleft(self):
- return self._rect.bottomleft
- @bottomleft.setter
- def bottomleft(self, value):
- self._rect.bottomleft # Run rect's onRead to update the Rect object.
- self._rect.bottomleft = value
- @property
- def bottomright(self):
- return self._rect.bottomright
- @bottomright.setter
- def bottomright(self, value):
- self._rect.bottomright # Run rect's onRead to update the Rect object.
- self._rect.bottomright = value
- @property
- def midleft(self):
- return self._rect.midleft
- @midleft.setter
- def midleft(self, value):
- self._rect.midleft # Run rect's onRead to update the Rect object.
- self._rect.midleft = value
- @property
- def midright(self):
- return self._rect.midright
- @midright.setter
- def midright(self, value):
- self._rect.midright # Run rect's onRead to update the Rect object.
- self._rect.midright = value
- @property
- def midtop(self):
- return self._rect.midtop
- @midtop.setter
- def midtop(self, value):
- self._rect.midtop # Run rect's onRead to update the Rect object.
- self._rect.midtop = value
- @property
- def midbottom(self):
- return self._rect.midbottom
- @midbottom.setter
- def midbottom(self, value):
- self._rect.midbottom # Run rect's onRead to update the Rect object.
- self._rect.midbottom = value
- @property
- def center(self):
- return self._rect.center
- @center.setter
- def center(self, value):
- self._rect.center # Run rect's onRead to update the Rect object.
- self._rect.center = value
- @property
- def centerx(self):
- return self._rect.centerx
- @centerx.setter
- def centerx(self, value):
- self._rect.centerx # Run rect's onRead to update the Rect object.
- self._rect.centerx = value
- @property
- def centery(self):
- return self._rect.centery
- @centery.setter
- def centery(self, value):
- self._rect.centery # Run rect's onRead to update the Rect object.
- self._rect.centery = value
- @property
- def width(self):
- return self._rect.width
- @width.setter
- def width(self, value):
- self._rect.width # Run rect's onRead to update the Rect object.
- self._rect.width = value
- @property
- def height(self):
- return self._rect.height
- @height.setter
- def height(self, value):
- self._rect.height # Run rect's onRead to update the Rect object.
- self._rect.height = value
- @property
- def size(self):
- return self._rect.size
- @size.setter
- def size(self, value):
- self._rect.size # Run rect's onRead to update the Rect object.
- self._rect.size = value
- @property
- def area(self):
- return self._rect.area
- @area.setter
- def area(self, value):
- self._rect.area # Run rect's onRead to update the Rect object.
- self._rect.area = value
- @property
- def box(self):
- return self._rect.box
- @box.setter
- def box(self, value):
- self._rect.box # Run rect's onRead to update the Rect object.
- self._rect.box = value
- if sys.platform == "darwin":
- # raise NotImplementedError('PyGetWindow currently does not support macOS. If you have Appkit/Cocoa knowledge, please contribute! https://github.com/asweigart/pygetwindow') # TODO - implement mac
- from ._pygetwindow_macos import *
- Window = MacOSWindow
- elif sys.platform == "win32":
- from ._pygetwindow_win import (
- Win32Window,
- getActiveWindow,
- getActiveWindowTitle,
- getWindowsAt,
- getWindowsWithTitle,
- getAllWindows,
- getAllTitles,
- )
- Window = Win32Window
- else:
- raise NotImplementedError(
- "PyGetWindow currently does not support Linux. If you have Xlib knowledge, please contribute! https://github.com/asweigart/pygetwindow"
- )
|