AtlatestRepositorysigil-wm
1
#!/usr/bin/env bash2
set -euo pipefail3
cd "$(dirname "$0")/.."4
make -j2 all build/protocol-client build/input-driver5
mkdir -p build/receipts6
runtime_dir=$(mktemp -d /tmp/sigil-wm-keyboard-group.XXXXXX)7
export XDG_RUNTIME_DIR="$runtime_dir" SIGIL_WM_REPL="$runtime_dir/repl"8
export WLR_BACKENDS=headless WLR_RENDERER=pixman WLR_HEADLESS_OUTPUTS=19
unset WAYLAND_DISPLAY DISPLAY10
server_pid= client_pid= input_pid=11
cleanup() {12
for child in "$input_pid" "$client_pid" "$server_pid"; do13
[[ -z $child ]] || kill "$child" 2>/dev/null || true14
[[ -z $child ]] || wait "$child" 2>/dev/null || true15
done16
rm -rf "$runtime_dir"17
}18
trap cleanup EXIT19
value() { bash scripts/msg "$SIGIL_WM_REPL" "$1"; }20
wait_value() {21
for ((attempt=0; attempt<100; attempt++)); do22
if value "$1" | grep -q '(value #t)'; then return; fi23
sleep 0.0524
done25
cat build/receipts/keyboard-group.log >&226
printf 'WAIT_FAILED=%s\n' "$1" >&227
return 128
}29
wait_log() {30
for ((attempt=0; attempt<600; attempt++)); do31
if grep -q "$2" "$1" 2>/dev/null; then return; fi32
sleep 0.133
done34
tail -20 "$1" >&235
return 136
}37
timeout 180 bash scripts/run-sigil -L src eval -f test/keyboard-group.sgl > build/receipts/keyboard-group.log 2>&1 &38
server_pid=$!39
wait_log build/receipts/keyboard-group.log '^WAYLAND_SOCKET='40
export WAYLAND_DISPLAY41
WAYLAND_DISPLAY=$(sed -n 's/^WAYLAND_SOCKET=//p' build/receipts/keyboard-group.log | head -1)42
mkfifo "$runtime_dir/client-control" "$runtime_dir/input-control"43
exec {client_control}<> "$runtime_dir/client-control"44
exec {input_control}<> "$runtime_dir/input-control"45
SIGIL_WM_CLIENT_CONTROL=1 SIGIL_WM_CLIENT_XDG_VERSION=6 timeout 150 build/protocol-client green 36000 < "$runtime_dir/client-control" > build/receipts/keyboard-group-client.log 2>&1 &46
client_pid=$!47
wait_value '(and (= (length windows) 1) (equal? last-plan applied-plan))'48
value '(define live-window (car windows))'49
value '(define first-observation (query-window! host live-window))'50
wait_value '(and (pair? observations) (pair? extents) (= (event-ref (car observations) id:) first-observation) (= (event-ref (car extents) id:) first-observation))'51
value '(define first-copy (car observations))'52
wait_value '(and (event-ref first-copy accepted?:) (event-ref first-copy mapped?:) (event-ref first-copy visible?:) (event-ref first-copy focused?:) (event-ref first-copy xdg-state?:) (not (event-ref first-copy activated?:)) (= (event-ref first-copy width:) 360) (= (event-ref first-copy height:) 240) (= (event-ref (car extents) version:) 6))'53
value '(define moved-plan (submit-plan! host (make-scene-plan (list (placement window: live-window box: (rect x: 25 y: 30 width: 300 height: 180) activated?: #t tiled: 15)) live-window 200)))'54
wait_value '(equal? applied-plan moved-plan)'55
value '(define moved-observation (query-window! host live-window))'56
wait_value '(and (= (event-ref (car observations) id:) moved-observation) (= (event-ref (car observations) x:) 25) (= (event-ref (car observations) y:) 30) (= (event-ref (car observations) width:) 300) (= (event-ref (car observations) height:) 180) (event-ref (car observations) activated?:) (= (event-ref (car observations) tiled:) 15) (= (event-ref first-copy width:) 360))'57
before_configures=$(grep -c '^CLIENT_CONFIGURE=' build/receipts/keyboard-group-client.log)58
value '(define unchanged-plan (submit-plan! host (make-scene-plan (list (placement window: live-window box: (rect x: 25 y: 30 width: 300 height: 180) activated?: #t tiled: 15)) live-window 200)))'59
wait_value '(equal? applied-plan unchanged-plan)'60
[[ $(grep -c '^CLIENT_CONFIGURE=' build/receipts/keyboard-group-client.log) == "$before_configures" ]]61
echo 'SCENE_NOOP=PASS unchanged plan sends no redundant client configure'62
timeout 150 build/input-driver < "$runtime_dir/input-control" > build/receipts/keyboard-group-input.log 2>&1 &63
input_pid=$!64
wait_log build/receipts/keyboard-group-input.log '^INPUT_DEVICE_READY'65
wait_value '(and (find (lambda (record) (= (dict-ref record device-type:) 0)) (dict-ref (host-snapshot host) devices:)) #t)'66
value '(define device (dict-ref (find (lambda (record) (= (dict-ref record device-type:) 0)) (dict-ref (host-snapshot host) devices:)) id:))'67
printf 'group 0\nkey 35\n' >&"$input_control"68
wait_value '(equal? keys (quote ((2023))))'69
wait_log build/receipts/keyboard-group-client.log '^CLIENT_KEYSYM=35,1,2023$'70
value '(begin (set! keys (quote ())) (set-keyboard-group! host device 1 fixed?: #f) (set-keyboard-group! host 1 0))'71
printf 'group 0\nkey 35\n' >&"$input_control"72
wait_value '(equal? keys (quote ((104))))'73
wait_log build/receipts/keyboard-group-client.log '^CLIENT_KEYSYM=35,1,104$'74
value '(begin (set! keys (quote ())) (configure-keyboard! host device "us,gr" 25 600 group: 1 fixed-group?: #t) (set-keyboard-group! host 1 1))'75
sleep 0.176
printf 'group 0\nkey 35\n' >&"$input_control"77
wait_value '(equal? keys (quote ((2023))))'78
value '(do ((index 0 (+ index 1))) ((= index 20)) (emulate-key! host 1 30 #t) (emulate-key! host 1 30 #f))'79
wait_value '(and (= binding-presses 20) (= (dict-ref (host-snapshot host) focus:) live-window))'80
if grep -q '^CLIENT_KEY=30,' build/receipts/keyboard-group-client.log; then exit 1; fi81
before_keys=$(grep -c '^CLIENT_KEY=35,1' build/receipts/keyboard-group-client.log)82
value '(begin (set! delay-forward? #t) (emulate-key! host 1 35 #t) (emulate-key! host 1 35 #f) (focus-window! host 0))'83
wait_value '(= (dict-ref (host-snapshot host) focus:) 0)'84
sleep 0.285
[[ $(grep -c '^CLIENT_KEY=35,1' build/receipts/keyboard-group-client.log) == "$before_keys" ]]86
value '(begin (set! delay-forward? #f) (focus-window! host live-window))'87
wait_value '(= (dict-ref (host-snapshot host) focus:) live-window)'88
value '(begin (emulate-key! host 1 36 #t) (emulate-key! host 1 36 #f))'89
wait_log build/receipts/keyboard-group-client.log '^CLIENT_KEY=36,1$'90
echo 'SEMANTIC_KEYS=PASS twenty queued binding presses across focus epochs stale forwarding refused fresh forwarding restored'91
for pair in 4:31 8:32 1:33 64:34; do92
modifier=${pair%:*} keycode=${pair#*:}93
printf 'mods %s\nkey %s\nmods 0\n' "$modifier" "$keycode" >&"$input_control"94
wait_log build/receipts/keyboard-group-client.log "^CLIENT_KEY_MODIFIERS=$keycode,1,$modifier,1$"95
wait_log build/receipts/keyboard-group-client.log "^CLIENT_KEY_MODIFIERS=$keycode,0,$modifier,1$"96
done97
echo 'FORWARDED_MODIFIERS=PASS real Control Alt Shift Super snapshots on key press and release'98
value '(begin (set! keys (quote ())) (define refused-keymap (configure-keyboard! host 1 "zz-no-such-layout" 25 600)))'99
wait_value '(and (pair? configurations) (= (event-ref (car configurations) id:) refused-keymap) (not (event-ref (car configurations) success?:)))'100
value '(begin (emulate-key! host 1 35 #t) (emulate-key! host 1 35 #f))'101
wait_value '(equal? keys (quote ((2023))))'102
echo 'KEYBOARD_REFUSAL=PASS invalid keymap typed refusal previous group and symbols retained'103
value '(define hidden-plan (submit-plan! host (make-scene-plan (list (placement window: live-window box: (rect x: 0 y: 0 width: 360 height: 240) shown?: #f suspended?: #t resize?: #f)) 0 200)))'104
wait_value '(equal? applied-plan hidden-plan)'105
printf 'z\n' >&"$client_control"106
wait_log build/receipts/keyboard-group-client.log '^CLIENT_SYNC=z$'107
value '(define hidden-state (query-window! host live-window))'108
wait_value '(and (= (event-ref (car observations) id:) hidden-state) (event-ref (car observations) suspended?:) (not (event-ref (car observations) visible?:)) (= (event-ref (car observations) width:) 300) (= (event-ref (car observations) height:) 180))'109
echo 'WINDOW_SUSPENSION=PASS explicit version-six committed state independent visibility and focus'111
value '(define hidden-focus (focus-window! host live-window))'112
wait_value '(and (pair? focus-results) (= (event-ref (car focus-results) id:) hidden-focus) (not (event-ref (car focus-results) accepted?:)) (= (dict-ref (host-snapshot host) focus:) 0))'113
printf 'q\n' >&"$client_control"114
wait "$client_pid"115
client_pid=116
wait_value '(null? windows)'117
value '(define retired-observation (query-window! host live-window))'118
wait_value '(and (= (event-ref (car observations) id:) retired-observation) (not (event-ref (car observations) accepted?:)))'119
echo 'WINDOW_OBSERVATION=PASS actual scene committed protocol state offsets version detached prior facts typed retirement refusal'120
value '(define retired-focus (focus-window! host live-window))'121
wait_value '(and (= (event-ref (car focus-results) id:) retired-focus) (not (event-ref (car focus-results) accepted?:)))'122
kill "$input_pid"123
wait "$input_pid" 2>/dev/null || true124
input_pid=125
value '(stop-host! host)'126
wait "$server_pid"127
server_pid=128
grep -q '^KEYBOARD_GROUP_HOST=PASS' build/receipts/keyboard-group.log129
echo 'KEYBOARD_GROUP=PASS fixed and following backend groups atomic reconfiguration real client keysyms typed hidden and retired focus refusal clean lifetime'