A better xrandr command-line experience
published (revision history)
Can we make a small improvement to xrandr command-line user experience so
that extra tools like arandr (GUI for xrandr) or autorandr become
unnecessary for some people (like me)? Yes, I think that making the --output
option a bit more powerful goes a long way, and lets me cover most use-cases
with just four shell functions/aliases.
Table of Contents
TL;DR
Grab it here: release branch, tarball.
What? Why?
The way monitor layouts work for most people with mainstream operating systems or desktop environments (like GNOME) is this: you connect an external monitor for the first time, your desktop expands to this monitor, then you can change its position or turn it off in the settings, and then this setup is remembered so that you don’t need to do it again the next time you connect it. People with non-mainstream X11 window managers (like xmonad, i3, awesomewm, fluxbox) can get a similar experience: arandr being the “settings UI” and autorandr handling the initial expansion, saving and restoring.
Still, many people don’t know about these tools, and just use plain xrandr, and then look a bit too nerdy when trying to connect to a projector at some meetup or conference. I’ve got to admit I used to be one of them: I had a script to handle external monitors at home/work, but connecting anything else was so unusual that I didn’t bother writing a script, and had to do it manually, and feel bad about myself afterwards.
This year I finally decided to do something about it. Not a big deal, right? Just adopt autorandr and be done with it. But the script is massive (1500 lines of code including various workarounds for X11 and driver bugs that are already fixed) and the format of its state/configuration files is undocumented, and that’s a bit of a red flag as I like to keep this stuff cleaned up and in version control. So I tried to think of something simpler.
The simple solution I came up with is to extend xrandr to allow shell globs as output names and disable unspecified outputs.
So instead of having several scripts like
now I just have
and I think that’s beautiful.
The source for the xrandr-smart
script as described is in my dotfiles
monorepo,
but the best way to obtain the most recent version of it is to use the
standalone/xrandr-smart
branch,
which can also be downloaded as a
tarball.
Behind the scenes
xrandr-smart
invokes the xrandr-auto-find
function
which resolves output globs (if the globs match nothing or more than one
output, it fails) and invokes the xrandr-auto-off
function
to disable all other unspecific outputs.
As an example, layout-vertical
might translate to:
xrandr-auto-off \
--output eDP-1 --auto --dpi 96 --primary \
--output HDMI-1 --auto --above eDP-1 --dpi 96
↓
xrandr \
--output eDP-1 --auto --dpi 96 --primary \
--output HDMI-1 --auto --above eDP-1 --dpi 96 \
--output DP-1 --off \
--output DP-2 --off \
--output HDMI-2 --off
And that’s all there is to it, really.
Limitations
There are two significant limitations compared to GNOME and autorandr:
-
The generic
layout-horizontal
,layout-vertical
scripts can only support the laptop panel and one external monitor. In reality, this isn’t a problem as triple head setups usual need fine-tuned positioning anyway. -
We need extra code to support layout saving and (possibly automatic) restoring. Turns out that’s just a few lines:
layout-auto
, keybindings1.
Future work
- We could additionally use parse-edid to get monitor vendor and model and
match against that as well. This could make
xrandr-smart
useful even in triple-head and non-laptop setups.
-
Yeah, I invoke this manually using a Fn-key combo. There’s an endless stream of bugs in the kernel, X server and GPU drivers, plus the occassional security issue in a screensaver, so I feel safer to just invoke it manually when I think everything is settled down. ↩