Sign up ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

is there a tool which enables one to:

  • remember current RandR configuration (position, orientation, resolution etc) on per-monitor basis,
  • automatically apply last known good configuration as soon as the display is plugged in, with no need to muck around with applets or xrandr(1)?

The configurations would have to be applied on a per-user, per-display basis.

If there is no such tool in the wild, I'd like to throw together one myself, but as far as I can see, there's no way to tell that a monitor has been plugged in. Do I have to poll with xrandr -q once in a while to figure out that an output was connected or disconnected, or is there a more efficient way to do it? Can udev be tuned to do just that?

share|improve this question
Are you sure there is no way to tell that a monitor has been plugged in with your card. Try running udevadm monitor --property from the terminal and plugging the monitor in. With my card, I see an event when it is plugged in. You may be able to use a +RUN rule in udev and some bash scripting to get what you want. However, I'm not sure how you would be able to implement this on a per user basis using udev. – Steven D Dec 3 '10 at 1:58
@Steven: Your comment should be an answer. It's not a complete answer, but it does make significant progress. If udev does see a hardware event, it should notify hal which sends a dbus event which can be seen by user code. – Gilles Dec 3 '10 at 19:39

11 Answers 11

up vote 11 down vote accepted

I'm using this simple (homemade) script that keeps polling RandR and switches between LVDS1 and VGA1 when VGA gets connected/disconnected.

It's a dirty solution, yet it's working just fine.

It's customized for my setup: you'll most likely need to change RandR output names (LVDS1 and VGA1) and unlike me you'll probably be fine with your RandR default mode for VGA.


# setting up new mode for my VGA
xrandr --newmode "1920x1080" 148.5 1920 2008 2052 2200 1080 1089 1095 1125 +hsync +vsync
xrandr --addmode VGA1 1920x1080

# default monitor is LVDS1

