summaryrefslogtreecommitdiff
path: root/docs/macos.md
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-06 18:11:36 -0300
committerGabriel Schneider <[email protected]>2026-09-07 13:59:12 -0300
commit60367d8fe23f6af98ec28e3cf6c2094dfe332df0 (patch)
tree310fc734173cf771881f4691c71909135fadde97 /docs/macos.md
parentfa82cac885cb4738fe36d1e49b4749b5a3e31a4a (diff)
downloadpardes-60367d8fe23f6af98ec28e3cf6c2094dfe332df0.tar.gz
pardes-60367d8fe23f6af98ec28e3cf6c2094dfe332df0.zip
Refactor panes and filesystem; replace FUSE with 9P
Consolidate pane, layout, memory and host code. Serve 9P by default over Unix sockets, with runtime mounts and optional TCP/QUIC transports. Remove FUSE and obsolete proof-of-concept examples. Fix highlighting and terminal-history performance, expand differential and stress-test infrastructure, sort navigation results while preserving the next occurrence, add syntax-colored Braille minimaps, remove SPC-k, and document 9P interaction as a repository skill.
Diffstat (limited to 'docs/macos.md')
-rw-r--r--docs/macos.md78
1 files changed, 17 insertions, 61 deletions
diff --git a/docs/macos.md b/docs/macos.md
index 0ce29bf9..2d9fb1cc 100644
--- a/docs/macos.md
+++ b/docs/macos.md
@@ -430,59 +430,17 @@ without a Force Touch trackpad and when the user has feedback switched off, so a
check here would only be a second place to be wrong — and it would be wrong the
moment an external trackpad is plugged in mid-session.
-## libproc, twice
+## Shell directories and nested Look
-Two features on this backend want to know something about a process that is not
-us, and on Linux both answers live in `/proc`. Darwin's equivalent is libproc,
-and it answers both.
+`host_io.shellCwd` reads a shell's working directory using
+`proc_pidinfo(PROC_PIDVNODEPATHINFO)`; Linux uses `/proc/<pid>/cwd`.
+The macOS host refreshes directories for panes that produced output, so idle
+frames do not poll every shell. `test/macos-snapshots/cwd.snap` covers the tag
+after `cd` and after an idle tick.
-**A pane's cwd** (`look.shellCwd`) is `readlink("/proc/<pid>/cwd")` there and
-`proc_pidinfo(PROC_PIDVNODEPATHINFO)` here. The tag shows it and a relative
-`Look` resolves against it, so it has to follow the shell rather than stay
-where the pane was spawned.
-
-*When* it is read differs from the other three shells, and deliberately. The
-tty, SDL and detached-daemon hosts poll every pane every frame — inline in the
-tty loop's frame path (`src/tty/tty.zig:1228-1231`), `pollCwds` in the SDL
-shell (`src/gui/gui.zig:4048`) and `pollFrame` in the daemon
-(`src/detached/server.zig:889`); here the drain has just finished
-saying exactly which shells produced bytes, and nothing else can have moved
-one — a `cd` is a command, and a shell that ran a command writes at least its
-next prompt. So `refreshCwds` reads only for panes flagged by that tick's
-output and an idle session costs no syscalls at all. `test/macos-snapshots/
-cwd.snap` holds the gating to it: the tag must be right after a `cd` and must
-survive a tick with nothing in it.
-
-**A pardes inside a pardes** (`src/nested.zig`) walks the ancestor chain
-looking for our own executable, and hands the file over rather than stacking a
-second full-screen UI inside a pane. `readlink("/proc/<pid>/exe")` becomes
-`proc_pidpath`, and the `PPid:` line of `/proc/<pid>/status` becomes
-`proc_bsdinfo.pbi_ppid`. That struct is hand-written, which is a thing to get
-silently wrong: a field ordering that puts something else where `ppid` should
-be still returns a plausible number, so a unit test compares `parentOf(getpid())`
-against `getppid()`.
-
-The socket half needed real portability work rather than a second spelling.
-Darwin has no `SOCK_CLOEXEC` and no `accept4`, so the flag is set with an
-`fcntl` after the fact — a race only against a fork on another thread, and
-every caller is past that (`src/nested.zig:81-93` names all three).
-`sun_path` is 104 bytes here against 108 there, so no
-buffer in the file spells a number any more; they are all sized from the field
-itself, and an address that does not fit is refused rather than truncated into
-a path pointing somewhere else.
-
-Identity gained a third sibling. `bin/pardes`, `bin/pardes-gui` and
-`pardes.app/Contents/MacOS/pardes` are three installed frontends of one
-program, so `samePardesExecutable` (`src/nested.zig:142`) compares BASENAMES
-and ignores the paths entirely — the GUI may be system-wide while the tty
-frontend sits in the user's own bin directory. `familyTail` strips a leading
-`pardes-gui` or `pardes` and requires what is left to be either empty or a
-valid `-os-arch` pair, which is what keeps `pardes-snap` and `pardes-perf` out
-of the family; `sameFamily` then accepts two names whose tails agree, or either
-of which has no tail at all. The bundle's copy always has none, because
-`CFBundleExecutable` is a fixed string: the bundled `pardes-macos-aarch64` is
-called `pardes` and nothing in the name records what it was. So `pardes
-src/foo.zig` inside the app's own shell opens a pane in the app.
+Nested launches use the same inherited 9P address and pane serial as other
+native hosts. They do not inspect ancestor processes or executable names.
+See [the control filesystem](fs.md) for paths and transports.
## Fonts and zoom
@@ -672,8 +630,7 @@ stacked filters. Their canonical macOS source is `shaders/crt.ci.metal`, which
the build installs as `pardes.app/Contents/Resources/crt.ci.metal`. The Swift
shell loads that exact asset with `CIKernel.kernels(withMetalString:)` and runs
it through a `CIContext` created from the system Metal device. The source is
-also a Zig build import, so `EffectCode` can print what the app executes when
-the source checkout is absent.
+also archived by the Zig build; `EffectCode` links to it without a checkout.
The ordinary CoreText/attachment/cursor pass is one function. With any scene
bit or panel track it targets a retained, backing-scale bitmap; kernels then
@@ -726,8 +683,8 @@ panes move and dissolve together. Scene CRT/ripple/glitch runs once after the
panel composition.
With no scene bit and no panel track the retained bitmap, Core Image context,
-and Metal passes are bypassed. `EffectCode Panel*` embeds this actual Metal
-file plus its direct Swift owner, the same files the app executes.
+and Metal passes are bypassed. `EffectCode Panel*` links to this Metal
+file and its Swift owner in the virtual filesystem.
### Transparent themes
@@ -870,7 +827,7 @@ already do (`install_app_bin`, `install_plist`, `install_scene_kernel`,
`CIKernel.kernels(withMetalString:)`. The same file is also an anonymous
module import named `effect-source-crt.ci.metal`, added by `build.zig`'s
per-shell module wiring under `if (shell == .macos)`, which is what lets
- `EffectCode` print the exact source the app executes.
+ `EffectCode` link to the exact source the app executes.
Its three entry points are `extern "C" [[stitchable]]`: the runtime compiler
looks for stitchable functions and rejects the WHOLE source with "cannot find
a valid stitchable Metal function in the source" when there are none, which
@@ -981,12 +938,11 @@ prohibited) `NSWindow`, over a real core with real ptys:
```sh
zig build macos-e2e -Dplatform=macos # run it
zig build macos-e2e -Dplatform=macos -- --update # regenerate the goldens
+zig build macos-e2e -Dplatform=macos -- test/macos-snapshots/rotate.snap
```
-The step always hands the harness the whole `test/macos-snapshots` directory,
-so naming one script after `--` runs it IN ADDITION to the suite rather than
-instead of it. To run a single script, invoke
-`zig-out/bin/pardes-macos-e2e test/macos-snapshots/rotate.snap` directly.
+With no paths, the harness runs `test/macos-snapshots`. Paths after `--`
+select scripts or directories instead. The executable stays in the build cache.
`test/macos_e2e.swift` links the same Swift sources the app does, minus
`main.swift`, into a second binary — test scaffolding does not ship inside the
@@ -1098,7 +1054,7 @@ used for the table and is not folded into the direct-path claim.
- **Detached sessions.** `Attach` (`SPC s a`) and `Detach` (`SPC s D`) exist on
every hosted platform, this one included, because `Builtin.enabled` is
`pardes.hosted`. Neither works here. `Detach` emits `Effect.detach`, this
- host fills in no `push_detach`, and `Pardes.perform` therefore reports
+ host fills in no `detach`, and `Pardes.perform` therefore reports
`error.NotAttached` on the pane's message row (`src/pardes.zig:6837`).
`Attach` emits `Effect.attach`, which `perform` turns into an `attach_req`
the shell is supposed to consume from OUTSIDE `pump` with `takeAttach` — and