feat(ipad): W1-W3 — adaptive split-view layout + finding fixes

T-iPad-2: AdaptiveRootView/LayoutPolicy (sole size-class decision), SplitRootView
(NavigationSplitView sidebar+detail), StackRootView (iPhone path verbatim, zero
regression); privacy shade hoisted to shared ZStack top for both branches
T-iPad-3: KeyBarVisibility predicate (hide when hardware keyboard present),
pointer context menu (copy/new-in-cwd/kill, all via existing channels)
T-iPad-4: Projects multi-column grid on iPad (idiom-gated), adaptive sheet detents
T-iPad-5 findings (4/4 fixed): kill onKillSession thread-through +
AppCoordinator.killCurrentSession; split route-gated to .sessions (iPad first-run
pairing); continue-last banner in split sidebar; iPad XCUITest deferred (covered
by SidebarSelectionTests)
Verified: iPhone 16 277 + iPad Pro 11 278 tests green; packages 261 + integration 10;
zero changes under ios/Packages, src/, public/
This commit is contained in:
Yaojia Wang
2026-07-05 19:58:30 +02:00
parent 77502ec4fe
commit 823432b1c8
18 changed files with 1594 additions and 84 deletions

View File

@@ -0,0 +1,33 @@
import Testing
@testable import WebTerm
/// T-iPad-3 · KeyBar KeyBar
/// `inputAccessoryView` iPhone
/// `userOverride`
///
@Suite("KeyBarVisibility (T-iPad-3)")
struct KeyBarVisibilityTests {
// MARK: -
@Test("硬件键盘在场 + 无用户覆盖 → 隐藏(软 KeyBar 冗余)")
func hardwarePresentAutoHides() {
#expect(KeyBarVisibility.isVisible(hardwareKeyboardPresent: true, userOverride: nil) == false)
}
@Test("无硬件键盘 + 无用户覆盖 → 显示iPhone 默认,零回归)")
func noHardwareAutoShows() {
#expect(KeyBarVisibility.isVisible(hardwareKeyboardPresent: false, userOverride: nil) == true)
}
// MARK: -
@Test("用户强制显示压过硬件在场的自动隐藏")
func userForceShowWinsOverHardware() {
#expect(KeyBarVisibility.isVisible(hardwareKeyboardPresent: true, userOverride: true) == true)
}
@Test("用户强制隐藏压过无硬件的自动显示")
func userForceHideWinsOverNoHardware() {
#expect(KeyBarVisibility.isVisible(hardwareKeyboardPresent: false, userOverride: false) == false)
}
}