Open-source project
phillipberndt/autorandr avatar
phillipberndt/autorandr

autorandr: a rewrite without auto-disper, and a pip line over plain http

Auto-detect the connected display hardware and load the appropriate X11 setup using xrandr

2,715 stars134 forksPythonLicense varies

At a glance

What is it?
A Python rewrite of a bash tool that picks an X11 display profile from the hardware currently connected. Two things to know before anything else: the pip line that fetches the tree is plain http run as root, and the Python version has no auto-disper support, so those users are sent to a separate legacy branch.
Who is it for?
Use a distribution package rather than either pip line. Arch, Debian sid, Fedora, Gentoo, NixOS, Guix, Slackware, FreeBSD, Void and the openSUSE build service all carry it, and none of them asks you to fetch a repository over unencrypted http as root.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 35 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 4, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The pip install line is plain http and it runs as root

Two pip routes are offered, and the one that fetches the repository tree is the weaker of the pair. The development route is `sudo pip install "git+http://github.com/phillipberndt/autorandr#egg=autorandr"`, which stacks two things worth pausing on: the scheme is http rather than https, and the command runs as root. The second route, `sudo pip install autorandr`, drops the URL and takes a named release instead, described as the stable version, so the tree and the package index are two different sources for the same tool and only one of them is encrypted. Both lines sit below a longer list of distribution packages: Arch, Debian sid, Fedora 39 and later, the FreeBSD Ports Collection, Gentoo, a NixOS module, a Guix package, a SlackBuild for Slackware 14.2, and Void Linux through XBPS, plus automated nightlies from the openSUSE build service in RPM and DEB form. Local `make deb` and `make rpm` targets are offered for anyone who would rather build a package.

sh
sudo pip install "git+http://github.com/phillipberndt/autorandr#egg=autorandr"
sudo pip install autorandr

The rewrite dropped auto-disper and points those users at legacy

This tree is a rewrite, not the original tool. The file describes it as a compatible Python rewrite of wertarbyte's autorandr, forked because that tree is unmaintained with lots of open pull requests and issues, with the changes the author thought were most important merged in. That leaves two capability statements in tension. The Python version is called better suited for non-standard configurations, with `--transform` and `--reflect` given as the cases. It also has no disper support yet, so anyone relying on auto-disper has to use the bash version, which lives on a separate `legacy` branch to be maintained until the upstream author finds the time to take his branch up again. Both versions use a compatible configuration file format, so a profile can be carried between them to some extent. Packaging for bash completion, XDG autostart, Nitrogen, pm-utils and systemd sits under `contrib/` rather than in the tree root.

The hook list announces three scripts and then names four

The advanced usage section opens by saying three more scripts can be placed in the configuration directory, then lists four. `postswitch` runs after a mode switch has taken place, and is offered for notifying window managers or other applications about the switch. `preswitch` runs before a mode switch takes place. `postsave` runs after a profile was stored or altered. The fourth is `predetect`, described as executed before detection, and that description stops mid-word after befor with nothing following it. So the sentence is one lower than the list, and the entry that would document the earliest hook is the one that carries no wording at all. The directory itself is defined by the XDG base directory spec, usually `~/.config/autorandr`, or `~/.autorandr` when an old installation for user configuration is still around, with `/etc/xdg/autorandr` for the system-wide copy.

_block_ returning 0 vetoes a profile before the screen setup is read

Each profile directory can also rule itself out. Placing a script named `_block_` inside it means the script is evaluated before the screen setup is inspected, and a return value of 0 skips the profile. The stated purpose is querying the status of a docking station you are about to leave, which is the case where hardware detection would otherwise settle on a profile meant for a dock that is no longer attached. Two related behaviours sit next to it. When no suitable profile can be identified, the current configuration is kept, and `--default <profile>` trades that for a fallback. The system-wide installation calls autorandr with `--default default` by default. Three special virtual configurations called `horizontal`, `vertical` and `common` generate a configuration from every screen currently connected, and symlinking `default` to one of those names adopts it without touching the system-wide configuration. Reloads of an already identical configuration are skipped as well, which `--force` overrides.

make all compiles nothing and labels a constant as autodetected

The build recipe has an unusual default. The `all` target echoes a message telling you to call `make install` or `make uninstall`, then prints a line headed by words about components being autodetected, and the value on that line is `$(DEFAULT_TARGETS)`. That variable is set once, unconditionally, to `autorandr` further down the same file under a comment for the autorandr rules themselves, so the autodetected list never varies. What the target does detect comes from pkg-config, and it reports four locations: the bash completions directory, the systemd unit directory, the udev rules directory, and the pm-utils sleep hooks directory. The same output notes that `TARGETS` can override the choice and that the systemd, pm-utils and udev variables must be set by hand when detection did not get them right, with a worked example using `/etc/pm/sleep.d`. There is also an extra `launcher` value for `TARGETS` that installs a program named `autorandr_launcher`, run by the user instead of through udev rules and described as more stable for some users.

