Linux user notes -- dual monitor hot plug
As a long time Linux user, I have to admit sometimes it is not easy to achieve some of the things that can be easily done in other OS (like macOS or Windows), but that one of the things I enjoy about Linux as well -- you need to force yourself to learn something, and once you've achieved it, you will learn from it and then realize how powerful Linux is. Anyway, for me, this had been one of the problems that had me troubled for a while -- using dual monitors, and have Linux automatically detect and extend desktops automatically.
Problem
I use bspwm as my tiling window manager, and polybar as the 'bar'. The problem I'm trying to solve here is to have the laptop automatically detect monitor hot-plug and then extend the bars with different layout to the new monitor. And when I unplugged the external monitor, the system revert back to single monitor layout.
Solution
The easiest way to achieve this is using udev. Based on my understanding, udev is similar to device manager in Windows. To solve this problem with udev, all you need to do is to create a new udev rule.
The first step is to find out which events are being triggered when the monitors are plugged/unplugged. To achieve this, you can use the udev monitor: udevadm monitor --environment --udev
. Plugin your monitor, and you will be able to see the events that are being triggered, as an example, here's what I got, when I plugged in my external monitor:
1 | UDEV [5012.844939] change /devices/pci0000:00/0000:00:02.0/drm/card0 (drm) |
Next, we are going to create the rules for this udev event. So we create a new file under /etc/udev/rules.d
folder, in this case I will call this file /etc/udev/rules.d/95-hdmi-plug.rules
, and here's the content of the file
1 | ACTION=="change", SUBSYSTEM=="drm", KERNEL=="card0" ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/kevin/.Xauthority", RUN+="/home/user/.monitor-hot-plug.sh" |
Notice how I matched the event: I used ACTION=="change", SUBSYSTEM=="drm", KERNEL=="card0"
, this is what comes directly from the monitoring after plugging in the external monitor. The ENV part is just setting some environment variables, which is necessary for X11. For the run part, I put in a script that is tailored to my need, it is quite short and simple, just telling xrandr to set the monitor positioning (probably not a best practice to hard code the positioning though):
1 |
|
At this point, we can start testing. You can definitely plug and remove the HDMI cable multiple times to test if it works, but that is a bit time consuming. We can use sudo udevadm test /sys/class/drm/card0
to see if the config file is correct.
Once you have done the necessary testing, it is important to reload the udev rules into the running system sudo udevadm control --reload-rules
Conclusion
This article explore how udev rules can be utilized to manage hot plug of external monitors. There are also some other different uses for this tool, such as detecting external mouse, external video cam etc. Use the references below to know more.