hyprwm / hypridle

Hyprland's idle daemon
BSD 3-Clause "New" or "Revised" License
373 stars 22 forks source link

`before_sleep_cmd` doesn't finish running before sleeping #49

Closed austinliuigi closed 5 months ago

austinliuigi commented 5 months ago

I have configured before_sleep_cmd = loginctl lock-session and lock_cmd = pidof hyprlock || hyprlock. However, after waking up my laptop from a suspend, it shows my desktop for a second then fades in hyprlock. Is it feasible to make sure hyprlock fully runs before sleeping so that my laptop wakes up immediately to a locked screen? This would be equivalent to the -w flag of swayidle.

vaxerski commented 5 months ago

that's unfortunately not solvable on our side

vigneshpai2003 commented 3 months ago

@austinliuigi did you find any workaround to this?

loginctl lock-session is just a trigger right, adding a sleep 3 command following it should give enough time for hyprlock to launch (I verified this by running loginctl lock-session; sleep 3; systemctl suspend from a terminal). But in hypridle, this doesn’t seem to work, my system goes into suspend even before before_sleep_cmd is done running, isn’t the point of this option to be executed before the suspend happens?

ehula commented 3 months ago

The option before_sleep_cmd should be removed or renamed then if the commands cannot be executed before sleep. Maybe re-institute once it is solvable.

Hubro commented 3 months ago

I think hypridle could register itself as an inhibitor using D-Bus. That would allow it to delay suspend for a while if a before_sleep_cmd is defined.

$ systemd-inhibit --list
WHO            UID  USER  PID     COMM            WHAT  WHY                                       MODE
NetworkManager 0    root  1733    NetworkManager  sleep NetworkManager needs to turn off networks delay
discord        1000 tomas 2553151 .Discord-wrappe sleep Application cleanup before suspend        delay
slack          1000 tomas 2553153 slack           sleep Application cleanup before suspend        delay

3 inhibitors listed.

That would be really sweet.


I naively tried to inhibit sleep myself with this command in before_sleep_cmd:

systemd-inhibit --what=sleep --who=tomas --why=screen-lock --mode=delay "hyprctl dispatch exec \"loginctl lock-session\" && sleep 3"

But alas, my system suspends before this command even has time to start. On resume, I get this error:

Failed to inhibit: The operation inhibition has been requested for is already running

So, at least on my system, it's clear the inhibit has to be in place before suspend is even triggered. My laptop goes to sleep insanely fast, the screen goes black instantly when I press the power button. I've tried in vain to find a system option that delays suspend by a few hundred ms by default, giving this command time to execute, but it doesn't seem to exist. I'm going to try to workaround it by writing a service with Before=sleep.target and Exec=sleep 0.3. :crossed_fingers:


EDIT: Nope, using systemd-suspend ... in before_sleep_cmd inherently doesn't work, because the system is already in the process of going to sleep. Systemd refuses to add a new inhibitor during this time. That's what the error above means.

aacebedo commented 3 days ago

I found a alternative solution for that (I had the problem with gtklock). I combined hypridle and systemd-lock-handler.

First I removed lock_cmd and unlock_cmd from hypridle.

Then I configured a systemd user service like this:

[Install]
RequiredBy=lock.target

[Service]
ExecStart=/nix/store/9rirdwdpa5avxr9dg73js84iydxbp450-gtklock-3.0.0/bin/gtklock -f -d
Type=forking

[Unit]
Description=Lock screen daemon
PartOf=lock.target

The lock target is brought by systemd-lock-handler. The latter delays the sleep using a sleep inhibit, calls all the lock.target required services and then deinhibit.