diff options
| author | 2026-05-29 11:18:15 +0100 | |
|---|---|---|
| committer | 2026-05-29 11:18:15 +0100 | |
| commit | ec3734c5ef9fcfe97c21cd19f198ec779ab5f052 (patch) | |
| tree | 578d98f90db4a174cc8045482bffa8a065fe724c /dot_config/systemd/user | |
| parent | 3848d890979bd5fafae92054f85061edf10edff3 (diff) | |
| download | dotfiles-ec3734c5ef9fcfe97c21cd19f198ec779ab5f052.tar.gz dotfiles-ec3734c5ef9fcfe97c21cd19f198ec779ab5f052.tar.bz2 dotfiles-ec3734c5ef9fcfe97c21cd19f198ec779ab5f052.zip | |
refactor(suspend): gate suspend on AC, drop bespoke zellij inhibit
New, simpler suspend policy:
AC plugged in -> never auto-suspends (lid close ignored, idle no-op)
On battery only -> lid close suspends, swayidle suspends at 30 min idle
This replaces the SSH/zellij-aware inhibit machinery with a rule that
matches the user's mental model: if you don't want the machine to
sleep, plug it in. Long-running tasks (builds, downloads, SSH
sessions, headless services) just need AC.
Changes:
* etc/systemd/logind.conf.d/20-lid-ac.conf: set
HandleLidSwitchExternalPower=ignore so logind itself handles the AC
case at the source. No userspace daemon, no race, no rate-limit risk.
* dot_local/bin/on-battery-suspend: tiny POSIX wrapper that exits 0
when any /sys/class/power_supply/{AC,ADP}*/online == 1, else execs
`systemctl suspend`.
* dot_config/systemd/user/swayidle.service: add
`timeout 1800 on-battery-suspend`. Idle suspend now exists, but only
when on battery.
* Delete zellij-inhibit-suspend.{path,service} + watcher script and
remove the entry from systemd-units/user.txt. The .path
re-trigger storm bug is moot because the whole mechanism is gone.
Manual suspends (sway XF86Sleep keybind, sway power submode `s`,
`systemctl suspend` over SSH) still always work regardless of AC --
explicit user intent wins.
Also drop /migrate-podman-to-btrfs.sh from .gitignore; the one-off
migration script has been deleted now that the user has switched their
podman storage to the btrfs driver.
On-host steps to apply:
chezmoi apply -v
systemctl --user daemon-reload
systemctl --user reset-failed zellij-inhibit-suspend.service zellij-inhibit-suspend.path || true
systemctl --user stop zellij-inhibit-suspend.path zellij-inhibit-suspend.service || true
systemctl --user disable zellij-inhibit-suspend.path || true
systemctl --user restart swayidle.service
# logind drop-in is reloaded automatically by the etc deploy script.
Verify:
systemctl status systemd-logind | grep -i lid
loginctl show-session $XDG_SESSION_ID | grep -i lid
# Unplug AC -> close lid -> should suspend.
# Plug AC -> close lid -> nothing happens.
Diffstat (limited to 'dot_config/systemd/user')
| -rw-r--r-- | dot_config/systemd/user/swayidle.service | 1 | ||||
| -rw-r--r-- | dot_config/systemd/user/zellij-inhibit-suspend.path | 15 | ||||
| -rw-r--r-- | dot_config/systemd/user/zellij-inhibit-suspend.service | 23 |
3 files changed, 1 insertions, 38 deletions
diff --git a/dot_config/systemd/user/swayidle.service b/dot_config/systemd/user/swayidle.service index 478c8f8..acd0196 100644 --- a/dot_config/systemd/user/swayidle.service +++ b/dot_config/systemd/user/swayidle.service @@ -10,6 +10,7 @@ ExecStart=/usr/bin/swayidle -w \ timeout 300 'swaymsg "output * power off"' \ resume 'swaymsg "output * power on"' \ timeout 330 'swaylock -f -e -c 000000' \ + timeout 1800 '%h/.local/bin/on-battery-suspend' \ before-sleep 'playerctl -a pause; swaylock -f -e -c 000000' \ lock 'swaylock -f -e -c 000000' Restart=on-failure diff --git a/dot_config/systemd/user/zellij-inhibit-suspend.path b/dot_config/systemd/user/zellij-inhibit-suspend.path deleted file mode 100644 index 2a4be21..0000000 --- a/dot_config/systemd/user/zellij-inhibit-suspend.path +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Description=Activate suspend inhibitor whenever zellij has a live session - -[Path] -# %t expands to $XDG_RUNTIME_DIR (typically /run/user/$UID); zellij keeps -# its per-version session sockets under this directory. Whenever the dir -# transitions from empty to non-empty, the service is (re)activated. -# The service's watcher then decides whether to actually hold the lock -# (only if at least one zellij was spawned from an SSH session); if not, -# it exits immediately and the service stops with no harm done. -DirectoryNotEmpty=%t/zellij -Unit=zellij-inhibit-suspend.service - -[Install] -WantedBy=default.target diff --git a/dot_config/systemd/user/zellij-inhibit-suspend.service b/dot_config/systemd/user/zellij-inhibit-suspend.service deleted file mode 100644 index 7c73c64..0000000 --- a/dot_config/systemd/user/zellij-inhibit-suspend.service +++ /dev/null @@ -1,23 +0,0 @@ -[Unit] -Description=Stay alive while any zellij session exists; inhibit suspend if SSH-spawned -Documentation=man:systemd-inhibit(1) man:zellij(1) -# Independent of any graphical session: this is meant to run on -# headless SSH-attached hosts too. The watcher itself decides whether -# the current zellij activity warrants inhibiting (SSH-spawned only), -# and acquires/releases its own systemd-inhibit lock dynamically. It -# stays alive for the whole zellij dir lifetime so the .path unit does -# not retrigger us in a busy loop when only local zellij sessions are -# active. -# Disable systemd's default start-rate limiter: even though the -# refactored watcher should not cycle anymore, a zero rate-limit makes -# this unit resilient if the user kills it manually. -StartLimitIntervalSec=0 - -[Service] -Type=simple -ExecStart=%h/.local/bin/zellij-inhibit-watcher -# Don't auto-restart: the .path unit reactivates us on the next session. -Restart=no - -[Install] -WantedBy=default.target |
