29

what is the most straightforward way to lock the screen AND suspend when closing the lid? I'm using event hooks in /etc/systemd/logind.conf and successfully suspend upon closing the lid. However I'm lost when it comes to the locking part - am I supposed to enable some screensaver service and how can I trigger two events at once in logind.conf?

slm
  • 363,520
  • 117
  • 767
  • 871
pldimitrov
  • 393
  • 1
  • 3
  • 5
  • Outside of scope so I'm commenting: in i3 it's very easy to assign keybindings to commands. Since `mod+L` was already assigned to `blurlock` for me, it was easy to have `mod+S` be `blurlock && systemctl suspend -i` instead. So, not when closing the lid, but works very well to choose whether I just want to lock, or lock and suspend. – pzkpfw Dec 20 '18 at 14:31

4 Answers4

21

There are a couple of examples in the Arch Wiki.

Basically, it involves creating a service file for your screen locker and ensuring it is hooked to either the suspend, hibernate or sleep targets.

If you use a simple screen locker like slock, /etc/systemd/system/lock.service would look like this:

[Unit]
Description=Lock the screen on resume from suspend

[Service]
User=jason
Environment=DISPLAY=:0
ExecStart=/usr/bin/slock

[Install]
WantedBy=suspend.target

Other examples on the wiki have more complex options, including shutting down and bringing up other services, etc.

Martin Monperrus
  • 1,221
  • 3
  • 12
  • 20
jasonwryan
  • 71,734
  • 34
  • 193
  • 226
  • Thanks, I saw that example but did not realize the `ExecStart=/usr/bin/slock` bit refers to locking at first glimpse. – pldimitrov Jul 05 '13 at 01:24
  • If I suspend and come back, my X display manager has a screen lock, that's great. But what about my ttys? What if I'm logged in, and I suspended and I forgot to exit from my ttys, people could switch to there and continue their operations. – CMCDragonkai Jan 27 '16 at 05:25
  • @CMCDragonkai you want [physlock](https://github.com/muennich/physlock) then... – jasonwryan Jan 27 '16 at 05:31
  • That looks great, how could one use physlock while disabling KDE's lock screen? I wouldn't want to have to unlock twice, through physlock then KDE's lock screen. – CMCDragonkai Jan 27 '16 at 06:02
  • @CMCDragonkai no idea: I avoid DEs for precisely that reason... – jasonwryan Jan 27 '16 at 06:15
  • 1
    This does work, but only if you are the only user of the system. A cleaner solution is to use `xss-lock` (available in Debian, Arch Linux; also Fedora next week) and run that as a user together with `i3lock` or `slock`. – Martin Ueding Mar 26 '16 at 16:58
  • @MartinUeding Not so: I use this one a multi-user system and it works fine... – jasonwryan Mar 26 '16 at 18:36
  • But only with one graphical session, right? Otherwise you would not have display 0. – Martin Ueding Mar 26 '16 at 21:46
  • @MartinUeding No with two. Recent versions of systemd mean you can remove that variable and your session will work fine with multiple instances of X running. – jasonwryan Mar 26 '16 at 21:52
  • Okay, I only have a problem with fixing DISPLAY. if one can get around that, is fine – Martin Ueding Mar 27 '16 at 09:18
  • FYI I am using i3lock and had to add ``--nofork`` – Benjamin Peter Jan 12 '18 at 22:13
  • 2
    @MartinUeding and @jasonwryan, `User` is hardcoded. The assumption that this machine will only be used by `jason` (or someone who knows his password, like his girlfriend, for example). Ideally, we'd want `User` to be whoever initiated the suspend, but I haven't found a solution for that (yet). – Rolf Mar 29 '18 at 19:51
  • By the way, `xss-lock` is nice but it looks for an X session, which I sometimes don't have. Maybe I can modify it and recompile it. – Rolf Mar 29 '18 at 19:53
  • 2
    Note that this will fail if the laptop unexpectedly cannot suspend (you may not notice, since you closed the lid): https://geoff.greer.fm/2018/01/02/linux-laptop-locking/ – Ben Ruijl Sep 29 '18 at 07:37
  • I wonder why you could not use [systemd --user](https://wiki.archlinux.org/title/systemd/User) instance for the job and put the unit file e.g. in `~/.config/systemd/user/` so not superuser privilege is needed? – jarno May 08 '21 at 10:33
  • 1
    `user` units cannot get triggered by `system` targets directly -- so there's no straightforward way for user units to start when locking/sleeping. [systemd-lock-handler](https://gitlab.com/WhyNotHugo/systemd-lock-handler) works around this by translating `system` events to `user` events. – WhyNotHugo May 24 '21 at 21:39
5

While jasonwryan's reply is correct, it is incomplete. In order to safely lock after suspending, instead of before - where a non-root process may prevent the kernel from suspending, you must add a Before= instance which forces systemd to wait for the ExecStart call to slock to start before suspending. Using sleep.target covers suspend, hibernate, and hybrid sleep.

[Unit]
 Description=Lock
+Before=sleep.target

 [Service]
 User=mustapha
 Environment=DISPLAY=:0
 ExecStart=/usr/local/bin/slock

 [Install]
-WantedBy=suspend.target
+WantedBy=sleep.target
2

If you use openrc with elogind is there an alternative solution (which is not systemd dependent):

#!/bin/sh
#
# /lib/elogind/system-sleep/lock.sh
# Lock before suspend integration with elogind

username=lerax
userhome=/home/$username
export XAUTHORITY="$userhome/.Xauthority"
export DISPLAY=":0.0"

case "${1}" in
        pre)
            su $username -c "/usr/bin/slock" &
            sleep 1s;
            ;;
esac

ref: https://gist.github.com/ryukinix/bd0c1ddcbbafdb4149ae70e41b7c822b

I'm posting this because was very difficult to find it a proper way that it works and this thread appears on first results of google about "lock after suspend" or whatever.

dessert
  • 1,687
  • 14
  • 29
Manoel Vilela
  • 302
  • 2
  • 12
1

All answers presented here have one fundamental flaw: They set the DISPLAY variable irespectively of what seat/session is active. And they involve writing your own systemd service file.

Thus, I suggest using the fact that logind (part of systemd, I believe) sends DBUS notifications before suspending. If you subscribe to these messages, you can start the screen locker from within you desktop environment and really lock the correct screen/session.

Additionally, there are programs like https://github.com/swaywm/swayidle that already implement this. For example, I've got this in my window manager's config:

exec swayidle -w \
    timeout 300  'swaylock -i $wallpaper' \
    timeout 600  'swaymsg "output * dpms off"' \
    resume       'swaymsg "output * dpms on"' \
    before-sleep 'swaylock -i $wallpaper' \
    lock         'swaylock -i $wallpaper'

To automagically lock the screen after some time, before suspending and whenever screen locking is requested. I've set HandleLidSwitch=lock in /etc/systemd/logind.conf to have my laptop locked when I close it.

Edit: You will also need to enable DBUS support your desktop session. I launch my window manager (sway) directly from the console, so my call became

exec dbus-run-session sway

Similarly, you could probably (I did not properly test this part) start your X window manger, i3 in the example using the following line in you ~/.xinitrc

exec dbus-launch i3 > /dev/null

Edit: Please note, that this answer is given much later. I do not if this was already possible when these answers were given and do not wish to discredit any of the other authors.

mox
  • 91
  • 1
  • 4