How to config hybrid-sleep after idle, and lock?

I’m setting up a nixos box. I’m trying to keep everything minimum, I use i3 as WM without a DE. Currently I’m trying to figure out how to configure nixos to:

  1. Sleep (hybrid-sleep preferably) after idle for certain time.
  2. Lock the screen before sleep, so password is required after wake up.

What is the preferred nixos/i3 way to do it?

Thanks~
Leira

❦ 24 août 2020 05:40 +00, Leira Hua via NixOS Discourse:

  1. Sleep (hybrid-sleep preferably) after idle for certain time.
  2. Lock the screen before sleep, so password is required after wake up.

What is the preferred nixos/i3 way to do it?

I don’t think there is anything specific to NixOS. For the first point,
this is the job of systemd-logind. In services.logind.extraConfig, you
can add:

IdleAction=hybrid-sleep
IdleActionSec=30min

To lock screen before sleep, you can use xss-lock.

Do you know if systemd-login can have different values if we are on battery or not?

❦ 24 août 2020 21:52 +00, Bruno Bigras via NixOS Discourse:

Do you know if systemd-login can have different values if we are on
battery or not?

It doesn’t seem to have this (man logind.conf).

Thanks for the answer.

I put these lines in my configuration.nix:

  # hybrid sleep when press power button
  services.logind.extraConfig = ''
    HandlePowerKey=suspend
    IdleAction=suspend
    IdleActionSec=1m
  '';

  # screen locker
  programs.xss-lock.enable = true;

And I have this line in in my i3 config:

exec --no-start-id xset s 180 10

I’ve verified:

  1. xset s activate works, screen locked.
  2. wait for 3 minutes, screen locked.
  3. systemctl suspend works, screen locked when wake up.
  4. Power button worked, system suspended when I press power button.
  5. No matter how long I wait, the machine didn’t suspend itself.

It seems to me logind didn’t get the idle hint, for some reason, despite xss-lock did lock screen after idle for 3 minutes. For some reason xss-lock got the idle hint, but logind didn’t. My questions are:

  1. How idle is detected?
  2. Do xss-lock and logind share the same source of idle hint, or not?
  3. How does logind detects/notified idle?
  4. How do I further debug this issue?

BTW, I just use a vanilla i3wm with no DE. If DE is the component providing idle detection, then what should I use for idle detection purpose with i3?

PS, I didn’t use hybrid-sleep in the config. hybrid-sleep didn’t work for me, it woke up with a black screen. Seems to be nvidia GPU related issue, but that’s an irrelevant story to the topic.

Thanks!

❦ 6 septembre 2020 20:20 GMT, Leira Hua via NixOS Discourse:

  1. Do xss-lock and logind share the same source of idle hint, or not?

xss-lock monitors the X session for idleness and manages the hint for
logind. You can check IdleHint with loginctl show-session 1 (get the
session number with loginctl). Check through SSH once the lock screen
has kicked in.

Thank you very much, @bernat! I was always confused of the whole process. Let me check if I understand it correctly now:

  1. X monitors user’s activity. If the user of X become inactive for a period of screensavor_time_out, X triggers a start_screensaver event.
  2. xset s sets screensavor_time_out.
  3. xss-lock is a start_screensaver event handler. It does 2 things when received an event:
    a. Start a notifier command, typically a locker app, default to i3lock.
    b. Send an idle_hint to the login manager.
  4. logind is the login manager of systemd, it listens to idle_hints from all the sessions. When all sessions are idle, after IdleActionSec period, it takes the IdleAction.

So xss-lock listens to start_screensaver event, and sets the idle_hint which logind listens to. Then the problem here can be:

  1. xss-lock didn’t set the idle_hint correctly.
  2. logind didn’t get the idle_hint correctly.
  3. Some sessions other than the idled X session was still active.
  4. logind didn’t take the IdleAction after IdleActionSec.

Then:

  1. How to confirm 1.? Where is the log for X (new to systemd)? Does xss-lock have entries in X logs?
  2. Below is My loginctl show-session output. But I wonder, when can I see IdleHint=yes? After xss-lock sets the idle_hint, but before IdleActionSec passes, and exactly within this window?
> loginctl show-session 2
Id=2
User=1000
Name=leira
...
Display=:0
Type=x11
...
State=active
IdleHint=no
IdleSinceHint=0
IdleSinceHintMonotonic=0
LockedHint=no
  1. Below is my loginctl list-session output. It seems the X session I’m using is the only session logged in.