# functions to switch from LVDS1 to VGA and vice versa
function ActivateVGA {
    echo "Switching to VGA1"
    xrandr --output VGA1 --mode 1920x1080 --dpi 160 --output LVDS1 --off
function DeactivateVGA {
    echo "Switching to LVDS1"
    xrandr --output VGA1 --off --output LVDS1 --auto

# functions to check if VGA is connected and in use
function VGAActive {
    [ $MONITOR = "VGA1" ]
function VGAConnected {
    ! xrandr | grep "^VGA1" | grep disconnected

# actual script
while true
    if ! VGAActive && VGAConnected

    if VGAActive && ! VGAConnected

    sleep 1s
share|improve this answer
Good script! Thanks, I needed something like this. I just copied it and set it up to run automatically. Thanks! – Linuxios Jan 31 '12 at 23:20

Responding to the "[a] way to tell that a monitor has been plugged in" part of the question:

The support still varies quite a bit, but with recent kernels there is some support for generating udev events when a display hotplug occurs. With kernel 2.6.38 and ATI X1400 hardware, I get an event the first time I connect a VGA display but no events on subsequent disconnects or reconnects of the display. Intel hardware may have better support. The NVIDIA proprietary driver does not currently support KMS; I haven't tried looking for hotplug events on NVIDIA hardware, but I'm doubtful it would work.

If you want to experiment with udev you could try the following steps:

  • update to the newest kernel
  • make sure that kernel mode setting (KMS) is enabled. If enabled, it should be reported in your kernel output. Mine says [drm] radeon kernel modesetting enabled and [drm] initializing kernel modesetting
  • run udevadm monitor --property and see if events are reported when you (dis-)connect displays

If you are getting udev events on display hotplug, you can trigger a script with a udev rule like:

ACTION=="change", SUBSYSTEM=="drm", HOTPLUG=="1", RUN+="/path/to/"

Note: This will not work if you use an nVIDIA GPU with the proprietary binary driver, since it does not use KMS. You will not get any udev events.

share|improve this answer

Regarding a tool which can store monitor configuration profiles on a per-user and per-display basis, autorandr will do exactly that.

My laptop has an NVIDIA card, so I use the disper backend instead of xrandr: Autorandr will use disper as the backend to manage your monitors if you call it as autodisper. For the rest of this post though, I'll refer to it as autorandr for consistency.

You can save profiles with autorandr --save profile_name. Running autorandr by itself will then give you a list of profiles, and identify which one is detected as the current configuration.

For instance:

$ autorandr
syncmaster19 (detected)

You can tell it to automatically load the appropriate profile for the current configuration with autorandr --change. This command, paired with a udev rule to run it when it is hotplugged, would do what you requested.

As an added precaution I've appended --default laptop to that command, which will make it default to the laptop's display if there is no saved profile that matches the current configuration. So the full command I use to switch displays is:

autorandr --change --default laptop

Unfortunately my machine doesn't give any udev output when I hotplug my monitor. I'm using the NVIDIA proprietary drivers, so that isn't surprising. So I have bound it to the XF68Display key (Fn-F8) for now, which is almost as good.

share|improve this answer
autorandr was a waste of time, bad documented, random monitor blinks, no install/uninstall instructions. Could solve it using udev – Leo Gallucci Jan 26 '14 at 15:38

I used the udev rule suggested above along with a shell script that looks like


dmode="$(cat /sys/class/drm/card0-VGA-1/status)"                        
export DISPLAY=:0                                                       
export XAUTHORITY=/home/yourusername/.Xauthority                              

if [ "${dmode}" = disconnected ]; then                                  
     /usr/bin/xrandr --auto                                              
elif [ "${dmode}" = connected ];then                                    
     /usr/bin/xrandr --output VGA1 --auto --right-of LVDS1               
else /usr/bin/xrandr --auto                                             


The Xauthority part is essential as well as the export DISPLAY, you can use echo $DISPLAY to see which number it's equal to. Use xrandr -q to see the external monitors you have. The last else statement is just to make sure that you're never stuck without a display.

share|improve this answer

I am not aware of such a tool and I guess that not a lot of hardware support the generation of such events (an Intel related discussion).

And polling would not be a very elegant solution - would waste CPU cycles and energy.

share|improve this answer
Polling once in two seconds or so to be a big waste? Usually, what you need is not an instantaneous reaction, 2-3 seconds delay is perfectly ok. By the way, ATAPI CD-ROM drivers do just that in all OSes. – Yaroslav Fedevych Dec 2 '10 at 23:05
No need to poll. Just use a udev rule like this one: DEVPATH=="/devices/pci0000:00/0000:00:02.0/drm/card0", ACTION=="change", RUN="/usr/local/sbin/triggerscreen" – Paul de Vrieze Nov 7 '13 at 10:22

A small program that waits for the X server to notify it about changed monitor configuration, and then executes a given command (e.g. the autorandr mentioned in another answer) is available at:

This seems to be a cleaner solution that using udev (where you have to worry about finding the right X server etc.)

share|improve this answer

I guess people looking at this question are not those that want to use GNOME, and those that use GNOME wouldn’t have to look at this question, but in the interest of completeness:

GNOME has this functionality built-in. If you change the setup via gnome-control-center, gnome-settings-daemon remembers it (in .config/monitors.xml) and automatically applies it when a monitor is plugged in or out.

share|improve this answer

When using peoro's solution, I got some extra output from xrandr, so I used the -c option for grep which counts the number of matches. I adapted it for HDMI and added audio switch as well:

# adapted from

# default monitor is LVDS1

# functions to switch from LVDS1 to HDMI1
function ActivateHDMI {
    xrandr --output HDMI1 --mode 1920x1080 --dpi 160 --output LVDS1 --off
    pactl set-card-profile 0 output:hdmi-stereo-extra1
function DeactivateHDMI {
    xrandr --output HDMI1 --off --output LVDS1 --auto
    pactl set-card-profile 0 output:analog-stereo

# functions to check if HDMI is connected and in use
function HDMIActive {
    [ $MONITOR = "HDMI1" ]
function HDMIConnected {
    [[ `xrandr | grep "^HDMI1" | grep -c disconnected` -eq 0 ]]

# actual script
while true
    if ! HDMIActive && HDMIConnected

    if HDMIActive && ! HDMIConnected

    sleep 1s
share|improve this answer

For those who, for whatever reason, don't want to take the hotplug route, it is still possible to not poll within a script using inotifywait:



renice +19 $$ >/dev/null



while [ 1 ]; do
    DUAL=$(cat /sys/class/drm/card0-DP-2/status)

    if [ "$OLD_DUAL" != "$DUAL" ]; then
        if [ "$DUAL" == "connected" ]; then
            echo 'Dual monitor setup'
            xrandr --output $SCREEN_LEFT --auto --rotate normal --pos 0x0 --output $SCREEN_RIGHT --auto --rotate normal --below $SCREEN_LEFT
            echo 'Single monitor setup'
            xrandr --auto


    inotifywait -q -e close /sys/class/drm/card0-DP-2/status >/dev/null

Polling with xrandr gave serious usability issues on my brand new laptop (mouse would stall periodically).

share|improve this answer

If you must have it automatically detect the display when it is plugged in, it seems that the cleanest solution is to add a UDEV rule to run a script containing your xrandr commands. Here is an example from one user's solution1:

Monitor (output) UDEV events with udevadm
This step will be most important for each user. Run udevadm monitor --environment --udev. Then connect your HDMI cable.

UDEV rule
Based on the output from the above command, the user created this UDEV rule at /etc/udev/rules.d/95-monitor-hotplug.rules.

KERNEL=="card0", SUBSYSTEM=="drm", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/dan/.Xauthority", RUN+="/usr/local/bin/"

Note the environment variables used so xrandr will be run under the user profile.

xrandr script

You may want to adjust the xrandr options to suit your needs.

#! /usr/bin/bash

export DISPLAY=:0
export XAUTHORITY=/home/dan/.Xauthority

function connect(){
    xrandr --output HDMI1 --right-of LVDS1 --preferred --primary --output LVDS1 --preferred 

function disconnect(){
      xrandr --output HDMI1 --off

xrandr | grep "HDMI1 connected" &> /dev/null && connect || disconnect
share|improve this answer

Editing my answer to make it simpler to setup.

Install autorandr to automate screen layout in xrandr, grab latest .deb from and run:

dpkg -i [file]

Setup autorandr with stored screen layouts

autorandr --save [docked|mobile|home|etc]

As an example, on my laptop without any monitors plugged in, I setup arandr the way I want it, then ran:

autorandr --save mobile

Then plugged in my hdmi and reconfigured arandr, then ran:

autorandr --save docked

After setting up each of your layouts you can run (replace 'mobile' with previous favored name, I used mobile):

autorandr --default mobile

Now that autorandr is all setup you can automate the process by installing a package which will poll for connected displays and run autorandr --change upon detection. Yes, I know about udev and you can set that up if it works for you, but in my testing udev didn't work for my hdmi consistently. It only worked 1 out of every 20 plugs/unplugs or so, and sometimes it just stopped altogether.

Download the latest .deb from here: then install with

dpkg -i [file]

It is most likely necessary that you run more tasks upon completion of autorandr --change, autorandr allows for these commands to be inserted into a file called ~/.autorandr/postswitch. Do as follows:

cd ~/.autorandr/ && touch postswitch && chmod +x postswitch

Now edit the postswitch file to have something similar to the following:

if pidof conky > /dev/null 2>&1; then
  killall conky
(sleep 2s && xrandr-adjust-brightness restore -q) &
(sleep 2s && nitrogen --restore) &
(sleep 3s && conky -q) &

Additionally you will likely want to add autorandr and poll-xrandr to your startups, something like the following two commands:

autorandr --change &
poll-xrandr &

Unplug or plug in a monitor and watch the magic!

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.