Skip to content

Add terminal right-click paste mode with long-press context menu + delay setting#2320

Open
wing2005 wants to merge 17 commits intomanaflow-ai:mainfrom
wing2005:feat/terminal-right-click-paste-menu
Open

Add terminal right-click paste mode with long-press context menu + delay setting#2320
wing2005 wants to merge 17 commits intomanaflow-ai:mainfrom
wing2005:feat/terminal-right-click-paste-menu

Conversation

@wing2005
Copy link
Copy Markdown

@wing2005 wing2005 commented Mar 29, 2026

Summary

  • Add terminal-only right-click behavior setting with two modes: Show Context Menu (default) or Paste from Clipboard.
  • Add optional Long Right Click Opens Context Menu behavior when paste mode is enabled.
  • Add configurable long-right-click delay in Settings: Fast (0.20s), Default (0.30s), Slow (0.45s), and reduce default delay to 0.30s.
  • Localize all new user-facing settings strings (EN/JA).

Testing

  • Built and launched tagged debug app:
    • ./scripts/reload.sh --tag right-click-paste --launch
  • Verified Settings wiring:
    • Terminal Right Click picker appears in Settings.
    • Long Right Click Opens Context Menu toggle appears when paste mode is selected.
    • Long Right Click Delay picker appears when long-right-click context menu is enabled.
  • Verified runtime behavior in terminal surface:
    • Context menu mode: right click opens terminal context menu.
    • Paste mode: short right click pastes from clipboard.
    • Paste mode + long-right-click enabled: long right click opens context menu.
  • Confirmed behavior is scoped to terminal mouse interactions.

Demo Video

  • Video URL or attachment: TBD

Review Trigger (Copy/Paste as PR comment)

@codex review
@coderabbitai review
@greptile-apps review
@cubic-dev-ai review

Checklist

  • I tested the change locally
  • I added or updated tests for behavior changes
  • I updated docs/changelog if needed
  • I requested bot reviews after my latest commit (copy/paste block above or equivalent)
  • All code review bot comments are resolved
  • All human review comments are resolved

Made with Cursor


Summary by cubic

Adds a terminal-only right‑click mode: context menu (default) or paste, with an optional long‑press menu and a configurable delay. Settings are exposed via app.* keys in settings.json and documented in the schema.

  • New Features

    • Setting: Terminal Right Click → “Show Context Menu” (default) or “Paste from Clipboard”.
    • Optional: “Long Right Click Opens Context Menu” in paste mode.
    • Delay options: Fast (0.20s), Default (0.30s), Slow (0.45s); JSON value clamped 0.15–1.0s.
    • Picker shows a “Custom (%@ s)” option when the duration in settings.json doesn’t match presets.
    • Settings JSON and schema: app.terminalRightClickBehavior, app.terminalRightClickLongPressContextMenuEnabled, app.terminalRightClickLongPressDuration (defaults included).
  • Bug Fixes

    • Keep AppKit context menu available in paste mode (Control‑click and other paths).
    • Avoid paste after right‑click drags; ignore small jitter; long‑press menu is more reliable.
    • Clear long‑press state on right‑drag/up even when no surface is active.
    • Reset All Settings restores right‑click defaults.
    • Standardized terminalContextMenu localization keys; restored browser.reactGrab strings; removed duplicate “Reset Terminal” menu entry.
    • Parsing app.terminalRightClickBehavior: invalid values no longer abort settings parse.
    • Preserve main’s runtime surface‑creation gating to avoid unintended surface creation.
    • Fix vendor/bonsplit submodule pointer to origin/main to restore build.

Written for commit dc47a10. Summary will update on new commits.

Summary by CodeRabbit

  • New Features

    • Configurable terminal right-click behavior: choose Context Menu or Paste from Clipboard.
    • Optional long-press to show context menu when Paste-from-Clipboard is selected, with enable/disable toggle and accessibility ID.
    • Adjustable long-press delay with Fast / Default / Slow presets; reset restores defaults.
  • Localization

    • Added English and Japanese UI strings for new settings and updated terminal context-menu labels.
    • Removed legacy “React Grab” localization entries.

Expose terminal-specific settings to switch right click from context menu to paste, with an optional long-right-click context menu fallback and configurable delay so users can tune interaction speed.

Made-with: Cursor
@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 29, 2026

@wing2005 is attempting to deploy a commit to the Manaflow Team on Vercel.

A member of the Team first needs to authorize it.

@chatgpt-codex-connector
Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 29, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Removes “React Grab” localization keys, adds en/ja localization for terminal right‑click settings and long‑press duration, introduces persisted terminal right‑click preferences and Settings UI, implements long‑press scheduling/cancellation and paste-vs-context‑menu behavior in the terminal view, and adjusts terminal context‑menu keying.

Changes

Cohort / File(s) Summary
Localization Strings
Resources/Localizable.xcstrings
Removed browser.reactGrab, menu.view.toggleReactGrab, shortcut.toggleReactGrab.label; added terminal right‑click settings keys (behavior/options/subtitles, long‑press toggle/duration/options) in en and ja; adjusted terminal context‑menu keys (triggerFlash/resetTerminal) and reordering.
Terminal View Event Handling
Sources/GhosttyTerminalView.swift
Removed runtime-surface creation gating; added state for long-right-click (DispatchWorkItem, flags, down location, drag detection), updated rightMouseDown/rightMouseDragged/rightMouseUp to schedule/cancel delayed menu or paste, refactored context menu construction, removed reset action, and cancelation in deinit.
App Settings / UI
Sources/cmuxApp.swift
Added @AppStorage backed preferences for terminal right‑click behavior, long‑press enable, and delay; added SettingsView UI controls and bindings (including clamped duration) and updated resetAllSettings() defaults.
Runtime Settings Model
Sources/App/WorkspaceRuntimeSettings.swift
Added TerminalRightClickSettings type (Behavior enum, accessors, clamping/defaults) to expose persisted keys and defaults.
Managed Settings / File Store
Sources/KeyboardShortcutSettingsFileStore.swift
Whitelisted new app.terminalRightClickBehavior/long‑press keys for managed settings validation and parsing; clamp long‑press duration on import and update auto-generated JSON template entries.

