Ubuntu – Turn off external monitor when inactive

14.04hdmimultiple-monitors

I added an external monitor to my laptop last week and have almost everything working like I want except for the Brightness & Lock behavior.

I've long had this set to "Turn screen off when inactive for: 5 minutes" and it works like a charm for the laptop screen – both before and after the addition of the external monitor. But it doesn't work on the external monitor. When I'm away from my desk for longer than I intended, I come back to a black laptop screen and the locked screen and login input on the external monitor.

The issue seems similar to this question, but in that one it appears that it's the primary monitor not going black. Which is why I'm posting this as a separate question.

Yes, I know I can turn the monitor's power off, and I do at night, but I'd like it to go black in synch with the native screen if possible.

I'm on 14.04. The monitor is connected via HDMI. The laptop is a VAIO with a little age on it now.

FOLLOW-UP EDIT

As a follow-up, when I tested the bash script in the accepted answer, I set a low timeout, ran the script from a terminal, watched both monitors dim to black, and then accepted the answer. Subsequently, I actually added the script (with a re-set timeout) to my startup scripts and bounced my machine.

After my first longer-than-expected absence, imagine my surprise when I came back to my desk to find my external monitor shining brightly!

Subsequent research has shown that this is likely caused by the HDMI monitor itself, and no script is going to fix it. Indeed, I've (accidentally) been at my desk when this script kicked in. Both monitors go black as they should, and then about a minute later, the external monitor turns itself back on. 🙁

Oh well. I tried.

Best Answer

I suspect the issue is the result of a bug, since I cannot find another cause. At least as a workaround the background script below could be used.

The script does the job on my system, but you'll have to try and see. If it doesn't work on your system, we can switch to xrandr to specifically switch of per monitor, but this is the simplest option.

Resources?

About resources you don't have to worry, the script checks once per ten seconds if the idle time is exceeded. Even if I make it 10 times per second, the load is practically none.

#!/usr/bin/env python3
import subprocess
import time

t = 300

scr = True
while True:
    time.sleep(10)
    idle = int(subprocess.check_output("xprintidle").decode("utf-8").strip())/1000
    if idle > t and scr == True:
        subprocess.Popen(["xset", "dpms", "force", "off"])
        scr = False
    elif idle < t and scr == False:
        subprocess.Popen(["xset", "dpms", "force", "on"])
        scr = True

How to use

  1. The script needs xprintidle:

    sudo apt-get install xprintidle
    
  2. Copy the script into an empty file, save it as switchoff.py

  3. In the head of the script, set the idle time (in seconds) in the line:

    t = 300
    
  4. Switch off your "normal" switch-off-screen-after-x idletime -settings

  5. Run the script with the command:

    python3 /path/to/switchoff.py
    
  6. If all works fine, add it to Startup Applications: Dash > Startup Applications > Add.

    Add the command:

    /bin/bash -c "sleep 15 &&  python3 /path/to/switchoff.py"
    

EDIT

As requested in a comment, below the bash version of the same script. You'd still need to install xprintidle though.

#!/bin/bash

# --- set the idle time in seconds below
let "t = 300"
# ---

let "div = 1000"
t=$(($t * $div))
scr=true

while true
do
  sleep 10
  let "idle = "$(xprintidle)""
  if  [ "$idle" -gt "$t" ] && [ "$scr" = true ] 
  then
    scr=false
    xset dpms force off
  elif [ "$idle" -lt "$t" ] && [ "$scr" = false ] 
  then
    xset dpms force on
    scr=true
  fi
done

Note

  • Since we don't know what causes the behaviour on your system, we still need to find out if it is necessary to specifically switch off your screens per screen by xrandr. You'd have to try.