Skip to content

fix(input): don't swallow unbound Cmd+Shift combinations - #1731

Closed
BillionClaw wants to merge 1 commit into
manaflow-ai:mainfrom
BillionClaw:clawoss/fix/cmd-shift-key-1773827347
Closed

BillionClaw wants to merge 1 commit into
manaflow-ai:mainfrom
BillionClaw:clawoss/fix/cmd-shift-key-1773827347

Conversation

@BillionClaw

@BillionClaw BillionClaw commented Mar 18, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #1718

Unbound Cmd+Shift+ combinations were being silently swallowed.
Now properly passed through to terminal applications via the kitty keyboard protocol.

Summary by CodeRabbit

Bug Fixes

  • Fixed unbound Cmd+Shift keyboard shortcuts being silently ignored in the terminal. These key combinations are now properly dispatched and will work as expected.

Summary by cubic

Ensure unbound Cmd+Shift+ shortcuts pass through to terminal apps instead of being swallowed by AppKit. We now route them directly to keyDown in performKeyEquivalent so they are sent via the kitty keyboard protocol (fixes #1718).

Written for commit 65f4c86. Summary will update on new commits.

Unbound Cmd+Shift+<key> combinations were being silently swallowed by
the two-pass timestamp mechanism in performKeyEquivalent. When no menu
item matches and no Ghostty binding exists, AppKit never redispatches
the event, causing it to be lost.

Now directly send unbound Cmd+Shift combinations through to keyDown
so they reach terminal applications via the kitty keyboard protocol.

Fixes manaflow-ai#1718
@coderabbitai

coderabbitai Bot commented Mar 18, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The change modifies GhosttyNSView.performKeyEquivalent to dispatch unbound Cmd+Shift key combinations directly to keyDown and return true, replacing the prior behavior of returning false and relying on AppKit redispatch. A clarifying comment was added documenting the motivation and behavior for issue #1718.

Changes

Cohort / File(s) Summary
Key Dispatch Fix
Sources/GhosttyTerminalView.swift
Modified performKeyEquivalent to dispatch unbound Cmd+Shift key combinations via keyDown instead of returning false, preventing silent event swallowing. Added clarifying comment block explaining the change and issue reference.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐰 A Cmd+Shift key, once lost to the void,
Now dances through AppKit, no longer destroyed,
With keyDown dispatch, it finds its true path—
To terminal hands, safe from AppKit's wrath! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive PR description provides issue reference and clear summary of the problem and solution, though it lacks comprehensive coverage of all template sections. Add Testing section (how tested, what verified), Demo Video (if applicable), Review Trigger block, and confirm all Checklist items are addressed in comments.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: preventing unbound Cmd+Shift key combinations from being silently consumed.
Linked Issues check ✅ Passed The PR directly addresses issue #1718 by fixing the root cause: unbound Cmd+Shift events are now dispatched via keyDown instead of relying on failed AppKit redispatch.
Out of Scope Changes check ✅ Passed Changes are limited to fixing the two-pass timestamp behavior in GhosttyNSView.performKeyEquivalent with a clarifying comment, directly addressing the scope of issue #1718.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

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.

@vercel

vercel Bot commented Mar 18, 2026

Copy link
Copy Markdown

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

A member of the Team first needs to authorize it.

@greptile-apps greptile-apps 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.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai coderabbitai 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.

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 4889-4896: The current block sets lastPerformKeyEvent, calls
keyDown(with: event) and returns true, which bypasses AppKit menu handling;
modify it so that for Cmd+Shift combinations you first call
NSApp.mainMenu?.performKeyEquivalent(event) and if that returns true let the
menu handle it (do not call keyDown or return true), otherwise fall back to
setting lastPerformKeyEvent, calling keyDown(with: event) and returning true;
update the logic around lastPerformKeyEvent and the call site where
keyDown(with:) is invoked so menu routing is attempted before the fallback
dispatch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5991e7af-377e-4afe-8287-8ac35794467b

📥 Commits

Reviewing files that changed from the base of the PR and between 0a99bb5 and 65f4c86.

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

Comment on lines +4889 to +4896
// First pass: instead of returning false and hoping for a redispatch
// (which AppKit may not do if no menu item matches), directly send
// unbound Cmd+Shift combinations through to keyDown so they reach the
// terminal application via the kitty keyboard protocol.
// This fixes issue #1718 where unbound Cmd+Shift+<key> was silently swallowed.
lastPerformKeyEvent = event.timestamp
return false
keyDown(with: event)
return true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Don’t consume unbound Cmd+Shift before menu routing.

Line 4895 now forwards unbound Command shortcuts straight to keyDown(with:) and returns true, which bypasses AppKit menu-equivalent handling. This can block app shortcuts like Cmd+Shift+P / Cmd+Shift+, / Cmd+Shift+T / Cmd+Shift+G when terminal focus is active.

Proposed fix
-            // First pass: instead of returning false and hoping for a redispatch
-            // (which AppKit may not do if no menu item matches), directly send
-            // unbound Cmd+Shift combinations through to keyDown so they reach the
-            // terminal application via the kitty keyboard protocol.
-            // This fixes issue `#1718` where unbound Cmd+Shift+<key> was silently swallowed.
-            lastPerformKeyEvent = event.timestamp
-            keyDown(with: event)
-            return true
+            let normalized = event.modifierFlags
+                .intersection(.deviceIndependentFlagsMask)
+                .subtracting([.capsLock, .numericPad, .function])
+            let isCmdShiftOnly = normalized == [.command, .shift]
+
+            if isCmdShiftOnly {
+                // Preserve app menu shortcuts first, then pass through unbound Cmd+Shift.
+                if let menu = NSApp.mainMenu, menu.performKeyEquivalent(with: event) {
+                    return true
+                }
+                keyDown(with: event)
+                return true
+            }
+
+            // Keep existing non-Cmd+Shift behavior.
+            lastPerformKeyEvent = event.timestamp
+            return false

Based on learnings: command-key routing should attempt NSApp.mainMenu.performKeyEquivalent before fallback handling to avoid swallowed app shortcuts.

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

In `@Sources/GhosttyTerminalView.swift` around lines 4889 - 4896, The current
block sets lastPerformKeyEvent, calls keyDown(with: event) and returns true,
which bypasses AppKit menu handling; modify it so that for Cmd+Shift
combinations you first call NSApp.mainMenu?.performKeyEquivalent(event) and if
that returns true let the menu handle it (do not call keyDown or return true),
otherwise fall back to setting lastPerformKeyEvent, calling keyDown(with: event)
and returning true; update the logic around lastPerformKeyEvent and the call
site where keyDown(with:) is invoked so menu routing is attempted before the
fallback dispatch.

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 1 file

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/GhosttyTerminalView.swift">

<violation number="1" location="Sources/GhosttyTerminalView.swift:4895">
P1: Unbound Command key equivalents are now always consumed, which can block normal AppKit menu shortcut routing for non-Shift Cmd shortcuts.</violation>
</file>

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

// This fixes issue #1718 where unbound Cmd+Shift+<key> was silently swallowed.
lastPerformKeyEvent = event.timestamp
return false
keyDown(with: event)

@cubic-dev-ai cubic-dev-ai Bot Mar 18, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: Unbound Command key equivalents are now always consumed, which can block normal AppKit menu shortcut routing for non-Shift Cmd shortcuts.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Sources/GhosttyTerminalView.swift, line 4895:

<comment>Unbound Command key equivalents are now always consumed, which can block normal AppKit menu shortcut routing for non-Shift Cmd shortcuts.</comment>

<file context>
@@ -4886,8 +4886,14 @@ class GhosttyNSView: NSView, NSUserInterfaceValidations {
+            // This fixes issue #1718 where unbound Cmd+Shift+<key> was silently swallowed.
             lastPerformKeyEvent = event.timestamp
-            return false
+            keyDown(with: event)
+            return true
         }
</file context>
Fix with Cubic

@CMLKevin

Copy link
Copy Markdown

I'll get the CLA signed — will follow up once it's done.

1 similar comment
@CMLKevin

Copy link
Copy Markdown

I'll get the CLA signed — will follow up once it's done.

@BillionClaw

Copy link
Copy Markdown
Contributor Author

Closing per repository blocklist: maintainer threatened to ban. All submissions to this repo have been suspended.

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.

Unbound Cmd+Shift+<key> key combinations are silently swallowed, they never reach terminal/kitty protocol

2 participants