Detect External Monitor

First post for this website completely in English.

I have a bunch of on going projects and things I'd like to talk about, but time is not on my side (as usual), but this I think it's worth talking about.

This is a very stupid guide on how to setup a simple script I wrote on how to detect the external monitor and use it automatically.

The basic setup and use I will cover are:

  • configure basic functionality of the script
  • setup keyboard keys (usually Fn+F7) for use with the script
  • autoload script at logon for using the external monitor automatically

Notes

Unfortunately this script works only under certain conditions. While researching before starting to write it I probably understood why nobody actually ever tried to do it (or maybe not and my searches didn't dig deep enough).
This script relies on a fantastic program called disper, which, at the moment, is working only on nVidia cards.

So, if you are a lucky owner of a laptop with an nVidia card and an external monitor/projector, this document is for you :-)

Requirements

As written in the head of the script, the requirements for it to work are:

  • disper (for gentoo-users: ebuild on bugzilla)
  • Xosd
  • xrandr
  • a RANDR capable Xorg installation
  • a quite recent nVidia card with dual head (tested on a 6200Go and a GT218)
  • an external monitor to use

Will it blend?

The script itself is very easy to use and understand, so you feel free to play with it, find its bugs and submit/request changes to it, it's free software! ;-)

Configure

Download the script from here.

The only thing you would like to change in the script is the default resolution your laptop has:

DefaultScreenSize="1920x1080" # CONFIGURE THIS VARIABLE

There's more you can tweak, but for the moment is enough.

Install the rest of dependencies written above.

Make it work!

Place the file in a safe enough position, I'd use as an example my solution: being in a multiuser environment I've preferred to use a system wide position as /usr/local/share/scripts/ so:

# cp detectExternalMonitor.sh /usr/local/share/scripts/
# chmod a+x /usr/local/share/scripts/detectExternalMonitor.sh
# ln -s /usr/local/share/scripts/detectExternalMonitor.sh /usr/local/bin/detectExternalMonitor

The last command assumes /usr/local/bin is in your $PATH.

Now try to launch it from a terminal (from within X) to see if it's working, like:

$ detectExternalMonitor -check
nothing to do

If you didn't had the monitor plugged in everything would have worked as above.

Mind that invoking the script without arguments would force the second display output, even if it's not enabled. In that case just invoke the script with -check as an argument.

Bind it!

Now we just need to bind the script to a key press (I would use Fn+F7 since it's used widely).

For doing this I've used xbindkeys. This program works with a daemon together with a configuration file that you will need to generate. In order to launch the daemon, just run it without arguments and add this program so that it could be started whenever you login into your wm (instructions not included). The first time you run it, it will require the configuration file to be present and show you how to generate it in case you don't have it.

Now launch it with -k and press the key combination (mine was Fn+F7) to find out the key you need to bind:

$ xbindkeys -k

Press combination of keys or/and click under the window.

You can use one of the two lines after NoCommand in $HOME/.xbindkeysrc to bind a key.

"NoCommand"
    m:0x0 + c:151
    XF86WakeUp

This is my output, but your can be different. In my case I just added this piece of code to .xbindkeysrc:

"detectExternalMonitor"
    m:0x0 + c:151

In case you cannot capture the keybinding check out your kernel log (/var/log/messages) for a line like:

atkbd.c: Unknown key pressed (translated set 2, code 0xf4 on isa0060/serio0).
atkbd.c: Use 'setkeycodes e074 <keycode>' to make it known.

In this case you need to "make it known": add a line like this in your system startup script:

setkeycodes e074 235

In gentoo it was added into /etc/conf.d/local.start.

I'd really like to understand where the "235" comes from, but my searches end here, if you know more, let me know :)

Btw, now you're done, key binded.

Final touches...

As you have added the xbindkeys daemon to the startup of your wm, you could do the same with the program itself adding the -check flag, that will automate the process without you to worry about it.

detectExternalMonitor -check

Some tech notes

The big problem in writing this script was to understand how to detect the external monitor.

It would have been great if nvidia-settings -q ConnectedDisplays worked, but with the monitor plugged in/out the values were not changing, so I must assume either it works only on recent hardware or I misunderstood something. Because of that I based the detect script on the default name of the external monitor (CRT-0): if it's not plugged in, the name will remain the default one, if the monitor is PnP (? I didn't have time to investigate what actually is sent read from the monitor.. EDID? if anyone knows...) it will show another name. Easy enough?

Since the external monitor enable/disable would blank out everything for a couple of seconds, I've tried to avoid to redo any action for example in case the monitor has been plugged in/out and stuff like that.

Moreover when switching manually I had to set a temp file, to realize some sort of state machine.

This script will obviously conflict with any script that will work with several copies of xorg.conf to be swiched on and off (seen a couple of these solutions around, but probably way too complicated IMHO).

I hope you'll enjoy it :-)

If you really liked it and want to improve it, please send me your thoughts, here in the comments or via the web mail form, I'd be happy to update it.