XRandR – finally, simple monitor configuration for Linux

The most recent Linux distribution releases - Ubuntu 7.10, Fedora 8 and so on - are now shipping with version 1.2 of the XRandR extension for the X server. This allows the user to dynamically change resolutions, refresh rates, and - this is the really impressive thing - switch monitors on and off on the fly. All of this, without ever having to edit xorg.conf, or restart the X server, or reboot. This was one of the major things that the Linux desktop lacked compared to other major operating systems.

Until very recently, using my external monitor with my laptop required several irritating customisations.

  1. To have it switch on, and run in Xinerama mode along with my laptop panel, required fiddling with MetaModes and other fiddly settings of the radeon driver.
  2. To drive it at its native resoution (1440x900) i had to add a custom modeline to xorg.conf (except on Fedora, for some reason).
  3. If the X server originally started without the external monitor attached, then it would have to be restarted to detect the monitor once it was attached. And restarting X means having to log out and lose all my application state.

XRandR 1.2 has removed all three of these irritations. It requires (almost) no preconfiguration, autodetects all resolutions correctly, and detects monitors when they are plugged in without a restart. Let’s take a brief look at some of what XRandR can do: this is basically what I do with it daily. Note that at the moment graphical tools to control XRandR are still under development and none are really at a releaseable state (in my opinion); but now that the infrastructure exists in the X server and the drivers, tools to control it will come soon. What I use here is the command-line tool, sensibly named xrandr. Let’s say I boot the computer without the external monitor plugged in. As you would expect, my desktop is automatically set to the native resolution of the laptop panel (in my case, 1024x768). I can see what resolutions and refresh rates are available:

$ xrandr -q
Screen 0: minimum 320 x 200, current 1024 x 768, maximum 2464 x 1024
VGA-0 disconnected (normal left inverted right x axis y axis)
DVI-0 disconnected (normal left inverted right x axis y axis)
LVDS connected 1024x768+0+0 (normal left inverted right x axis y axis) 0mm x 0mm
   1024x768 60.0*+ 60.0
   800x600 60.3
   640x480 59.9
S-video disconnected (normal left inverted right x axis y axis)

This tells me that the only attached monitor is the laptop panel (called LVDS); that it can run at the three different resolutions listed, and at the refresh rates listed next to the resolutions. The “*” indicates the mode that is currently in use, and the “+” indicates which mode is preferred by the monitor. If i wanted to, I could switch to some other resolution:

$ xrandr --output LVDS --mode 800x600

But that looks horrible, so I switch back to the preferred resolution:

$ xrandr --output LVDS --auto

Now everything’s back to normal. There are various rotation and reflection options as well, but I won’t discuss them because (a) they’re silly, and (b) you can look them up in the man page if you need them. Here comes the interesting part. Now I plug in my external monitor. Nothing happens immediately; but if I run the query command, there’s some new information:

$ xrandr -q
Screen 0: minimum 320 x 200, current 1024 x 768, maximum 2464 x 1024
VGA-0 connected (normal left inverted right x axis y axis)
   1440x900 59.9 + 75.0 59.9
   1280x1024 75.0 59.9
   1280x960 74.9
   1360x765 59.8
   1152x864 74.8 60.0
   1024x768 75.1 70.1 65.7 60.0
   832x624 74.6
   800x600 72.2 75.0 60.3 56.2
   640x480 75.0 72.8 66.7 60.0
   720x400 70.1
DVI-0 disconnected (normal left inverted right x axis y axis)
LVDS connected 1024x768+0+0 (normal left inverted right x axis y axis) 0mm x 0mm
   1024x768 60.0*+ 60.0
   800x600 60.3 640x480 59.9
S-video disconnected (normal left inverted right x axis y axis)

So I can now see all the modes supported by the external monitor (called VGA-0). I switch the monitor on:

$ xrandr --output VGA-0 --auto

This switches on the monitor in a sort-of clone mode: the output from the laptop panel is duplicated on the external monitor; but because the external monitor is larger, it appears in the top left, and the desktop size expands to the size of the external monitor. (At the moment, GNOME doesn’t handle this too well, and the GNOME panel stays in the same place, meaning that it’s in the middle of what’s visible on the external monitor.) So now I can switch off the laptop panel:

$ xrandr --output LVDS --off

(GNOME handles this correctly and moves the panel.) Now, if you look at the query output above, you’ll see that the monitor claims that its preferred mode has a refresh rate of 59.9Hz, although it also supports a 75Hz mode at the same resolution. I find the latter mode more friendly on my eyes, so I switch to it:

$ xrandr --output VGA-0 --mode 1440x900 --rate 75.0

I want to use the extra desktop space available on my laptop panel; but by default it would just be cloning the output of the external monitor, which wouldn’t help. So I use another option to position the outputs:

$ xrandr --output LVDS --auto --left-of VGA-0

This places the panel to the left of the external monitor. There are corresponding --right-of, --above and --below options. Finally, I want to switch off the external monitor so that I can take my laptop away from the desk:

$ xrandr --output VGA-0 --off

Now I’m back where I started. This is all very cool, but there are a couple of cautionary notes. The necessary drivers are only included in very recent distro releases (Ubuntu 7.10 and Fedora 8 in particular). Currently only the open-source Intel, Radeon and NV drivers support XRandR 1.2; neither the ATi nor the NVIDIA proprietary drivers support it. For now, you pretty much have to use the command-line tool - though that will change quickly. Finally, you sometimes have to set the Virtual option in xorg.conf to indicate the largest possible size of your desktop - but this is a one-off setting, and I hope that distros will start setting it to a sensible default automatically.

Written on December 6, 2007