#!/usr/bin/env bash # A window that wants the whole output must ask for ExclusionMode.Ignore and # nothing else. Quickshell's exclusiveZone setter forces exclusionMode back to # Normal as a side effect, so a window declaring both # # exclusiveZone: 0 # exclusionMode: ExclusionMode.Ignore # # ends up with whichever property the QML engine applied last, and that order # is not ours to control: the 2026-09-14 Qt/Quickshell update flipped it, every # full-screen overlay slid down under the bar, and the screenshot picker's # frozen frame stopped lining up with the screen it was a picture of. This pins # the order-independent idiom: Ignore alone, never paired with exclusiveZone. set -uo pipefail repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" qs="$repo_dir/config/dot/quickshell" fail() { printf 'exclusion idiom contract: %s\n' "$1" >&2; exit 1; } [[ -d "$qs/modules" ]] || fail "missing $qs/modules" python3 - "$qs" <<'PY' import re, sys, pathlib qs = pathlib.Path(sys.argv[1]) problems = [] ignore = re.compile(r'\bexclusionMode\s*:\s*ExclusionMode\.Ignore\b') zone = re.compile(r'^\s*(?:WlrLayershell\.)?exclusiveZone\s*:', re.M) checked = 0 for path in sorted(qs.rglob('*.qml')): text = path.read_text() if not ignore.search(text): continue checked += 1 for m in zone.finditer(text): line = text.count('\n', 0, m.start()) + 1 problems.append(f"{path.relative_to(qs)}:{line}: exclusiveZone set in a file that uses " "ExclusionMode.Ignore; drop it, Ignore already means -1") if checked == 0: problems.append("no window uses ExclusionMode.Ignore; the overlays this pins are gone") if problems: print('\n'.join(problems), file=sys.stderr) sys.exit(1) PY