Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
name: CI

on:
workflow_dispatch:
push:
branches:
- master
paths:
- ".github/workflows/ci.yml"
- "pyproject.toml"
- "mypy.ini"
- "**/*.py"
pull_request:
paths:
- ".github/workflows/ci.yml"
- "pyproject.toml"
- "mypy.ini"
- "**/*.py"

concurrency:
# Cancel previous runs for the same PR
# Don't cancel successive pushes to master
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
ruff:
runs-on: ubuntu-latest
timeout-minutes: &timeout-minutes 5
steps:
- uses: actions/checkout@v6
- uses: astral-sh/ruff-action@v4.0.0

mypy:
runs-on: ${{ matrix.os }}
timeout-minutes: *timeout-minutes
strategy:
# mypy is os and python-version sensitive. Test on all supported combinations
matrix:
# Arm runners are faster (as long as the same wheels are available)
os: [windows-11-arm, ubuntu-24.04-arm, macos-latest]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
fail-fast: false
steps:
- uses: actions/checkout@v6
- uses: astral-sh/setup-uv@v8.2.0
with:
python-version: ${{ matrix.python-version }}
activate-environment: true
- run: uv sync --locked
- run: mypy . --python-version=${{ matrix.python-version }}

tests:
runs-on: ${{ matrix.os }}
timeout-minutes: *timeout-minutes
strategy:
# Test on all supported runtime combinations
matrix:
# Arm runners are faster (as long as the same wheels are available)
# This project doesn't have any code that should act differently per architecture
os: [windows-11-arm, ubuntu-24.04-arm, macos-latest]
# TODO: Run tests in parallel on free-threaded python to catch free-threading issues
# See: https://py-free-threading.github.io/testing/
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
fail-fast: false
steps:
- uses: actions/checkout@v6
# - name: Install Linux Packages
# if: ${{ startsWith(matrix.os, 'ubuntu') }}
# run: |
# sudo apt update
# sudo apt install gedit xvfb x11-xserver-utils openbox dbus-x11
- uses: astral-sh/setup-uv@v8.2.0
with:
python-version: ${{ matrix.python-version }}
activate-environment: true
- run: uv sync --locked
# - name: Run tests (Linux)
# if: ${{ startsWith(matrix.os, 'ubuntu') }}
# working-directory: tests
# run: xvfb-run --server-args="-screen 0 1280x1024x24" bash -c "openbox & sleep 1 && dbus-launch --exit-with-session python test_pywinbox.py"
- name: Run tests # (Windows & macOS)
# if: ${{ !startsWith(matrix.os, 'ubuntu') }}
working-directory: tests
run: python test_pywinbox.py
- name: Run tests (MacNSBox)
if: ${{ startsWith(matrix.os, 'macos') }}
working-directory: tests
run: python test_MacNSBox.py

sphinx:
runs-on: ubuntu-24.04-arm # Keep in sync with build.os in .readthedocs.yaml
timeout-minutes: *timeout-minutes
steps:
- uses: actions/checkout@v6
- uses: astral-sh/setup-uv@v8.2.0
with:
python-version: "3.14" # Keep in sync with build.tools.python in .readthedocs.yaml
activate-environment: true
- run: uv sync --locked --no-default-groups --group=docs
- name: Build docs
# TODO: Add --fail-on-warning, but still too many warnings right now
run: sphinx-build --keep-going --builder html docs/source docs/_build/html
29 changes: 0 additions & 29 deletions .github/workflows/type-checking.yml

This file was deleted.

10 changes: 7 additions & 3 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ version: 2

