feat(hypr): cut the session over to the Quickshell locker - #3
Merged
Conversation
The lock intent took three paths: the keybind ran hyprlock directly and bypassed logind, the idle timeout went through hypridle's lock_cmd, and pre-sleep went through loginctl. Nothing converged and LockedHint was never set. The keybind now goes through loginctl lock-session, so all three raise one dbus lock event and share one lock_cmd and one fallback chain. lock_cmd asks Quickshell to lock and matches the returned value: qs ipc call prints `Target not found.` and exits 0 when the shell is alive but the lock module failed to load, so exit status cannot distinguish that from success. hyprlock stays as the last link for the one case where a fallback is real -- the shell already dead when the lock is requested. inhibit_sleep is pinned to 3 so suspend waits for a compositor-confirmed lock. auto resolves to 1 here, because hypridle chooses by detecting whether hyprlock is launched before sleep and this config's pre-sleep command is loginctl lock-session -- dropping the inhibitor the moment loginctl returns, which is precisely the race. The four idle timeouts are unchanged. Refs #71
Without the pointer bump a fresh machine still checks out the old commit, and the lock_cmd added alongside would find no lock target and fall through to hyprlock on every lock. Refs #71
Observed during the cutover pull: the watcher fired part-way through the checkout, failed on a module that had not landed yet, and then went quiet, leaving the old generation serving with no sign of a problem. Refs #71
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements bhdai/quickshell_config#71 (parent spec bhdai/quickshell_config#62). This is the
cutover: it points the live session at the Quickshell locker and converges the three lock
paths onto one. All ten sub-issues of the build spec are merged, which is what this was
gated on.
What changes
config/hypr/binds.lua— the lock keybind ranhyprlockdirectly and bypassed logindentirely. It becomes
loginctl lock-session, so the keybind, the 300 s idle timeout andpre-sleep all raise one dbus lock event and share one lock command and one fallback chain.
logind's
LockedHintfinally gets set whichever path fired. Lid close needs no config ofits own — logind's
HandleLidSwitchissuspend, which runsbefore_sleep_cmd, which isalready
loginctl lock-session.config/hypr/hypridle.conf—lock_cmdasks Quickshell to lock and matches thereturned value, and
inhibit_sleepis pinned to3.config/quickshell— submodule bumped to1e19de2, the merged locker.Without the bump a fresh machine still checks out the old commit, and the new
lock_cmdwould find no lock target and fall through to hyprlock on every lock.
README.md— a "Session locking" section covering the above, the~/.faceone-timestep, and how to apply a change to either file.
Why value-matched, not exit status
Measured on this machine while preparing this PR:
trueTarget not found.Function not found.Exit status cannot distinguish "the shell is alive but the lock module failed to load" from
success.
grep -qx truecan — all three failure rows fall through to hyprlock, and onlytruestops the chain.Why
inhibit_sleep = 3rather thanautoautoresolves to 1 here. hypridle chooses between 1 and 3 by detecting whetherhyprlock is launched before sleep, and this config's pre-sleep command is
loginctl lock-session— so the inhibitor would drop the momentloginctlreturns, beforeanything is on screen. That is precisely the race. Confirmed after the restart:
Cost of pinning: it disables the lock/unlock hooks, neither of which is used.
hyprlock stays
config/hypr/hyprlock.confand/etc/pam.d/hyprlockare untouched and the package staysinstalled. hyprlock remains the last link in
lock_cmdfor the one case where a fallback isreal — the shell already dead when the lock is requested, so nothing holds the lock yet
and no compositor flag is involved. The
pidofguard against a double launch is retained.It is also the safety net while the new locker is being proven.
Acceptance criteria
LockedHintis set.pidofguard retained.found 4 rules./etc/pam.d/quickshell-lock,/etc/pam.d/quickshell-fprint),~/.face→~/Pictures/profile/bird_profile.png.misc:allow_session_lock_restoreis still off (bool: false,set: false).Applied to the running session
The live session was carried onto this state while preparing the PR: submodule pulled, the
shell reloaded (
qs ipc call lock isLockednow answersfalseinstead ofTarget not found.),hyprctl reloadrun, and hypridle restarted on the new config.Not verified here — needs a human at the display
I have no display, so nothing below was exercised. Draft until they pass:
busctl get-property org.freedesktop.login1 /org/freedesktop/login1/session/_32 org.freedesktop.login1.Session LockedHintshould read
truewhile locked.never the desktop. This is the race the inhibitor closes.
qs kill), then lock — hyprlock should come up instead.