From 7f7667c5b69b818bafb6c65f71694cd8fae1f1ee Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Wed, 31 May 2023 16:24:43 +0200 Subject: [PATCH] lock-and-sleep: properly handle all edge cases --- home/.local/bin/lock-and-sleep | 42 ++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/home/.local/bin/lock-and-sleep b/home/.local/bin/lock-and-sleep index 11bc0a8e..0fd4cdf6 100755 --- a/home/.local/bin/lock-and-sleep +++ b/home/.local/bin/lock-and-sleep @@ -1,16 +1,34 @@ -#!/usr/bin/env execlineb +#!/usr/bin/env python3 # # Requires swaylock > 1.7.2. -piperw 3 4 -background { swaylock --ready-fd 4 } -importas SWAYLOCK ! -if { fdmove 0 3 forstdin -x0 i exit 0 } fdclose 3 -foreground { powerctl mem } +import os +import sys +import subprocess -# While swaylock continues running, go back to sleep after 10 seconds idle. -# FIXME: Broken, only works once. See: https://github.com/swaywm/swayidle/issues/144 -background { swayidle timeout 10 "powerctl mem" } -importas SWAYIDLE ! -wait { $SWAYLOCK } -kill $SWAYIDLE +(r, w) = os.pipe() +os.set_inheritable(r, False) +swaylock = subprocess.Popen(["swaylock", "--ready-fd", str(w)], pass_fds=(w,)) + +# Wait for swaylock to be ready. +with os.fdopen(r, "rb") as ready_pipe: + while True: + pipe_data = ready_pipe.read(1) + if pipe_data == b"": + print("fatal: swaylock closed fd before locking") + sys.exit(1) + if pipe_data == b"\n": + break + +while True: + subprocess.call(["powerctl", "mem"]) # blocks until wakeup from sleep. + + wayidle = subprocess.Popen(["wayidle", "--timeout", "10"]) + + (pid, returncode) = os.wait() + if pid == swaylock.pid: + wayidle.kill() + sys.exit(returncode) + if pid == wayidle.pid and returncode != 0: + print("fatal: wayidle exited non-zero") + sys.exit(returncode) # swaylock will continue running -- 2.38.5