| | |
| | | print(json.dumps(report, indent=2, ensure_ascii=False), file=sys.stderr) |
| | | sys.exit(1) |
| | | |
| | | def is_locked_fill(color): |
| | | return ( |
| | | color.get("blue", 0) >= 0.85 |
| | | and color.get("green", 0) >= 0.55 |
| | | and color.get("red", 1) <= 0.58 |
| | | and color.get("alpha", 0) >= 0.70 |
| | | ) |
| | | |
| | | def is_white(color): |
| | | return ( |
| | | color.get("red", 0) >= 0.94 |
| | | and color.get("green", 0) >= 0.94 |
| | | and color.get("blue", 0) >= 0.94 |
| | | and color.get("alpha", 0) >= 0.88 |
| | | ) |
| | | |
| | | root = report.get("rootView", {}) |
| | | items = root.get("appShelfItems", []) |
| | | columns = root.get("waterfallColumns", []) |
| | |
| | | require(segment_by_id[4].get("windowCount") == 0, "B1 must remain visible as empty Space") |
| | | require(segment_by_id[5].get("windowCount") == 1, "B2 fullscreen Space must remain visible") |
| | | require("locked" in segment_by_id[1].get("visualStates", []), "locked Space must expose locked visual state") |
| | | require(segment_by_id[1].get("borderWidth", 0) >= 5.5, "locked Space must use a heavy blue border") |
| | | require(segment_by_id[1].get("borderWidth", 99) <= 2.0, "locked Space must not use the old heavy border") |
| | | require(segment_by_id[1].get("backgroundKind") == "solid", "locked Space must use a solid light-blue fill") |
| | | require(is_locked_fill(segment_by_id[1].get("backgroundColor", {})), "locked Space fill must be clean light blue") |
| | | require(is_white(segment_by_id[1].get("labelColor", {})), "locked Space label text must be pure white") |
| | | require(is_white(segment_by_id[1].get("countColor", {})), "locked Space count text must be pure white") |
| | | require(is_white(segment_by_id[1].get("appColor", {})), "locked Space app text must be pure white") |
| | | require(all(is_white(color) for color in segment_by_id[1].get("windowBlockColors", [])), "locked Space window blocks must be pure white") |
| | | lock_shadow = segment_by_id[1].get("shadowColor", {}) |
| | | require(lock_shadow.get("red", 0) >= 0.90 and lock_shadow.get("green", 0) >= 0.90 and lock_shadow.get("blue", 0) >= 0.90, "locked Space must use a white glow") |
| | | require(segment_by_id[1].get("shadowOpacity", 0) >= 0.60, "locked Space glow must be visibly stronger than hover") |
| | |
| | | "cardWindowIDs": [card.get("windowID") for card in cards], |
| | | "lockedSpace": root.get("spaceFilterLockedSpaceID"), |
| | | "lockedBorderWidth": segment_by_id[1].get("borderWidth"), |
| | | "lockedBackgroundColor": segment_by_id[1].get("backgroundColor"), |
| | | "lockedLabelColor": segment_by_id[1].get("labelColor"), |
| | | "lockedWindowBlockColors": segment_by_id[1].get("windowBlockColors"), |
| | | "lockedShadowOpacity": segment_by_id[1].get("shadowOpacity"), |
| | | "lockedShadowRadius": segment_by_id[1].get("shadowRadius"), |
| | | "waterfallLeftBlankWidth": left_blank_width, |
| | |
| | | print(json.dumps(report, indent=2, ensure_ascii=False), file=sys.stderr) |
| | | sys.exit(1) |
| | | |
| | | def is_locked_fill(color): |
| | | return ( |
| | | color.get("blue", 0) >= 0.85 |
| | | and color.get("green", 0) >= 0.55 |
| | | and color.get("red", 1) <= 0.58 |
| | | and color.get("alpha", 0) >= 0.70 |
| | | ) |
| | | |
| | | def is_white(color): |
| | | return ( |
| | | color.get("red", 0) >= 0.94 |
| | | and color.get("green", 0) >= 0.94 |
| | | and color.get("blue", 0) >= 0.94 |
| | | and color.get("alpha", 0) >= 0.88 |
| | | ) |
| | | |
| | | root = report.get("rootView", {}) |
| | | segments = root.get("spaceLaneSegments", []) |
| | | segment_by_id = {segment.get("spaceID"): segment for segment in segments} |
| | |
| | | require(root.get("waterfallColumnCount") == 0, "root Waterfall must be empty") |
| | | require(root.get("spaceLaneLabels") == ["A1", "A2", "A3", "B1", "B2"], "Space Lane must stay global while empty Space is locked") |
| | | require("locked" in segment_by_id[3].get("visualStates", []), "empty locked Space must expose locked visual state") |
| | | require(segment_by_id[3].get("borderWidth", 0) >= 5.5, "empty locked Space must still use a heavy locked border") |
| | | require(segment_by_id[3].get("borderWidth", 99) <= 2.0, "empty locked Space must not use the old heavy border") |
| | | require(segment_by_id[3].get("backgroundKind") == "solid", "empty locked Space must use the same light-blue fill") |
| | | require(is_locked_fill(segment_by_id[3].get("backgroundColor", {})), "empty locked Space fill must be clean light blue") |
| | | require(is_white(segment_by_id[3].get("labelColor", {})), "empty locked Space label text must be pure white") |
| | | require(is_white(segment_by_id[3].get("countColor", {})), "empty locked Space count text must be pure white") |
| | | require(is_white(segment_by_id[3].get("appColor", {})), "empty locked Space app text must be pure white") |
| | | empty_shadow = segment_by_id[3].get("shadowColor", {}) |
| | | require(empty_shadow.get("red", 0) >= 0.90 and empty_shadow.get("green", 0) >= 0.90 and empty_shadow.get("blue", 0) >= 0.90, "empty locked Space must use white glow") |
| | | require(segment_by_id[3].get("shadowOpacity", 0) >= 0.60, "empty locked Space glow must be visible") |
| | | require(segment_by_id[3].get("backgroundKind") == "clear", "empty locked Space must not use gray/gradient fill") |
| | | require(segment_by_id[4].get("backgroundKind") == "clear", "empty sibling Space must not inherit gray/gradient fill") |
| | | |
| | | print(json.dumps({ |
| | |
| | | "lockedSpace": report.get("spaceFilterLockedSpaceID"), |
| | | "appCount": report.get("appCount"), |
| | | "columnCount": report.get("columnCount"), |
| | | "a3BorderWidth": segment_by_id[3].get("borderWidth"), |
| | | "a3BackgroundColor": segment_by_id[3].get("backgroundColor"), |
| | | "a3LabelColor": segment_by_id[3].get("labelColor"), |
| | | "a3BackgroundKind": segment_by_id[3].get("backgroundKind"), |
| | | "b1BackgroundKind": segment_by_id[4].get("backgroundKind") |
| | | }, indent=2, ensure_ascii=False)) |
| | |
| | | |
| | | print(json.dumps({ |
| | | "case": "locked-space-double-click", |
| | | "quickSwitchVisible": report.get("quickSwitchVisible"), |
| | | "lastSpaceFilterAction": report.get("lastSpaceFilterAction"), |
| | | "lastSpaceActivationSpaceID": report.get("lastSpaceActivationSpaceID"), |
| | | "lastSpaceActivationDisplayIdentifier": report.get("lastSpaceActivationDisplayIdentifier") |
| | | }, indent=2, ensure_ascii=False)) |
| | | PY |
| | | } |
| | | |
| | | assert_direct_space_double_click_report() { |
| | | /usr/bin/python3 - "$1" <<'PY' |
| | | import json |
| | | import sys |
| | | |
| | | path = sys.argv[1] |
| | | with open(path, "r", encoding="utf-8") as file: |
| | | report = json.load(file) |
| | | |
| | | def require(condition, message): |
| | | if not condition: |
| | | print(message, file=sys.stderr) |
| | | print(json.dumps(report, indent=2, ensure_ascii=False), file=sys.stderr) |
| | | sys.exit(1) |
| | | |
| | | root = report.get("rootView", {}) |
| | | |
| | | require(report.get("quickSwitchVisible") is False, "direct double-click Space must close Quick Switch") |
| | | require(report.get("spaceFilterActive") is False, "direct double-click Space must not leave filter active") |
| | | require(root.get("spaceFilterActive") is False, "root must show no filter after direct Space activation") |
| | | require(report.get("lastSpaceFilterAction") == "activateSpace", "direct double-click Space must record activateSpace") |
| | | require(report.get("lastCommittedWindowID") is None, "direct double-click Space must not commit a window") |
| | | require(report.get("lastActivationWindowID") is None, "direct double-click Space must not target a window") |
| | | require(report.get("lastActivationResult") is None, "direct double-click Space must not run window activation") |
| | | require(report.get("lastCommitSource") is None, "direct double-click Space must not have a commit source") |
| | | require(report.get("lastSpaceActivationSpaceID") == 1, "direct double-click A1 must request Space 1 activation") |
| | | require(report.get("lastSpaceActivationDidRequestFocus") is True, "debug Space activation must request focus") |
| | | require(report.get("lastSpaceActivationDisplayIdentifier") == "debug", "fixture must use debug Space activation service") |
| | | require(report.get("lastSpaceActivationError") is None, "debug Space activation must not fail") |
| | | require(root.get("lastMouseCommand") == "double-click-space:1", "last mouse command must be double-click-space:1") |
| | | |
| | | print(json.dumps({ |
| | | "case": "direct-space-double-click", |
| | | "quickSwitchVisible": report.get("quickSwitchVisible"), |
| | | "lastSpaceFilterAction": report.get("lastSpaceFilterAction"), |
| | | "lastSpaceActivationSpaceID": report.get("lastSpaceActivationSpaceID"), |
| | |
| | | FULLSCREEN_REPORT="$REPORT_PREFIX-fullscreen-report.json" |
| | | LOCK_THEN_FULLSCREEN_REPORT="$REPORT_PREFIX-lock-then-fullscreen-report.json" |
| | | LOCKED_DOUBLE_CLICK_REPORT="$REPORT_PREFIX-locked-double-click-report.json" |
| | | DIRECT_DOUBLE_CLICK_REPORT="$REPORT_PREFIX-direct-double-click-report.json" |
| | | |
| | | run_report "$LOCK_A1_REPORT" "click-space:1" "click-space:1" "visible" "lock" |
| | | assert_lock_a1_report "$LOCK_A1_REPORT" |
| | |
| | | run_report "$LOCKED_DOUBLE_CLICK_REPORT" "click-space:1,double-click-space:1" "double-click-space:1" "space-hidden" |
| | | assert_locked_space_double_click_report "$LOCKED_DOUBLE_CLICK_REPORT" |
| | | |
| | | run_report "$DIRECT_DOUBLE_CLICK_REPORT" "double-click-space:1" "double-click-space:1" "space-hidden" |
| | | assert_direct_space_double_click_report "$DIRECT_DOUBLE_CLICK_REPORT" |
| | | |
| | | trap - EXIT |
| | | cleanup |
| | | |