Wednesday, 17 September 2014

randrctl — profile-based screen manager for X

While having some free time, decided to automate one of my daily routines — setting up external display.

Idea appeared long before I was told about famous (or not?) autorandr project.
So if you are familiar with autorandr, you are already familiar with randrctl idea.


How often have you to plug external display to your laptop, how many different setups do you have? I have 3: no external display, office setup, where laptop stands below old 19" external display and home setup, where laptop stands beside of my shiny 23" fullhd display. To set them all up, I created 3 scripts in my home directory:,,

That couldn't be good. So I decided to develop an utility to manage my screen setup in the same way networks are managed in archlinux. So it would be possible to do
$ randrctl switch-to office
instead of calling custom shell script.


And here it is: randrctl on github (tah-dam!). Project has a descriptive readme (I believe), but here is a brief list of what is done already
  • support for display mode (resolution), position, rotation and panning (the latter is not supported in autorandr afaik)
  • switching between profiles
  • executing custom commands before and after the switch or in the case randrctl fails
  • profile creation from current screen setup

Under the hood it performs calls to xrandr utility to get info about current setup and to apply new settings.


Installation instructions are on github. Basic idea is that you clone a git repo and allow python to install the module. And then you copy exemplary configs to specific locations and copy completion functions for bash and zsh if you need them.

For archers there is a package on AUR.


All configuration is currently stored under /etc/randrctl/ (which may be not such a good idea, because screen setup usually do not require root privileges, I know. I'm working on it).

/etc/randrctl/config.ini allows to declare custom commands on profile switch or failure. The whole property value gets executed in a shell, so all these &&s, ||s, pipes and redirections are supported. While composing your custom commands, you can get profile name from $randr_profile environment variable. Error, if it happens, is stored to $randr_error.

Profiles are stored under /etc/randrctl/profiles/ as plain text files in json format. Profile structure and property names are self-descriptive, I believe:
    "outputs": {
        "LVDS1": {
            "mode": "1366x768",
            "panning": "1366x1080"
        "DP1": {
            "mode": "1920x1080",
            "pos": "1366x0".
            "rotate": "inverted"
    "primary": "DP1"


Running randrctl without parameters (or with canonical -h or --help) will tell you all you can do with it. And you can:
  • check your current screen setup
    $ randrctl show
  • dump it to file (note that root is required here)
    # randrctl dump my_setup
  • check stored profiles
    $ randrctl show my_setup
  • list your profiles
    $ randrctl list
  • and finally, apply profile settings
    $ randrctl switch-to my_setup

Planned features

Right now I'm thinking about 2 things:
  1. autodetecting when display is plugged via udev and applying profile, that matches display EDID (I come with this idea before knowing about autorandr, I swear ;))
  2. support for user profiles and configurations. This will allow to run randrctl without root
Of course there is always a room for code and experience improvements, so these will take place also.

Tuesday, 18 February 2014

Secondary display not turning on after resume in linux

Occasionally my external display resisted to turn on after being re-plugged into laptop after suspend-resume cycle. The issue appeared again today, after I suspended laptop in the office and resumed it at home.

Tuning Display and Monitor in KDE Control Centre had no effect. Any attempts to turn on external display with xrandr failed silently or with error cannot find crtc for output.

Eventually, after playing around, noticed suspicious xrandr output

% xrandr
Screen 0: minimum 320 x 200, current 1440 x 1848, maximum 32767 x 32767
LVDS1 connected primary 1366x768+0+1080 (normal left inverted right x axis y axis) 277mm x 156mm
   1366x768       60.0*+
   1024x768       60.0  
   800x600        60.3     56.2  
   640x480        59.9  
VGA1 disconnected 1440x900+0+0 (normal left inverted right x axis y axis) # suspicious line

It appeared, that VGA1 output still remains kind of active, and laptop can only handle one external display at time.
Solution was as simple as this
% xrandr --output VGA1 --off