Sequence Diagram

sequenceDiagram
    participant User
    participant SettingsView
    participant UserDefaults
    participant GhosttyNSView
    participant DispatchQueue
    participant Clipboard

    User->>SettingsView: change right-click behavior/delay
    SettingsView->>UserDefaults: save setting value

    User->>GhosttyNSView: right-click on terminal
    GhosttyNSView->>UserDefaults: read TerminalRightClickSettings

    alt Behavior == pasteFromClipboard
        GhosttyNSView->>DispatchQueue: schedule delayed work item (after delay)
        Note right of DispatchQueue: rgba(100,149,237,0.5)
        alt long-press fires
            DispatchQueue->>GhosttyNSView: execute work item -> show context menu
            GhosttyNSView->>GhosttyNSView: set didTriggerContextMenuOnLongRightClick
        else short click (release before delay)
            User->>GhosttyNSView: right-up before fire
            GhosttyNSView->>DispatchQueue: cancel work item
            GhosttyNSView->>Clipboard: paste(nil)
        end
    else Behavior == contextMenu
        GhosttyNSView->>GhosttyNSView: build & show context menu immediately
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐇 I twitched my whiskers on a right-click day,
Hold for a menu or tap to paste away,
Prefs tucked in keys, in English and Nihongo too,
A delayed little hop, and the menu will woo,
The rabbit clicked once — then the text simply flew.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.23% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main changes: adding terminal right-click paste mode with long-press context menu and delay configuration.
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.
Description check ✅ Passed The pull request description follows the template with complete sections: Summary (what changed and why), Testing (how tested and verified), and a Checklist. All required information is present.

✏️ 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.

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.

1 issue found across 3 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Sources/cmuxApp.swift">

<violation number="1" location="Sources/cmuxApp.swift:3915">
P2: Reset All Settings doesn’t restore the new terminal right-click preferences, so these values stay customized after a global reset.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread Sources/cmuxApp.swift
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 29, 2026

Greptile Summary

This PR adds a configurable terminal right-click behavior: the default context-menu mode is unchanged, while a new "Paste from Clipboard" mode turns short right-clicks into paste and optionally opens the context menu on a long press with a configurable delay (Fast/Default/Slow). All three previously flagged issues (drag-triggers-unintended-paste, mid-gesture settings change, stale modifier flags in long-press timer) are resolved in this revision.

The one minor leftover: terminalContextMenu.resetTerminal is added to Localizable.xcstrings but the menu item and @objc resetTerminal(_:) handler that used it were removed in the same PR, leaving a dead localization key.

Confidence Score: 5/5

Safe to merge; all previous blocking concerns are resolved and the only remaining finding is a dead localization string.

All P0/P1 findings from prior review rounds are addressed. The single remaining finding (orphaned terminalContextMenu.resetTerminal localization key) is a P2 style/cleanup issue that does not affect runtime behaviour.

Resources/Localizable.xcstrings — orphaned terminalContextMenu.resetTerminal key should be cleaned up.

Important Files Changed

Filename Overview
Sources/GhosttyTerminalView.swift Core right-click paste implementation: per-gesture behavior capture, drag-threshold guard, long-press timer with fresh modifier flags. Previously flagged issues (stale mods, drag paste, mid-gesture settings change) are addressed. Also removes allowsRuntimeSurfaceCreation() lifecycle guards and resetTerminal context-menu item as unrelated cleanup.
Sources/App/WorkspaceRuntimeSettings.swift New TerminalRightClickSettings enum with well-typed behavior, clamped duration (0.15–1.0 s), and safe defaults. Clean and self-contained.
Sources/KeyboardShortcutSettingsFileStore.swift Adds JSON parsing and reset defaults for the three new right-click settings keys; clamping is applied consistently at parse time.
Sources/cmuxApp.swift Settings UI rows for right-click behavior, long-press toggle, and delay picker with conditional display logic; reset path correctly restores all three defaults.
web/data/cmux-settings.schema.json Schema entries added for the three new app.* keys with correct types, enums, minimum/maximum, and defaults matching Swift constants.
Resources/Localizable.xcstrings EN/JA strings added for all new settings UI labels; terminalContextMenu.resetTerminal key is added but the menu item and handler that consumed it were removed in the same PR, leaving an orphaned entry.

Sequence Diagram

