35

Is there a way to save my monitor settings? I have an external monitor at work, but each morning i have to plug it in, rearrange the windows from being side by side to being on top of each other. Can I just save this?

10 Answers 10

17

Long story short (that is: do what Nicolas Bernaerts suggests, but I spare you the details): monitors configuration is actually saved in ~/.config/monitors.xml, but it's not applied at startup/login.

The steps to overcome this are:

Log in with the wrong monitors configuration.

Remove current monitor configuration:

cd .config
mv monitors.xml{,.bak}

Use the Displays application to arrange the monitors as you wish (I have one side monitor rotated counterclockwise). arrange your monitors as you wish

Once you press Apply, a new monitors.xml is created.

Now, download and make executable the script and the launcher that force the monitor configuration based on the newly created config file:

$ sudo wget -O /usr/local/sbin/update-monitor-position https://raw.githubusercontent.com/NicolasBernaerts/ubuntu-scripts/master/ubuntugnome/update-monitor-position
$ sudo chmod +x /usr/local/sbin/update-monitor-position
$ sudo wget -O /usr/share/applications/update-monitor-position.desktop https://raw.githubusercontent.com/NicolasBernaerts/ubuntu-scripts/master/ubuntugnome/update-monitor-position.desktop
$ sudo chmod +x /usr/share/applications/update-monitor-position.desktop

At this point, the monitors' configuration can be fixed by launching the update monitor position application.

If you want this to be automatic, simply add a startup application, with the following entries:

  • Name: Update Monitors Position
  • Command: update-monitor-position 5
  • Comment: Force monitors position 5 seconds after login

enter image description here

7
5

Configuration for all your monitors - hot-plugged or not - should be stored in $HOME/.config/monitors.xml by the xrandr plugin for gnome-settings-daemon, which is what actually applies the configuration you make in the Monitors capplet.

Since it seems that this isn't working properly for everyone, there's clearly a bug somewhere. Urgh.

1
  • Yeah, and as maco says, if i shut off the computer and boot it back up, it remembers, just not when it's already on. Oct 12, 2010 at 16:39
4

First three steps to connect your external monitor the way you want and 4th is to save the settings.

  1. Connect your external monitor and check its supported resolution:

    xrandr -q
    
  2. Give the following command (This will disable your laptop monitor):

    xrandr --output LVDS1 --off --output TV1 --off --output VGA1 --mode 1280x1024 --pos 0x0 --rotate normal
    
  3. If you want both laptop and external enabled:

    xrandr --output LVDS1 --mode yyyyXzzzz --pos 0x0 --rotate normal --output TV1 --off --output VGA1 --mode 1280x1024 --pos 0x0 --rotate normal
    

    (yyyyXzzzz - your laptop resolution.)

    The above configuration will clone your screen. Play with "--right-of / --left-of" option if you want.

  4. If you need this settings while login, add the checks in /etc/X11/Xsession.d/45custom_xrandr-settings (You might need to create one).

    xrandr |grep VGA1 | grep " connected " | if [ $? -eq 0 ]; then xrandr --output LVDS1 --off --output TV1 --off --output VGA1 --mode 1280x1024 --pos 0x0 --rotate normal  #Change the way u need ; fi
    
4

At office, I have 3 monitors on my laptop, and 2 at home. Two of office monitors are set vertical, while other monitors are at normal orientation.

A. monitors.xml is in ~/.config.

  1. Delete it
  2. Set the display at office setup
  3. Rename just created "monitors.xml" to "monitors-office.xml".

B. Get shell script, "update-monitor-position".

  1. Change the "MONITOR_XML" definition, "monitors.xml" to "monitors-office.xml".

  2. Save it as "update-monitor-position-office", in executable path (/usr/local/sbin/).

  3. Touch the permission -> executable by "Me".

C. Get desktop shortcut, "update-monitor-position.desktop"

  1. Change "Exec" definition, "update-monitor-position" to
    "update-monitor-position-office".
  2. Save it as "update-monitor-position-office.desktop"
  3. Touch the permission -> executable by "Me".

update-monitor-position-office.desktop:

[Desktop Entry]
Type=Application
Exec=update-monitor-position-office
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Name[en_US]=Office Monitors Position
Name=Office Monitors Position
Comment[en_US]=Force monitors position from monitor-office.xml
Comment=Force monitors position from monitor-office.xml
Icon=display

Shell script, update-monitor-position-office

#!/bin/bash
# -------------------------------------------------
#  Get monitors configuration from monitor.xml and apply it for current user session.
#  In case of multiple definitions in monitor.xml only first one is used.
#
#  See http://bernaerts.dyndns.org/linux/74-ubuntu/309-ubuntu-dual-display-monitor-position-lost
#  for instructions
#
#  Parameters :
#    $1 : waiting time in sec. before forcing configuration (optional)
#
#  Revision history :
#    19/04/2014, V1.0 - Creation by N. Bernaerts
#    10/07/2014, V1.1 - Wait 5 seconds for X to fully initialize
#    01/09/2014, V1.2 - Correct NULL file bug (thanks to Ivan Harmady) and handle rotation
#    07/10/2014, V1.3 - Add monitors size and rate handling (idea from jescalante)
#    08/10/2014, V1.4 - Handle primary display parameter
#    08/12/2014, V1.5 - Waiting time in seconds becomes a parameter
# -------------------------------------------------

