RandR support in GNOME

This is the work to integrate support for the RandR X extension into GNOME, to support multiple monitors, projectors, and changing monitor resolutions and rotations.

Tracker bugs

Notable bugs

Intel graphics and the panel

On laptops, the Intel driver reports the VGA output (and possibly others) before the LVDS. Gnome-panel then picks the first output in the list as its "primary monitor". People don't like this because it puts their panel in the external display.

530969 mentions the super-common case of having overlapping outputs ("clone mode" or "mirror screens"), where the panel wrongly uses the resolution from the external monitor. This is bad if the outputs are of different resolutions; the panel then shows up not at the bottom of the screen, but somewhere in the middle, corresponding to the resolution of the "other" monitor.

To-do

See this comment about RANDR 1.3 introducing the concept of a "primary monitor" for use by clients. We need that.

Keying monitor configurations

You have your laptop on the road, obviously with no external monitor. You want a good gnome-panel configuration for your single LCD.

Then you go home or to the office, where you use a docking station and/or an external monitor. You want gnome-panel to remember the configuration that you like on those setups.

It makes sense for apps to be able to know when they are running in a RANDR configuration that they already saw. It is probably enough to add an API like

  • char *gnome_rr_config_get_token (GnomeRRConfig *config);

that returns an opaque string that identifies that configuration. Then the panel could store its setup for a particular RANDR configuration in GConf, under a /apps/panel/randr-setups/token directory.

The panel could keep only the latest N configurations in that fashion, to avoid growing the GConf data indefinitely. The assumption is that you don't regularly use more than a handful of RANDR setups (home, office, on-the-road).

RANDR policies in GNOME

As most things in X, the RANDR extension does not define any policies for how it is used. This section documents how GNOME views RANDR and how we use it.

Storage of RANDR configurations

A RANDR configuration is a set of outputs, CRTCs, and their relationships (which CRTC drives which output with which modeline). GNOME remembers the configurations which the user has saved in $(XDG_CONFIG_HOME)/monitors.xml (normally ~/.config/monitors.xml). The code responsible for reading and writing this file is in gnome-desktop/libgnome-desktop/gnome-rr-config.c.

The configuration file looks like this:

<monitors version="1">
  <configuration>
    ...
  </configuration>
  <configuration>
    ...
  </configuration>
</monitors>

FIXME: document that file.

Each configuration remembers a set of monitors and how they are set up. For example, the first configuration may be for your laptop's LCD only. A second configuration may be for that LCD plus a certain projector on the VGA output, running at a certain resolution. GNOME tries to reuse a configuration if it matches the monitors that are currently plugged in, so that you don't have to configure everything by hand every time you plug in the same set of monitors.

Centralization of changes to the RANDR configuration

Although any X client may change the RANDR configuration, GNOME prefers to centralize this through a D-Bus API exported by the RANDR plug-in of gnome-settings-daemon. The Display Settings capplet (gnome-display-properties) uses the GnomeRR API to save monitors.xml as described above, and then calls the D-Bus API to make gnome-settings-daemon change the RANDR configuration to what was just saved.

Gnome-settings-daemon has a confirmation dialog with a timeout, that lets the user say if the display looks fine after changing the monitor's parameters. Unfortunately some monitors lie about their capabilities, and graphics drivers are sometimes buggy, so we need to allow users to back out of an illegible display.

Handling of the XF86Display hotkey

The RANDR plug-in in gnome-settings-daemon grabs the XF86Display hotkey, which some laptops have — on Thinkpads it is Fn-F7; on HP laptops it is Fn-F4; etc.

When one hits the XF86Display hotkey repeatedly, gnome-settings-daemon cycles the screen configuration between these:

  • The current configuration.
  • Mirror screens ("clone mode") - displays are set to the same resolution, and at offset (0, 0).
  • Extended desktop with side-by-side monitors ("Xinerama mode") - laptop display is put on the left, and all other displays are put sequentially to the right.
  • Laptop-only - external displays are turned off.
  • Other-only - laptop display is turned off; external displays are turned on and placed at offset (0, 0)

Handling of hotplug and unsuspend

When (if!) the X server detects that the user has plugged or unplugged a monitor, then it sends out a RANDR event to clients that have requested so. X basically says, "the monitors changed", and it is up to clients to implement a policy to handle this. This also happens if X detects that monitors changed when a laptop comes back from suspend (such as when monitors get plugged/unplugged while the laptop is suspended). Again, this gets handled in the RANDR plug-in in gnome-settings-daemon.

Any outputs that got disconnected ("monitor unplugged") are turned off.

Any outputs that got connected ("monitor plugged in") are turned on, set to their preferred resolution, and laid out left-to-right to form an extended desktop.

As of 2009/Jun/22, there is commented-out code in gsd-xrandr-manager.c with an alternative policy. With it, g-s-d looks in the saved configurations to see if there is a suitable one for the monitors that are currently plugged in. A comment in the code describes why that policy is disabled in favor of the one described above.

RANDR coverage in GNOME

As of 2009/Jun/22, GNOME uses the following protocol requests from RANDR:

  RRGetCrtcInfo
  RRGetOutputInfo
  RRGetOutputProperty (currently only for the EDID_DATA atom)
  RRGetScreenResources
  RRGetScreenResourcesCurrent if RANDR 1.3 is available
  RRGetScreenSizeRange

  RRQueryVersion

  RRSelectInput
  RRSetCrtcConfig
  RRSetScreenSize

We also handle RRScreenChangeNotify events as a catch-all for changes in the X server's RANDR state. We don't handle the more detailed RRCrtcChangeNotify nor RROutputChangeNotify events.

Attic/RandR (last edited 2013-11-22 22:10:52 by WilliamJonMcCann)