> loginctl list-sessions
SESSION  UID USER  SEAT  TTY
      2 1000 leira seat0

And also, what will see in journalctl for setting idle_hint?

Thanks!

❦ 6 septembre 2020 22:26 GMT, Leira Hua via NixOS Discourse:

  1. How to confirm 1.? Where is the log for X (new to systemd)? Does xss-lock have entries in X logs?
  2. Below is My loginctl show-session output. But I wonder, when can
    I see IdleHint=yes? After xss-lock sets the idle_hint, but
    before IdleActionSec passes, and exactly within this window?

Yes. If you can’t use SSH to check that, use something like sleep 120; loginctl show-session 1.

I set the screensavor_time_out to 30s with xset s 30. Then I ran sleep 60; loginctl show-session 1. It did lock after 30s, but after another 70s or so, I unlocked it. loginctl printed:

State=active
IdleHint=no
IdleSinceHint=0
IdleSinceHintMonotonic=0

I stopped the xss-lock service by systemctl --user stop xss-lock, and run xss-lock -- i3lock -n in command line. This time, it did lock after 30s, and it even suspended after another 60s, as IdleActionSec=1m. And when I woke it up and unlock, I saw loginctl printed IdleHint=yes.

So it worked when starting xss-lock in command line directly. But it didn’t work as a systemd user service.

systemctl --user show xss-lock shows FragmentPath=/nix/store/r8cx06ach9vqjvk7fp32fxbqqz30pkwb-unit-xss-lock.service/xss-lock.service. I went to that file, and attempted to recreated the exact command line used with this user service:

env LOCALE_ARCHIVE=/nix/store/ssk7zb76r9ydy6h6p7kzjsiqq7amcray-glibc-locales-2.31/lib/locale/locale-archive PATH=/nix/store/gd3nl6hcc8mzq8fmxdvl6czh3l0n4la5-coreutils-8.31/bin:/nix/store/ab8kxlz6pkaw2qnskqhmrlhbqd8pjq3k-findutils-4.7.0/bin:/nix/store/r8jl0nvjlqzhdmh5vnfrqfnf496gkjy7-gnugrep-3.4/bin:/nix/store/rl2frzwv9gl6b0fxbr0mav432f8h6vs3-gnused-4.8/bin:/nix/store/kg0k2hrldivj2cfr57088nzj8zmvpr06-systemd-245.6/bin:/nix/store/gd3nl6hcc8mzq8fmxdvl6czh3l0n4la5-coreutils-8.31/sbin:/nix/store/ab8kxlz6pkaw2qnskqhmrlhbqd8pjq3k-findutils-4.7.0/sbin:/nix/store/r8jl0nvjlqzhdmh5vnfrqfnf496gkjy7-gnugrep-3.4/sbin:/nix/store/rl2frzwv9gl6b0fxbr0mav432f8h6vs3-gnused-4.8/sbin:/nix/store/kg0k2hrldivj2cfr57088nzj8zmvpr06-systemd-245.6/sbin TZDIR=/nix/store/gr6rjrscqn0ldhrkq937l5b0qvx5adi1-tzdata-2019c/share/zoneinfo /nix/store/i5p5fyimvwp975g5d6cb1f20wnrd10y2-xss-lock-git-2018-05-31/bin/xss-lock -- /nix/store/3ypnw1c35h75nknkcp2yqfi4v6pj08i5-betterlockscreen-3.0.1/bin/betterlockscreen -l dimblur

When running this command in command line, it still worked as expected. It locked after 30s, and suspended after 60s, and loginctl shows IdleHint=yes.

What might be the reason that xss-lock.service couldn’t report idle hint?

❦ 8 septembre 2020 05:07 GMT, Leira Hua via NixOS Discourse:

What might be the reason that xss-lock.service couldn’t report idle
hint?

Maybe you didn’t import the current X environment into systemd? This
would prevent access to DBUS user-session. Check with systemctl --user show-environment | grep DBUS.

Maybe you hit nixos/displayManager: add XDG_SESSION_ID to systemd user environment by evenbrenden · Pull Request #93764 · NixOS/nixpkgs · GitHub. Currently, calling loginctl lock-session will not trigger xss-lock when run as a user service because it doesn’t know what session to use. Could be the case for idle hints as well. You could try passing --session [session ID] to programs.xss-lock.extraOptions using your current session ID just to check if this is it. Make sure you run systemctl --user restart xss-lock.service after rebuilding.

@evenbrenden Thanks! That’s exactly the problem. I just verified with hard coded session ID. I will pick that fix.