renderer: a frame the embedder presents itself wakes no main-thread present (sync line)

Merged
LA
17h ago
+268-7

Summary

  • The same change as #75 (into release/cmux-9ce9b7d0-e2), cherry-picked with -x onto release/cmux-sync-20261104 (the upstream-sync line that cmux PR manaflow-ai/cmux#35478 pins). The ghostty-next pin carries the change whichever cmux PR moves it first.
  • With GHOSTTY_HOST_PRESENT_EMBEDDER, a frame of the host size kept for the embedder's present, which the layer cannot show in its bounds now, goes to no main-queue block (setSurfaceCallback dropped it there). The skip is decided under the Core Animation lock and then fresh.mutex, only while the kept frame is still that frame (Metal.embedderShowsKeptFrame). All other frames still go through main. See #75 for the full description, the kept-frame rule after a host change, and the four Codex rounds.
  • The cherry-picks applied with no conflict. IOSurfaceLayer.zig is the same file on both lines; Metal.zig, ghostty.h and NEXT.md differ only outside the changed parts.

Testing

Observed / Not run

  • Observed: the run above; zig fmt --check and zig ast-check with Zig 0.17.0.
  • Not run: the cmux side (see #75).

Changelog

none


Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Cherry-picks #75 onto release/cmux-sync-20261104 so the ghostty-next pin carries the fix whichever cmux PR moves it first. When GHOSTTY_HOST_PRESENT_EMBEDDER is on, a frame of the host size kept for the embedder's present no longer wakes the main thread: setSurfaceCallback previously dropped it after dispatching to the main queue.

  • The skip is decided under the Core Animation lock then fresh.mutex, and only while the kept frame is still that frame; a host change drops it, so a skipped frame never shows for a later equal size (A->B->A).
  • All other frames — first frames, frames at the shown size, frames for bounds the embedder already set, frames of a size the host no longer has — still go through main.