make
DEFAULT_TARGETS=autorandr

setup.py declares 1.15.post1 and still advertises Python 2

The packaging metadata has not moved with the code. `setup.py` declares the version as `1.15.post1`, while the newest published tag is 1.15 from 2024-03-03, and commits behind it continued to 2026-08-31, leaving the tree well past its own release. The classifier list is older still: Python 2 and 2.7 are still advertised, alongside 3.3, 3.4, then 3.6 through 3.10, which skips 3.5 entirely and stops at 3.10. The long description is read from README.md inside a bare except clause, falling back to the same one-line sentence if the file cannot be opened, the module is declared through `py_modules`, and the single console script entry point resolves to `exception_handled_main`. `xrandr` is the only keyword given, and it is also the only place the driver tool gets named anywhere, since the prose never mentions it. The root carries a man page in `autorandr.1`, a `.flake8` file, and no test directory and no CI directory.

A GPLv3 text file in the root next to an empty license field

Three places in the repository name the GNU General Public License version 3: the license paragraph of the file itself, the `license` field in setup.py, which reads `GPLv3`, and a `gpl-3.0.txt` sitting in the root beside the Makefile. The repository's license metadata field, on the other hand, carries nothing, and the text links none of the three. That disagreement is worth settling by reading the files rather than the metadata, because an empty field is an absent record and not a statement about terms. The contributor list in the same section runs alphabetically by first name through more than twenty entries and then breaks order for its final four, with Jan-Oliver Kaiser and Alexandre Viau arriving after Victor Häggqvist, so the tail of that list was appended rather than sorted.

Editorial conclusion

Use a distribution package rather than either pip line. Arch, Debian sid, Fedora, Gentoo, NixOS, Guix, Slackware, FreeBSD, Void and the openSUSE build service all carry it, and none of them asks you to fetch a repository over unencrypted http as root. Before configuring profiles, confirm your setup does not depend on auto-disper: the Python version those packages carry has no support for it, and the bash implementation sits on a legacy branch upstream has not taken back up. And size the hook directory for four scripts, not the three the text announces.

Frequently asked questions

How do I install autorandr?

Four routes are given. Run `autorandr.py` as a stand-alone binary, or run `make install` as root, which also places the files that trigger autorandr when a monitor is connected or removed, when the system resumes from suspend, and when a user logs into an X11 session. Take the system package from Arch, Debian sid, Fedora 39 and later, the FreeBSD Ports Collection, Gentoo, NixOS, Guix, a SlackBuild for Slackware 14.2 or Void Linux, with openSUSE build service nightlies and local `make deb` and `make rpm` targets listed as well. Or use one of the two pip lines.

How do I use autorandr day to day?

Save a profile for each hardware setup with `autorandr --save <name>`, for instance mobile and docked, then let detection pick one by calling `autorandr` with no arguments, which prints the active profile and marks the detected one. Apply a profile with `autorandr --change`, load one by hand with `autorandr --load <profile>` or the shorter `autorandr <profile>`, and add `--force` when an identical configuration is being skipped on purpose.

Why is xrandr not found when autorandr runs?

The file does not address a missing xrandr anywhere. The repository description calls the tool a loader for the X11 setup using xrandr, and xrandr is the only keyword setup.py declares, but no dependency, version, path or package name for it appears in the installation or usage text. A missing binary therefore has to be diagnosed from the system side, not from these instructions.

Is arandr or autorandr the better choice?

The text never names arandr and never compares the two, so it cannot settle that. What it does state is that this project keeps a legacy bash branch beside the Python rewrite, that both use a compatible configuration file format so you can switch between them to some extent, and that the Python version is the one better suited to `--transform` and `--reflect`. Anyone comparing tools should read the arandr side elsewhere.

Does autorandr support Wayland sessions?

Nothing here claims it does. The description and the setup.py keyword both name xrandr, which is the X11 tool, the configuration directory follows the XDG base directory spec, and every trigger described is an X11 session login or a monitor event. Wayland does not appear in the file at all, and no alternative backend or compositor limitation is documented, so X11 is the only target with anything written down.

Official sources

  1. Issues
  2. phillipberndt/autorandr on GitHub
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/phillipberndt-autorandr.svg)](https://hysenlabs.com/projects/phillipberndt-autorandr)