Skip to content

Allow Command-Escape keybindings#4307

Open
jakeleventhal wants to merge 2 commits into
pingdotgg:mainfrom
jakeleventhal:t3code/allow-esc-keybindings
Open

Allow Command-Escape keybindings#4307
jakeleventhal wants to merge 2 commits into
pingdotgg:mainfrom
jakeleventhal:t3code/allow-esc-keybindings

Conversation

@jakeleventhal

@jakeleventhal jakeleventhal commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Screen.Recording.2026-07-22.at.4.30.09.PM.mov
  • allow modified Escape to be recorded as mod+esc while keeping bare Escape as the recorder cancel action
  • bridge native Command-Escape input into the focused Electron renderer, including preview webviews
  • register the macOS shortcut only while T3 Code is focused so it is not claimed while the app is in the background

Root cause

macOS consumes a physical Command-Escape chord before Chromium emits the renderer keyboard event. The keybinding recorder therefore stayed blank even though its web-level normalization supported mod+esc.

Validation

  • vp test run apps/web/src/components/settings/KeybindingsSettings.logic.test.ts apps/desktop/src/keybindings/NativeKeybindingCapture.test.ts apps/desktop/src/preview/Manager.test.ts apps/desktop/src/window/DesktopWindow.test.ts (56 tests)
  • targeted vp lint for all changed files
  • vp run typecheck in apps/desktop
  • vp run typecheck in apps/web
  • manually verified a physical Command-Escape chord records mod+esc in T3 Code Dev

Note

Allow Command-Escape to be captured and recorded as a keybinding

  • On macOS, registers a global Command+Escape shortcut while the main window is focused and forwards it to the focused WebContents via a new NATIVE_KEYBINDING_CAPTURE_CHANNEL IPC channel; unregisters on blur or close.
  • On non-macOS, intercepts Meta+Escape via before-input-event on the window's WebContents, prevents default, and sends the same payload.
  • Preview tabs (Manager.ts) and preload scripts forward the IPC message into the page as a synthetic keydown Escape event with modifier flags.
  • In the keybinding settings UI, mod+Escape is now recorded as a valid shortcut; bare Escape still cancels capture.

Macroscope summarized 70f663e.


Note

Medium Risk
Touches global shortcuts and low-level keyboard handling across main window and preview webviews; focus/blur registration limits macOS side effects but incorrect lifecycle could still steal or miss chords.

Overview
Command-Escape can now be recorded as mod+esc in keybinding settings on desktop, where macOS previously swallowed the chord before the renderer saw it.

A new desktop:native-keybinding-capture IPC path normalizes meta+Escape in the main process, prevents default where needed, and preloads re-inject a synthetic keydown on the focused element. On macOS, Command+Escape is registered via globalShortcut only while the main window is focused and unregistered on blur/close; on other platforms the main window uses before-input-event. Preview webviews get the same intercept in PreviewManager.

In KeybindingsSettings, capture runs keybindingFromKeyboardEvent before treating Escape as cancel, so modified Escape becomes a shortcut while bare Escape still exits recording.

Reviewed by Cursor Bugbot for commit 70f663e. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 550ed8b0-496a-40b2-8a87-10533cad6b80

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ 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.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 22, 2026
@jakeleventhal
jakeleventhal marked this pull request as ready for review July 22, 2026 20:38
@macroscopeapp

macroscopeapp Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces new capability for Command-Escape keybindings, involving global shortcut registration on macOS and new IPC channels for keyboard event forwarding. The runtime behavior changes to the keybinding capture system warrant human review.

You can customize Macroscope's approvability policy. Learn more.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d9d2d6ae96

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const captureInput = nativeKeybindingCaptureInput(input);
if (captureInput) {
event.preventDefault();
wc.send(NATIVE_KEYBINDING_CAPTURE_CHANNEL, captureInput);

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 Badge Forward preview Command-Escape back to the app

When a preview webview owns focus, this sends the synthetic Escape keydown into the guest page, but T3 app shortcuts are resolved by the parent renderer's window keydown listener (apps/web/src/routes/_chat.tsx) and the existing preview shortcut bridge forwards app shortcuts with mainWindow.value.webContents.sendInputEvent. As a result, a user-assigned mod+esc command such as preview refresh/toggle will not run while focus is inside the preview, even though the commit explicitly tries to support focused preview webviews; route this captured chord to the main window as an app shortcut rather than only to wc.

Useful? React with 👍 / 👎.

input: Pick<Input, "type" | "key" | "meta" | "control" | "alt" | "shift">,
): NativeKeybindingCaptureInput | null {
const key = input.key.toLowerCase();
if (input.type !== "keyDown" || (key !== "escape" && key !== "esc") || !input.meta) {

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 Badge Capture Ctrl-Escape for non-Mac mod bindings

On non-Mac platforms mod is derived from ctrlKey in keybindingFromKeyboardEvent, but both desktop before-input-event paths call this helper, which only accepts input.meta. In the Windows/Linux scenario where Ctrl+Escape needs the native bridge instead of a normal renderer keydown, the helper returns null, while the only synthesized chord would be Meta+Escape and record/run as meta+esc rather than the newly allowed mod+esc; pass the platform or accept control for non-Darwin callers.

Useful? React with 👍 / 👎.

if (Electron.globalShortcut.isRegistered(MACOS_MOD_ESCAPE_ACCELERATOR)) {
return;
}
const registered = Electron.globalShortcut.register(MACOS_MOD_ESCAPE_ACCELERATOR, () => {

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 Badge Bridge macOS Escape chords with extra modifiers

On macOS this registers only the exact Command+Escape accelerator and the callback always emits the MACOS_MOD_ESCAPE_INPUT payload with ctrl/alt/shift false. The recorder now accepts and serializes extra modifiers on Escape, so Cmd+Shift+Esc/Cmd+Option+Esc keybindings can be saved but never captured or triggered on the platform that needs this native bridge; register and dispatch each modifier variant, or capture the actual flags, instead of hard-coding the unmodified chord.

Useful? React with 👍 / 👎.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 70f663e. Configure here.

ctrlKey: false,
altKey: false,
shiftKey: false,
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

macOS shortcut drops modifier keys

Medium Severity

On macOS, the global shortcut for Command+Escape always sends a fixed input payload that incorrectly sets shiftKey, altKey, and ctrlKey to false. This means any additional modifiers pressed with Command+Escape are ignored, leading to incorrect keybinding capture compared to other platforms.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 70f663e. Configure here.

const focusedWebContents = Electron.webContents.getFocusedWebContents();
if (focusedWebContents && !focusedWebContents.isDestroyed()) {
focusedWebContents.send(NATIVE_KEYBINDING_CAPTURE_CHANNEL, MACOS_MOD_ESCAPE_INPUT);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cmd+Escape triggers bare Escape handlers

Medium Severity

While the main window is focused on macOS, every physical Command+Escape chord registers a global shortcut and forwards a synthetic keydown whose key is Escape. Several UI layers treat any Escape key as cancel/back (settings navigation, chat selection clear, preview pick teardown) without checking modifiers, so Command+Escape outside keybinding capture can trigger those actions unintentionally.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 70f663e. Configure here.

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

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant