Skip to main content

Robust, zero-config X11 display hotplug policy daemon for dwm/i3

Project description

xrandrw

PyPI version Python versions License: MIT

Zero-config, self-healing X11 display-layout daemon for dwm/i3 and other bare-X11 window managers. It watches for monitor hotplug/unplug, remembers each display by its EDID identity, and auto-places externals relative to a primary using a persistent attach-order policy — so your monitors end up where you left them, every time.

Pure Python standard library (optional systemd-python for journald logging).

Install

End-user (isolated, lands the xrandrw console-script at ~/.local/bin):

pipx install .

Development (editable):

pip install -e .

Optional journald logging extra:

pip install ".[journald]"

Usage

xrandrw exposes six modes:

Command Description
xrandrw --apply Apply the layout once (default when no flag is given).
xrandrw --watch Poll topology and re-apply on change.
xrandrw --daemon Watch for display changes via event-driven RandR notifications and re-apply (systemd entry point).
xrandrw --print Print xrandr --query output and exit.
xrandrw --set-pref OUTPUT_OR_ID SIDE Set a display's preferred side: right-of, left-of, above, below.
xrandrw --list-state Dump the placement state JSON.

Configuration

Config resolves from (lowest to highest precedence): built-in defaults → /etc/xdg/xrandrw.conf~/.config/xrandrw.conf → process environment. Each key can be set in a config file (KEY=value lines) or via an environment variable of the same name.

Key Purpose
USE_XWALLPAPER 0 = feh/fehbg, 1 = xwallpaper.
WALL Wallpaper image path.
HIDPI_WIDTH Treat internal panel as HiDPI when preferred-mode width ≥ this.
POLL_INTERVAL Watch-loop poll interval in seconds.
LOG_LEVEL none, err, info, notice, debug.
LOG_FILE Optional JSON-lines log file (unset = journald/stderr).
LOCKFILE Apply-lock path.
PREF_DEFAULT_SIDE Default side for new/unknown monitors.
EXCESS_WINDOW_SEC / EXCESS_THRESHOLD Churn-backoff window and threshold.

See xrandrw.conf.sample for an annotated template — copy it to ~/.config/xrandrw.conf and edit.

systemd user service

The repo ships a --user unit that runs xrandrw --daemon with Restart=always and sd_notify integration. Install and enable it via the Makefile:

make install    # pipx install . + copy conf sample + unit
make enable     # systemctl --user daemon-reload && enable --now

make install uses pipx install --force ., which places the console-script at ~/.local/bin/xrandrw — exactly the ExecStart path the unit expects. Run systemctl --user daemon-reload after any reinstall.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

xrandrw-0.1.1.tar.gz (37.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

xrandrw-0.1.1-py3-none-any.whl (26.2 kB view details)

Uploaded Python 3

File details

Details for the file xrandrw-0.1.1.tar.gz.

File metadata

  • Download URL: xrandrw-0.1.1.tar.gz
  • Upload date:
  • Size: 37.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for xrandrw-0.1.1.tar.gz
Algorithm Hash digest
SHA256 e4383904df26129c5377b837e45753f262b4262a3e8510648655adc6c1614334
MD5 9f365c1f56d02a4f8ad02b7931d394d8
BLAKE2b-256 f0a5518ea00ef24354599a9cd5cb542fa3d5f5bd3307d66820aed9d9cabed5ed

See more details on using hashes here.

File details

Details for the file xrandrw-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: xrandrw-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 26.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for xrandrw-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ea2b11f75d13fbcc8ccea1cf2c6131e4017903c68b4efbae3485f2c54eb4e8e2
MD5 e5d2feb8ed0e8896f81636bc343c62c1
BLAKE2b-256 f2a230f7eec5e173ef18db1ec1e22211ba3063e3261d5798f3e7978ca2c82253

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page