screen-lock: the operator's lock screen is kept, i3lock-color with its blur, ring and clock

The first version swapped the colour build for the distribution's plain i3lock and locked to black;
adopting means keeping what the operator had. Plain i3lock remains the fallback, with a blurred
screenshot of its own.
This commit is contained in:
jochen
2026-10-04 17:05:58 +02:00
parent 8b97cc9b41
commit 3c832f3f06
4 changed files with 48 additions and 17 deletions
+10
View File
@@ -71,3 +71,13 @@ locker's options change with it.
- `node-lock-screen`, `x11-display` and the `xinitrc` slot are ADR 0208's. Until the controller knows
them, `mctl` reads them as unknown.
- `xset` comes with the display server's module (`xorg`).
## The operator's look is kept (changed 2026-10-04)
The first version replaced the colour build with the distribution's plain i3lock, which locked to a
black screen. It is reverted: the lock looks as it did before the mesh, with the screen blurred, an
orange ring, the time and the date. That is i3lock-color, which comes from the distribution's user
repository, so it is kept as found and no longer declared absent. The package and how such software
reaches a machine are research 027's first question. The locker checks which build it has. On a
machine with only the plain i3lock, it shows a blurred screenshot it takes itself, with the plain
ring.
@@ -8,7 +8,7 @@ import (
// screen-lock's shape (novox/hq ADR 0208, research 026/04): it claims node-lock-screen serving lock,
// requires the X display on its own machine, installs the watcher and the distribution's locker,
// declares the colour build and xscreensaver absent, places its locker, and starts the watcher and
// keeps the colour build where it is found (the operator's look), declares xscreensaver absent, places its locker, and starts the watcher and
// the timeouts once, from the session's start. The lock key is the window manager's.
func TestItClaimsTheLockScreenSeatServingLockAndRequiresTheXDisplay(t *testing.T) {
@@ -24,10 +24,10 @@ func TestItClaimsTheLockScreenSeatServingLockAndRequiresTheXDisplay(t *testing.T
}
}
func TestTheDistributionsLockerReplacesTheColourBuildAndXscreensaverGoes(t *testing.T) {
func TestTheColourBuildIsKeptWithAFallbackAndXscreensaverGoes(t *testing.T) {
m := readManifest(t)
present, absent := m.packages()
if !reflect.DeepEqual(present, []string{"xss-lock", "i3lock"}) || !reflect.DeepEqual(absent, []string{"i3lock-color", "xscreensaver"}) {
if !reflect.DeepEqual(present, []string{"xss-lock", "i3lock"}) || !reflect.DeepEqual(absent, []string{"xscreensaver"}) {
t.Fatalf("packages: %v, absent %v", present, absent)
}
m.sameAsSource(t, "wrapper", "files/bin/screen-lock")
@@ -36,9 +36,14 @@ func TestTheDistributionsLockerReplacesTheColourBuildAndXscreensaverGoes(t *test
t.Fatalf("the locker: %v", wrapper)
}
c := wrapper["content"].(string)
// The colour build's options only once it has said it is the colour build: the distribution's
// i3lock refuses an option it does not know, and the screen would not lock at all.
check := strings.Index(c, "i3lock --version 2>&1 | grep -qi color")
fallback := strings.Index(c, "\nelse\n")
for _, colourOnly := range []string{"--ring-color", "--blur", "--clock", "--indicator", "--time-str"} {
if strings.Contains(c, colourOnly) {
t.Errorf("the wrapper passes %s, which only the colour build knows", colourOnly)
at := strings.Index(c, colourOnly)
if at < 0 || check < 0 || at < check || at > fallback {
t.Errorf("%s is passed outside the colour build's branch", colourOnly)
}
}
if !strings.Contains(c, "XSS_SLEEP_LOCK_FD}<&-") {
+27 -5
View File
@@ -2,9 +2,11 @@
# screen-lock (module screen-lock, novox/hq ADR 0208): the locker. xss-lock runs it on idle, before
# suspend and on logind's Lock, and node-lock-screen's `lock` ends in it.
#
# The distribution's i3lock: a black screen, failed attempts shown, an empty Enter ignored. The colour
# build the predecessor used is not in the distribution; it can come back as a pinned archive
# (ADR 0205), and then only these options change.
# The operator's look, adopted from the predecessor's my-i3lock: the screen as it was, blurred, with
# an orange ring, the time and the date. That needs i3lock-color, from the distribution's user
# repository, kept as found until the mesh carries such software (novox/hq research 027, question 1).
# On a machine without it the distribution's i3lock shows the same blurred screen, taken here, with
# its own plain ring; failing that, black.
#
# Before a suspend, xss-lock hands this script a lock on the sleep (XSS_SLEEP_LOCK_FD) and suspends
# once it is released. The locker must not inherit it, or the machine would wait for the unlock
@@ -12,13 +14,33 @@
# xss-lock's own documented pattern for i3lock.
set -u
options=(--color=000000 --show-failed-attempts --ignore-empty-password)
# One locker: a second press of the key, or a lock while locked, changes nothing.
if pgrep -xu "$EUID" i3lock >/dev/null; then
exit 0
fi
if i3lock --version 2>&1 | grep -qi color; then
blank='#00000000' clear='#ffffff22' accent='#ca4a00' wrong='#880000bb' verifying='#bb00bbbb'
options=(
--insidever-color="$clear" --ringver-color="$verifying"
--insidewrong-color="$clear" --ringwrong-color="$wrong"
--inside-color="$blank" --ring-color="$accent" --line-color="$blank" --separator-color="$accent"
--verif-color="$accent" --wrong-color="$accent" --time-color="$accent" --date-color="$accent"
--layout-color="$accent" --keyhl-color="$wrong" --bshl-color="$wrong"
--screen 1 --blur 5 --ring-width=7.0 --clock --indicator
--time-str="%H:%M:%S" --date-str="%A, %Y-%m-%d"
--time-font=sans-serif --date-font=sans-serif --verif-font=sans-serif
--wrong-font=sans-serif --layout-font=sans-serif --keylayout 1
--show-failed-attempts --ignore-empty-password
)
else
options=(--color=000000 --show-failed-attempts --ignore-empty-password)
shot="${XDG_RUNTIME_DIR:-/tmp}/screen-lock.png"
if command -v magick >/dev/null && magick import -window root -resize 25% -blur 0x3 -resize 400% "$shot" 2>/dev/null; then
options+=(--image="$shot")
fi
fi
if [[ -e /dev/fd/${XSS_SLEEP_LOCK_FD:--1} ]]; then
kill_i3lock() { pkill -xu "$EUID" "$@" i3lock; }
trap kill_i3lock TERM INT
+1 -7
View File
@@ -29,12 +29,6 @@
}
],
"resources": [
{
"id": "colour-locker",
"type": "package",
"package": "i3lock-color",
"absent": true
},
{
"id": "screensaver",
"type": "package",
@@ -57,7 +51,7 @@
"path": "${machine:account-home}/.local/bin/screen-lock",
"owner": "${machine:account}",
"mode": "0755",
"content": "#!/usr/bin/env bash\n# screen-lock (module screen-lock, novox/hq ADR 0208): the locker. xss-lock runs it on idle, before\n# suspend and on logind's Lock, and node-lock-screen's `lock` ends in it.\n#\n# The distribution's i3lock: a black screen, failed attempts shown, an empty Enter ignored. The colour\n# build the predecessor used is not in the distribution; it can come back as a pinned archive\n# (ADR 0205), and then only these options change.\n#\n# Before a suspend, xss-lock hands this script a lock on the sleep (XSS_SLEEP_LOCK_FD) and suspends\n# once it is released. The locker must not inherit it, or the machine would wait for the unlock\n# before sleeping; it is released once i3lock is up, so the machine never sleeps unlocked. This is\n# xss-lock's own documented pattern for i3lock.\nset -u\n\noptions=(--color=000000 --show-failed-attempts --ignore-empty-password)\n\n# One locker: a second press of the key, or a lock while locked, changes nothing.\nif pgrep -xu \"$EUID\" i3lock >/dev/null; then\n\texit 0\nfi\n\nif [[ -e /dev/fd/${XSS_SLEEP_LOCK_FD:--1} ]]; then\n\tkill_i3lock() { pkill -xu \"$EUID\" \"$@\" i3lock; }\n\ttrap kill_i3lock TERM INT\n\ti3lock \"${options[@]}\" {XSS_SLEEP_LOCK_FD}<&-\n\texec {XSS_SLEEP_LOCK_FD}<&-\n\twhile kill_i3lock -0; do\n\t\tsleep 0.5\n\tdone\nelse\n\ttrap 'kill %%' TERM INT\n\ti3lock --nofork \"${options[@]}\" &\n\twait\nfi\n"
"content": "#!/usr/bin/env bash\n# screen-lock (module screen-lock, novox/hq ADR 0208): the locker. xss-lock runs it on idle, before\n# suspend and on logind's Lock, and node-lock-screen's `lock` ends in it.\n#\n# The operator's look, adopted from the predecessor's my-i3lock: the screen as it was, blurred, with\n# an orange ring, the time and the date. That needs i3lock-color, from the distribution's user\n# repository, kept as found until the mesh carries such software (novox/hq research 027, question 1).\n# On a machine without it the distribution's i3lock shows the same blurred screen, taken here, with\n# its own plain ring; failing that, black.\n#\n# Before a suspend, xss-lock hands this script a lock on the sleep (XSS_SLEEP_LOCK_FD) and suspends\n# once it is released. The locker must not inherit it, or the machine would wait for the unlock\n# before sleeping; it is released once i3lock is up, so the machine never sleeps unlocked. This is\n# xss-lock's own documented pattern for i3lock.\nset -u\n\n# One locker: a second press of the key, or a lock while locked, changes nothing.\nif pgrep -xu \"$EUID\" i3lock >/dev/null; then\n\texit 0\nfi\n\nif i3lock --version 2>&1 | grep -qi color; then\n\tblank='#00000000' clear='#ffffff22' accent='#ca4a00' wrong='#880000bb' verifying='#bb00bbbb'\n\toptions=(\n\t\t--insidever-color=\"$clear\" --ringver-color=\"$verifying\"\n\t\t--insidewrong-color=\"$clear\" --ringwrong-color=\"$wrong\"\n\t\t--inside-color=\"$blank\" --ring-color=\"$accent\" --line-color=\"$blank\" --separator-color=\"$accent\"\n\t\t--verif-color=\"$accent\" --wrong-color=\"$accent\" --time-color=\"$accent\" --date-color=\"$accent\"\n\t\t--layout-color=\"$accent\" --keyhl-color=\"$wrong\" --bshl-color=\"$wrong\"\n\t\t--screen 1 --blur 5 --ring-width=7.0 --clock --indicator\n\t\t--time-str=\"%H:%M:%S\" --date-str=\"%A, %Y-%m-%d\"\n\t\t--time-font=sans-serif --date-font=sans-serif --verif-font=sans-serif\n\t\t--wrong-font=sans-serif --layout-font=sans-serif --keylayout 1\n\t\t--show-failed-attempts --ignore-empty-password\n\t)\nelse\n\toptions=(--color=000000 --show-failed-attempts --ignore-empty-password)\n\tshot=\"${XDG_RUNTIME_DIR:-/tmp}/screen-lock.png\"\n\tif command -v magick >/dev/null && magick import -window root -resize 25% -blur 0x3 -resize 400% \"$shot\" 2>/dev/null; then\n\t\toptions+=(--image=\"$shot\")\n\tfi\nfi\n\nif [[ -e /dev/fd/${XSS_SLEEP_LOCK_FD:--1} ]]; then\n\tkill_i3lock() { pkill -xu \"$EUID\" \"$@\" i3lock; }\n\ttrap kill_i3lock TERM INT\n\ti3lock \"${options[@]}\" {XSS_SLEEP_LOCK_FD}<&-\n\texec {XSS_SLEEP_LOCK_FD}<&-\n\twhile kill_i3lock -0; do\n\t\tsleep 0.5\n\tdone\nelse\n\ttrap 'kill %%' TERM INT\n\ti3lock --nofork \"${options[@]}\" &\n\twait\nfi\n"
}
],
"build": {