Run script when monitor is connected
An alternative way to run a command if a screen is connected or disconnected
An alternative solution would be to run a tiny background script. Running the script below in the background, I could not measure any increase in processor load whatsoever.
It is an easy an convenient way to run a script, or any other command, whenever a second screen is connected or disconnected.
The example script
- Simply checks every five seconds how many times the string " connected " occurs in the output of the command
xrandr
(mind the space after "connected" to prevent false matches with "disconnected"). Each occurrence represents a connected screen. - If the number of occurrences changes, either a screen was connected or disconnected. The change is "noticed" by the script and can be connected to a command, you can set in the head section of the script.
The script
#!/usr/bin/env python3
import subprocess
import time
#--- set both commands (connect / disconnect) below
connect_command = "gedit"
disconnect_command = ""
#---
def get(cmd): return subprocess.check_output(cmd).decode("utf-8")
# - to count the occurrenc of " connected "
def count_screens(xr): return xr.count(" connected ")
# - to run the connect / disconnect command(s)
def run_command(cmd): subprocess.Popen(["/bin/bash", "-c", cmd])
# first count
xr1 = None
while True:
time.sleep(5)
# second count
xr2 = count_screens(get(["xrandr"]))
# check if there is a change in the screen state
if xr2 != xr1:
print("change")
if xr2 == 2:
# command to run if connected (two screens)
run_command(connect_command)
elif xr2 == 1:
# command to run if disconnected (one screen)
# uncomment run_command(disconnect_command) to enable, then also comment out pass
pass
# run_command(disconnect_command)
# set the second count as initial state for the next loop
xr1 = xr2
How to use
- Copy the script into an empty file, save it as
connect_screen.py
In the head section, set the command to run on connect ( I set "gedit" as an example, mind the quotes). Also it is possible to set a command on disconnect, likewise. Else leave
disconnect_command = ""
as it is.If you do use a disconnect- command, also uncomment the line:
run_command(disconnect_command)
and comment out the line:
pass
As indicated in the script
- Test-run the script from a terminal, connect your screen and see if all works fine.
If all works fine, add it to your startup applications: Dash > Startup Applications > Add the command:
/bin/bash -c "sleep 15&&python3 /path/to/connect_screen.py"
The
sleep 15
is to make the desktop start up completely before the script starts to run. Just to make sure.
EDIT
How to run the script on start up in a "smart" way.
The break of sleep 15
should work in general, but since the start up time differs per system, It might take some experimenting to find the right break time. With a small addition, the script becomes "smart", and waits for the xrandr
command to be successful before it starts the actual script. If you use the version below, you only need to add the command:
python3 /path/to/connect_screen.py
to your Startup Applications. Further usage is exactly the same as the version above.
The script
#!/usr/bin/env python3
import subprocess
import time
#--- set both commands (connect / disconnect) below
connect_command = "gedit"
disconnect_command = ""
#---
while True:
time.sleep(5)
try:
subprocess.Popen(["xrandr"])
except:
pass
else:
break
# function to get the output of xrandr
def get(cmd): return subprocess.check_output(cmd).decode("utf-8")
# - to count the occurrenc of " connected "
def count_screens(xr): return xr.count(" connected ")
# - to run the connect / disconnect command(s)
def run_command(cmd): subprocess.Popen(["/bin/bash", "-c", cmd])
# first count
xr1 = None
while True:
time.sleep(5)
# second count
xr2 = count_screens(get(["xrandr"]))
# check if there is a change in the screen state
if xr2 != xr1:
if xr2 == 2:
# command to run if connected (two screens)
run_command(connect_command)
elif xr2 == 1:
# command to run if disconnected (one screen)
# uncomment run_command(disconnect_command) to enable, then also comment out pass
pass
# run_command(disconnect_command)
# set the second count as initial state for the next loop
xr1 = xr2
This can be achieved from following bash script as well.
#!/usr/bin/env bash
xrandr=$(xrandr)
con_monitors=$(echo $xrandr | grep -c " connected ")
if [[ $con_monitors -gt 1 ]]; then
# All the layouts are saved in "screenlayout" folder.
# eg cmd. xrandr --output HDMI-1 --mode 2560x1440 --pos 0x0 --rotate normal --output DP-1 --off --output eDP-1 --primary --mode 1920x1080 --pos 283x1440 --rotate normal --output DP-2 --off
for layout in ~/.screenlayout/*.sh; do
./layout
done
fi