sequenceDiagram
    participant User
    participant GhosttyNSView
    participant Timer as DispatchWorkItem (long-press)
    participant Surface as GhosttyTerminalSurface
    participant Clipboard

    User->>GhosttyNSView: rightMouseDown
    GhosttyNSView->>GhosttyNSView: capture behavior (paste mode)
    GhosttyNSView->>Timer: arm long-press timer (0.20–0.45 s)

    alt long press fires before release
        Timer->>GhosttyNSView: buildContextMenu (fresh modifierFlags)
        GhosttyNSView->>Surface: GHOSTTY_MOUSE_PRESS (right)
        GhosttyNSView->>User: popUp context menu
        GhosttyNSView->>GhosttyNSView: didTriggerContextMenuOnLongRightClick = true
        User->>GhosttyNSView: rightMouseUp
        GhosttyNSView->>GhosttyNSView: skip paste (context menu already shown)
    else drag > 4 pt threshold
        User->>GhosttyNSView: rightMouseDragged
        GhosttyNSView->>Timer: cancel long-press timer
        GhosttyNSView->>GhosttyNSView: didRightMouseDrag = true
        User->>GhosttyNSView: rightMouseUp
        GhosttyNSView->>GhosttyNSView: skip paste (drag detected)
    else short click, no drag
        User->>GhosttyNSView: rightMouseUp
        GhosttyNSView->>Timer: cancel long-press timer
        GhosttyNSView->>Clipboard: paste(nil)
    end
Loading

Reviews (2): Last reviewed commit: "Merge origin/main into feat/terminal-rig..." | Re-trigger Greptile

Comment thread Sources/GhosttyTerminalView.swift
Comment thread Sources/GhosttyTerminalView.swift
Comment thread Sources/GhosttyTerminalView.swift
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Sources/cmuxApp.swift`:
- Around line 3915-3920: The resetAllSettings() implementation in SettingsView
doesn't reset the new AppStorage fields terminalRightClickBehavior,
terminalRightClickLongPressContextMenuEnabled, and
terminalRightClickLongPressDuration; update resetAllSettings() to explicitly set
terminalRightClickBehavior =
TerminalRightClickSettings.defaultBehavior.rawValue,
terminalRightClickLongPressContextMenuEnabled =
TerminalRightClickSettings.defaultLongPressContextMenuEnabled, and
terminalRightClickLongPressDuration =
TerminalRightClickSettings.defaultLongPressDuration so the “Reset All Settings”
flow returns the terminal right-click settings to their defaults.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1df57049-4445-4ca3-a193-fd2366156883

📥 Commits

Reviewing files that changed from the base of the PR and between 45090d2 and f9a020e.

📒 Files selected for processing (3)
  • Resources/Localizable.xcstrings
  • Sources/GhosttyTerminalView.swift
  • Sources/cmuxApp.swift

Comment thread Sources/cmuxApp.swift
Ensure the global settings reset flow restores terminal right-click behavior, long-press menu toggle, and long-press delay to their defaults.

Made-with: Cursor
@wing2005
Copy link
Copy Markdown
Author

Addressed the reset-flow issue identified by cubic and CodeRabbit.

Fix

  • Updated resetAllSettings() to reset:
    • terminalRightClickBehavior
    • terminalRightClickLongPressContextMenuEnabled
    • terminalRightClickLongPressDuration

Commit

  • dc34d427

Track right-button drag state during paste-mode gestures so releasing after movement no longer triggers clipboard paste, while preserving long-press context menu behavior.

Made-with: Cursor
@wing2005
Copy link
Copy Markdown
Author

Updated PR with a follow-up fix for right-click drag jitter.

Fix

  • Prevent paste on rightMouseUp when a right-button drag occurred.
  • Added didRightMouseDrag gesture state tracking so tiny movement while holding right click no longer causes unintended paste.

Commit

  • 6b81b78f

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Sources/GhosttyTerminalView.swift`:
- Around line 6442-6447: The menu(for:) method currently returns nil when
TerminalRightClickSettings.behavior() == .pasteFromClipboard which suppresses
Control-click and other AppKit-triggered contextual menus; remove that branch so
menu(for:) always returns buildContextMenu(for: event) (i.e., delete the
conditional early-return) and rely on rightMouseDown(with:) and
armLongRightClickContextMenuIfNeeded to handle paste-mode right-click behavior
and long-press behavior respectively.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 226f3192-4f54-46b7-8c05-2816ddc5e227

📥 Commits

Reviewing files that changed from the base of the PR and between dc34d42 and 6b81b78.

📒 Files selected for processing (1)
  • Sources/GhosttyTerminalView.swift

Comment thread Sources/GhosttyTerminalView.swift
@wing2005
Copy link
Copy Markdown
Author

Addressed the latest CodeRabbit contextual-menu concern.

Fix

  • Removed the paste-mode early return in menu(for:).
  • menu(for:) now always returns buildContextMenu(for:), preserving AppKit contextual-menu paths (e.g. Control-click) while right-click paste behavior remains handled in mouse handlers.

Commit

  • 0c6ede81

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Sources/GhosttyTerminalView.swift (1)

6446-6493: ⚠️ Potential issue | 🟡 Minor

Localize the extracted context-menu titles.

Now that the menu is constructed here, titles like Trigger Flash, Copy, Paste, and the split actions are still hard-coded English. Please switch them to String(localized:..., defaultValue:...) and add xcstrings entries so the new right-click flows stay translated in supported locales.

As per coding guidelines, “All user-facing strings must be localized using String(localized: "key.name", defaultValue: "English text") … Never use bare string literals in … UI elements”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/GhosttyTerminalView.swift` around lines 6446 - 6493, The context menu
in buildContextMenu uses hard-coded English titles; replace each literal title
("Trigger Flash", "Copy", "Paste", "Split Horizontally", "Split Vertically")
with localized variants using String(localized: "key.name", defaultValue:
"English text") and update the corresponding NSMenuItem creation calls (the
items returned for selectors triggerFlash(_:), copy(_:), paste(_:),
splitHorizontally(_:), splitVertically(_:)) to use those localized strings; also
add matching entries to the .xcstrings resource file for each key name so
translations can be provided.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Sources/GhosttyTerminalView.swift`:
- Around line 6367-6375: The long-press context-menu timer is being cancelled on
any tiny right-button movement which prevents the menu from ever firing; in the
right-mouse-drag handling path that checks TerminalRightClickSettings.behavior()
and ghostty_surface_mouse_captured(surface), preserve the didRightMouseDrag flag
for paste suppression but only invalidate/cancel the long-press timer and set
didTriggerContextMenuOnLongRightClick when the drag distance exceeds a small
threshold (e.g., a few pixels) instead of on the first drag event; update the
logic in the methods around requestPointerFocusRecovery(),
armLongRightClickContextMenuIfNeeded(with:), and the right-drag handling so
minor jitter just sets didRightMouseDrag but does not cancel the timer until
movement > threshold.

