Using LightDM with an External Monitor on a Laptop or with the Multi-monitor Setups
Like many other users, I find it convenient to connect an external monitor to my laptop sometimes. As I often do this, I expect this functionality to work flawlessly but, unfortunately, I experienced some problems when using LightDM on Arch Linux . By default, LightDM tries to mirror data on multiple displays, and it does not work well when you have monitors with different resolutions. In this post, I want to share my solution to this problem. I expect that this solution might be useful not only for laptop users but for the workstation users with multi-monitor setups as well. Moreover, if LightDM's user interface sometimes stops responding to your actions, this post might be useful for you.
In general, on a laptop with an external monitor, I expect the login screen to appear on it and have the laptop screen disabled in that case. If there are multiple external monitors connected to the system, I want only one of them used for a login screen.
Fortunately, these actions can be programmed using a UNIX shell script build around the functionality of the xrandr
utility.
When used without any parameters it prints the list of monitor outputs alongside the information about the connected monitors:
artem@artbox:~$ xrandr Screen 0: minimum 8 x 8, current 1366 x 768, maximum 32767 x 32767 LVDS1 connected 1366x768+0+0 (normal left inverted right x axis y axis) 340mm x 190mm 1366x768 60.03*+ 1280x720 59.74 1024x768 60.00 1024x576 60.00 59.90 59.82 960x540 60.00 59.63 59.82 800x600 60.32 56.25 864x486 60.00 59.92 59.57 640x480 59.94 720x405 59.51 60.00 58.99 680x384 60.00 640x360 59.84 59.32 60.00 DP1 disconnected (normal left inverted right x axis y axis) HDMI1 disconnected (normal left inverted right x axis y axis) VGA1 disconnected (normal left inverted right x axis y axis) VIRTUAL1 disconnected (normal left inverted right x axis y axis)
We could filter out the information about the available outputs using the UNIX tools:
artem@artbox:~$ xrandr | grep connected | cut -d ' ' -f 1-2 LVDS1 connected DP1 disconnected HDMI1 disconnected VGA1 disconnected VIRTUAL1 disconnected
Keeping in mind that an internal laptop screen is usually connected using the LVDS
interface, we could use the information obtained from the xrandr
tool to achieve what is required.
Let's outline the logic of the script using pseudo-code:
var primary_out = nil var to_disable = nil foreach monitor_out in list_monitor_outputs() do if is_connected(monitor_out) then if is_connected_via_LVDS(monitor_out) then to_disable = monitor_out else if primary_out == nil then primary_out = monitor_out else disable_monitor_output(monitor_out) endif endif endfor if primary_out != nil and to_disable != nil then set_as_primary_monitor_output(primary_out) disable_monitor_output(to_disable) else if primary_out != nil then set_as_primary_monitor_output(primary_out) endif
After translating the pseudo-code above into a shell script, I got the following code:
#!/bin/sh # the script will not work if xrandr is not available if [ -z "$(which xrandr)" ]; then exit 1 fi DISABLE_SUBSTRING="LVDS" TO_DISABLE="" PRIMARY_OUT="" old_IFS="${IFS}" IFS=$'\n' for out in `xrandr | grep connected | cut -d ' ' -f 1-2`; do name=`echo $out | cut -d ' ' -f 1` state=`echo $out | cut -d ' ' -f 2` if [ "$state" = "connected" ]; then case "$name" in # disable a monitor connected via LVDS ${DISABLE_SUBSTRING}*) if [ -z "$TO_DISABLE" ]; then TO_DISABLE="$name" fi ;; *) # set the 'first' external monitor as the # primary one, disable the other external monitors if [ -z "$PRIMARY_OUT" ]; then PRIMARY_OUT="$name" else xrandr --output "$name" --off fi ;; esac fi done IFS="${old_IFS}" # If there is an internal screen, as well as at least one external monitor, then # disable the internal monitor and use the external monitor as the primary one. # # Otherwise, if there are any external monitors, use the 'first' detected one # as the primary monitor. if [ -n "$TO_DISABLE" ] && [ -n "$PRIMARY_OUT" ]; then xrandr --output "$PRIMARY_OUT" --primary --auto --output "$TO_DISABLE" --off elif [ -n "$PRIMARY_OUT" ]; then xrandr --output "$PRIMARY_OUT" --primary --auto fi exit 0
To use the script, one should save it into an executable file and alter the LightDM's settings to use it to configure the displays.
In order to accomplish this one should change the display-setup-script
in the [Seat:*]
section of the LightDM configuration file (/etc/lightdm/lightdm.conf
):
[Seat:*] ... display-setup-script=/path/to/the-script ...
To apply the new settings, please restart the LightDM daemon. The next LightDM session should use the script to configure monitors.
Categories: UNIX/Linux Tips Hacks