git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

verify/popup-constrain-test (2.9K)

 1 #!/usr/bin/env bash
 2 # popup-constrain-test — behavioral test for submenu unconstraining in
 3 # xdg_popup.rs::handle_reposition. wlroots wants the unconstrain box in the
 4 # ROOT window's surface coordinates; measuring it from a submenu's parent
 5 # menu instead shifted the screen by the menu's offset, so Chrome's
 6 # three-dot submenus were pushed past the top edge or failed to flip.
 7 #
 8 # Setup: a private cce-shadow instance and verify/clients' popup-nest — a
 9 # fixed-size window at a known spot with a menu and a nested submenu, each
10 # asking to flip sideways and slide vertically (what Chrome asks for).
11 # Two cases, each asserting the submenu lands fully on the 1280x720 output:
12 #
13 #   1. a tall submenu off a menu low in the window: must slide up to fit
14 #   2. a submenu off a menu near the right edge: must flip to the left
15 #
16 # Extra args pass to `cce-shadow start`, so `--bin ../target/release/cce-fx`
17 # pins the tree's own build.
18 
19 set -euo pipefail
20 
21 here=$(cd "$(dirname "$0")" && pwd)
22 repo=$(dirname "$here")
23 shadow="$repo/scripts/cce-shadow"
24 out=$(mktemp)
25 inst=""
26 fails=0
27 
28 cleanup() {
29     [ -n "$inst" ] && "$shadow" --instance "$inst" stop >/dev/null 2>&1 || true
30     rm -f "$out"
31 }
32 trap cleanup EXIT
33 
34 echo "==> building test clients"
35 cargo build --quiet --manifest-path "$here/clients/Cargo.toml"
36 client="$here/clients/target/debug/popup-nest"
37 
38 run_case() {
39     local label=$1; shift
40     : >"$out"
41     inst=$("$shadow" start --new "${start_args[@]}" 2>&1 | sed -n "s/.*claimed instance '\([^']*\)'.*/\1/p")
42     [ -n "$inst" ] || { echo "FAIL: could not claim a shadow instance"; exit 1; }
43     sc() { "$shadow" --instance "$inst" "$@"; }
44     sc ctl idle timeouts 0 0 >/dev/null
45     sc ctl place-next test.popupnest 100 100 >/dev/null
46     sc run "$client" "$@" >"$out" 2>&1 &
47     for _ in $(seq 1 50); do grep -q '^submenu' "$out" && break; sleep 0.2; done
48     sleep 0.5
49     local wx wy mx my sx sy sw sh _x
50     read -r wx wy < <(sc ctl windows --json | jq -r 'select(.app_id=="test.popupnest") | "\(.x) \(.y)"')
51     read -r _x mx my _ _ < <(grep '^menu' "$out") || true
52     read -r _x sx sy sw sh < <(grep '^submenu' "$out") || true
53     if [ -z "${sx:-}" ]; then
54         echo "FAIL: $label: no submenu configure"; cat "$out"; fails=$((fails + 1))
55     else
56         local lx=$((wx + mx + sx)) ly=$((wy + my + sy))
57         if [ $lx -ge 0 ] && [ $ly -ge 0 ] && [ $((lx + sw)) -le 1280 ] && [ $((ly + sh)) -le 720 ]; then
58             echo "PASS: $label: submenu at x $lx..$((lx + sw)) y $ly..$((ly + sh))"
59         else
60             echo "FAIL: $label: submenu at x $lx..$((lx + sw)) y $ly..$((ly + sh)), off the 1280x720 output"
61             fails=$((fails + 1))
62         fi
63     fi
64     sc stop >/dev/null 2>&1 || true
65     inst=""
66 }
67 
68 start_args=("$@")
69 run_case "tall submenu slides up" --menu-at 500,250 --sub 200x600
70 run_case "submenu near the right edge flips left" --menu-at 700,100 --sub 200x300
71 
72 [ $fails -eq 0 ] && echo "all passed" || { echo "$fails failed"; exit 1; }