Files
terminalX/vendor/libghostty-spm/docs/guide/uikit-appkit.html
kid aa92d0e676 初始提交:terminalX 可运行态(M0/M1/M1.5 已真机验证)
- M0: libghostty SSH 终端(渲染/输入/连接)+ 白屏修复(OutputGate) + 会话状态机/自动重连
- M1: tsnet 用户态组网 + SSH-over-tsnet(fd 桥),shell 级真机验证;R5(Go+gvisor+C+++Swift 同进程) retire
- M1.5: tmux -CC 原生 tab(MVP)
- 结构: packages/(TXCore·TXTransport), apps/TerminalX, vendor/(libghostty-spm/libssh2/mbedtls/tsnet-bridge), artifacts/
- 文档: CLAUDE.md + docs/HANDOFF.md(新会话入口)
- 环境: 认证代理→依赖 vendor 本地化;Go 在 ~/.local/go;仅模拟器/未签名
- 待续: M2 mosh, tmux 多 pane, M4 安全(host key/SE)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 10:20:46 +08:00

125 lines
4.9 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light dark">
<title>GhosttyKit · UIKit &amp; AppKit</title>
<link rel="stylesheet" href="../styles.css">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/github.min.css"
integrity="sha384-eFTL69TLRZTkNfYZOLM+G04821K1qZao/4QLJbet1pP4tcF+fdXq/9CdqAbWRl/L"
crossorigin="anonymous"
media="(prefers-color-scheme: light)">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/github-dark.min.css"
integrity="sha384-wH75j6z1lH97ZOpMOInqhgKzFkAInZPPSPlZpYKYTOqsaizPvhQZmAtLcPKXpLyH"
crossorigin="anonymous"
media="(prefers-color-scheme: dark)">
</head>
<body>
<nav class="topbar" aria-label="Primary">
<a class="home" href="../index.html">GhosttyKit</a>
<a href="../index.html">Overview</a>
<a href="index.html" aria-current="page">Guide</a>
<a href="../api/index.html">API</a>
<a href="../architecture.html">Architecture</a>
<a href="../build.html">Build</a>
</nav>
<main>
<h1>UIKit &amp; AppKit</h1>
<nav class="on-this-page" aria-label="On this page">
<strong>On this page:</strong>
<a href="#view">View</a>
<a href="#delegate">Delegate</a>
<a href="#ios-input">iOS input</a>
</nav>
<p><code>TerminalView</code> resolves to <code>UITerminalView</code> on UIKit and <code>AppTerminalView</code> on AppKit. Catalyst follows UIKit.</p>
<h2 id="view">View setup</h2>
<pre><code class="language-swift">import GhosttyTerminal
let terminalView = TerminalView(frame: .zero)
let controller = TerminalController(configuration: .default)
terminalView.controller = controller
terminalView.configuration = TerminalSurfaceOptions(
backend: .inMemory(session)
)
terminalView.delegate = coordinator
</code></pre>
<p>The view owns the native input layer and the Metal-backed surface. <code>TerminalController</code> owns Ghostty app lifecycle, configuration resolution, themes, and surface creation.</p>
<h2 id="delegate">Delegate callbacks</h2>
<p>Adopt the delegate protocols that match your host UI. A single coordinator object can implement multiple protocols.</p>
<pre><code class="language-swift">final class Coordinator:
TerminalSurfaceTitleDelegate,
TerminalSurfaceGridResizeDelegate,
TerminalSurfaceBellDelegate,
TerminalSurfaceLifecycleDelegate
{
func terminalDidChangeTitle(_ title: String) {}
func terminalDidResize(_ size: TerminalGridMetrics) {}
func terminalDidRingBell() {}
func terminalDidAttachSurface(_ surface: TerminalSurface) {}
func terminalDidDetachSurface() {}
}
</code></pre>
<h2 id="ios-input">iOS input</h2>
<p><code>UITerminalView</code> conforms to <code>UITextInput</code>. Hardware keys enter through <code>pressesBegan</code>, software keyboard text enters through <code>insertText</code>, and marked text flows through the shared IME handler.</p>
<p>On iOS, the input accessory bar provides Esc, Tab, arrows, symbols, Paste, and sticky Ctrl/Alt/Cmd modifiers. Configure colors through <code>inputAccessoryStyle</code>.</p>
<pre><code class="language-swift">#if canImport(UIKit)
terminalView.inputAccessoryStyle = .init(
regularBackground: .secondarySystemBackground,
regularForeground: .label,
activeBackground: .label,
activeForeground: .systemBackground
)
#endif
</code></pre>
<p>Hosts with a custom keyboard bar can hide the bundled accessory and drive sticky modifiers through the public sticky APIs.</p>
<pre><code class="language-swift">#if canImport(UIKit)
terminalView.inputAccessoryItems = []
#endif
</code></pre>
<p>The default button list is available as <code>TerminalInputAccessoryItem.defaultItems</code>. Hosts can provide a smaller list while keeping the bundled bar styling and key dispatch behavior.</p>
<pre><code class="language-swift">#if canImport(UIKit)
terminalView.inputAccessoryItems = [
.esc,
.ctrl,
.alt,
.command,
.divider,
.tab,
.arrowLeft,
.arrowRight,
.paste,
]
#endif
</code></pre>
<nav class="pager" aria-label="Sibling pages">
<a class="prev" href="swiftui.html">SwiftUI</a>
<a class="parent" href="index.html">↑ Guide</a>
<a class="next" href="in-memory.html">Host-managed I/O</a>
</nav>
<footer>
GhosttyKit · <a href="https://github.com/Lakr233/libghostty-spm">github.com/Lakr233/libghostty-spm</a>
</footer>
</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/highlight.min.js"
integrity="sha384-GdEWAbCjn+ghjX0gLx7/N1hyTVmPAjdC2OvoAA0RyNcAOhqwtT8qnbCxWle2+uJX"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/languages/swift.min.js"
integrity="sha384-TfALNLT6HJzZieazgsVvFM0DzFWQsgl0d7mdwPLyg1yg7XE4QwLY4jqmJRNnI1S4"
crossorigin="anonymous"></script>
<script>hljs.highlightAll();</script>
</body>
</html>