systemd/logind IdleAction taken despite not being idle
carloabelli opened this issue · 27 comments
I am trying to enable auto suspend through systemd/logind. In /etc/systemd/logind.conf
I have the lines:
IdleAction=suspend
IdleActionSec=1min
However this causes my system to suspend every 1 minute regardless of activity or inactivity. My guess was that sway is not correctly reporting its idle state based on systemd/systemd#1295.
Seems like something that should be implemented in swayidle
, but since the decision was made not to handle the dbus session stuff inside the compositor I guess calling No idea about this actually, it'll probably workSetIdleHint
won't be possible (because swayidle
is not the session manager).
Similarly, the Lock
signal should be listened to.
cc @snaggen
Not sure how idle is handled in the logind context, but without the swayidle patch sway are not initializing any idle handling for Wayland. Not sure if that would improve things, but otherwise it could be an idea to look into making wlr idle handling sync the logind idle timers also.
I would probably suggest just turning off the systemd timers and using swayidle alone.
@SirCmpwn is there documentation for using swayidle? I can't seem to find any and man swayidle
does not seem to work.
swayidle is only available on the 1.0 alpha, the stable releases do not include it.
busctl --system call org.freedesktop.login1 /org/freedesktop/login1/session/$XDG_SESSION_ID org.freedesktop.login1.Session SetIdleHint $value
for the other way around:
busctl --system get-property org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager BlockInhibited | grep -q '[:"]idle[:"]'
I put the former in a systemd-idle
script and the latter in idle_blocked
. Then I write swayidle timeout 1 'systemd-idle true' resume 'systemd-idle false' timeout x 'if ! idle_blocked; then swaylock; fi'
.
I just ran into the same problem:
When changing IdleAction
from the default ignore
to suspend
within /etc/systemd/logind.conf
then the laptop even though during keybaord-usage and mouse-usage suspends every IdleActionSec
.
Is there a reason not to have swayidle (with logind support) support setting the IdleHint for the session?
No
This doesn't seem to work for me.
I have idlehint 120
in my swayidle command, but logind still suspends every IdleActionSec
.
Digging in, I don't see an inhibit from swayidle:
❯ gdbus call -y -d org.freedesktop.login1 -o /org/freedesktop/login1 -m org.freedesktop.login1.Manager.ListInhibitors
([('sleep', 'electron', 'Application cleanup before suspend', 'delay', uint32 1000, uint32 13258), ('sleep', 'NetworkManager', 'NetworkManager needs to turn off networks', 'delay', 0, 653), ('sleep', 'UPower', 'Pause device polling', 'delay', 0, 8951)],)
Actually, it's IdleHint that's not getting the right value:
❯ gdbus call -y -d org.freedesktop.login1 -o /org/freedesktop/login1/session/auto -m org.freedesktop.DBus.Properties.Get org.freedesktop.login1.Session IdleHint
(<true>,)
ref: https://www.freedesktop.org/wiki/Software/systemd/logind/
@electrickite is this the right way to configure?
@edrex The idlehint
event will cause swayidle to set the logind IdleHint to True after <seconds>
of inactivity. When activity resumes, it will set IdleHint to false.
So idlehint 120
will set IdleHint true after the user is idle for 120 seconds. Logind should then execute its IdleAction after an additional IdleActionSec as configured in logind.conf.
I noticed that IdleHint was only correctly set if swayidle was executed from the sway config using an exec command: it was not able to connect to the D-Bus session if run from the terminal of a logged in session.
I see debug message SetIdleHint 0
but the value on the bus is still True
.
The issue seems to be that the SetIdleHint
calls are being ignored:
❯ gdbus call -y -d org.freedesktop.login1 -o /org/freedesktop/login1/session/auto -m org.freedesktop.login1.Session.SetIdleHint false
()
~
❯ gdbus call -y -d org.freedesktop.login1 -o /org/freedesktop/login1/session/auto -m org.freedesktop.DBus.Properties.Get org.freedesktop.login1.Session IdleHint
(<true>,)
I noticed that IdleHint was only correctly set if swayidle was executed from the sway config using an exec command: it was not able to connect to the D-Bus session if run from the terminal of a logged in session.
This is interesting. Does logind ignore SetIdleHint
if not called by the session pid
? Anyway, swayidle launched from sway config exec
doesn't help for me.
Any process can set an inhibit lock. Should swayidle be using this mechanism instead?
Any process can set an inhibit lock. Should swayidle be using this mechanism instead?
The goal of this feature (or at least the PR) is to correctly set the session IdleHint. I would prefer not to use inhibitor locks - they are semantically distinct from the session idle state.
It seems as though SetIdleHint is not being set at all on your system? i.e. even manually calling it via gdbus does not work?
The goal of this feature (or at least the PR) is to correctly set the session IdleHint. I would prefer not to use inhibitor locks - they are semantically distinct from the session idle state.
Ok, I understand
It seems as though SetIdleHint is not being set at all on your system? i.e. even manually calling it via gdbus does not work?
Looks to be. I'm on arch. Does the above work for you?
Logind only checks that the calling process is owned by the session owner:
Useful reference: https://www.freedesktop.org/wiki/Software/systemd/writing-desktop-environments/
To verify that the call is getting to logind, tried setting idlehint as another user:
fuser❯ gdbus call -y -d org.freedesktop.login1 -o /org/freedesktop/login1/session/_31 -m org.freedesktop.login1.Session.SetIdleHint false
Error: GDBus.Error:org.freedesktop.DBus.Error.AccessDenied: Only owner of session may set idle hint
gdbus monitor -y -d org.freedesktop.login1 -o /org/freedesktop/login1/session/auto
doesn't report any property changes, so it's evidently not some other caller immediately setting it back to true.
Two other reports of similar behavior (calling IdleHint false doesn't change the property value from true):
gdbus monitor -y -d org.freedesktop.login1 -o /org/freedesktop/login1/session/auto doesn't report any property changes, so it's evidently not some other caller immediately setting it back to true.
I don't believe the auto session emits events for idle hint changes. At least from my experiments, I didn't see property change evnts when monitoring the auto session object, but I did if I monitored the actual session object with the session name. (Also on arch)
I noticed that IdleHint was only correctly set if swayidle was executed from the sway config using an exec command: it was not able to connect to the D-Bus session if run from the terminal of a logged in session.
Why would that be? Afaik, logind wouldn't be able to tell if it was started from an exec in config or not.
@edrex FWIW, I just verified that I am able to set the IdleHint for the session from the terminal. (Arch, sway, no display manager). Note that these commands use the session path, as @tmccombs suggests.
$ dbus-send --system --print-reply --dest=org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager.ListSessions
method return time=1574128317.662196 sender=:1.8 -> destination=:1.104 serial=70 reply_serial=2
array [
struct {
string "1"
uint32 1100
string "corey"
string "seat0"
object path "/org/freedesktop/login1/session/_31"
}
]
$ gdbus call -y -d org.freedesktop.login1 -o /org/freedesktop/login1/session/_31 -m org.freedesktop.DBus.Properties.Get org.freedesktop.login1.Session IdleHint
(<false>,)
$ gdbus call -y -d org.freedesktop.login1 -o /org/freedesktop/login1/session/_31 -m org.freedesktop.login1.Session.SetIdleHint true
()
$ gdbus call -y -d org.freedesktop.login1 -o /org/freedesktop/login1/session/_31 -m org.freedesktop.DBus.Properties.Get org.freedesktop.login1.Session IdleHint
(<true>,)
@tmccombs I did a little digging into why swayidle could only set the IdleHint when run from exec
in sway config. Turns out it was a different issue: I was running swayidle from bash under the GNOME Terminal emulator. gnome-terminal-server
is started as a systemd user service, which are not associated with a particular session. So any child process also lacks a session, meaning that swayidle cannot determine the correct session from its PID.
When run from swaymsg, swayidle is executed within the session context.
I don't believe the auto session emits events for idle hint changes.
Same using explicit session (_31
for me)
I just verified that I am able to set the IdleHint for the session from the terminal.
@electrickite what about setting back to false
? The behavior I'm seeing is the props (IdleHint
and LockedHint
) are stuck true
.
Anyway it doesn't look to be specific to swayidle so I sent it upstream. Thanks for engaging with me to troubleshoot.
systemd/systemd#14053 (comment):
currently you can mark a tty session idle, but never unmark it
This feature will not work properly under a TTY session. Perhaps the time has come for a wlroots display manager swaywm/wlroots#540 (comment)
Isn't this a systemd bug?
this is currently be discussed on the systemd side too, see systemd/systemd#14489
Isn't this a systemd bug?
Kind of. My understanding is it is expected (but not ideal) behaviour, because Logind doesn't expect a console session to change into a graphical session.
A PR was merged into systemd today that should land in v246. It adds a SetType method to the logind dbus interface. This will at least allow systemd to support a session type upgrade, although the compositor will still need to implement the switch.
Thanks for your work in pushing that through, @electrickite!