| | |
| | | |
| | | aligner_pids_for_current_app() { |
| | | ps -axo pid=,args= | while read -r pid command; do |
| | | case "$command" in |
| | | "$APP/Contents/MacOS/Aligner"*) echo "$pid" ;; |
| | | esac |
| | | if [[ "$command" == "$APP/Contents/MacOS/Aligner"* ]] \ |
| | | || [[ "$command" == "/Applications/Aligner.app/Contents/MacOS/Aligner"* ]] \ |
| | | || [[ "$command" == "$HOME/Applications/Aligner.app/Contents/MacOS/Aligner"* ]]; then |
| | | echo "$pid" |
| | | fi |
| | | done |
| | | } |
| | | |
| | |
| | | stop_current_aligner |
| | | } |
| | | |
| | | keyboard_right_sequence() { |
| | | keyboard_index_sequence() { |
| | | local target_index="$1" |
| | | local sequence="" |
| | | local symbols="1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| | | |
| | | for ((index = 0; index < target_index; index++)); do |
| | | if [ -n "$sequence" ]; then |
| | | sequence="$sequence,right" |
| | | if [ "$target_index" -ge "${#symbols}" ]; then |
| | | fail "keyboard index sequence does not support target index $target_index" |
| | | fi |
| | | |
| | | echo "${symbols:$target_index:1}" |
| | | } |
| | | |
| | | normalize_keyboard_sequence() { |
| | | local sequence="$1" |
| | | local symbols="1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| | | local normalized="" |
| | | local IFS=, |
| | | |
| | | for raw_part in $sequence; do |
| | | local part |
| | | part="$(printf "%s" "$raw_part" | tr '[:lower:]' '[:upper:]')" |
| | | if [ "${#part}" -eq 1 ] && [[ "$symbols" == *"$part"* ]]; then |
| | | part="app:$part" |
| | | else |
| | | sequence="right" |
| | | part="$raw_part" |
| | | fi |
| | | |
| | | if [ -n "$normalized" ]; then |
| | | normalized="$normalized,$part" |
| | | else |
| | | normalized="$part" |
| | | fi |
| | | done |
| | | |
| | | echo "$sequence" |
| | | echo "$normalized" |
| | | } |
| | | |
| | | wait_for_report() { |
| | |
| | | elif mode == "keyboard": |
| | | require(root.get("keyboardCommandsApplied") == expected_key_sequence, "debug key sequence must be applied in order") |
| | | require(root.get("lastKeyboardCommand") == expected_key_sequence[-1], "last keyboard command must match the alignment target") |
| | | require(root.get("selectedAppGroupIndex") == target_app_index, "keyboard focus must select the target appGroupIndex") |
| | | require(item.get("isSelected") is True, "target App Shelf item must expose selected state") |
| | | require("selectedVisualSuppressed" in item.get("visualStates", []), "non-hovered keyboard-selected App Shelf item must suppress selected visual state") |
| | | cards = column.get("cards", []) |
| | | require(cards, "target Waterfall column must include cards") |
| | | require(root.get("selectedWindowID") == cards[0].get("windowID"), "right-arrow focus into target column must select its first window") |
| | | require(root.get("keyboardFocusedAppGroupIndex") == target_app_index, "keyboard App focus must target the requested App") |
| | | require(root.get("hoveredAppGroupIndex") == target_app_index, "keyboard App focus must become hovered appGroupIndex") |
| | | require(root.get("hoverTargetKind") == "app", "keyboard App focus must expose an App hover target") |
| | | require(root.get("hoverTargetSource") == "keyboard", "keyboard App focus must be reported as keyboard sourced") |
| | | require(item.get("isHovered") is True, "target App Shelf item must expose hover state") |
| | | require("hover" in item.get("visualStates", []), "target App Shelf item must expose hover visual state") |
| | | require(item.get("isSelected") is False, "keyboard App focus must not immediately move selected window") |
| | | require(root.get("selectionChangedByLastCommand") is False, "keyboard App focus must not change selected window") |
| | | require(root.get("lastCommittedWindowID") is None, "keyboard alignment without Enter must not commit a window") |
| | | else: |
| | | require(False, f"unknown alignment mode {mode!r}") |
| | |
| | | local args=( |
| | | --round0-skip-permissions |
| | | --round01-open-quick-switch |
| | | --round01-waterfall-view-mode=vertical |
| | | --round01-fixture-app-count="$app_count" |
| | | --round01-fixture-windows-per-app="$windows_per_app" |
| | | --round01-debug-overlay-width="$overlay_width" |
| | |
| | | expected_mouse_sequence="$sequence" |
| | | args+=(--round01-debug-mouse-sequence="$sequence") |
| | | elif [ "$mode" = "keyboard" ]; then |
| | | expected_key_sequence="$sequence" |
| | | expected_key_sequence="$(normalize_keyboard_sequence "$sequence")" |
| | | args+=(--round01-debug-key-sequence="$sequence") |
| | | else |
| | | fail "unknown fixture mode: $mode" |
| | |
| | | REGULAR_RIGHT_INDEX=$((FIXTURE_APP_COUNT - 1)) |
| | | NARROW_MIDDLE_INDEX=$((NARROW_FIXTURE_APP_COUNT / 2)) |
| | | NARROW_RIGHT_INDEX=$((NARROW_FIXTURE_APP_COUNT - 1)) |
| | | REGULAR_KEY_SEQUENCE="$(keyboard_right_sequence "$REGULAR_RIGHT_INDEX")" |
| | | NARROW_KEY_SEQUENCE="$(keyboard_right_sequence "$NARROW_RIGHT_INDEX")" |
| | | REGULAR_KEY_SEQUENCE="$(keyboard_index_sequence "$REGULAR_RIGHT_INDEX")" |
| | | NARROW_KEY_SEQUENCE="$(keyboard_index_sequence "$NARROW_RIGHT_INDEX")" |
| | | |
| | | trap cleanup EXIT |
| | | stop_current_aligner |