Skip to content

Commit

Permalink
v0.7 pre-release
Browse files Browse the repository at this point in the history
  • Loading branch information
Kalmat committed Apr 17, 2024
1 parent 78c70d3 commit 363865a
Show file tree
Hide file tree
Showing 22 changed files with 818 additions and 4,771 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ instance/
.coverage
htmlcov/

dist/
build/
*.egg-info/
.vscode/
/make_dev_wheel.bat
dist/
*.whl
6 changes: 3 additions & 3 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
0.4, 2023/10/11 -- ALL: Added getMonitor() as alias for getDisplay()
LINUX: Fixed getAllMonitors() returns empty list if XDG_CURRENT_DESKTOP is not set, improved getClientFrame() and getExtraFrameSize() by properly using _NET_EXTENTS and GTK_EXTENTS, Added a new Window.LEGACY_NAME="WM_NAME" property (for apps not setting _NET_WM_NAME)
(ewmhlib): Fixed Mint returning str (not bytes) in some properties. Fixed Mint not having get_monitors() method in xrandr extension.
MACOS: Fixed lowerWindow(), raiseWindow() and isAlive. Fixed test_pywinctl.py to avoid crashing in small screens
LINUX: Added ewmhlib as separate module. Fixed getAllMonitors() returns empty list if XDG_CURRENT_DESKTOP is not set. Improved getClientFrame() and getExtraFrameSize() by properly using _NET_EXTENTS and GTK_EXTENTS, Added a new Window.LEGACY_NAME="WM_NAME" property (for apps not setting _NET_WM_NAME)
(ewmhlib): Fixed Mint returning str (not bytes) in some properties. Fixed Mint not having get_monitors() method in xrandr extension.
MACOS: Removed MacOSNSWindow. Fixed lowerWindow(), raiseWindow() and isAlive. Fixed test_pywinctl.py to avoid crashing in small screens
0.3, 2023/09/20 -- LINUX: Improved Wayland support for some apps which (surprisingly) work using X11/XOrg (thanks to SamuMazzi for his help!).
0.2, 2023/09/09 -- LINUX: Added experimental Wayland support (only if unsafe mode enabled and only for some apps).
Fixed ewmhlib freezing in Wayland when connecting to display ":1", and added some performance improvements
Expand Down
74 changes: 34 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ My most sincere thanks and acknowledgement. amongst many others (see AUTHORS.txt

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

There are three kind of function to be used within PyWinCtl:
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
- Window class:
- Methods: You need a Window object to control or get info on the target window on screen. It's possible to get a Window object by using any of the general methods (e.g. getActiveWidow() or getWindowsWithTitle()). You can also use windows 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: 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.
- Properties: Window attributes, getters and setters, that also require to use a Window object

A very simple example:
Expand All @@ -54,43 +54,41 @@ A very simple example:

These functions 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) | (GET/SET) position (x, y) |
| [getWindowsAt](docstrings.md#getwindowsat) | [resizeTo](docstrings.md#resizeto) | (GET/SET) left (x) |
| [getTopWindowAt](docstrings.md#gettopwindowat) | [move / moveRel](docstrings.md#move) | (GET/SET) top (y) |
| [displayWindowsUnderMouse](docstrings.md#displaywindowsundermouse) | [moveTo](docstrings.md#moveto) | (GET/SET) right (x) |
| [version](docstrings.md#version) | [raiseWindow](docstrings.md#raisewindow) | (GET/SET) bottom (y) |
| [checkPermissions](docstrings.md#checkpermissions) (macOS only) | [lowerWindow](docstrings.md#lowerwindow) | (GET/SET) topleft (x, y) |
| | [alwaysOnTop](docstrings.md#alwaysontop) | (GET/SET) topright (x, y) |
| | [alwaysOnBottom](docstrings.md#alwaysonbottom) | (GET/SET) bottomleft (x, y) |
| | [sendBehind](docstrings.md#sendbehind) | (GET/SET) bottomright (x, y) |
| | [acceptInput](docstrings.md#acceptinput) | (GET/SET) midtop (x, y) |
| | [getAppName](docstrings.md#getappname) | (GET/SET) midleft (x, y) |
| | [getHandle](docstrings.md#gethandle) | (GET/SET) midbotton (x, y) |
| | [getParent](docstrings.md#getparent) | (GET/SET) midright (x, y) |
| | [setParent](docstrings.md#setparent) | (GET/SET) center (x, y) |
| | [getChildren](docstrings.md#getchildren) | (GET/SET) centerx (x, y) |
| | [isParent](docstrings.md#isparent) | (GET/SET) centery (x, y) |
| | [isChild](docstrings.md#ischild) | (GET/SET) size (width, height) |
| | [getDisplay](docstrings.md#getdisplay) | (GET/SET) width |
| | [getExtraFrameSize](docstrings.md#getextraframesize) | (GET/SET) height |
| | [getClientFrame](docstrings.md#getclientframe) | (GET/SET) box (x, y, width, height) |
| | | (GET/SET) rect (x, y, right, bottom) |

| 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)) |
| [getWindowsAt](docstrings.md#getwindowsat) | [resizeTo](docstrings.md#resizeto) | (GET/SET) position (x, y) |
| [getTopWindowAt](docstrings.md#gettopwindowat) | [move / moveRel](docstrings.md#move) | (GET/SET) left (x) |
| [displayWindowsUnderMouse](docstrings.md#displaywindowsundermouse) | [moveTo](docstrings.md#moveto) | (GET/SET) top (y) |
| [version](docstrings.md#version) | [raiseWindow](docstrings.md#raisewindow) | (GET/SET) right (x) |
| [checkPermissions](docstrings.md#checkpermissions) (macOS only) | [lowerWindow](docstrings.md#lowerwindow) | (GET/SET) bottom (y) |
| | [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 |
| | | (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, so there are two separate classes you can use:
- To control your own application's windows: MacOSNSWindow() is based on NSWindow Objects (you have to pass the NSApp() and the NSWindow() objects reference).
- To control other applications' windows: MacOSWindow() 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!***
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>***

Expand Down Expand Up @@ -280,7 +278,3 @@ To test this module on your own system, cd to "tests" folder and run:

python3 test_pywinctl.py

MacOSNSWindow class and methods can be tested by running this, also on "tests" folder:

python3 test_MacNSWindow.py

Binary file removed dist/PyWinCtl-dev0.1-py3-none-any.whl
Binary file not shown.
8 changes: 0 additions & 8 deletions docs/requirements.txt

This file was deleted.

7 changes: 4 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,16 @@
license='BSD 3',
packages=find_packages(where='src'),
package_dir={'': 'src'},
package_data={"pywinctl": ["py.typed"], "ewmhlib": ["py.typed"]},
package_data={"pywinctl": ["py.typed"]},
test_suite='tests',
install_requires=[
"pywin32>=302; sys_platform == 'win32'",
"python-xlib>=0.21; sys_platform == 'linux'",
"ewmhlib>=0.1; sys_platform == 'linux'",
"pyobjc>=8.1; sys_platform == 'darwin'",
"typing_extensions>=4.4.0",
"pywinbox>=0.6",
"pymonctl>=0.6"
"pywinbox>=0.7",
"pymonctl>=0.8"
],
extras_require={
'dev': [
Expand Down
9 changes: 0 additions & 9 deletions src/pywinctl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@
"getAllScreens", "getScreenSize", "getWorkArea", "getMousePos"
]

import sys

# Mac only
if sys.platform == "darwin":
__all__ += ["NSWindow"]

__version__ = "0.4"


Expand All @@ -30,6 +24,3 @@ def version(numberOnly: bool = True) -> str:
getTopWindowAt, getWindowsAt, displayWindowsUnderMouse,
getAllScreens, getScreenSize, getWorkArea, getMousePos
)

if sys.platform == "darwin":
from ._main import NSWindow
Loading

0 comments on commit 363865a

Please sign in to comment.