Files
saphid--frame-control/ios/FrameControl/App/FrameControlApp.swift
T
saphidandClaude Opus 5.5 fe87a9d826 Keep the page clear of iOS safe areas everywhere; research typing, pointing and mirroring into the Frame
- Header, content, tab bar, status strip, drawer and toasts add the notch,
  Dynamic Island, rounded-corner and home-indicator insets on every side
  (zero on desktops). Phones on their side use the bottom tab bar layout.
- The phone tab bar hides while a text field has focus, instead of riding
  on the keyboard.
- DEBUG hook FRAME_TEST_LANDSCAPE for checking this in the Simulator.
- docs/streaming.md: iPhone mirroring (UxPlay, broadcast extension) and
  keyboard/mouse input (uinput needs no sudo on the Frame, verified).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-27 21:26:32 +10:00

45 lines
2.2 KiB
Swift

import SwiftUI
@main
struct FrameControlApp: App {
@StateObject private var model = AppModel()
@Environment(\.scenePhase) private var scenePhase
var body: some Scene {
WindowGroup {
RootView(model: model)
.task {
#if DEBUG
// Simulator testing without the pairing screen: print this device's key,
// and connect to FRAME_TEST_HOST with it (`simctl launch` passes
// SIMCTL_CHILD_FRAME_TEST_HOST through as FRAME_TEST_HOST).
print("FRAME_CONTROL_KEY: \(model.authorizedKeysLine)")
// FRAME_TEST_LANDSCAPE=1 turns the app on its side, to check the safe areas there.
if ProcessInfo.processInfo.environment["FRAME_TEST_LANDSCAPE"] != nil,
let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
scene.requestGeometryUpdate(.iOS(interfaceOrientations: .landscapeRight))
}
// FRAME_TEST_PAIR="host|user|password" runs the real password pairing.
if model.settings == nil, let pair = ProcessInfo.processInfo.environment["FRAME_TEST_PAIR"] {
let f = pair.components(separatedBy: "|")
if f.count == 3 { await model.pair(host: f[0], user: f[1], password: f[2]); return }
}
if model.settings == nil, let host = ProcessInfo.processInfo.environment["FRAME_TEST_HOST"] {
await model.useKey(host: host, user: "steamos")
return
}
#endif
if model.settings != nil { await model.connect() }
}
.onOpenURL { url in
// frame-control://install?… from a website (docs/web-install.md).
guard let link = InstallLink(url.absoluteString), model.pendingInstallLinks.count < 5 else { return }
model.pendingInstallLinks.append(link)
}
.onChange(of: scenePhase) { _, phase in
if phase == .active { model.resume() }
}
}
}
}