# monitor.xml path
MONITOR_XML="$HOME/.config/monitors-office.xml"

# get number of declared monitors
NUM=$(xmllint --xpath 'count(//monitors/configuration['1']/output)' $MONITOR_XML)

# loop thru declared monitors to create the command line parameters
for (( i=1; i<=$NUM; i++)); do
  # get attributes of current monitor (name and x & y positions)
  NAME=$(xmllint --xpath 'string(//monitors/configuration['1']/output['$i']/@name)' $MONITOR_XML 2>/dev/null)
  POS_X=$(xmllint --xpath '//monitors/configuration['1']/output['$i']/x/text()' $MONITOR_XML 2>/dev/null)
  POS_Y=$(xmllint --xpath '//monitors/configuration['1']/output['$i']/y/text()' $MONITOR_XML 2>/dev/null)
  ROTATE=$(xmllint --xpath '//monitors/configuration['1']/output['$i']/rotation/text()' $MONITOR_XML 2>/dev/null)
  WIDTH=$(xmllint --xpath '//monitors/configuration['1']/output['$i']/width/text()' $MONITOR_XML 2>/dev/null)
  HEIGHT=$(xmllint --xpath '//monitors/configuration['1']/output['$i']/height/text()' $MONITOR_XML 2>/dev/null)
  RATE=$(xmllint --xpath '//monitors/configuration['1']/output['$i']/rate/text()' $MONITOR_XML 2>/dev/null)
  PRIMARY=$(xmllint --xpath '//monitors/configuration['1']/output['$i']/primary/text()' $MONITOR_XML 2>/dev/null)

  # if position is defined for current monitor, add its position and orientation to command line parameters
  [ -n "$POS_X" ] && PARAM_ARR=("${PARAM_ARR[@]}" "--output" "$NAME" "--pos" "${POS_X}x${POS_Y}" "--fbmm" "${WIDTH}x${HEIGHT}" "--rate" "$RATE" "--rotate" "$ROTATE")

  # if monitor is defined as primary, adds it to command line parameters
  [ "$PRIMARY" = "yes" ] && PARAM_ARR=("${PARAM_ARR[@]}" "--primary")
done

# if needed, wait for some seconds (for X to finish initialisation)
[ -n "$1" ] && sleep $1

# position all monitors
xrandr "${PARAM_ARR[@]}"
2
  • Hey @jey, you answered this in January 2018. (while Nicolas script is 4 years old...). May I assume this is still working under a recent Ubuntu 16.x / 18.x? – And: do you have any assumption, if it would work under Ubuntu-MATE as well? (I do see said monitors.xml on my system...)
    – Frank N
    Aug 2, 2018 at 7:37
  • Frank, mine says "16.04.5 LTS". One point, after "dist-upgrade", I had to go through the process, and then reboot. The "System Settings -> Displays" works funny on my system. I am not in the mode to try 18.x. Thanks,
    – jay
    Aug 3, 2018 at 14:33
2

I prefer to run this script from a terminal since I open one first after login.

First login with the bad configuration - monitors not placed correctly:

cd ~/.config
mv ~/.config/monitors.xml{,.bak}

Now set your monitors with system settings to create a new ~/.config/monitors.xml file with proper settings.

Copy Nicolas Bernaerts's fixed script from my repo: https://raw.githubusercontent.com/alextomko/monitors/master/monitors and put it in a path to run from terminal.

$ ls -l ~/bin
# if you don't have this directory then create it - do not be logged in as root here.

$ mkdir /home/$USER/bin

$ echo $PATH
# should show /home/username/bin if the dir existed or if you had to create.

$ wget -P ~/bin https://raw.githubusercontent.com/alextomko/monitors/master/monitors
$ chmod +x ~/bin/monitors

# Log out, lock, reboot or whatever it takes to make monitor settings lost for you and run the script.
$ monitors
2

Thank you for pointing me at the ~/.config/monitors.xml file.

I found that there was one created at the time I specified the layout I wanted, and also some kind of back-up, monitors.xml~ which differed in just the characteristic I wanted to change.

If I simply eliminated this backup file, I found that my newly-created one took effect the next time I restarted my machine. No need to download any script.

I guess, if there had been a bug, it has since been fixed.

Also guessing, I'm surmising the backup file got re-instated somehow, but with it gone, the primary file remains the only file in effect.

This worked both on a setup running Ubu 16.04 and one running 19.10

Again, thanks for pointing me at the file.

2
  • Also worked on my Ubuntu 20.04
    – Ralph
    Jan 20, 2023 at 21:36
  • 1
    But only works 1-2 times
    – Ralph
    Jan 26, 2023 at 23:55
1

Ubuntu 12.04 remembers hot-plugged monitor settings. But they are only applied when you reopen the System configuration > Displays applet. This is the case for me, at least, and this is definitively a bug.

