detached c2e9def

fix(demo): kill launcher process groups and trap before creating the work dir

commit
c2e9def3be042f920f5607e82b529e225fbbfbbf
author
brice · · 2026-10-21 05:29 UTC
parent
87924a1
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
checks
2/2
3 files · +9 -4
M docs/media/demo.mp4 +0 -0 binary file: no text diff

binary file: no text diff

M docs/media/demo.png +0 -0 binary file: no text diff

binary file: no text diff

M tools/demo/record.sh +9 -4
@@ -9,16 +9,17 @@ for command in docker go ffmpeg; do
99 done
1010 docker info >/dev/null 2>&1 || { echo 'Docker daemon unavailable; start rootless Docker first.' >&2; exit 1; }
1111 work=$(mktemp -d "${TMPDIR:-/tmp}/neferwl-demo.XXXXXX")
12-printf 'Capture directory: %s\n' "$work"
13-mkdir -p "$work/shots" docs/media
1412 compositor='' launcher='' feeder='' success=''
1513 container=neferwl-demo-$$
1614 cleanup() {
1715 local status=$?
1816 trap - EXIT
19- for pid in "$launcher" "$feeder" "$compositor"; do
20- if [[ -n $pid ]]; then kill "$pid" 2>/dev/null || true; fi
17+ # launcher and feeder run with job control (set -m) in their own process
18+ # groups, so killing the group also stops their sleep/docker exec children.
19+ for pid in "$launcher" "$feeder"; do
20+ if [[ -n $pid ]]; then kill -- "-$pid" 2>/dev/null || kill "$pid" 2>/dev/null || true; fi
2121 done
22+ if [[ -n $compositor ]]; then kill "$compositor" 2>/dev/null || true; fi
2223 docker rm -f "$container" >/dev/null 2>&1 || true
2324 for pid in "$launcher" "$feeder" "$compositor"; do
2425 if [[ -n $pid ]]; then wait "$pid" 2>/dev/null || true; fi
@@ -32,6 +33,8 @@ cleanup() {
3233 trap cleanup EXIT
3334 trap 'exit 130' INT
3435 trap 'exit 143' TERM
36+printf 'Capture directory: %s\n' "$work"
37+mkdir -p "$work/shots" docs/media
3538 docker build -t neferwl-demo -f tools/demo/Dockerfile tools/demo
3639 CGO_ENABLED=0 go build -o "$work/neferwl" ./cmd/neferwl
3740 state=$work/state
@@ -86,10 +89,12 @@ docker exec -d --user demo "$container" foot --title 'System / NeferWL' bash -c
8689 # The first app is launched before t=0. FIFO input and shell launches now
8790 # share this epoch, independent of compositor/image/container startup time.
8891 SECONDS=0
92+set -m
8993 { cat tools/demo/input.txt; printf '\nkey Ctrl+Alt+BackSpace\n'; } >&3 &
9094 feeder=$!
9195 launch_apps &
9296 launcher=$!
97+set +m
9398 # --timeout exits nonzero; accept only its explicit timeout log entry.
9499 if ! wait "$compositor"; then
95100 grep -q '"reason":"timeout"' "$log" || exit 1
@@ -9,16 +9,17 @@ for command in docker go ffmpeg; do
9 done9 done
10 docker info >/dev/null 2>&1 || { echo 'Docker daemon unavailable; start rootless Docker first.' >&2; exit 1; }10 docker info >/dev/null 2>&1 || { echo 'Docker daemon unavailable; start rootless Docker first.' >&2; exit 1; }
11 work=$(mktemp -d "${TMPDIR:-/tmp}/neferwl-demo.XXXXXX")11 work=$(mktemp -d "${TMPDIR:-/tmp}/neferwl-demo.XXXXXX")
12-printf 'Capture directory: %s\n' "$work"
13-mkdir -p "$work/shots" docs/media
14 compositor='' launcher='' feeder='' success=''12 compositor='' launcher='' feeder='' success=''
15 container=neferwl-demo-$$13 container=neferwl-demo-$$
16 cleanup() {14 cleanup() {
17 local status=$?15 local status=$?
18 trap - EXIT16 trap - EXIT
19- for pid in "$launcher" "$feeder" "$compositor"; do17+ # launcher and feeder run with job control (set -m) in their own process
20- if [[ -n $pid ]]; then kill "$pid" 2>/dev/null || true; fi18+ # groups, so killing the group also stops their sleep/docker exec children.
19+ for pid in "$launcher" "$feeder"; do
20+ if [[ -n $pid ]]; then kill -- "-$pid" 2>/dev/null || kill "$pid" 2>/dev/null || true; fi
21 done21 done
22+ if [[ -n $compositor ]]; then kill "$compositor" 2>/dev/null || true; fi
22 docker rm -f "$container" >/dev/null 2>&1 || true23 docker rm -f "$container" >/dev/null 2>&1 || true
23 for pid in "$launcher" "$feeder" "$compositor"; do24 for pid in "$launcher" "$feeder" "$compositor"; do
24 if [[ -n $pid ]]; then wait "$pid" 2>/dev/null || true; fi25 if [[ -n $pid ]]; then wait "$pid" 2>/dev/null || true; fi
@@ -32,6 +33,8 @@ cleanup() {
32 trap cleanup EXIT33 trap cleanup EXIT
33 trap 'exit 130' INT34 trap 'exit 130' INT
34 trap 'exit 143' TERM35 trap 'exit 143' TERM
36+printf 'Capture directory: %s\n' "$work"
37+mkdir -p "$work/shots" docs/media
35 docker build -t neferwl-demo -f tools/demo/Dockerfile tools/demo38 docker build -t neferwl-demo -f tools/demo/Dockerfile tools/demo
36 CGO_ENABLED=0 go build -o "$work/neferwl" ./cmd/neferwl39 CGO_ENABLED=0 go build -o "$work/neferwl" ./cmd/neferwl
37 state=$work/state40 state=$work/state
@@ -86,10 +89,12 @@ docker exec -d --user demo "$container" foot --title 'System / NeferWL' bash -c
86 # The first app is launched before t=0. FIFO input and shell launches now89 # The first app is launched before t=0. FIFO input and shell launches now
87 # share this epoch, independent of compositor/image/container startup time.90 # share this epoch, independent of compositor/image/container startup time.
88 SECONDS=091 SECONDS=0
92+set -m
89 { cat tools/demo/input.txt; printf '\nkey Ctrl+Alt+BackSpace\n'; } >&3 &93 { cat tools/demo/input.txt; printf '\nkey Ctrl+Alt+BackSpace\n'; } >&3 &
90 feeder=$!94 feeder=$!
91 launch_apps &95 launch_apps &
92 launcher=$!96 launcher=$!
97+set +m
93 # --timeout exits nonzero; accept only its explicit timeout log entry.98 # --timeout exits nonzero; accept only its explicit timeout log entry.
94 if ! wait "$compositor"; then99 if ! wait "$compositor"; then
95 grep -q '"reason":"timeout"' "$log" || exit 1100 grep -q '"reason":"timeout"' "$log" || exit 1

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 24

Tags 10

↑↓ moveenter openesc close