PyWinCtl


NamePyWinCtl JSON
Version 0.4.1 PyPI version JSON
download
home_pagehttps://github.com/Kalmat/PyWinCtl
SummaryCross-Platform toolkit to get info on and control windows on screen
upload_time2024-09-23 08:33:39
maintainerNone
docs_urlNone
authorKalmat
requires_python>=3.9
licenseCopyright (c) 2021, Kalmat <palookjones@gmail.com> All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the PyWinCtl nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ Original module (PyGetWindow, Windows support only) Copyright (c) 2015, Al Sweigart All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the PyAutoGUI nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
keywords activate close control geometry gui hide lower maximize menu minimize mouse-position move name position raise resize restore screen-size show size title window
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # PyWinCtl <a name="pywinctl"></a>
[![Type Checking](https://github.com/Kalmat/PyWinCtl/actions/workflows/type-checking.yml/badge.svg?branch=dev)](https://github.com/Kalmat/PyWinCtl/actions/workflows/type-checking.yml)
[![PyPI version](https://badge.fury.io/py/PyWinCtl.svg)](https://badge.fury.io/py/PyWinCtl)
[![Documentation Status](https://readthedocs.org/projects/pywinctl/badge/?version=latest)](https://pywinctl.readthedocs.io/en/latest/?badge=latest)
[![Downloads](https://static.pepy.tech/badge/pywinctl/month)](https://pepy.tech/project/pywinctl)


Cross-Platform module to get info on and control windows on screen.

With PyWinCtl you can retrieve info or control windows from other open applications, as well as use it as a cross-platform toolkit to manipulate your own application windows.

This module is a Python 3 evolution from [asweigart's PyGetWindow module](https://github.com/asweigart/PyGetWindow), which adds Linux/X11 and macOS support to the MS Windows-only original module, multi-monitor support, and many additional features; in the hope others can use it, test it or contribute.

My most sincere thanks and acknowledgement. amongst many others (see AUTHORS.txt), to [MestreLion](https://github.com/MestreLion), [super-ibby](https://github.com/super-ibby), [Avasam](https://github.com/Avasam), [macdeport](https://github.com/macdeport) and [holychowders](https://github.com/holychowders) for their help and moral boost.

1. [Window Features](#window-features)
   1. [Important macOS notice](#macos-notice)
   2. [Important Linux notice](#linux-notice)
2. [Window Change Notifications](#watchdog])
   1. [Important comments](#watchdog-comments)
   2. [Important macOS Apple Script version notice](#watchdog-macos-comments)
3. [Menu Features](#menu-features)
4. [Install](#install)
5. [Support](#support)
6. [Using this code](#using)
7. [Test](#test)


## Window Features <a name="window-features"></a>

There are three kinds of functions to be used within PyWinCtl:
- General, independent functions: These functions can be directly invoked at module level, without the need of referencing a Window object (e.g. `pywinctl.getActiveWindow()` or `pywinctl.getAllTitles()`)
- Window class: You need a Window object to control or get info on the target window on screen. It is possible to get a Window object by using any of the general methods (e.g. getActiveWidow() or getWindowsWithTitle()). You can also use the window id, as returned by PyQt's self.winId() or tkinter's root.frame(), which is very handy to get the Window object for your own application.
  - Methods: functions within Window class to get info or perform actions and changes on target window (e.g. `window.resizeTo(800, 600)` or `window.close()`)
  - Properties: Window attributes, getters and setters, that also require to use a Window object (e.g. `window.title` or `window.center = (500, 300)`)

These features are available at the moment, in all three platforms (Windows, Linux and macOS)

|                  General, independent functions:                   |                Window class methods:                 |                                  Window class properties:                                  |
|:------------------------------------------------------------------:|:----------------------------------------------------:|:------------------------------------------------------------------------------------------:|
|          [getActiveWindow](docstrings.md#getactivewindow)          |             [close](docstrings.md#close)             |                             (GET) [title](docstrings.md#title)                             |
|     [getActiveWindowTitle](docstrings.md#getactivewindowtitle)     |          [minimize](docstrings.md#minimize)          |            (GET) [updatedTitle](docstrings.md#updatedtitle) (MacOSWindow only)             |
|            [getAllWindows](docstrings.md#getallwindows)            |          [maximize](docstrings.md#maximize)          |                       (GET) [isMaximized](docstrings.md#ismaximized)                       |
|             [getAllTitles](docstrings.md#getalltitles)             |           [restore](docstrings.md#restore)           |                       (GET) [isMinimized](docstrings.md#isminimized)                       |
|      [getWindowsWithTitle](docstrings.md#getwindowswithtitle)      |              [hide](docstrings.md#hide)              |                          (GET) [isActive](docstrings.md#isactive)                          |
|          [getAllAppsNames](docstrings.md#getallappsnames)          |              [show](docstrings.md#show)              |                         (GET) [isVisible](docstrings.md#isvisible)                         |
|          [getAppsWithName](docstrings.md#getappswithname)          |          [activate](docstrings.md#activate)          |                          (GET) [isAlive](docstrings.md#isvisible)                          |
|  [getAllAppsWindowsTitles](docstrings.md#getallappswindowstitles)  |      [resize / resizeRel](docstrings.md#resize)      | **Position / Size** (inherited from [PyWinBox module](https://github.com/Kalmat/PyWinBox)) |
|                         geetAllWindowsDict                         |          [resizeTo](docstrings.md#resizeto)          |                                 (GET/SET) position (x, y)                                  |
|           [getWindowsAt](docstrings.md#getwindowsat)           |         [move / moveRel](docstrings.md#move)         |                                     (GET/SET) left (x)                                     |
| [getTopWindowAt](docstrings.md#gettopwindowat) |            [moveTo](docstrings.md#moveto)            |                                     (GET/SET) top (y)                                      |
|                  [displayWindowsUnderMouse](docstrings.md#displaywindowsundermouse)                  |       [raiseWindow](docstrings.md#raisewindow)       |                                    (GET/SET) right (x)                                     |
|  [version](docstrings.md#version)   |       [lowerWindow](docstrings.md#lowerwindow)       |                                    (GET/SET) bottom (y)                                    |
|         [checkPermissions](docstrings.md#checkpermissions) (macOS only)                                                           |       [alwaysOnTop](docstrings.md#alwaysontop)       |                                  (GET/SET) topleft (x, y)                                  |
|                                                                    |    [alwaysOnBottom](docstrings.md#alwaysonbottom)    |                                 (GET/SET) topright (x, y)                                  |
|                                                                    |        [sendBehind](docstrings.md#sendbehind)        |                                (GET/SET) bottomleft (x, y)                                 |
|                                                                    |       [acceptInput](docstrings.md#acceptinput)       |                                (GET/SET) bottomright (x, y)                                |
|                                                                    |        [getAppName](docstrings.md#getappname)        |                                  (GET/SET) midtop (x, y)                                   |
|                                                                    |         [getHandle](docstrings.md#gethandle)         |                                  (GET/SET) midleft (x, y)                                  |
|                                                                    |         [getParent](docstrings.md#getparent)         |                                 (GET/SET) midbotton (x, y)                                 |
|                                                                    |         [setParent](docstrings.md#setparent)         |                                 (GET/SET) midright (x, y)                                  |
|                                                                    |       [getChildren](docstrings.md#getchildren)       |                                  (GET/SET) center (x, y)                                   |
|                                                                    |          [isParent](docstrings.md#isparent)          |                                   (GET/SET) centerx (x)                                    |
|                                                                    |           [isChild](docstrings.md#ischild)           |                                   (GET/SET) centery (y)                                    |
|                                                                    |        [getDisplay](docstrings.md#getdisplay)        |                               (GET/SET) size (width, height)                               |
|                                                                    | [getExtraFrameSize](docstrings.md#getextraframesize) |                                      (GET/SET) width                                       |
|                                                                    |    [getClientFrame](docstrings.md#getclientframe)    |                                      (GET/SET) height                                      |
|                                                                    |                        getPID                        |                             (GET/SET) box (x, y, width, height                             |
|                                                                    |                                                      |                            (GET/SET) rect (x, y, right, bottom)                            |

***Important macOS notice <a name="macos-notice"></a>***

macOS doesn't "like" controlling windows from other apps. MacOSWindow() class is based on Apple Script, so it is non-standard, slower and, in some cases, tricky (uses window name as reference, which may change or be duplicate), but it's working fine in most cases. You will likely need to grant permissions on Settings -> Security&Privacy -> Accessibility. ***Notice some applications will have limited Apple Script support or no support at all, so some or even all methods may fail!***

***Important Linux notice <a name="linux-notice"></a>***

The enormous variety of Linux distributions, Desktop Environments, Window Managers, and their combinations, make it impossible to test in all scenarios.

This module has been tested OK in some X11 setups: Ubuntu/Gnome, Ubuntu/KDE, Ubuntu/Unity, Mint/Cinnamon and Raspbian/LXDE. Except for Mint/Cinnamon and Ubuntu 22.04+, `sendBehind()` method doesn't properly work!

In Wayland (the new GNOME protocol for Ubuntu 22.04+), it is not possible to retrieve the active window nor the list 
of open windows, so `getActiveWindow()` and `getAllWindows()` will not likely work even though unsafe-mode is  
enabled (built-in and "official" applications do not populate their Xid nor their X-Window object, so it may work for
other applications like Chrome or your own application windows)

In case you find problems in other configs, please [open an issue](https://github.com/Kalmat/PyWinCtl/issues). Furthermore, if you have knowledge in these other configs, do not hesitate to contribute!

## Window Change Notifications <a name="watchdog"></a>

Window watchdog sub-class, running in a separate Thread, will allow to define hooks and its callbacks to be notified when some window states change. Accessible through 'watchdog' submodule.

The watchdog will automatically stop when window doesn't exist anymore or main program quits.

    isAliveCB:      callback to invoke when window is not alive anymore. Set to None to not to watch this
                    Passes the new alive status value (False)
    
    isActiveCB:     callback to invoke if window changes its active status. Set to None to not to watch this
                    Passes the new active status value (True/False)
    
    isVisibleCB:    callback to invoke if window changes its visible status. Set to None to not to watch this
                    Passes the new visible status value (True/False)

    isMinimizedCB:  callback to invoke if window changes its minimized status. Set to None to not to watch this
                    Passes the new minimized status value (True/False)

    isMaximizedCB:  callback to invoke if window changes its maximized status. Set to None to not to watch this
                    Passes the new maximized status value (True/False)
    
    resizedCB:      callback to invoke if window changes its size. Set to None to not to watch this
                    Passes the new size (width, height)
    
    movedCB:        callback to invoke if window changes its position. Set to None to not to watch this
                    Passes the new position (x, y)
    
    changedTitleCB: callback to invoke if window changes its title. Set to None to not to watch this
                    Passes the new title (as string)
                    IMPORTANT: In MacOS AppScript version, if title changes, watchdog will stop unless using setTryToFind(True)

    changedDisplayCB: callback to invoke if window changes display. Set to None to not to watch this
                      Passes the new display name (as string)

|              watchdog sub-module methods:               |
|:-------------------------------------------------------:|
|              [start](docstrings.md#start)               |
|    [updateCallbacks](docstrings.md#updatecallbacks)     |
|     [updateInterval](docstrings.md#updateinterval)      |
| [setTryToFind](docstrings.md#settrytofind) (macOS only) |
|       [isAlive](docstrings.md#-watchdog-isalive)        |
|               [stop](docstrings.md#stop)                |

Example:

    import pywinctl as pwc
    import time

    def activeCB(active):
        print("NEW ACTIVE STATUS", active)

    def movedCB(pos):
        print("NEW POS", pos)

    npw = pwc.getActiveWindow()
    npw.watchdog.start(isActiveCB=activeCB)
    npw.watchdog.setTryToFind(True)
    print("Toggle focus and move active window")
    print("Press Ctl-C to Quit")
    i = 0
    while True:
        try:
            if i == 50:
                npw.watchdog.updateCallbacks(isActiveCB=activeCB, movedCB=movedCB)
            if i == 100:
                npw.watchdog.updateInterval(0.1)
                npw.watchdog.setTryToFind(False)
            time.sleep(0.1)
        except KeyboardInterrupt:
            break
        i += 1
    npw.watchdog.stop()


***Important comments <a name="watchdog-comments"></a>***

- The callbacks definition MUST MATCH their invocation params (boolean, string or (int, int))
- The watchdog is asynchronous, so notifications won't be immediate (adjust interval value to your needs). Use window object properties instead (e.g. isAlive)
- Position and size notifications will trigger several times between initial and final values
- When updating callbacks, remember to set ALL desired callbacks. Non-present (None) callbacks will be deactivated

***Important macOS Apple Script version notice <a name="watchdog-macos-comments"></a>***

- Might be very slow and resource-consuming
- It uses the title to identify the window, so if it changes, the watchdog will consider it is not available anymore and will stop
- To avoid this, use ''tryToFind(True)'' method to try to find the new title (not fully guaranteed since it uses a similarity check, so the new title might not be found or correspond to a different window)


## Menu Features <a name="menu-features"></a>

***Available in: MS-Windows and macOS Apple Script version (Win32Window() and MacOSWindow() classes)***

menu sub-class for Menu info and control methods, accessible through 'menu' submodule.

|              menu sub-module methods:              |
|:--------------------------------------------------:|
|          [getMenu](docstrings.md#getmenu)          |
|      [getMenuInfo](docstrings.md#getmenuinfo)      |
| [getMenuItemCount](docstrings.md#getmenuitemcount) |
|  [getMenuItemInfo](docstrings.md#getmenuiteminfo)  |
|  [getMenuItemRect](docstrings.md#getmenuitemrect)  |
|    [clickMenuItem](docstrings.md#clickmenuitem)    |

MS-Windows example (notice it is language-dependent):

    import pywinctl as pwc
    import subprocess
    # import json

    subprocess.Popen('notepad')
    windows = pwc.getWindowsWithTitle('notepad', condition=pwc.Re.CONTAINS, flags=pwc.Re.IGNORECASE)
    if windows:
        win = windows[0]
        menu = win.menu.getMenu()
        # print(json.dumps(menu, indent=4, ensure_ascii=False))  # Prints menu dict in legible format
        ret = win.menu.clickMenuItem(["File", "Exit"])           # Exit program
        if not ret:
            print("Option not found. Check option path and language")
    else:
        print("Window not found. Check application name and language")

Menu dictionary (returned by getMenu() method) will likely contain all you may need to handle application menu:

    Key:            item title
    Values:
      "parent":     parent sub-menu handle
      "hSubMenu":   item handle (!= 0 for sub-menus only)
      "wID":        item ID (required for other actions, e.g. clickMenuItem())
      "rect":       Rect struct of the menu item. (Windows: It is relative to window position, so it won't likely change if window is moved or resized)
      "item_info":  [Optional] Python dictionary (macOS) / MENUITEMINFO struct (Windows)
      "shortcut":   shortcut to menu item, if any (macOS: only if item_info is included)
      "entries":    sub-items within the sub-menu (or not present otherwise)
                    these sub-items will have this very same format, in a nested struct.

Note not all windows/applications will have a menu accessible by these methods.

## Install <a name="install"></a>

To install this module on your system, you can use pip: 

    pip3 install pywinctl

or

    python3 -m pip install pywinctl

Alternatively, you can download the wheel file (.whl) available in the [Download page](https://pypi.org/project/PyWinCtl/#files) and run this (don't forget to replace 'x.xx' with proper version number):

    pip install PyWinCtl-x.xx-py3-none-any.whl

You may want to add `--force-reinstall` option to be sure you are installing the right dependencies version.

Then, you can use it on your own projects just importing it:

    import pywinctl as pwc

## Support <a name="support"></a>

In case you have a problem, comments or suggestions, do not hesitate to [open issues](https://github.com/Kalmat/PyWinCtl/issues) on the [project homepage](https://github.com/Kalmat/PyWinCtl)

## Using this code <a name="using"></a>

If you want to use this code or contribute, you can either:

* Create a fork of the [repository](https://github.com/Kalmat/PyWinCtl), or 
* [Download the repository](https://github.com/Kalmat/PyWinCtl/archive/refs/heads/master.zip), uncompress, and open it on your IDE of choice (e.g. PyCharm)

Be sure you install all dependencies described on "requirements.txt" by using pip

## Test <a name="test"></a>

To test this module on your own system, cd to "tests" folder and run:

    python3 test_pywinctl.py


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Kalmat/PyWinCtl",
    "name": "PyWinCtl",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "activate, close, control, geometry, gui, hide, lower, maximize, menu, minimize, mouse-position, move, name, position, raise, resize, restore, screen-size, show, size, title, window",
    "author": "Kalmat",
    "author_email": "Kalmat <palookjones@gmail.com>",
    "download_url": null,
    "platform": null,
    "description": "# PyWinCtl <a name=\"pywinctl\"></a>\r\n[![Type Checking](https://github.com/Kalmat/PyWinCtl/actions/workflows/type-checking.yml/badge.svg?branch=dev)](https://github.com/Kalmat/PyWinCtl/actions/workflows/type-checking.yml)\r\n[![PyPI version](https://badge.fury.io/py/PyWinCtl.svg)](https://badge.fury.io/py/PyWinCtl)\r\n[![Documentation Status](https://readthedocs.org/projects/pywinctl/badge/?version=latest)](https://pywinctl.readthedocs.io/en/latest/?badge=latest)\r\n[![Downloads](https://static.pepy.tech/badge/pywinctl/month)](https://pepy.tech/project/pywinctl)\r\n\r\n\r\nCross-Platform module to get info on and control windows on screen.\r\n\r\nWith PyWinCtl you can retrieve info or control windows from other open applications, as well as use it as a cross-platform toolkit to manipulate your own application windows.\r\n\r\nThis module is a Python 3 evolution from [asweigart's PyGetWindow module](https://github.com/asweigart/PyGetWindow), which adds Linux/X11 and macOS support to the MS Windows-only original module, multi-monitor support, and many additional features; in the hope others can use it, test it or contribute.\r\n\r\nMy most sincere thanks and acknowledgement. amongst many others (see AUTHORS.txt), to [MestreLion](https://github.com/MestreLion), [super-ibby](https://github.com/super-ibby), [Avasam](https://github.com/Avasam), [macdeport](https://github.com/macdeport) and [holychowders](https://github.com/holychowders) for their help and moral boost.\r\n\r\n1. [Window Features](#window-features)\r\n   1. [Important macOS notice](#macos-notice)\r\n   2. [Important Linux notice](#linux-notice)\r\n2. [Window Change Notifications](#watchdog])\r\n   1. [Important comments](#watchdog-comments)\r\n   2. [Important macOS Apple Script version notice](#watchdog-macos-comments)\r\n3. [Menu Features](#menu-features)\r\n4. [Install](#install)\r\n5. [Support](#support)\r\n6. [Using this code](#using)\r\n7. [Test](#test)\r\n\r\n\r\n## Window Features <a name=\"window-features\"></a>\r\n\r\nThere are three kinds of functions to be used within PyWinCtl:\r\n- General, independent functions: These functions can be directly invoked at module level, without the need of referencing a Window object (e.g. `pywinctl.getActiveWindow()` or `pywinctl.getAllTitles()`)\r\n- Window class: You need a Window object to control or get info on the target window on screen. It is possible to get a Window object by using any of the general methods (e.g. getActiveWidow() or getWindowsWithTitle()). You can also use the window id, as returned by PyQt's self.winId() or tkinter's root.frame(), which is very handy to get the Window object for your own application.\r\n  - Methods: functions within Window class to get info or perform actions and changes on target window (e.g. `window.resizeTo(800, 600)` or `window.close()`)\r\n  - Properties: Window attributes, getters and setters, that also require to use a Window object (e.g. `window.title` or `window.center = (500, 300)`)\r\n\r\nThese features are available at the moment, in all three platforms (Windows, Linux and macOS)\r\n\r\n|                  General, independent functions:                   |                Window class methods:                 |                                  Window class properties:                                  |\r\n|:------------------------------------------------------------------:|:----------------------------------------------------:|:------------------------------------------------------------------------------------------:|\r\n|          [getActiveWindow](docstrings.md#getactivewindow)          |             [close](docstrings.md#close)             |                             (GET) [title](docstrings.md#title)                             |\r\n|     [getActiveWindowTitle](docstrings.md#getactivewindowtitle)     |          [minimize](docstrings.md#minimize)          |            (GET) [updatedTitle](docstrings.md#updatedtitle) (MacOSWindow only)             |\r\n|            [getAllWindows](docstrings.md#getallwindows)            |          [maximize](docstrings.md#maximize)          |                       (GET) [isMaximized](docstrings.md#ismaximized)                       |\r\n|             [getAllTitles](docstrings.md#getalltitles)             |           [restore](docstrings.md#restore)           |                       (GET) [isMinimized](docstrings.md#isminimized)                       |\r\n|      [getWindowsWithTitle](docstrings.md#getwindowswithtitle)      |              [hide](docstrings.md#hide)              |                          (GET) [isActive](docstrings.md#isactive)                          |\r\n|          [getAllAppsNames](docstrings.md#getallappsnames)          |              [show](docstrings.md#show)              |                         (GET) [isVisible](docstrings.md#isvisible)                         |\r\n|          [getAppsWithName](docstrings.md#getappswithname)          |          [activate](docstrings.md#activate)          |                          (GET) [isAlive](docstrings.md#isvisible)                          |\r\n|  [getAllAppsWindowsTitles](docstrings.md#getallappswindowstitles)  |      [resize / resizeRel](docstrings.md#resize)      | **Position / Size** (inherited from [PyWinBox module](https://github.com/Kalmat/PyWinBox)) |\r\n|                         geetAllWindowsDict                         |          [resizeTo](docstrings.md#resizeto)          |                                 (GET/SET) position (x, y)                                  |\r\n|           [getWindowsAt](docstrings.md#getwindowsat)           |         [move / moveRel](docstrings.md#move)         |                                     (GET/SET) left (x)                                     |\r\n| [getTopWindowAt](docstrings.md#gettopwindowat) |            [moveTo](docstrings.md#moveto)            |                                     (GET/SET) top (y)                                      |\r\n|                  [displayWindowsUnderMouse](docstrings.md#displaywindowsundermouse)                  |       [raiseWindow](docstrings.md#raisewindow)       |                                    (GET/SET) right (x)                                     |\r\n|  [version](docstrings.md#version)   |       [lowerWindow](docstrings.md#lowerwindow)       |                                    (GET/SET) bottom (y)                                    |\r\n|         [checkPermissions](docstrings.md#checkpermissions) (macOS only)                                                           |       [alwaysOnTop](docstrings.md#alwaysontop)       |                                  (GET/SET) topleft (x, y)                                  |\r\n|                                                                    |    [alwaysOnBottom](docstrings.md#alwaysonbottom)    |                                 (GET/SET) topright (x, y)                                  |\r\n|                                                                    |        [sendBehind](docstrings.md#sendbehind)        |                                (GET/SET) bottomleft (x, y)                                 |\r\n|                                                                    |       [acceptInput](docstrings.md#acceptinput)       |                                (GET/SET) bottomright (x, y)                                |\r\n|                                                                    |        [getAppName](docstrings.md#getappname)        |                                  (GET/SET) midtop (x, y)                                   |\r\n|                                                                    |         [getHandle](docstrings.md#gethandle)         |                                  (GET/SET) midleft (x, y)                                  |\r\n|                                                                    |         [getParent](docstrings.md#getparent)         |                                 (GET/SET) midbotton (x, y)                                 |\r\n|                                                                    |         [setParent](docstrings.md#setparent)         |                                 (GET/SET) midright (x, y)                                  |\r\n|                                                                    |       [getChildren](docstrings.md#getchildren)       |                                  (GET/SET) center (x, y)                                   |\r\n|                                                                    |          [isParent](docstrings.md#isparent)          |                                   (GET/SET) centerx (x)                                    |\r\n|                                                                    |           [isChild](docstrings.md#ischild)           |                                   (GET/SET) centery (y)                                    |\r\n|                                                                    |        [getDisplay](docstrings.md#getdisplay)        |                               (GET/SET) size (width, height)                               |\r\n|                                                                    | [getExtraFrameSize](docstrings.md#getextraframesize) |                                      (GET/SET) width                                       |\r\n|                                                                    |    [getClientFrame](docstrings.md#getclientframe)    |                                      (GET/SET) height                                      |\r\n|                                                                    |                        getPID                        |                             (GET/SET) box (x, y, width, height                             |\r\n|                                                                    |                                                      |                            (GET/SET) rect (x, y, right, bottom)                            |\r\n\r\n***Important macOS notice <a name=\"macos-notice\"></a>***\r\n\r\nmacOS doesn't \"like\" controlling windows from other apps. MacOSWindow() class is based on Apple Script, so it is non-standard, slower and, in some cases, tricky (uses window name as reference, which may change or be duplicate), but it's working fine in most cases. You will likely need to grant permissions on Settings -> Security&Privacy -> Accessibility. ***Notice some applications will have limited Apple Script support or no support at all, so some or even all methods may fail!***\r\n\r\n***Important Linux notice <a name=\"linux-notice\"></a>***\r\n\r\nThe enormous variety of Linux distributions, Desktop Environments, Window Managers, and their combinations, make it impossible to test in all scenarios.\r\n\r\nThis module has been tested OK in some X11 setups: Ubuntu/Gnome, Ubuntu/KDE, Ubuntu/Unity, Mint/Cinnamon and Raspbian/LXDE. Except for Mint/Cinnamon and Ubuntu 22.04+, `sendBehind()` method doesn't properly work!\r\n\r\nIn Wayland (the new GNOME protocol for Ubuntu 22.04+), it is not possible to retrieve the active window nor the list \r\nof open windows, so `getActiveWindow()` and `getAllWindows()` will not likely work even though unsafe-mode is  \r\nenabled (built-in and \"official\" applications do not populate their Xid nor their X-Window object, so it may work for\r\nother applications like Chrome or your own application windows)\r\n\r\nIn case you find problems in other configs, please [open an issue](https://github.com/Kalmat/PyWinCtl/issues). Furthermore, if you have knowledge in these other configs, do not hesitate to contribute!\r\n\r\n## Window Change Notifications <a name=\"watchdog\"></a>\r\n\r\nWindow watchdog sub-class, running in a separate Thread, will allow to define hooks and its callbacks to be notified when some window states change. Accessible through 'watchdog' submodule.\r\n\r\nThe watchdog will automatically stop when window doesn't exist anymore or main program quits.\r\n\r\n    isAliveCB:      callback to invoke when window is not alive anymore. Set to None to not to watch this\r\n                    Passes the new alive status value (False)\r\n    \r\n    isActiveCB:     callback to invoke if window changes its active status. Set to None to not to watch this\r\n                    Passes the new active status value (True/False)\r\n    \r\n    isVisibleCB:    callback to invoke if window changes its visible status. Set to None to not to watch this\r\n                    Passes the new visible status value (True/False)\r\n\r\n    isMinimizedCB:  callback to invoke if window changes its minimized status. Set to None to not to watch this\r\n                    Passes the new minimized status value (True/False)\r\n\r\n    isMaximizedCB:  callback to invoke if window changes its maximized status. Set to None to not to watch this\r\n                    Passes the new maximized status value (True/False)\r\n    \r\n    resizedCB:      callback to invoke if window changes its size. Set to None to not to watch this\r\n                    Passes the new size (width, height)\r\n    \r\n    movedCB:        callback to invoke if window changes its position. Set to None to not to watch this\r\n                    Passes the new position (x, y)\r\n    \r\n    changedTitleCB: callback to invoke if window changes its title. Set to None to not to watch this\r\n                    Passes the new title (as string)\r\n                    IMPORTANT: In MacOS AppScript version, if title changes, watchdog will stop unless using setTryToFind(True)\r\n\r\n    changedDisplayCB: callback to invoke if window changes display. Set to None to not to watch this\r\n                      Passes the new display name (as string)\r\n\r\n|              watchdog sub-module methods:               |\r\n|:-------------------------------------------------------:|\r\n|              [start](docstrings.md#start)               |\r\n|    [updateCallbacks](docstrings.md#updatecallbacks)     |\r\n|     [updateInterval](docstrings.md#updateinterval)      |\r\n| [setTryToFind](docstrings.md#settrytofind) (macOS only) |\r\n|       [isAlive](docstrings.md#-watchdog-isalive)        |\r\n|               [stop](docstrings.md#stop)                |\r\n\r\nExample:\r\n\r\n    import pywinctl as pwc\r\n    import time\r\n\r\n    def activeCB(active):\r\n        print(\"NEW ACTIVE STATUS\", active)\r\n\r\n    def movedCB(pos):\r\n        print(\"NEW POS\", pos)\r\n\r\n    npw = pwc.getActiveWindow()\r\n    npw.watchdog.start(isActiveCB=activeCB)\r\n    npw.watchdog.setTryToFind(True)\r\n    print(\"Toggle focus and move active window\")\r\n    print(\"Press Ctl-C to Quit\")\r\n    i = 0\r\n    while True:\r\n        try:\r\n            if i == 50:\r\n                npw.watchdog.updateCallbacks(isActiveCB=activeCB, movedCB=movedCB)\r\n            if i == 100:\r\n                npw.watchdog.updateInterval(0.1)\r\n                npw.watchdog.setTryToFind(False)\r\n            time.sleep(0.1)\r\n        except KeyboardInterrupt:\r\n            break\r\n        i += 1\r\n    npw.watchdog.stop()\r\n\r\n\r\n***Important comments <a name=\"watchdog-comments\"></a>***\r\n\r\n- The callbacks definition MUST MATCH their invocation params (boolean, string or (int, int))\r\n- The watchdog is asynchronous, so notifications won't be immediate (adjust interval value to your needs). Use window object properties instead (e.g. isAlive)\r\n- Position and size notifications will trigger several times between initial and final values\r\n- When updating callbacks, remember to set ALL desired callbacks. Non-present (None) callbacks will be deactivated\r\n\r\n***Important macOS Apple Script version notice <a name=\"watchdog-macos-comments\"></a>***\r\n\r\n- Might be very slow and resource-consuming\r\n- It uses the title to identify the window, so if it changes, the watchdog will consider it is not available anymore and will stop\r\n- To avoid this, use ''tryToFind(True)'' method to try to find the new title (not fully guaranteed since it uses a similarity check, so the new title might not be found or correspond to a different window)\r\n\r\n\r\n## Menu Features <a name=\"menu-features\"></a>\r\n\r\n***Available in: MS-Windows and macOS Apple Script version (Win32Window() and MacOSWindow() classes)***\r\n\r\nmenu sub-class for Menu info and control methods, accessible through 'menu' submodule.\r\n\r\n|              menu sub-module methods:              |\r\n|:--------------------------------------------------:|\r\n|          [getMenu](docstrings.md#getmenu)          |\r\n|      [getMenuInfo](docstrings.md#getmenuinfo)      |\r\n| [getMenuItemCount](docstrings.md#getmenuitemcount) |\r\n|  [getMenuItemInfo](docstrings.md#getmenuiteminfo)  |\r\n|  [getMenuItemRect](docstrings.md#getmenuitemrect)  |\r\n|    [clickMenuItem](docstrings.md#clickmenuitem)    |\r\n\r\nMS-Windows example (notice it is language-dependent):\r\n\r\n    import pywinctl as pwc\r\n    import subprocess\r\n    # import json\r\n\r\n    subprocess.Popen('notepad')\r\n    windows = pwc.getWindowsWithTitle('notepad', condition=pwc.Re.CONTAINS, flags=pwc.Re.IGNORECASE)\r\n    if windows:\r\n        win = windows[0]\r\n        menu = win.menu.getMenu()\r\n        # print(json.dumps(menu, indent=4, ensure_ascii=False))  # Prints menu dict in legible format\r\n        ret = win.menu.clickMenuItem([\"File\", \"Exit\"])           # Exit program\r\n        if not ret:\r\n            print(\"Option not found. Check option path and language\")\r\n    else:\r\n        print(\"Window not found. Check application name and language\")\r\n\r\nMenu dictionary (returned by getMenu() method) will likely contain all you may need to handle application menu:\r\n\r\n    Key:            item title\r\n    Values:\r\n      \"parent\":     parent sub-menu handle\r\n      \"hSubMenu\":   item handle (!= 0 for sub-menus only)\r\n      \"wID\":        item ID (required for other actions, e.g. clickMenuItem())\r\n      \"rect\":       Rect struct of the menu item. (Windows: It is relative to window position, so it won't likely change if window is moved or resized)\r\n      \"item_info\":  [Optional] Python dictionary (macOS) / MENUITEMINFO struct (Windows)\r\n      \"shortcut\":   shortcut to menu item, if any (macOS: only if item_info is included)\r\n      \"entries\":    sub-items within the sub-menu (or not present otherwise)\r\n                    these sub-items will have this very same format, in a nested struct.\r\n\r\nNote not all windows/applications will have a menu accessible by these methods.\r\n\r\n## Install <a name=\"install\"></a>\r\n\r\nTo install this module on your system, you can use pip: \r\n\r\n    pip3 install pywinctl\r\n\r\nor\r\n\r\n    python3 -m pip install pywinctl\r\n\r\nAlternatively, you can download the wheel file (.whl) available in the [Download page](https://pypi.org/project/PyWinCtl/#files) and run this (don't forget to replace 'x.xx' with proper version number):\r\n\r\n    pip install PyWinCtl-x.xx-py3-none-any.whl\r\n\r\nYou may want to add `--force-reinstall` option to be sure you are installing the right dependencies version.\r\n\r\nThen, you can use it on your own projects just importing it:\r\n\r\n    import pywinctl as pwc\r\n\r\n## Support <a name=\"support\"></a>\r\n\r\nIn case you have a problem, comments or suggestions, do not hesitate to [open issues](https://github.com/Kalmat/PyWinCtl/issues) on the [project homepage](https://github.com/Kalmat/PyWinCtl)\r\n\r\n## Using this code <a name=\"using\"></a>\r\n\r\nIf you want to use this code or contribute, you can either:\r\n\r\n* Create a fork of the [repository](https://github.com/Kalmat/PyWinCtl), or \r\n* [Download the repository](https://github.com/Kalmat/PyWinCtl/archive/refs/heads/master.zip), uncompress, and open it on your IDE of choice (e.g. PyCharm)\r\n\r\nBe sure you install all dependencies described on \"requirements.txt\" by using pip\r\n\r\n## Test <a name=\"test\"></a>\r\n\r\nTo test this module on your own system, cd to \"tests\" folder and run:\r\n\r\n    python3 test_pywinctl.py\r\n\r\n",
    "bugtrack_url": null,
    "license": "Copyright (c) 2021, Kalmat <palookjones@gmail.com> All rights reserved.  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:  * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.  * Neither the name of the PyWinCtl nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  ------------------------------------------------------------------------------  Original module (PyGetWindow, Windows support only) Copyright (c) 2015, Al Sweigart All rights reserved.  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:  * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.  * Neither the name of the PyAutoGUI nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  ",
    "summary": "Cross-Platform toolkit to get info on and control windows on screen",
    "version": "0.4.1",
    "project_urls": {
        "Homepage": "https://github.com/Kalmat/PyWinCtl"
    },
    "split_keywords": [
        "activate",
        " close",
        " control",
        " geometry",
        " gui",
        " hide",
        " lower",
        " maximize",
        " menu",
        " minimize",
        " mouse-position",
        " move",
        " name",
        " position",
        " raise",
        " resize",
        " restore",
        " screen-size",
        " show",
        " size",
        " title",
        " window"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "be338e4f632210b28fc9e998a9ab990e7ed97ecd2800cc50038e3800e1d85dbe",
                "md5": "7513de7103013e7a00caed82c1e0f7b6",
                "sha256": "4d875e22969e1c6239d8c73156193630aaab876366167b8d97716f956384b089"
            },
            "downloads": -1,
            "filename": "PyWinCtl-0.4.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7513de7103013e7a00caed82c1e0f7b6",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 63158,
            "upload_time": "2024-09-23T08:33:39",
            "upload_time_iso_8601": "2024-09-23T08:33:39.881537Z",
            "url": "https://files.pythonhosted.org/packages/be/33/8e4f632210b28fc9e998a9ab990e7ed97ecd2800cc50038e3800e1d85dbe/PyWinCtl-0.4.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-09-23 08:33:39",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Kalmat",
    "github_project": "PyWinCtl",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "pywinctl"
}
        
Elapsed time: 0.32955s