# Set the OS, Python version and other tools you might need
build:
os: ubuntu-22.04
os: ubuntu-24.04 # Keep in sync with runs-on in .github/workflows/ci.yml
tools:
python: "3.11"
python: "3.14" # Keep in sync with python-version in .github/workflows/ci.yml
# You can also specify other tool versions:
# nodejs: "20"
# rust: "1.70"
Expand All @@ -32,4 +32,8 @@ sphinx:
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- requirements: requirements.txt
# https://docs.readthedocs.com/platform/latest/build-customization.html#install-dependencies-with-uv
- method: uv
command: sync
groups:
- docs
1 change: 1 addition & 0 deletions AUTHORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ Kalmat https://github.com/Kalmat
elraymond (https://github.com/elraymond)
Leonard Bruns https://github.com/roym899
lappely - https://github.com/poipoiPIO
Avasam - https://github.com/Avasam

2 changes: 2 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
0.8, 2026/XX/XX -- ALL: Removed unused dependency on `typing_extensions`
WIN32: Replaced bare `except:` clauses with `except Exception:`, preventing accidental suppression of system-exit signals (KeyboardInterrupt, SystemExit) during error handling.
0.7, 2024/03/22 -- LINUX: Added ewmhlib as separate module. (Really) Fixed position and size for GNOME (by using GTK_EXTENTS)
0.6, 2023/10/12 -- LINUX: Improved position and size for GNOME (by using GTK_EXTENTS)
WIN32: Fixed GetAwarenessFromDpiAwarenessContext not supported on Windows Server
Expand Down
24 changes: 15 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# PyWinBox

[![Type Checking](https://github.com/Kalmat/PyWinBox/actions/workflows/type-checking.yml/badge.svg)](https://github.com/Kalmat/PyWinBox/actions/workflows/type-checking.yml)
[![CI](https://github.com/Kalmat/PyWinBox/actions/workflows/ci.yml/badge.svg)](https://github.com/Kalmat/PyWinBox/actions/workflows/ci.yml)
[![PyPI version](https://badge.fury.io/py/PyWinBox.svg)](https://badge.fury.io/py/PyWinBox)


Expand Down Expand Up @@ -85,17 +85,17 @@ These are useful data structs (named tuples, actually) you can use to better man

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

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

pip3 install pywinbox
python -m pip install pywinbox

or
or using uv:

python3 -m pip install pywinbox
uv add pywinbox

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

pip install PyWinBox-x.x.xx-py3-none-any.whl
python -m pip install PyWinBox-x.x.xx-py3-none-any.whl

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

Expand All @@ -114,14 +114,20 @@ If you want to use this code or contribute, you can either:
* Create a fork of the [repository](https://github.com/Kalmat/PyWinBox), or
* [Download the repository](https://github.com/Kalmat/PyWinBox/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
Be sure you install all dev dependencies by running:

uv sync

or
python -m venv .venv
python -m pip install -e . --group=dev

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

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

python3 test_pywinbox.py
uv run test_pywinbox.py

For macOS NSWindow, you can also test using:

python3 test_MacNSBox.py
uv run test_MacNSBox.py
3 changes: 1 addition & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import re
import time
from urllib.request import urlretrieve

project = 'PyWinBox'
year = time.strftime("%Y")
Expand Down Expand Up @@ -42,8 +43,6 @@

# -- Copy the modules documentation ------------------------------------------
# https://stackoverflow.com/questions/66495200/is-it-possible-to-include-external-rst-files-in-my-documentation
from urllib.request import urlretrieve

urlretrieve(
"https://raw.githubusercontent.com/kalmat/pywinbox/master/README.md",
"index.md"
Expand Down
21 changes: 21 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[mypy]
mypy_path = src/, typings/
exclude = build/, dist/
strict = True

# Leverage type inference for function return type
disallow_untyped_calls = False
disallow_incomplete_defs = False
disallow_untyped_defs = False

disable_error_code =
# https://github.com/python/mypy/issues/6232 (redefinition with correct type)
attr-defined, assignment,

# https://github.com/ronaldoussoren/pyobjc/issues/198
# https://github.com/ronaldoussoren/pyobjc/issues/417
# https://github.com/ronaldoussoren/pyobjc/issues/419
[mypy-objc.*]
follow_untyped_imports = True
[mypy-Quartz.*]
allow_any_generics = True
87 changes: 87 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
[build-system]
requires = ["uv_build>=0.11.21,<0.12"]
build-backend = "uv_build"

[project.urls]
Homepage = "https://github.com/Kalmat/PyWinBox"
Repository = "https://github.com/Kalmat/PyWinBox.git"
Issues = "https://github.com/Kalmat/PyWinBox/issues"
Changelog = "https://github.com/Kalmat/PyWinBox/blob/HEAD/CHANGES.txt"
Documentation = "https://pywinbox.readthedocs.io/"

[project]
name = "PyWinBox"
version = "0.7"
description = "Cross-Platform and multi-monitor toolkit to handle rectangular areas and windows box"
authors = [{ name = "Kalmat", email = "palookjones@gmail.com" }]
readme = "README.md"
license = "BSD-3-Clause"
license-files = ["LICENSE.txt"]
requires-python = ">=3.9"
keywords = [
"left",
"top",
"right",
"bottom",
"size",
"width",
"height",
"topleft",
"bottomleft",
"topright",
"bottomright",
"midtop",
"midleft",
"midbottom",
"midright",
"center",
"centerx",
"centery",
"box",
"rect",
"boundingbox",
"area",
]
classifiers = [
"Development Status :: 4 - Beta",
"Environment :: Win32 (MS Windows)",
"Environment :: X11 Applications",
"Environment :: MacOS X",
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"pywin32>=302; sys_platform == 'win32'",
"python-xlib>=0.21; sys_platform == 'linux'",
"ewmhlib>=0.1; sys_platform == 'linux'",
"pyobjc>=8.1; sys_platform == 'darwin'",
]

[dependency-groups]
docs = ["myst-parser"]
dev = [
{ include-group = "docs" },
"ruff>=0.15.16",
"ewmhlib",
"pywinctl>=0.3",
"mypy>=0.990,<2",
"types-python-xlib>=0.32",
"types-pywin32>=305.0.0.3",
]

[tool.uv]
exclude-newer = "1 week"
[tool.uv.exclude-newer-package]
# Kalmat owns these packages
ewmhlib = false
pywinctl = false
8 changes: 0 additions & 8 deletions requirements.txt

This file was deleted.

Loading
Loading