Tahoe 26 Liquid Glass integration: theme picker hooks, layer-background mode, focus-report leak fix#40
Conversation
When enabled, the renderer sets bg_color alpha to 0 so the host app can provide the terminal background via CALayer.backgroundColor. This allows instant coverage during view resizes without alpha double-stacking between the GPU bg pass and the layer background.
In addition to zeroing bg_color alpha (needed for cell compositing), explicitly skip the fullscreen background fill draw step. This avoids relying on alpha=0 as a no-op for the draw pass and makes the intent explicit.
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 59 minutes and 34 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR updates Ghostty to better support macOS 26 “Liquid Glass” embedding needs and fixes a focus-reporting leak by aligning behavior with xterm focus reporting semantics.
Changes:
- Stop emitting an immediate focus sequence when DECSET 1004 (focus reporting) is enabled, and add a regression test.
- Add
macos-background-from-layerconfig and update the renderer to skip the fullscreen background fill when the host supplies background via CALayer. - Introduce an “initial focused state” plumbed through the embedded runtime/C API and macOS Swift surface configuration, and seed terminal focus state during surface init.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/termio/stream_handler.zig | Avoid immediate focus report on enabling focus mode; add test to prevent regressions. |
| src/renderer/generic.zig | Add derived config flag and skip fullscreen background fill in layer-background mode; adjust bg alpha behavior on macOS. |
| src/config/Config.zig | Add macos-background-from-layer configuration flag and documentation. |
| src/apprt/embedded.zig | Add focus state to embedded Surface + Options and expose it for initial seeding/inheritance. |
| src/Surface.zig | Read initial focus state from runtime surface and seed terminal/render-thread focus flags. |
| macos/Sources/Ghostty/Surface View/SurfaceView.swift | Plumb initial focus through Swift configuration into the C surface config. |
| include/ghostty.h | Extend ghostty_surface_config_s with a focused field. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| render_thread.flags.focused = initial_focused; | ||
|
|
There was a problem hiding this comment.
render_thread.flags.focused is seeded from initial_focused, but the renderer implementation itself is still initialized with focused = true (see renderer/generic.zig). If initial_focused is ever false, the renderer thread will later process the first .focus = true message and call renderer.setFocus(true), which currently asserts because the renderer already thinks it is focused. This also means an initially-unfocused surface would render with focused cursor/state until a focus transition occurs.
To fix this, ensure the renderer thread applies the initial focus state to the renderer before the event loop starts (and before starting cursor blink), e.g. on thread startup call renderer.setFocus(false) when flags.focused is false, or otherwise synchronize renderer focus with initial_focused without relying on a subsequent focus transition.
Greptile SummaryThis PR wires up three features for the cmux/Liquid Glass integration: cmux theme-picker hooks (manual IO mode + write callback), a
Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Host as Host (cmux/SwiftUI)
participant Embedded as embedded.zig Surface
participant Core as Surface.zig (Core)
participant IO as termio / IO thread
participant Terminal as terminal.flags
Host->>Embedded: "ghostty_surface_new(config{focused=true})"
Embedded->>Embedded: "Surface.init(opts{focused=true})"
Embedded->>Core: CoreSurface.init()
Core->>Core: "initial_focused = rt_surface.initialFocused() → true"
Core->>IO: "render_thread.flags.focused = true"
Core->>Terminal: "terminal.flags.focused = true (seeded before IO starts)"
Note over Terminal: DECSET 1004 can now be set without<br/>emitting a spurious CSI I/O
Core->>IO: io_thread.start()
IO-->>Terminal: App enables DECSET 1004 (.focus_event)
Note over IO,Terminal: setMode(.focus_event) — no synthetic report emitted<br/>(fix for issue #2446)
Host->>Embedded: ghostty_surface_set_focus(surface, false)
Embedded->>Core: focusCallback(false)
Core->>Terminal: "focused = false"
Core->>IO: "sends .focus = false message"
IO-->>Host: CSI O (focus-out) emitted only here
|
DECSET 2031 (ColorPaletteUpdates) should notify applications only when the color scheme changes, not immediately on enable. The unsolicited initial report leaks into applications that enable the mode without arranging to consume a response, surfacing as literal `?997;1n` text in the shell input buffer. Mirrors the fix applied to DECSET 1004 focus reporting in manaflow-ai#40. Fixes manaflow-ai/cmux#2636
Companion to cmux #2647 (Adopt macOS 26 Liquid Glass design) and cmux #2646 (sidebar sections). Both cmux PRs pin to this ghostty SHA; merging here lets them bump pointer back to manaflow-ai/ghostty#main.
Summary
Three logical groups, combined into one PR because cmux tests them together:
cmux theme picker integration
macos-background-from-layer config (needed for Liquid Glass translucent backgrounds)
macos-background-from-layerconfig flagFocus-report leak fix (ghostty-org/ghostty ghostty-org#2446)
Test plan
zig buildcleanmacos-background-from-layer = true, Ghostty skips the fullscreen background draw — required for the SwiftUI.glassmaterial in cmux Liquid Glass mode to show throughSummary by cubic
Adds macOS layer-provided background support for Tahoe 26 Liquid Glass, integrates
cmuxtheme picker hooks, and fixes a startup focus-report leak. The renderer can now skip its fullscreen background pass on macOS, and surfaces seed initial focus so DECSET 1004 doesn't emit at startup.New Features
macos-background-from-layer(macOS): lets the host CALayer provide the background; renderer zeros bg alpha and skips the fullscreen fill. Enables Liquid Glass behavior.cmux: picker renderscmuxtheme data with safe preview writes, startup parity, and system theme respect.Bug Fixes
focusedstate and seed the terminal before IO. Enabling DECSET 1004 no longer sends an immediate focus sequence.Written for commit 9fa3ab0. Summary will update on new commits.