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:
22
ios/App/WebTerm/Wiring/LayoutMode.swift
Normal file
22
ios/App/WebTerm/Wiring/LayoutMode.swift
Normal file
@@ -0,0 +1,22 @@
|
||||
import SwiftUI
|
||||
|
||||
/// T-iPad-2 · 自适应根视图的布局模式。
|
||||
public enum LayoutMode: Equatable {
|
||||
/// 现有 iPhone 路径:`NavigationStack`(列表 → push 终端)。
|
||||
case stack
|
||||
/// iPad 分栏:`NavigationSplitView`(sidebar 会话列表 + detail 终端)。
|
||||
case split
|
||||
}
|
||||
|
||||
/// T-iPad-2 · **唯一** size-class 决策点(仿 `PrivacyShadePolicy` 的纯谓词
|
||||
/// 先例)。视图内严禁散落 `if sizeClass == …`(PLAN_IOS_IPAD §4)—— 所有
|
||||
/// 分支只从这里读一次,故可 100% 单测。
|
||||
///
|
||||
/// regular 宽度(iPad 全屏 / 大分屏 / Stage Manager 大窗)→ `.split`;
|
||||
/// compact 或 nil(iPhone / iPad Slide Over / 小分屏 / size class 未定)→
|
||||
/// `.stack`。nil 走最保守回退:退到现有已测的 iPhone 路径,绝不误判成分栏。
|
||||
public enum LayoutPolicy {
|
||||
public static func mode(horizontalSizeClass: UserInterfaceSizeClass?) -> LayoutMode {
|
||||
horizontalSizeClass == .regular ? .split : .stack
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user