2

Running Ubuntu 16.04 with Unity, I want that

  • when I leave my laptop untouched for 5 minutes, turn the screen off
  • 1 minute after turning the screen off for inactivity, lock the screen.

  • when I close the laptop lid, do NOT immediately lock the screen, but act like if the lid was still open and lock after 5+1 minutes (or similar).

In System Settings → Brightness & Lock, if set Lock to ON and configure the appropriate time (1 minute), it locks the screen accordingly after it has been turned off for inactivity. However, it also immeidately locks the screen on closing the lid, which I don't want.
Setting it to OFF makes it not lock the screen on closing the lid, but also leaves it unlocked after turning the screen off for inactivity.

I have set both "lid-close-actions" to "nothing" in dconf already:

$ gsettings get org.gnome.settings-daemon.plugins.power lid-close-ac-action
'nothing'
$ gsettings get org.gnome.settings-daemon.plugins.power lid-close-battery-action
'nothing'

How can I make Ubuntu lock the screen only after a specific time of user inactivity, regardless of the lid position?

1 Answer 1

2

The background script below will do pretty much exactly as you describe

  • switch off the screen after x seconds
  • lock the screen after y seconds

The script

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

# set screen off after x seconds
off = 300
# lock screen after x seconds
lock = 360

# check idle every x seconds
res = 3

def get(cmd):
    return subprocess.check_output(cmd).decode("utf-8").strip()

def test(t, threshold):
    return int(t)/1000 < threshold

testoff1 = True
testlock1 = True

t1 = 0

while True:
    time.sleep(res)
    t2 = get("xprintidle")
    testoff2 = test(t2, off); testlock2 = test(t2, lock)
    if (testoff2, testoff1) == (False, True):
        subprocess.Popen(["xset", "dpms", "force", "off"])
    if (testlock2, testlock1) == (False, True):
        subprocess.Popen(["gnome-screensaver-command", "-l"])                
    testoff1 = testoff2; testlock1 = testlock2

How to use

Like you mention, you need to switch off existing lid actions:

gsettings set org.gnome.settings-daemon.plugins.power lid-close-ac-action 'nothing'

and:

gsettings set org.gnome.settings-daemon.plugins.power lid-close-battery-action 'nothing'

and furtermore:

gsettings set org.gnome.desktop.screensaver lock-enabled false

and

gsettings set org.gnome.desktop.session idle-delay 0

since we now take care of our own procedures.

then:

  1. The script uses xprintidle, to check the idle time

    sudo apt-get install xprintidle
    
  2. Copy the script into an empty file, save it as set_times.py
  3. In the head section of the script, set the idle time to switch off the screen (in seconds):

    # set screen off after x seconds
    off = 300
    

    and the time to lock the screen:

    # lock screen after x seconds
    lock = 360
    

    These times are set independently to each other, you may set both in any order you like (either lock first, then switch off, or the other way around)

    You can set the time "resolution", the frequency the idle time is checked, (and thus the set time is rounded by):

    # check idle every x seconds
    res = 3
    

    but you might as well

  4. Test- run it:

    python3 /path/to/set_times.py
    
  5. If all works fine, add it to Startup Applications: Dash > Startup Applications > Add. Add the command:

    python3 /path/to/set_times.py
    

Explanation on the concept

  • The command xprintidle returns the current idle time (no input from mouse or keyboard)
  • The script then tests if the set time is smaller then a defined threshold, and compares the state with a few seconds ago.
  • If there is a change in state (True --> False) any action can be taken. This is done for both switch off screen, running:

    xset dpms force off
    

    and lock screen, running:

    gnome-screensaver-command -l
    

Notes

  • Off course we can also make the time(s) to switch off and lock the screen arguments to run the script with:

    #!/usr/bin/env python3
    import subprocess
    import time
    import sys
    
    off = int(sys.argv[1]) if len(sys.argv) > 1 else 300
    lock = int(sys.argv[2]) if len(sys.argv) > 2 else off + 60
    # check idle every x seconds
    res = int(sys.argv[3]) if len(sys.argv) > 3 else 5
    
    def get(cmd):
        return subprocess.check_output(cmd).decode("utf-8").strip()
    
    def test(t, threshold):
        return int(t)/1000 < threshold
    
    testoff1 = True
    testlock1 = True
    
    t1 = 0
    
    while True:
        time.sleep(res)
        t2 = get("xprintidle")
        testoff2 = test(t2, off); testlock2 = test(t2, lock)
        if (testoff2, testoff1) == (False, True):
            subprocess.Popen(["xset", "dpms", "force", "off"])
        if (testlock2, testlock1) == (False, True):
            subprocess.Popen(["gnome-screensaver-command", "-l"])
        testoff1 = testoff2; testlock1 = testlock2
    

    Then running:

    python3 /path/to/set_times.py 300 360
    

    will switch off the screen after five minutes, lock the screen after six.

  • The additional burden of the script is zero.

2
  • Thanks. I made some edits to your code and fixed a few bugs... ;-) Also, you should probably add that in System Settings → Brightness & Lock, I have to switch the Turn screen off when inactive for to Never and Lock to OFF.
    – Byte Commander
    Jan 7, 2017 at 12:04
  • @ByteCommander I copied the gsettings commands from your question, so I copied your bugs :) Ah, I also copied sys.argv[1], forgot to change it... Jan 7, 2017 at 12:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.