Skip to content

Add ghostty_surface_foreground_pid C API for cmux#46

Open
tamekuniz wants to merge 1 commit into
manaflow-ai:mainfrom
tamekuniz:cmux-foreground-pid-api
Open

Add ghostty_surface_foreground_pid C API for cmux#46
tamekuniz wants to merge 1 commit into
manaflow-ai:mainfrom
tamekuniz:cmux-foreground-pid-api

Conversation

@tamekuniz
Copy link
Copy Markdown

@tamekuniz tamekuniz commented Apr 21, 2026

Summary

  • Adds ghostty_surface_foreground_pid() C API that exposes the foreground process group PID (as int32_t) of a surface's pty master.
  • Returns -1 when unavailable (no pty / tcgetpgrp failure / PID > INT32_MAX).
  • Backed by the existing Surface.getProcessInfo(.foreground_pid) path, which uses tcgetpgrp(master_fd) on macOS.

Motivation

cmux uses this to detect when a CLI tool (Claude Code / Codex / Gemini) is the foreground process of a pty so it can switch Enter-key semantics on a per-process basis (Enter=newline for CLI, Enter=submit otherwise).

Files

  • include/ghostty.h
  • src/apprt/embedded.zig

Follows the pattern of the existing cmux-specific exports (ghostty_surface_select_cursor_cell, ghostty_surface_clear_selection).

Test plan

  • zig build -Demit-xcframework=true -Dxcframework-target=universal -Doptimize=ReleaseFast succeeds
  • nm on the resulting libghostty.a shows T _ghostty_surface_foreground_pid
  • cmux Debug build links against the rebuilt xcframework and resolves the new symbol

🤖 Generated with Claude Code


Summary by cubic

Adds a C API ghostty_surface_foreground_pid() to fetch the foreground process group PID for a surface’s pty master. This enables cmux to switch Enter-key behavior when a CLI tool is in the foreground.

  • New Features
    • Returns int32_t PID; -1 if no pty, tcgetpgrp fails, or PID > INT32_MAX.
    • Uses Surface.getProcessInfo(.foreground_pid) under the hood (tcgetpgrp on macOS).

Written for commit 22ad48b. Summary will update on new commits.

Summary by CodeRabbit

  • New Features
    • Exposed a new API function to retrieve the process identifier of the foreground process running in a surface.

Exposes the foreground process group PID of a surface's pty master via
a new ghostty_surface_foreground_pid() C API. Returns the PID as int32_t,
or -1 when unavailable (no pty, tcgetpgrp failure, or PID > INT32_MAX).

Backed by the existing Surface.getProcessInfo(.foreground_pid) path,
which uses tcgetpgrp(master_fd) on macOS.

Used by cmux to detect when a CLI tool (Claude Code / Codex / Gemini)
is the foreground process so it can switch Enter-key semantics on a
per-process basis (cmux-specific).
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cd10d2a2-5b4c-449b-b0e7-1b08f70b3a4a

📥 Commits

Reviewing files that changed from the base of the PR and between 3b684a0 and 22ad48b.

📒 Files selected for processing (2)
  • include/ghostty.h
  • src/apprt/embedded.zig

📝 Walkthrough

Walkthrough

A new public C-ABI function is introduced to expose the foreground process ID of a Ghostty terminal surface. The function declaration is added to the public header file, and its implementation in the embedded runtime queries the process information from the surface core, returning the foreground PID or -1 on failure.

Changes

Cohort / File(s) Summary
Public API Addition
include/ghostty.h, src/apprt/embedded.zig
Added new exported function ghostty_surface_foreground_pid() that returns the foreground process ID as a signed 32-bit integer. Implementation queries surface core process info and handles null values and integer overflow by returning -1.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Poem

🐰 A surface now reveals its secrets deep,
The foreground PID for us to keep,
One little function, clean and bright,
Returns the process in the light! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a new C API function ghostty_surface_foreground_pid for cmux. It is concise, specific, and directly reflects the core modification in the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 21, 2026

Greptile Summary

This PR exposes the foreground process group ID of a surface's pty master as a new C API function ghostty_surface_foreground_pid(), returning int32_t (-1 on failure). The implementation correctly delegates to the existing getProcessInfo(.foreground_pid) path and handles all unavailability cases (no pty, tcgetpgrp failure, Windows).

Confidence Score: 5/5

Safe to merge — minimal, well-scoped addition that follows established patterns with no correctness issues.

The implementation is straightforward, delegates to a well-tested existing code path, correctly handles all failure cases, and matches the C header declaration. The only finding is a P2 style nit on an unnecessary cast.

No files require special attention.

Important Files Changed

Filename Overview
src/apprt/embedded.zig Adds ghostty_surface_foreground_pid CAPI export that calls getProcessInfo(.foreground_pid) via the existing pty path, returns -1 on unavailability; follows established pattern for cmux-specific exports.
include/ghostty.h Adds int32_t ghostty_surface_foreground_pid(ghostty_surface_t) declaration in the correct location alongside other cmux-specific exports, correctly typed to match the Zig return type.

Sequence Diagram

sequenceDiagram
    participant C as cmux (C caller)
    participant API as ghostty_surface_foreground_pid
    participant S as Surface.getProcessInfo
    participant T as Termio.getProcessInfo
    participant E as Exec.getProcessInfo
    participant P as PosixPty.tcgetpgrp

    C->>API: ghostty_surface_foreground_pid(surface)
    API->>S: core_surface.getProcessInfo(.foreground_pid)
    S->>T: io.getProcessInfo(.foreground_pid)
    T->>E: backend.getProcessInfo(.foreground_pid)
    E->>P: subprocess.pty.getProcessInfo(.foreground_pid)
    P-->>E: u64 (pgid) or null
    E-->>T: ?u64
    T-->>S: ?u64
    S-->>API: ?u64
    API-->>C: int32_t (pgid) or -1
Loading

Reviews (1): Last reviewed commit: "Add ghostty_surface_foreground_pid C API..." | Re-trigger Greptile

Comment thread src/apprt/embedded.zig
/// pty master, or -1 if unavailable (cmux-specific).
export fn ghostty_surface_foreground_pid(surface: *Surface) i32 {
const raw = surface.core_surface.getProcessInfo(.foreground_pid) orelse return -1;
if (raw > @as(u64, @intCast(std.math.maxInt(i32)))) return -1;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Redundant cast in overflow guard

std.math.maxInt(i32) returns a comptime_int, so Zig will coerce it to u64 automatically in the comparison — the @as(u64, @intCast(...)) wrapper is unnecessary. The simpler form is equivalent:

Suggested change
if (raw > @as(u64, @intCast(std.math.maxInt(i32)))) return -1;
if (raw > std.math.maxInt(i32)) return -1;

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant