Основываясь на различных источниках, которые я собрал вместе ~/.config/systemd/user/screenlock.service
:
[Unit]
Description=Lock X session
Before=sleep.target
[Service]
Environment=DISPLAY=:0
ExecStart=/usr/bin/xautolock -locknow
[Install]
WantedBy=sleep.target
Я включил это используя systemctl --user enable screenlock.service
. Но после перезагрузки, входа в систему, приостановки и возобновления (проверено как с systemctl suspend
закрытием крышки, так и при закрытии крышки) экран не блокируется и в нем ничего нетjournalctl --user-unit screenlock.service
. Что я делаю неправильно?
Запуск DISPLAY=:0 /usr/bin/xautolock -locknow
блокирует экран, как и ожидалось.
$ systemctl --version
systemd 215
+PAM -AUDIT -SELINUX -IMA -SYSVINIT +LIBCRYPTSETUP +GCRYPT +ACL +XZ +SECCOMP -APPARMOR
$ awesome --version
awesome v3.5.5 (Kansas City Shuffle)
• Build: Apr 11 2014 09:36:33 for x86_64 by gcc version 4.8.2 (nobody@)
• Compiled against Lua 5.2.3 (running with Lua 5.2)
• D-Bus support: ✔
$ slim -v
slim version 1.3.6
Если я сразу запускаю systemctl --user start screenlock.service
блокировки экрана и получаю сообщение журнала journalctl --user-unit screenlock.service
, значит, ExecStart
это правильно.
Соответствующий .xinitrc
раздел :
xautolock -locker slock &
Создание системного сервиса с тем же файлом работает (то slock
есть активно при возобновлении):
# ln -s "${HOME}/.config/systemd/user/screenlock.service" /usr/lib/systemd/system/screenlock.service
# systemctl enable screenlock.service
$ systemctl suspend
Но я не хочу добавлять пользовательский файл снаружи $HOME
по нескольким причинам:
- Пользовательские сервисы должны быть четко отделены от системных сервисов
- Пользовательские сервисы должны контролироваться без использования привилегий суперпользователя
- Конфигурация должна легко контролироваться версией
systemd-user
все еще очень облупленный; заставить его работать как часть сессии с помощью подхода, который я изложил, поможет сузить проблему; это все, что я могу предложить./etc/systemd/system/
или$HOME/.local/systemd/system
не вводить что-либо/usr
вручную. Как отметил @jasonwryan, пользовательские сессии все еще не считаются производственными качествами; но они становятся ближе.Ответы:
sleep.target
специфично для системных сервисов. Причина в том, чтоsleep.target
это не волшебная цель, которая автоматически активируется перед сном. Это просто обычная цель, которая переводит систему в спящий режим, поэтому у «пользовательских» экземпляров, конечно, не будет эквивалента. (И, к сожалению, экземпляры 'user' в настоящее время не могут зависеть от общесистемных сервисов.)(Это и есть весь бизнес «жесткого кодирования $ DISPLAY». Каждый раз, когда вы жестко программируете параметры сеанса в ОС, основанной на многопользовательском / многоместном Unix, root убивает котенка.)
Таким образом, есть два хороших способа сделать это (я предлагаю второй):
Способ 1
Создайте системную службу (или ловушку systemd-sleep (8)), которая заставляет systemd-logind транслировать сигнал «блокировать все сеансы», когда система переходит в спящий режим:
Затем в сеансе X11 (т. Е. Из ~ / .xinitrc) запустите что-то, реагирующее на сигнал:
(GNOME, Cinnamon, KDE,
Enlightenmentуже поддерживают это изначально.)Способ 2
В сеансе X11 запустите что-то, что непосредственно отслеживает переход системы в спящий режим, например, подключившись к «ингибиторам» systemd-logind.
Вышеупомянутый xss-lock фактически делает это, даже без явного сигнала «блокировать все», поэтому достаточно запустить его:
Он запустится,
slock
как только увидит, что systemd-logind готовится приостановить работу компьютера.источник
xss-lock
находится в AUR, поэтому нет необходимости создавать его вручную.systemd-lock-handler
скрипт Python, который может выполнить это: https://github.com/grawity/code/blob/master/desktop/systemd-lock-handler .источник