---

Outside diff comments:
In `@Sources/GhosttyTerminalView.swift`:
- Around line 6446-6493: The context menu in buildContextMenu uses hard-coded
English titles; replace each literal title ("Trigger Flash", "Copy", "Paste",
"Split Horizontally", "Split Vertically") with localized variants using
String(localized: "key.name", defaultValue: "English text") and update the
corresponding NSMenuItem creation calls (the items returned for selectors
triggerFlash(_:), copy(_:), paste(_:), splitHorizontally(_:),
splitVertically(_:)) to use those localized strings; also add matching entries
to the .xcstrings resource file for each key name so translations can be
provided.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bcf73f0e-aa45-482a-88c0-63fc1cc52627

📥 Commits

Reviewing files that changed from the base of the PR and between 6b81b78 and 0c6ede8.

📒 Files selected for processing (1)
  • Sources/GhosttyTerminalView.swift

Comment thread Sources/GhosttyTerminalView.swift
@wing2005 wing2005 force-pushed the feat/terminal-right-click-paste-menu branch from 0c6ede8 to 84a5903 Compare March 29, 2026 14:44
@wing2005
Copy link
Copy Markdown
Author

Patched and amended with the latest review fixes:\n\n- Added long-right-click drag-cancel threshold so tiny pointer jitter no longer cancels the long-press timer ( threshold).\n- Localized terminal context menu titles (, , , , ) with EN/JA keys in .\n\nAmended commit: (force-pushed).

@wing2005
Copy link
Copy Markdown
Author

Correction to previous comment (shell formatting issue):

Patched and amended with the latest review fixes:

  • Added long-right-click drag-cancel threshold so tiny pointer jitter no longer cancels the long-press timer (4pt threshold).
  • Localized terminal context menu titles (Trigger Flash, Copy, Paste, Split Horizontally, Split Vertically) with EN/JA keys in Localizable.xcstrings.

Amended commit: 84a5903 (force-pushed).

@wing2005
Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 30, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Preserve AppKit contextual menu paths while using right-click paste mode, make long-right-click more reliable, and ensure right-click gesture handling uses consistent behavior/modifier state. Also localize terminal context menu item titles.

Made-with: Cursor
@wing2005 wing2005 force-pushed the feat/terminal-right-click-paste-menu branch from 84a5903 to a7d0a39 Compare March 30, 2026 06:27
Resolve cmuxApp settings-section conflicts while keeping terminal right-click paste/long-press behavior changes and main-branch copy-on-select settings updates.

Made-with: Cursor
Reconcile localization key namespace updates from main with terminal right-click paste/long-press changes by standardizing on terminalContextMenu keys and preserving new right-click settings entries.

Made-with: Cursor
@ryanwuer
Copy link
Copy Markdown

ryanwuer commented Apr 2, 2026

Waiting for this PR to be merged. We set right-click-action = paste in ghostty config to make paste easily but the context-menu shows at the same time, which is a bit of annoying.

wing2005 added 2 commits April 5, 2026 09:25
Integrate latest main branch updates while preserving terminal right-click paste/long-press behavior and associated context-menu localization changes.

Made-with: Cursor
Remove the leftover SettingsView helper that references terminalCopyOnSelectEnabled, which no longer exists on current main.

Made-with: Cursor
@wing2005
Copy link
Copy Markdown
Author

wing2005 commented Apr 5, 2026

PR readiness pass complete on latest head (777bc31):\n- Branch is mergeable with main (no conflicts).\n- Unresolved review threads: 0.\n- All non-Vercel checks are passing (Socket, cubic, CodeRabbit).\n\nRemaining blocker is Vercel authorization for the Manaflow team. A team member needs to authorize via the Vercel check link, then re-run that check.

Resolve GhosttyTerminalView conflicts: keep main Cmd-hover/word-path and
layer-background config paths; preserve right-click context menu behavior.

Made-with: Cursor
wing2005 added 5 commits April 9, 2026 09:56
- Restore GhosttyNSView wordPathHoverActive property and cursor cleanup in
  viewDidMoveToWindow / mouseExited (main Cmd-path hover).
- Extract terminal right-click App settings into terminalRightClickAppSettingsRows()
  to satisfy Swift type-checker; use configurationReview: .settingsOnly on those
  rows until settings.json paths are registered.

Made-with: Cursor
- Add app.terminalRightClickBehavior, long-press menu toggle, and duration to
  CmuxSettingsFileStore supported paths, parseAppSection, and default template.
- Document keys in cmux-settings.schema.json.
- Point Settings UI rows at the new app.* configurationReview paths.

Made-with: Cursor
Resolve conflicts: keep terminal right-click settings UI, merge Terminal
scroll bar settings from main, restore prepareSurfaceForPaste helpers,
add React Grab localization entries, align terminal paste JA/ko strings.

Made-with: Cursor
Keep main's DEBUG surface helpers in GhosttyTerminalView (required by recordDebugForceRefresh call sites).