1

jay's answer almost worked for me, but I needed to do a couple extra steps. I'd make this a comment on his answer but I don't have the reputation.

In the file update-monitor-position-office:

  1. My version of bash (4.3.48) complained about the lack of a space following "i++" on line 28.
  2. My version of xrandr (1.5) did not recognize the "--fbmm" option on line 40. I had to change this to "--mode". This was hard to diagnose because xrandr did not actually give me an error, it just executed the command without doing anything.
0

No, there's no way to save configurations on hot-plugged monitors. If you plug in before boot, GNOME should remember the configuration on each boot on a per-device basis (ie, connecting to your monitor at work versus the one at home).

4
  • Damn, ok. Is there a third party application than can do this? I know Mac OS X does this, and Windows 7 (from what I've tried with the little experience I have with W7). Oct 11, 2010 at 21:16
  • The GNOME monitor configuration should save this information for hotplugged monitors, too. It does for me.
    – RAOF
    Oct 11, 2010 at 23:11
  • RAOF: weird, since discussion on the ubuntu-devel mailing list earlier this week said it doesn't.
    – maco
    Oct 11, 2010 at 23:31
  • the configuration is actually saved in ~/.config/monitors.xml, but it is not applied at startup Jan 4, 2016 at 9:04
0

Note that in Ubuntu 18.04, the monitors.xml layout seems to be different, so some of the xpath queries don't work anymore. I adapted the shell script posted by @jay to work accordingly:

#!/bin/bash
# -------------------------------------------------
#  Get monitors configuration from monitor.xml and apply it for current user session.
#  In case of multiple definitions in monitor.xml only first one is used.
#
#  See http://bernaerts.dyndns.org/linux/74-ubuntu/309-ubuntu-dual-display-monitor-position-lost
#  for instructions
#
#  Parameters :
#    $1 : waiting time in sec. before forcing configuration (optional)
#
#  Revision history :
#    19/04/2014, V1.0 - Creation by N. Bernaerts
#    10/07/2014, V1.1 - Wait 5 seconds for X to fully initialize
#    01/09/2014, V1.2 - Correct NULL file bug (thanks to Ivan Harmady) and handle rotation
#    07/10/2014, V1.3 - Add monitors size and rate handling (idea from jescalante)
#    08/10/2014, V1.4 - Handle primary display parameter
#    08/12/2014, V1.5 - Waiting time in seconds becomes a parameter
#    06/17/2020, V1.6 - Adapted to new monitors version = 2 (see https://askubuntu.com/a/993592/93077)
# -------------------------------------------------

# monitor.xml path
MONITOR_XML="$HOME/.config/monitors-office.xml"

# get number of declared monitors
NUM=$(xmllint --xpath 'count(//monitors/configuration['1']/logicalmonitor)' $MONITOR_XML)
# loop thru declared monitors to create the command line parameters
for (( i=1; i<=$NUM; i++)); do
  # get attributes of current monitor (name and x & y positions)
  NAME=$(xmllint --xpath 'string(//monitors/configuration['1']/logicalmonitor['$i']//connector/text())' $MONITOR_XML 2>/dev/null)
  POS_X=$(xmllint --xpath '//monitors/configuration['1']/logicalmonitor['$i']/x/text()' $MONITOR_XML 2>/dev/null)
  POS_Y=$(xmllint --xpath '//monitors/configuration['1']/logicalmonitor['$i']/y/text()' $MONITOR_XML 2>/dev/null)
  #ROTATE=$(xmllint --xpath '//monitors/configuration['1']/logicalmonitor['$i']/rotation/text()' $MONITOR_XML 2>/dev/null)
  WIDTH=$(xmllint --xpath '//monitors/configuration['1']/logicalmonitor['$i']//width/text()' $MONITOR_XML 2>/dev/null)
  HEIGHT=$(xmllint --xpath '//monitors/configuration['1']/logicalmonitor['$i']//height/text()' $MONITOR_XML 2>/dev/null)
  RATE=$(xmllint --xpath '//monitors/configuration['1']/logicalmonitor['$i']//rate/text()' $MONITOR_XML 2>/dev/null)
  PRIMARY=$(xmllint --xpath '//monitors/configuration['1']/logicalmonitor['$i']/primary/text()' $MONITOR_XML 2>/dev/null)
  # if position is defined for current monitor, add its position and orientation to command line parameters
  [ -n "$POS_X" ] && PARAM_ARR=("${PARAM_ARR[@]}" "--output" "$NAME" "--pos" "${POS_X}x${POS_Y}" "--fbmm" "${WIDTH}x${HEIGHT}" "--rate" "$RATE" "--rotate" "normal")
  # if monitor is defined as primary, adds it to command line parameters
  [ "$PRIMARY" = "yes" ] && PARAM_ARR=("${PARAM_ARR[@]}" "--primary")
done
# if needed, wait for some seconds (for X to finish initialisation)
[ -n "$1" ] && sleep $1

# position all monitors
xrandr "${PARAM_ARR[@]}"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .