AtlatestRepositorysigil-wm

sigil-wm / tree / scriptstest-constraints

1#!/usr/bin/env bash
2set -euo pipefail
3cd "$(dirname "$0")/.."
4make -j2 all build/protocol-client build/input-driver build/lock-client
5mkdir -p build/receipts
6runtime_dir=$(mktemp -d /tmp/sigil-wm-constraints.XXXXXX)
7export XDG_RUNTIME_DIR="$runtime_dir" SIGIL_WM_REPL="$runtime_dir/repl"
8export WLR_BACKENDS=headless WLR_RENDERER=pixman WLR_HEADLESS_OUTPUTS=1
9unset WAYLAND_DISPLAY DISPLAY
10server_pid= client_pid= input_pid= lock_pid=
11cleanup() {
12 for child in "$lock_pid" "$input_pid" "$client_pid" "$server_pid"; do
13 [[ -z $child ]] || kill "$child" 2>/dev/null || true
14 [[ -z $child ]] || wait "$child" 2>/dev/null || true
15 done
16 rm -rf "$runtime_dir"
18trap cleanup EXIT
19value() { bash scripts/msg "$SIGIL_WM_REPL" "$1"; }
20wait_value() {
21 for ((attempt=0; attempt<100; attempt++)); do
22 if value "$1" | grep -q '(value #t)'; then return; fi
23 sleep 0.05
24 done
25 cat build/receipts/constraints.log >&2
26 return 1
28wait_count() {
29 local count
30 for ((attempt=0; attempt<200; attempt++)); do
31 count=$(grep -c "$2" "$1" 2>/dev/null || true)
32 if (( ${count:-0} >= $3 )); then return; fi
33 sleep 0.05
34 done
35 tail -30 "$1" >&2
36 tail -20 build/receipts/constraints.log >&2
37 return 1
39sample() {
40 value '(set! sample-token (query-pointer! host))' >/dev/null
41 wait_value '(let ((sample (dict-ref (host-snapshot host) pointer-state:))) (and sample (= (event-ref sample id:) sample-token)))'
43point_is() {
44 sample
45 wait_value "(let ((sample (dict-ref (host-snapshot host) pointer-state:))) (and (= (event-ref sample x-milli:) $1) (= (event-ref sample y-milli:) $2)))"
47timeout 160 bash scripts/run-sigil -L src eval -f test/constraints.sgl > build/receipts/constraints.log 2>&1 &
48server_pid=$!
49wait_count build/receipts/constraints.log '^WAYLAND_SOCKET=' 1
50export WAYLAND_DISPLAY
51WAYLAND_DISPLAY=$(sed -n 's/^WAYLAND_SOCKET=//p' build/receipts/constraints.log | head -1)
52mkfifo "$runtime_dir/client-control" "$runtime_dir/input-control" "$runtime_dir/lock-control"
53exec {client_control}<> "$runtime_dir/client-control"
54exec {input_control}<> "$runtime_dir/input-control"
55exec {lock_control}<> "$runtime_dir/lock-control"
56SIGIL_WM_CLIENT_CONSTRAINTS=1 timeout 150 build/protocol-client green 36000 < "$runtime_dir/client-control" > build/receipts/constraint-client.log 2>&1 &
57client_pid=$!
58wait_value '(= (length windows) 1)'
59wait_count build/receipts/constraint-client.log '^CLIENT_RELATIVE_READY' 1
60timeout 150 build/input-driver < "$runtime_dir/input-control" > build/receipts/constraint-input.log 2>&1 &
61input_pid=$!
62wait_count build/receipts/constraint-input.log '^INPUT_DEVICE_READY' 1
63value '(define sample-token #f)'
64value '(emulate-motion! host 1 100 100)'
65point_is 100000 100000
66printf 'l\n' >&"$client_control"
67wait_count build/receipts/constraint-client.log '^CLIENT_SYNC=l' 1
68wait_value '(and (= (length (dict-ref (host-snapshot host) constraints:)) 1) (not (dict-ref (car (dict-ref (host-snapshot host) constraints:)) active?:)))'
69if grep -q '^CLIENT_LOCKED' build/receipts/constraint-client.log; then exit 1; fi
70value '(begin (set! accept? #t) (choose-constraint!))'
71wait_count build/receipts/constraint-client.log '^CLIENT_LOCKED' 1
72value '(define states-before states)'
73for ((index=1; index<=20; index++)); do printf 'relative 8192 4096 %s\n' "$((700+index))" >&"$input_control"; done
74wait_count build/receipts/constraint-input.log '^INPUT_ACK=' 20
75wait_count build/receipts/constraint-client.log '^CLIENT_RELATIVE=' 20
76point_is 100000 100000
77wait_value '(= states states-before)'
78printf 'h\nu\n' >&"$client_control"
79wait_value '(null? (dict-ref (host-snapshot host) constraints:))'
80point_is 160000 180000
81wait_value '(and (pair? hints) (event-ref (car hints) accepted?:))'
82echo 'CONSTRAINT_LOCK=PASS explicit inert admission native relative path zero per-motion facts accepted scoped hint'
83printf 'c\n' >&"$client_control"
84wait_count build/receipts/constraint-client.log '^CLIENT_CONFINED' 1
85printf 'motion 500 500\n' >&"$input_control"
86wait_count build/receipts/constraint-input.log '^INPUT_ACK=' 21
87sample
88wait_value '(let ((p (dict-ref (host-snapshot host) pointer-state:))) (and (<= 20000 (event-ref p x-milli:)) (< (event-ref p x-milli:) 320000) (<= 20000 (event-ref p y-milli:)) (< (event-ref p y-milli:) 320000)))'
89printf 'r\n' >&"$client_control"
90wait_count build/receipts/constraint-client.log '^CLIENT_UNCONFINED' 1
91printf 'absolute 120 100\n' >&"$input_control"
92wait_count build/receipts/constraint-client.log '^CLIENT_CONFINED' 2
93printf 'motion 500 500\n' >&"$input_control"
94wait_count build/receipts/constraint-input.log '^INPUT_ACK=' 23
95sample
96wait_value '(let ((p (dict-ref (host-snapshot host) pointer-state:))) (and (<= 100000 (event-ref p x-milli:)) (< (event-ref p x-milli:) 160000) (<= 80000 (event-ref p y-milli:)) (< (event-ref p y-milli:) 140000)))'
97printf 'u\n' >&"$client_control"
98wait_value '(null? (dict-ref (host-snapshot host) constraints:))'
99echo 'CONSTRAINT_CONFINE=PASS native bounds committed region shrink deactivation reentry'
100value '(begin (set! allow-hints? #f) (emulate-motion! host 1 100 100))'
101printf 'l\n' >&"$client_control"
102wait_count build/receipts/constraint-client.log '^CLIENT_LOCKED' 2
103printf 'h\nu\n' >&"$client_control"
104wait_value '(and (= (length hints) 2) (not (event-ref (car hints) accepted?:)))'
105point_is 100000 100000
106value '(set! allow-hints? #t)'
107printf 'n\n' >&"$client_control"
108wait_count build/receipts/constraint-client.log '^CLIENT_LOCKED' 3
109value '(focus-window! host 0)'
110wait_count build/receipts/constraint-client.log '^CLIENT_UNLOCKED' 1
111printf 'u\n' >&"$client_control"
112wait_value '(null? (dict-ref (host-snapshot host) constraints:))'
113point_is 100000 100000
114echo 'CONSTRAINT_SCOPE=PASS refused hint default region immediate activation focus-epoch deactivation no stale warp'
115value '(redraw!)'
116wait_value '(= (dict-ref (host-snapshot host) focus:) (car windows))'
117printf 'o\n' >&"$client_control"
118wait_count build/receipts/constraint-client.log '^CLIENT_LOCKED' 4
119value '(focus-window! host 0)'
120wait_value '(null? (dict-ref (host-snapshot host) constraints:))'
121printf 'u\n' >&"$client_control"
122value '(redraw!)'
123wait_value '(= (dict-ref (host-snapshot host) focus:) (car windows))'
124printf 'l\n' >&"$client_control"
125wait_count build/receipts/constraint-client.log '^CLIENT_LOCKED' 5
126timeout 40 build/lock-client draw < "$runtime_dir/lock-control" > build/receipts/constraint-lock.log 2>&1 &
127lock_pid=$!
128wait_count build/receipts/constraint-lock.log '^LOCKED ' 1
129wait_value '(and locked? (not (dict-ref (car (dict-ref (host-snapshot host) constraints:)) active?:)))'
130relative_before=$(grep -c '^CLIENT_RELATIVE=' build/receipts/constraint-client.log)
131printf 'motion 30 40\n' >&"$input_control"
132wait_count build/receipts/constraint-input.log '^INPUT_ACK=' 24
133printf 's\n' >&"$client_control"
134wait_count build/receipts/constraint-client.log '^CLIENT_SYNC=s' 1
135[[ $(grep -c '^CLIENT_RELATIVE=' build/receipts/constraint-client.log) == "$relative_before" ]]
136printf 'u\n' >&"$lock_control"
137wait "$lock_pid"
138lock_pid=
139wait_value '(not locked?)'
140wait_count build/receipts/constraint-client.log '^CLIENT_LOCKED' 6
141printf 'u\n' >&"$client_control"
142value '(for-each (lambda (window) (close-window! host window)) windows)'
143wait "$client_pid"
144client_pid=
145kill "$input_pid"
146wait "$input_pid" 2>/dev/null || true
147input_pid=
148wait_value '(and (null? windows) (= (host-statistic host 1) 0))'
149value '(stop-host! host)'
150wait "$server_pid"
151server_pid=
152grep -q '^CONSTRAINT_HOST=PASS' build/receipts/constraints.log
153if grep -q 'event handler failed' build/receipts/constraints.log; then cat build/receipts/constraints.log >&2; exit 1; fi
154echo 'CONSTRAINTS=PASS one-shot cleanup lock isolation authenticated restoration ownership'