hyprlock
hyprlock copied to clipboard
`systemctl suspend-then-hibernate` suspends before blur gets applied in hyprlock
systemctl suspend-then-hibernate is too fast, and the blur dosen't get applied completely, its only applied 40% and the rest of blur gets applied after system resumes.
Is there a way to for hyprlock to say that it has completed its operation and system can suspend now. like inhibiting operation until its ready.
# BACKGROUND
background {
monitor =
path = screenshot
blur_passes = 3
contrast = 0.8916
brightness = 0.8172
vibrancy = 0.1696
vibrancy_darkness = 0.0
}
# GENERAL
general {
no_fade_in = false
grace = 0
disable_loading_bar = true
}
AFAIK, no
@KAGEYAM4, i have another issue with lockscreen fades in after resume from suspend-then-hibernate I have hypridle set up, so it fires hyprlock after susptend-then-hibernate is started That way i came up with a hacky way by adding ExecStartPre=/bin/sleep 5 into /usr/lib/systemd/system/systemd-suspend-then-hibernate.service, which solves issue gradually fading in the lockscreen and then sleeping
@mintyleaf Thanks you. you idea is good. This method is officially documented here https://wiki.archlinux.org/title/Power_management/Suspend_and_hibernate#Custom_systemd_units. I was trying to use it to sleep 5 and hyprlock. But i was getting into perminssion/variable issue.
Using your idea i will just create a unit/drop-in whose whole purpose would be too delay the sleep.
ExecStartPre=/bin/sleep 5 into /usr/lib/systemd/system/systemd-suspend-then-hibernate.service, which solves issue gradually fading in the lockscreen and then sleeping
Hope you did not actually edited /usr/lib/systemd/system/systemd-suspend-then-hibernate.service and it was just an exmple because this file will be overwritten when systemd will get new version over update. The better way for doing this would be to use https://wiki.archlinux.org/title/systemd#Drop-in_files.
@mintyleaf This is what i am using ->
/etc/systemd/system/root-suspend.service
[Unit]
Description=Local system suspend actions
Before=sleep.target
[Service]
Type=simple
ExecStartPre=-/usr/bin/sleep 1
ExecStart=-/usr/bin/true
[Install]
WantedBy=sleep.target
And then enable it using -> sudo systemctl enable root-suspend.service
Note->
- For me 1 sec delay is enough for hyprlock to get fully applied
- Disadvantage of using this unit file is that this delay is applied to every action like - suspend.target, hibernate.target, hybrid-sleep.target, or suspend-then-hibernate.target
@KAGEYAM4, btw the 1 sec delay is not enough for me, do you have fade in animation enabled? 5 secs is totally ok
Thanks for providing the service drop-in for a more robust way Editing suspend-then-hibernate itself is worth only as a proof of concept indeed
i'd suggest to rename this issue and mention that hack in hyprwiki, as it affects to the whole purpose of fade in animation and user experience in general
@KAGEYAM4, btw the 1 sec delay is not enough for me, do you have fade in animation enabled? 5 secs is totally ok
Yes it works perfectly for me, i think it may be because of different cpu. This is what i am using - https://github.com/end-4/dots-hyprland/blob/75e73896adab30573d9efd71d0656e8a409b4efd/.config/hypr/hyprlock/status.sh
i'd suggest to rename this issue and mention that hack in hyprwiki, as it affects to the whole purpose of fade in animation and user experience in general
I want to still find some better solution, like if there was a way for lockscreen-application to notify system that it has locked screen and systemd can sleep now because with current solution everyone has to add different delay.
I will try asking what other Desktop-Environment does to solve this.
@mintyleaf i think maybe i found one. @vaxerski can you please see maybe if this would work.
man logind.conf - InhibitDelayMaxSec ->
Specifies the maximum time a system shutdown or sleep request is
delayed due to an inhibitor lock of type "delay" being active before
the inhibitor is ignored and the operation executes anyway. Defaults to 5.
When hyprlock start, it will create inhibit of type delay, and when hyprlock has fully painted the lockscreen it will release the lock.
I used systemd-inhibit --what=sleep --mode=delay sleep 1000 to create inhibit of type=delay, but it was run in different terminal, so not sure maybe it would be too late when hyprlock creates inhibit.
Should this issue be re-opened?
I'll reopen, but prolly won't work on this, feel free to make a mr
Would you prefer hyprlock or hypridle to grab the inhibitor lock? It seems more reasonable to me if hypridle does it, since (1) it already has sdbus as a dependency and (2) the inhibition only makes sense if hyprlock was triggered by an idle service.
What do you think?
I dont mind but I fail to see how hypridle would know when hyprlock is done taking a screenshot and fading in
Hypridle wouldn't be able to know, but it can use a delay type inhibitor, which would delay sleep for up to the time specified by the InhibitDelayMaxSec option in logind.conf, which the user can configure.
- this is what swayidle does with the -w option
If hyprlock were to grab the inhibitor instead of hypridle, it could use a block type inhibitor, releasing it only once the fade-in is finished. This is nice since sleep is guaranteed to occur after hyprlock has faded in, without any variability from machine to machine or possible tinkering of delay times that the user needs to do. However, like mentioned above:
It seems more reasonable to me if hypridle does it, since (1) it already has sdbus as a dependency and (2) the inhibition only makes sense if hyprlock was triggered by an idle service.
Would you prefer hypridle or hyprlock to handle the inhibitor lock?
Hypridle wouldn't be able to know, but it can use a delay type inhibitor, which would delay sleep for up to the time specified by the
InhibitDelayMaxSecoption inlogind.conf, which the user can configure.
But with this we are back to depending on user to specify delay, which should be avoided.
If hyprlock were to grab the inhibitor instead of hypridle, it could use a block type inhibitor, releasing it only once the fade-in is finished. This is nice since sleep is guaranteed to occur after hyprlock has faded in, without any variability from machine to machine or possible tinkering of delay times that the user needs to do.
This would be best, but not sure about which one should be used - delay or block.
It seems more reasonable to me if hypridle does it, since (1) it already has sdbus as a dependency and (2) the inhibition only makes sense if hyprlock was triggered by an idle service.
(2) Maybe, but there are other cases too where a person dosen't use hypridle, for example who waana avoid idle daemon, because they specifically lock thes screen themselves ( hyprlock ; systemctl suspend ), or where someone usess different idle daemon ( maybe swayidle or something else in future ).
We should go with hyprlock triggring the inhibitor lock, the only problem that i think could happen is that - what if it's too late for hyprlock to create the inhibitor then we will have to go with hypridle creating the inhibitor.
what if it's too late for hyprlock to create the inhibitor then we will have to go with hypridle creating the inhibitor.
This is a good point. I tried explicity grabbing the inhibitor lock on the user-side by setting the following in hypridle.conf:
lock_cmd = pidof hyprlock || systemd-inhibit --what=sleep --mode=delay hyprlock
However, it failed with the error message:
Failed to inhibit: The operation inhibition has been requested for is already running
which shows that it is most like too late to grab the inhibitor lock in the command that hypridle executes.
what if it's too late for hyprlock to create the inhibitor then we will have to go with hypridle creating the inhibitor.
This is a good point. I tried explicity grabbing the inhibitor lock on the user-side by setting the following in
hypridle.conf:lock_cmd = pidof hyprlock || systemd-inhibit --what=sleep --mode=delay hyprlockHowever, it failed with the error message:
Failed to inhibit: The operation inhibition has been requested for is already runningwhich shows that it is most like too late to grab the inhibitor lock in the command that hypridle executes.
Let's just hope that in binary it will be fast enough.
Alright, I could make a PR but I would like to get @vaxerski's opinion on whether it should be done in hyprlock or hypridle
likely idle
Hypridle wouldn't be able to know, but it can use a delay type inhibitor, which would delay sleep for up to the time specified by the InhibitDelayMaxSec option in logind.conf, which the user can configure. This is what swayidle does with the -w option
So if this get implemented in hypridle, will user have to configure InhibitDelayMaxSec option in logind.conf?
If yes, is it right to just set a value for InhibitDelayMaxSec based on hyprlock? Like i don't know the usecase currently but i would like to keep it at default 5 sec, so that other applicaton that depend on this default behaviour works correctly.
if this was configurable by command-line, then those who have mutiple systems will have change flag based of that cpu performance.
Locking is job of hyprlock and it has make sure that lock-screen was painted completely before suspend and other events.
you can make it default 5 and configurable
Can we relly have something dynamic. No configuration on user end for the amount of sec to delay to lockscreen to wait completely.
In sway they are using fork/daemonizing behavior of swaylock to check if lock completed or not ->
static void cmd_exec(char *param) {
swayidle_log(LOG_DEBUG, "Cmd exec %s", param);
pid_t pid = fork();
if (pid == 0) {
if (!state.wait) {
pid = fork();
}
if (pid == 0) {
sigset_t set;
sigemptyset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
signal(SIGINT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGUSR1, SIG_DFL);
char *const cmd[] = { "sh", "-c", param, NULL, };
execvp(cmd[0], cmd);
swayidle_log_errno(LOG_ERROR, "execve failed!");
exit(1);
} else if (pid < 0) {
swayidle_log_errno(LOG_ERROR, "fork failed");
exit(1);
}
exit(0);
} else if (pid < 0) {
swayidle_log_errno(LOG_ERROR, "fork failed");
} else {
swayidle_log(LOG_DEBUG, "Spawned process %s", param);
if (state.wait) {
swayidle_log(LOG_DEBUG, "Blocking until process exits");
}
int status = 0;
waitpid(pid, &status, 0);
if (state.wait && WIFEXITED(status)) {
swayidle_log(LOG_DEBUG, "Process exit status: %d", WEXITSTATUS(status));
}
}
}
state.waitis-wcommandline of swayidle.swaylock -fdaemonizes the process.
I am asking in there IRC for there rationale of using this method, here's the commit by the way - https://github.com/swaywm/swayidle/commit/5b653e8fbf8c4f33b45068e04576101b1bf73cce
Found it, will have to go through them -> https://github.com/swaywm/sway/pull/3382 https://github.com/swaywm/sway/issues/3119
Edit - so after reading them, they just went with fork/wait method. These was one mention of how xss-lock works ->
-l, --tranfer-sleep-lock
Allow the locker process to inherit the file descriptor that represents the delay lock obtained from the login manager.
The corresponding index will be made available in the environment variable $XSS_SLEEP_LOCK_FD;
this will only be set if the reason for locking is that the system is preparing to go to sleep.
The locker should close this file descriptor to indicate it is ready.
That seems like the way to go, thanks for looking into it. So to make sure we're on the same page:
- hypridle can optionally block until commands that it spawns terminate
- uses delay type inhibitor lock
- hyprlock can optionally daemonize (detach from controlling terminal) after it fades in
- this can effectively act as a signal to hypridle that it is finished since the original (non-forked) process that hypridle spawned terminates
- hypridle can optionally block until commands that it spawns terminate
Because this behaviou would be for before_sleep_cmd, can this create problem in case like this - before_sleep_cmd = loginctl lock-session & playerctl pause & some-other-command. In this case the if we use forking/daemonize - would it work?
fixed in https://github.com/hyprwm/hypridle/pull/122