summaryrefslogtreecommitdiff
path: root/docs/ghostty-macos-notes.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/ghostty-macos-notes.md')
-rw-r--r--docs/ghostty-macos-notes.md53
1 files changed, 32 insertions, 21 deletions
diff --git a/docs/ghostty-macos-notes.md b/docs/ghostty-macos-notes.md
index 556831af..3974d0d8 100644
--- a/docs/ghostty-macos-notes.md
+++ b/docs/ghostty-macos-notes.md
@@ -11,19 +11,22 @@ which records where pardes deliberately went the other way.
## The seam is small, and it is a hand-written C header
-`include/ghostty.h` is 1207 lines for an application of ghostty's size: about 90
-exported functions, four opaque handles (`typedef void* ghostty_app_t` and
-friends, `:56-60`), and one callback struct. Everything is a `void*` on the C
-side; the Zig `export fn` signatures carry the real types, so the compiler checks
-one end and the other is untyped by construction.
+`include/ghostty.h` is 1207 lines for an application of ghostty's size: exactly
+90 exported function declarations, four opaque handles (`typedef void*
+ghostty_app_t` and friends, `:57-60`), and one callback struct. Everything is a
+`void*` on the C side; the Zig `export fn` signatures carry the real types, so
+the compiler checks one end and the other is untyped by construction.
-The header is **not generated**. It is maintained by hand, with `IMPORTANT: Any
-changes here update include/ghostty.h` comments scattered through the Zig
-(`src/input/key.zig:83`, `src/apprt/action.zig:75`). What keeps it honest is a
-test: `build.zig:359-365` runs `addTranslateC` over the header and imports the
-result into the unit-test build, and `src/lib/enum.zig:91-141` walks every Zig
-enum asserting each tag equals the matching `GHOSTTY_*` constant, failing in both
-directions — a Zig tag with no C constant, and a C constant with no Zig tag.
+The header is **not generated**. It is maintained by hand, with reminders
+scattered through the Zig — an `IMPORTANT: Any changes here update
+include/ghostty.h` comment at `src/input/key.zig:83`, and a six-step checklist
+for adding an action whose fourth step is "Update `include/ghostty.h`"
+(`src/apprt/action.zig:69-78`). What keeps it honest is a
+test: ghostty's own `build.zig:359-365` runs `addTranslateC` over the header and
+imports the result into the unit-test build, and `src/lib/enum.zig:91-141`
+walks every Zig enum asserting each tag equals the matching `GHOSTTY_*`
+constant, failing in both directions — a Zig tag with no C constant, and a C
+constant with no Zig tag.
This is the single most transferable thing in the repository, it costs about ten
lines of build plumbing, and it runs on Linux. pardes now does the same thing in
@@ -32,8 +35,9 @@ well, because a hand-written header drifts in signatures too.
## Zig→host is one callback, not N
-`ghostty_runtime_config_s` (`include/ghostty.h:999-1027`) holds `userdata` and
-six function pointers: `wakeup`, `action`, `read_clipboard`,
+`ghostty_runtime_config_s` (`include/ghostty.h:1018-1027`) holds `userdata`,
+one capability bool (`supports_selection_clipboard`) and six function
+pointers: `wakeup`, `action`, `read_clipboard`,
`confirm_read_clipboard`, `write_clipboard`, `close_surface`. Only `wakeup` and
the clipboard ones are what they look like. Everything else the core wants from
the host — new window, set title, toggle fullscreen, desktop notification,
@@ -51,8 +55,9 @@ comptime {
The payoff is that adding a feature adds an enum case, not a struct field: hosts
that do not implement it return `false` and the ABI never changed. Worth copying
-the day a fixed callback list starts growing. pardes has two callbacks today and
-does not need it yet.
+the day a fixed callback list starts growing. pardes has three callbacks today
+— `wakeup`, `set_clipboard`, `read_clipboard` (`Runtime` in `src/macos.zig:153`)
+— and does not need it yet.
Two userdata scopes, worth noting: the runtime struct's `userdata` is
app-scoped, and each surface carries its own. Swift round-trips both with
@@ -64,7 +69,7 @@ lifetime stays entirely on the Swift side.
This is the surprising part and the main thing pardes did *not* copy.
Swift creates an `NSView`, gives it a non-zero frame, and passes the bare
-pointer through a tagged platform union (`include/ghostty.h:448-465`):
+pointer through a tagged platform union (`include/ghostty.h:448-460`):
```c
typedef struct { void* nsview; } ghostty_platform_macos_s;
@@ -168,10 +173,16 @@ routing shaders through Xcode build rules.
header-drift test — runs on Linux. `flake.nix:63-66` excludes Darwin from
buildable platforms entirely.
-pardes skips lipo, the xcframework, the Xcode project and codesigning. All four
-exist to ship a signed universal bundle to someone else's machine; a dev build
-needs a `swiftc` invocation and a directory with a plist in it. They are the
-named upgrade path in `docs/macos.md`, in that order.
+pardes skips lipo, the xcframework and the Xcode project. Those three exist to
+ship a universal bundle that something other than this app can link, and they
+are the named upgrade path in `docs/macos.md`, in that order. Codesigning is no
+longer on that list: the `codesign --force --sign` step in the macos branch of
+pardes's `build.zig` is reached by `b.getInstallStep().dependOn(&sign.step)`, so
+it runs as part of an ordinary `zig build -Dplatform=macos`, ad-hoc
+(`-`) by default because an unsigned arm64 bundle does not launch at all, and
+`-Dmacos-identity=` swaps in a Developer ID and adds `--options runtime
+--timestamp`. So a dev build here is a `swiftc` invocation, a directory with a
+plist in it, and one `codesign`.
## Small things worth remembering