From b6e11990cc9bd3c838ad6cdd9e53caafff0fd7cb Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Thu, 18 Jun 2026 23:24:21 +0800
Subject: [PATCH] Add vertical App Shelf keyboard focus

---
 C3.tools/round1-app-column-alignment-fixture-qa.sh |   55 +++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 39 insertions(+), 16 deletions(-)

diff --git a/C3.tools/round1-app-column-alignment-fixture-qa.sh b/C3.tools/round1-app-column-alignment-fixture-qa.sh
index 5e63221..73a3bd5 100755
--- a/C3.tools/round1-app-column-alignment-fixture-qa.sh
+++ b/C3.tools/round1-app-column-alignment-fixture-qa.sh
@@ -58,19 +58,40 @@
   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() {
@@ -196,12 +217,14 @@
 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}")
@@ -268,7 +291,7 @@
     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"
@@ -308,8 +331,8 @@
 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

--
Gitblit v1.9.3