0

I'm using SDDM (with Kubuntu if that matters) on a quasi headless setup, i.e., it normally has no monitor connected. Now there are some servicing tasks where I'd like to temporarily connect an external monitor to the system to work locally. It is a handheld USB-C monitor. Unfortunately, when no user is currently logged in and only the SDDM login screen would be displayed, the monitor does not turn on. I can then blindly type the password to log in and the monitor will start to work, but this is not really convenient, especially if somebody else has to do the maintenance. When the monitor is connected at boot time, it displays the login screen just fine. But if I then unplug it and plug it in a bit later (without being logged in), it will again not display anything.

The problem is that I don't really know what's going on with the monitor/output when nothing is displayed, as xrandr is of little help via SSH:

$ xrandr
Can't open display 
$ xrandr -display :0
Authorization required, but no authorization protocol specified

Can't open display :0 $ xrandr -display :1 Can't open display :1 $ xrandr -display :2 Can't open display :2

Is there a way to regularly (or on demand, like when a monitor is connected) tell SDDM to reconfigure itself like it does when the computer boots with a monitor already attached? Or can I somehow use xrandr to enable the output even when there is no monitor connected?

Thanks!

1 Answers1

0

So far I wasn't able to find a solution to this, but at least a workaround. xrandr actually detects when a display is connected or disconnected while the greeter is displayed, but this alone is not perfectly reliable. For some reason, it only really picks up the full changes when SDDM is restarted, which also makes it enable the display. However, since there still is a change in xrandr's output, I'm using this to detect if anything changed, and if so, I restart SDDM. But only when the greeter is shown, as display disconnects and reconnects are already handled properly when somebody is actually logged into KDE Plasma.

The core of the functionality is this script, stored as /usr/local/bin/restart_sddm_on_connected_display.sh:

#!/bin/bash

Run this script (as root) when using sddm to ensure that a newly connected

display gets activated, instead of just staying blank. It does so by

checking the output of xrandr and if it changed (meaning that an output was

connected/disconnected or something else changed with the displays), it

restarts sddm iif the greeter is currently running.

DEBUG=0

Check if sddm-greeter is running; do nothing if not.

if ! pgrep -x sddm-greeter > /dev/null; then [ $DEBUG -eq 1 ] && echo "sddm-greeter not running, exiting." exit 0 fi

Guess XAUTHORITY if empty.

if [ -z "$XAUTHORITY" ]; then # Prepare XAUTHORITY with the path of the first found file in # /var/run/sddm/, fail if none found. export XAUTHORITY=$(find /var/run/sddm/ -name 'xauth_*' | head -n 1) if [ -z "$XAUTHORITY" ]; then exit 1 fi fi

[ $DEBUG -eq 1 ] && echo "XAUTHORITY: $XAUTHORITY"

Set DISPLAY if not already set.

if [ -z "$DISPLAY" ]; then export DISPLAY=:0 fi

[ $DEBUG -eq 1 ] && echo "DISPLAY: $DISPLAY"

Run xrandr and save its output to a temporary file.

xrandr > /tmp/.xrandr_output || exit 1

Compare the output of xrandr to the previous output.

xrandr_output_change=$(diff -Nu100 /tmp/.xrandr_output_previous /tmp/.xrandr_output)

Store current output as previous output.

mv /tmp/.xrandr_output /tmp/.xrandr_output_previous

Restart sddm if the output changed.

if [ -n "$xrandr_output_change" ]; then echo "xrandr output change detected:" echo "$xrandr_output_change" echo "Restarting sddm..." systemctl restart sddm sleep 5 # Restarting sddm may change the xrandr output, so store it to avoid # restarting sddm again in the next run. export XAUTHORITY=$(find /var/run/sddm/ -name 'xauth_*' | head -n 1) xrandr > /tmp/.xrandr_output_previous

else [ $DEBUG -eq 1 ] && echo "No change in xrandr output, exiting." exit 0 fi

Then there's a simple helper script to run this again and again in a loop, so that changes can actually be detected when they happen (a cleaner solution would be to use some kind of notification system, but I don't know what is available to reliably detect such changes). So this is /usr/local/bin/loop_restart_sddm_on_connected_display.sh:

#!/bin/bash

Run this script (as root) in the background to pick up newly connected

displays and restart sddm to activate them when currently no output is active.

Set sleep time if empty.

if [ -z "$SLEEP_TIME" ]; then SLEEP_TIME=10 fi

Set restarting script if empty.

if [ -z "$RESTART_SCRIPT" ]; then RESTART_SCRIPT="/usr/local/bin/restart_sddm_on_connected_display.sh" fi

while true; do $RESTART_SCRIPT sleep $SLEEP_TIME done

And here's the systemd service file /etc/systemd/system/loop_restart_sddm_on_connected_display.service to have this run automatically:

[Unit]
Description=Restart sddm on connected display changes
After=network.target

[Service] ExecStart=/usr/local/bin/loop_restart_sddm_on_connected_display.sh Restart=always Type=simple KillSignal=SIGTERM

[Install] WantedBy=multi-user.target

While my use case probably isn't that common, the workaround might still be of value for somebody else. And maybe SDDM will be able to handle such cases by itself some time in the future.