Made-with: Cursor
Resolve cmuxApp.swift conflict: main moved runtime settings to
WorkspaceRuntimeSettings.swift; keep that structure and add
TerminalRightClickSettings there instead of duplicating at top of cmuxApp.

Made-with: Cursor
@wing2005
Copy link
Copy Markdown
Author

@codex review
@coderabbitai review
@greptile-apps review
@cubic-dev-ai review

@chatgpt-codex-connector
Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@cubic-dev-ai
Copy link
Copy Markdown

cubic-dev-ai Bot commented Apr 23, 2026

@codex review
@coderabbitai review
@greptile-apps review
@cubic-dev-ai review

@wing2005 I have started the AI code review. It will take a few minutes to complete.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 23, 2026

@wing2005: Triggering an incremental review of the latest head. I'll evaluate the new changes, including the long-press drag-cancel threshold, the refactored menu(for:)/buildContextMenu(for:) split, the TerminalRightClickSettings enum wiring, and the EN/JA localization additions.


🧠 Learnings used
Learnt from: lawrencecchen
Repo: manaflow-ai/cmux PR: 2525
File: Sources/GhosttyTerminalView.swift:481-513
Timestamp: 2026-04-02T10:13:39.235Z
Learning: Repo: manaflow-ai/cmux — In Sources/GhosttyTerminalView.swift, terminal file-link resolution trims trailing unmatched closing delimiters “) ] } >” only when they are dangling (more closers than openers), preserving wrapped tokens like “(file:///tmp/a.png)”. Implemented via terminalFileLinkTrailingClosingDelimiters and count comparison inside trimTrailingTerminalFileLinkPunctuation(_:) and exercised by a regression test (PR `#2525`, commit 3f5c5b6d).

Learnt from: solssak
Repo: manaflow-ai/cmux PR: 2397
File: Sources/TerminalController.swift:0-0
Timestamp: 2026-03-31T02:33:40.981Z
Learning: Repo: manaflow-ai/cmux — In Sources/TerminalController.swift, prefer ghostty_surface_text (via writePTYText) for large socket text payloads; do not manually wrap with \e[200~/\e[201~. Ghostty inserts bracketed-paste markers itself when mode 2004 is enabled. Threshold is pasteTextThreshold = 256; control scalars still go through handleControlScalar and short text through sendTextEvent.

Learnt from: mrosnerr
Repo: manaflow-ai/cmux PR: 2545
File: Sources/GhosttyTerminalView.swift:0-0
Timestamp: 2026-04-05T20:53:23.880Z
Learning: Repo: manaflow-ai/cmux — In Sources/GhosttyTerminalView.swift inside TerminalSurface.createSurface(for:), resolvedInitialInput must:
- Append "\n" only for explicit initialInput (validated earlier to reject embedded \n/\r);
- Preserve baseConfig.initialInput exactly as provided by Ghostty (no trimming, no newline checks), to honor Ghostty’s raw-bytes startup-input semantics.

Learnt from: BillionClaw
Repo: manaflow-ai/cmux PR: 1755
File: Sources/GhosttyTerminalView.swift:4889-4903
Timestamp: 2026-03-18T16:50:14.396Z
Learning: Repo: manaflow-ai/cmux — In Sources/GhosttyTerminalView.swift, GhosttyNSView.performKeyEquivalent(with:) must only route Command key equivalents to NSApp.mainMenu when shouldRouteCommandEquivalentDirectlyToMainMenu(event) returns true; otherwise, handle the key directly via keyDown to forward unbound Cmd+Shift combinations to the terminal and preserve the Cmd+` exclusion.

Learnt from: mrosnerr
Repo: manaflow-ai/cmux PR: 0
File: :0-0
Timestamp: 2026-04-05T21:26:10.710Z
Learning: Repo: manaflow-ai/cmux — In Sources/Workspace.swift, applySessionPanelMetadata() must gate listeningPorts restoration on the per-panel snapshot.terminal?.isRemoteBacked flag (not workspace-wide remoteTerminalStartupCommand()), so that local panels are always eligible for port restore regardless of current SSH state. Fixed in commit 4d0fd871 (PR `#2545`).

Learnt from: lawrencecchen
Repo: manaflow-ai/cmux PR: 3124
File: Sources/Panels/ReactGrab.swift:102-287
Timestamp: 2026-04-23T03:30:35.842Z
Learning: Repo: manaflow-ai/cmux — In Sources/Panels/ReactGrab.swift, ReactGrabPastebackContentFilter.filtered(_:) uses isAllowedPastebackScalar(_:) which: (1) rejects dangerousScalars (BiDi U+202A–202E, U+2066–2069; zero-width U+200B–200F; U+FEFF); (2) allows \t (0x09) and \n (0x0A); (3) rejects all other C0/C1 control scalars (0x00–0x1F and 0x7F–0x9F). This matches the TerminalController/BrowserPickerMessageHandler filtering convention and prevents hostile page content from injecting terminal control sequences via the ReactGrab pasteback path.

Learnt from: outoftime
Repo: manaflow-ai/cmux PR: 1528
File: Sources/GhosttyTerminalView.swift:3220-3228
Timestamp: 2026-03-17T18:25:33.286Z
Learning: Repo: manaflow-ai/cmux — In Sources/GhosttyTerminalView.swift within TerminalSurface.createSurface(for:), when constructing XDG_DATA_DIRS for Fish vendor_conf.d auto-sourcing, treat empty or whitespace-only values from initialEnvironmentOverrides, env, getenv, and ProcessInfo as unset before prefixing the integrationDir. This avoids producing a trailing colon. Keep XDG_DATA_DIRS in protectedStartupEnvironmentKeys so initialEnvironmentOverrides cannot overwrite the prefixed value.

Learnt from: lejahmie
Repo: manaflow-ai/cmux PR: 2371
File: cmuxTests/CJKIMEInputTests.swift:1325-1335
Timestamp: 2026-03-31T10:56:43.241Z
Learning: Repo: manaflow-ai/cmux — In `cmuxTests/CJKIMEInputTests.swift`, `GhosttyOptionDeleteRegressionTests.testRightOptionLiteralCharacterSetsAltRightInRawModsFallbackPath` intentionally omits `consumed_mods & GHOSTTY_MODS_ALT_RIGHT` assertions. That test simulates the fallback path (no `NX_DEVICERALTKEYMASK` bit in event flags; right-side state injected via `debugSetRightOptionModifierDownForUITest(true)`), where `consumed_mods` depends on translation-mod flags and is unstable in synthetic test contexts. Only `mods & (ALT | ALT_RIGHT)` is asserted here. The `consumed_mods` coverage is provided by the deterministic `testRightOptionDeleteSetsAltRightModifier` test, which uses the direct `NX_DEVICERALTKEYMASK` modifier flag path.

Learnt from: outoftime
Repo: manaflow-ai/cmux PR: 1528
File: Resources/shell-integration/fish/vendor_conf.d/cmux-fish-integration.fish:541-546
Timestamp: 2026-03-17T13:59:10.665Z
Learning: Repo: manaflow-ai/cmux — The socket command `report_git_branch` (parsed in Sources/TerminalController.swift) expects the branch name as an **unquoted, bare token**. Wrapping the branch name in double quotes causes it to be silently discarded by the parser. This matches the bash/zsh shell integration convention. Do not suggest quoting the branch argument for this command; the fix was attempted in commit 829437c7 and immediately reverted because it broke branch reporting.

Learnt from: tayl0r
Repo: manaflow-ai/cmux PR: 0
File: :0-0
Timestamp: 2026-04-08T03:36:30.160Z
Learning: Repo: manaflow-ai/cmux — AppDelegate.FileBrowserDrawerState threading pattern (PR `#1909`, commit e0e57809): FileBrowserDrawerState must be threaded through AppDelegate.configure() as a weak stored property (matching the sidebarState pattern), passed through both configure() call sites, with registerMainWindow parameter made non-optional. The fallback `?? FileBrowserDrawerState()` must NOT be used as it creates detached instances that are not properly owned by the window context.

Learnt from: qkrwpdlr
Repo: manaflow-ai/cmux PR: 0
File: :0-0
Timestamp: 2026-03-23T07:01:33.134Z
Learning: Repo: manaflow-ai/cmux — In Sources/Panels/BrowserPanel.swift, BrowserPickerMessageHandler gates WKScriptMessage delivery via NSEvent.addLocalMonitorForEvents(.leftMouseDown): on Option+click it stamps ProcessInfo.processInfo.systemUptime into lastNativeOptionClickTime; userContentController(_:didReceive:) rejects postMessages where elapsed >= 1.0s and zeroes the timestamp after acceptance (one-shot). The NSEvent monitor is removed in BrowserPickerMessageHandler.deinit. BrowserPanel.bindWebView(_:) removes the old script message handler and nils pickerMessageHandler before re-registering (prevents monitor leaks on profile change/webView replacement). BrowserPanel.deinit also removes the "cmuxPointer" script message handler.

Learnt from: qkrwpdlr
Repo: manaflow-ai/cmux PR: 0
File: :0-0
Timestamp: 2026-03-23T07:12:42.553Z
Learning: Repo: manaflow-ai/cmux — In Sources/TerminalController.swift and Sources/Panels/BrowserPanel.swift, BiDi override (U+202A–202E, U+2066–2069) and zero-width char (U+200B–200F, U+FEFF) filtering is implemented via a shared `dangerousScalars: Set<UInt32>` in each class. v2SanitizeWebText() truncates to 200 chars; v2SanitizeXPath() caps at 2000 chars for selector fidelity. Both use a shared v2SanitizeScalar() predicate. BrowserPickerMessageHandler.sanitize() uses the same dangerousScalars pattern with a 200-char cap.
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@chatgpt-codex-connector
Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

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.

3 issues found across 6 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Resources/Localizable.xcstrings">

<violation number="1" location="Resources/Localizable.xcstrings:11289">
P2: Removed localization keys are still referenced by UI/menu/shortcut code, causing localization fallback regressions.</violation>

<violation number="2" location="Resources/Localizable.xcstrings:88589">
P2: Repurposed `resetTerminal` entry retains stale Korean text from `triggerFlash`, causing incorrect localization.</violation>
</file>

<file name="Sources/KeyboardShortcutSettingsFileStore.swift">

<violation number="1" location="Sources/KeyboardShortcutSettingsFileStore.swift:437">
P2: Invalid `app.terminalRightClickBehavior` value aborts parsing of the rest of the `app` section due to an early `return`.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread Resources/Localizable.xcstrings
Comment thread Resources/Localizable.xcstrings Outdated
Comment thread Sources/KeyboardShortcutSettingsFileStore.swift Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Sources/GhosttyTerminalView.swift (1)

4305-4319: ⚠️ Potential issue | 🟠 Major

Keep closed terminal surfaces from being recreated.

After teardownSurface() marks the lifecycle closed and clears surface, stale attach/background-start callbacks can still call createSurface(for:). That can spawn a new Ghostty runtime for a panel that canAcceptPortalBinding(...) would reject as non-live.

Proposed lifecycle guard
     func attachToView(_ view: GhosttyNSView) {
 `#if` DEBUG
         dlog(
             "surface.attach surface=\(id.uuidString.prefix(5)) view=\(Unmanaged.passUnretained(view).toOpaque()) " +
             "attached=\(attachedView != nil ? 1 : 0) hasSurface=\(surface != nil ? 1 : 0) inWindow=\(view.window != nil ? 1 : 0)"
         )
 `#endif`
+        guard portalLifecycleState == .live else {
+#if DEBUG
+            dlog(
+                "surface.attach.skip surface=\(id.uuidString.prefix(5)) " +
+                "reason=lifecycleState state=\(portalLifecycleState.rawValue)"
+            )
+#endif
+            return
+        }
 
         // If already attached to this view, nothing to do.
     private func createSurface(for view: GhosttyNSView) {
+        guard portalLifecycleState == .live else {
+#if DEBUG
+            dlog(
+                "surface.create.skip surface=\(id.uuidString.prefix(5)) " +
+                "reason=lifecycleState state=\(portalLifecycleState.rawValue)"
+            )
+#endif
+            return
+        }
+
         `#if` DEBUG
         let resourcesDir = getenv("GHOSTTY_RESOURCES_DIR").flatMap { String(cString: $0) } ?? "(unset)"
-        guard surface == nil, attachedView != nil else { return }
+        guard portalLifecycleState == .live, surface == nil, attachedView != nil else { return }
         guard !backgroundSurfaceStartQueued else { return }
         backgroundSurfaceStartQueued = true
 
         DispatchQueue.main.async { [weak self] in
             guard let self else { return }
             self.backgroundSurfaceStartQueued = false
+            guard self.portalLifecycleState == .live else { return }
             guard self.surface == nil, let view = self.attachedView else { return }

Also applies to: 4334-4341, 4918-4938

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/GhosttyTerminalView.swift` around lines 4305 - 4319, The
attach/background-start paths call createSurface(for:) even after
teardownSurface() has set the lifecycle to closed and cleared surface; add a
lifecycle guard so these callbacks bail out when the panel is closed: before
calling createSurface(for:) (in the branches around surface == nil at the shown
sites and the other similar blocks), check the lifecycle/closed flag (or call
canAcceptPortalBinding(...) / a new isClosed/isLive property) and return if
closed, ensuring createSurface(for:) is never invoked for a closed panel and
preventing a new Ghostty runtime from being spawned for non-live panels.
🧹 Nitpick comments (2)
Sources/App/WorkspaceRuntimeSettings.swift (1)

123-126: Centralize the long-press clamp bounds.

The 0.15/1.00 bounds are duplicated in Sources/KeyboardShortcutSettingsFileStore.swift (Line 445). Exposing them here avoids drift if the range is ever tuned.

♻️ Proposed change
     static let defaultLongPressDuration: TimeInterval = 0.30
+    static let minLongPressDuration: TimeInterval = 0.15
+    static let maxLongPressDuration: TimeInterval = 1.00
@@
     static func longPressDuration(defaults: UserDefaults = .standard) -> TimeInterval {
         let raw = defaults.object(forKey: longPressDurationKey) as? Double ?? defaultLongPressDuration
-        return min(max(raw, 0.15), 1.00)
+        return min(max(raw, minLongPressDuration), maxLongPressDuration)
     }

And in KeyboardShortcutSettingsFileStore.swift:

-            let clamped = min(max(raw, 0.15), 1.00)
+            let clamped = min(
+                max(raw, TerminalRightClickSettings.minLongPressDuration),
+                TerminalRightClickSettings.maxLongPressDuration
+            )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/App/WorkspaceRuntimeSettings.swift` around lines 123 - 126, Introduce
centralized min/max constants in WorkspaceRuntimeSettings and use them instead
of hard-coded literals: add e.g. static let minLongPressDuration: TimeInterval =
0.15 and static let maxLongPressDuration: TimeInterval = 1.0 alongside existing
defaultLongPressDuration and longPressDurationKey, then update the
longPressDuration(defaults:) implementation to clamp using those constants
(min/max) rather than 0.15/1.00; finally update the duplicate clamp in
KeyboardShortcutSettingsFileStore (referencing the
KeyboardShortcutSettingsFileStore type) to use
WorkspaceRuntimeSettings.minLongPressDuration and .maxLongPressDuration so both
places share the same source of truth and run tests to confirm behavior.
Sources/GhosttyTerminalView.swift (1)

8148-8173: Add DEBUG dlog() coverage for the new right-click gesture paths.

The new paste-mode and long-press branches are mouse event paths, but they do not emit DEBUG events, making right-click regressions hard to diagnose.

As per coding guidelines, All debug events (keys, mouse, focus, splits, tabs) must be logged to the unified debug log using the dlog() function and wrapped in #if DEBUG / #endif preprocessor directives.

Also applies to: 8309-8329

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/GhosttyTerminalView.swift` around lines 8148 - 8173, Add DEBUG dlog()
calls wrapped in `#if` DEBUG / `#endif` to cover the new right-click gesture paths
in rightMouseDown(with:): log entering the pasteFromClipboard branch (before
requestPointerFocusRecovery/armLongRightClickContextMenuIfNeeded), log when
cancelLongRightClickContextMenu() is invoked, and log the mouse position/button
send (before calling ghostty_surface_mouse_pos and
ghostty_surface_mouse_button); similarly add matching dlog() coverage in the
corresponding long-press/context-menu handling code paths (e.g.,
armLongRightClickContextMenuIfNeeded and the code around
ghostty_surface_mouse_button) so all right-click branches emit unified debug
events.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Resources/Localizable.xcstrings`:
- Around line 88589-88604: The Korean localization for
terminalContextMenu.resetTerminal is stale (value '플래시 실행' from old key) —
update the "ko" stringUnit for terminalContextMenu.resetTerminal to the correct
Korean translation for "Reset Terminal" (e.g., "터미널 재설정") or change its
stringUnit state to "needs review" so the English fallback is used; modify the
"ko" block for terminalContextMenu.resetTerminal accordingly without altering
the English or Japanese entries.

In `@Sources/cmuxApp.swift`:
- Around line 4481-4568: The picker for terminal long-right-click delay only
offers fixed tags (0.20, 0.30, 0.45) so arbitrary clamped values (e.g. 0.25)
don't show a coherent selection; update the SettingsPickerRow (selection:
terminalLongRightClickDurationSelection) to append a dynamic "Custom" option
when terminalRightClickLongPressDuration is not equal to any of the preset tags
— render a localized label like "Custom (0.25s)" (using the current
terminalRightClickLongPressDuration) and tag it with the actual
terminalRightClickLongPressDuration so the picker reflects and preserves
arbitrary clamped values. Ensure the existing binding
terminalLongRightClickDurationSelection and clamping logic remain unchanged.

In `@Sources/GhosttyTerminalView.swift`:
- Around line 8175-8188: The rightMouseDragged handler currently bails out when
`surface` is nil, leaving the delayed long-right-click work item and gesture
flags alive; move or duplicate the cleanup so that
`cancelLongRightClickContextMenu()` is invoked and gesture state
(`didRightMouseDrag`, `rightMouseDownLocation` checks) is handled regardless of
`surface` presence before any early return, then only call
`ghostty_surface_mouse_pos(...)` if `surface` exists; apply the same change to
the corresponding `rightMouseUp` handler (the block around lines 8190-8205) so
pending menu work items and flags are always cleared even if the `surface` has
been torn down or detached.

---

Outside diff comments:
In `@Sources/GhosttyTerminalView.swift`:
- Around line 4305-4319: The attach/background-start paths call
createSurface(for:) even after teardownSurface() has set the lifecycle to closed
and cleared surface; add a lifecycle guard so these callbacks bail out when the
panel is closed: before calling createSurface(for:) (in the branches around
surface == nil at the shown sites and the other similar blocks), check the
lifecycle/closed flag (or call canAcceptPortalBinding(...) / a new
isClosed/isLive property) and return if closed, ensuring createSurface(for:) is
never invoked for a closed panel and preventing a new Ghostty runtime from being
spawned for non-live panels.

---

Nitpick comments:
In `@Sources/App/WorkspaceRuntimeSettings.swift`:
- Around line 123-126: Introduce centralized min/max constants in
WorkspaceRuntimeSettings and use them instead of hard-coded literals: add e.g.
static let minLongPressDuration: TimeInterval = 0.15 and static let
maxLongPressDuration: TimeInterval = 1.0 alongside existing
defaultLongPressDuration and longPressDurationKey, then update the
longPressDuration(defaults:) implementation to clamp using those constants
(min/max) rather than 0.15/1.00; finally update the duplicate clamp in
KeyboardShortcutSettingsFileStore (referencing the
KeyboardShortcutSettingsFileStore type) to use
WorkspaceRuntimeSettings.minLongPressDuration and .maxLongPressDuration so both
places share the same source of truth and run tests to confirm behavior.

In `@Sources/GhosttyTerminalView.swift`:
- Around line 8148-8173: Add DEBUG dlog() calls wrapped in `#if` DEBUG / `#endif` to
cover the new right-click gesture paths in rightMouseDown(with:): log entering
the pasteFromClipboard branch (before
requestPointerFocusRecovery/armLongRightClickContextMenuIfNeeded), log when
cancelLongRightClickContextMenu() is invoked, and log the mouse position/button
send (before calling ghostty_surface_mouse_pos and
ghostty_surface_mouse_button); similarly add matching dlog() coverage in the
corresponding long-press/context-menu handling code paths (e.g.,
armLongRightClickContextMenuIfNeeded and the code around
ghostty_surface_mouse_button) so all right-click branches emit unified debug
events.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: be8fa21f-62fb-4295-a046-caa4035ea2cf

📥 Commits

Reviewing files that changed from the base of the PR and between 84a5903 and c0ddfb2.

📒 Files selected for processing (5)
  • Resources/Localizable.xcstrings
  • Sources/App/WorkspaceRuntimeSettings.swift
  • Sources/GhosttyTerminalView.swift
  • Sources/KeyboardShortcutSettingsFileStore.swift
  • Sources/cmuxApp.swift

Comment thread Resources/Localizable.xcstrings Outdated
Comment thread Sources/cmuxApp.swift
Comment thread Sources/GhosttyTerminalView.swift
…ure cleanup

- Restore browser.reactGrab strings; remove duplicate resetTerminal entry
- Add custom long-press duration picker row for non-preset values
- Stop aborting full app section parse on invalid terminalRightClickBehavior
- Clear long-press state on right-drag/up even when surface is nil

Made-with: Cursor
Resolve GhosttyTerminalView: keep main's allowsRuntimeSurfaceCreation gating
(attachView + createSurface + requestBackgroundSurfaceStartIfNeeded) and add
the helper next to recordRuntimeSurfaceCreation.

Made-with: Cursor
Merge had advanced the pointer to an older snapshot without
BonsplitConfiguration.SplitActionButton; restore main's revision so CmuxConfig builds.

Made-with: Cursor
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.

2 participants