Repository navigation
Revert "Fix arrow key navigation in IME candidate window during composition (#3694)" - #3849
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThis PR simplifies the IME key-event handling pipeline by removing early text-input key-equivalent routing, narrowing the IME suppression decision to marked-text state and accumulated text, and updating test interception to Objective-C method swizzling. Keyboard layout capture becomes conditional, marked-text clearing is guarded on non-empty state, and large test suites for Zhuyin candidate navigation are removed. ChangesIME Key-Event Handling Simplification
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
Greptile SummaryThis reverts #3694 ("Fix arrow key navigation in IME candidate window"), which introduced a broad
Confidence Score: 5/5Clean revert of a confirmed regression — restores the narrow marked-text-only suppression path that was working before #3694 and fixes broken arrow-key navigation for all Korean/Japanese/Pinyin IME users. Every changed line either deletes code introduced by #3694 or restores an exact pre-#3694 spelling. The post-revert suppression logic is small and easy to audit: it only fires when marked text is present and text or selection actually changed, which matches the intended invariant. Conflict resolution in the DEBUG accessor block is correct and introduces no new logic. The test swizzle switch from a DEBUG static hook to standard ObjC method_exchangeImplementations is the right approach and the pattern is implemented correctly. No files require special attention. The largest deletion is in cmuxTests/CJKIMEMarkedSelectionTests.swift, but those tests were exclusively for the reverted #3694 behavior. Important Files Changed
Sequence DiagramsequenceDiagram
participant W as NSWindow
participant V as GhosttyNSView.keyDown
participant I as interpretKeyEvents
participant S as shouldSuppressGhosttyKeyForwarding
participant G as Ghostty terminal
W->>V: keyDown(event)
V->>I: interpretKeyEvents([translationEvent])
I-->>V: marked text state updated
V->>S: before, after, accumulatedText
alt marked text present and text or selection changed
S-->>V: true - suppress
else no marked text or state unchanged
S-->>V: false - forward
V->>G: sendGhosttyKey(keyEvent)
end
Reviews (1): Last reviewed commit: "Revert "Fix arrow key navigation in IME ..." | Re-trigger Greptile |
Apple Zhuyin reports plain Down during marked text as moveDown: without changing composition, so simply consuming the arrow or asking AppKit's app-candidate panel does not show the IME candidate menu. Keep the #3691 intercept exact, then replay the IME candidate expansion key into NSTextInputContext only for that unchanged Down case. Constraint: #3691 scope is exact Apple Zhuyin, active marked text, plain Down/Up only; Up remains consume-only for candidate navigation Rejected: private AppKit candidate presentation selectors | dogfood still showed no Zhuyin candidate menu Rejected: broad IME routing/keyUp state/window reroute | reverted in #3849 after breaking other IMEs Confidence: medium Scope-risk: narrow Directive: Do not widen this beyond Apple Zhuyin marked-text Down without per-IME shell-forwarding regression guards and manual IME dogfood Tested: git diff --check Tested: ./scripts/test-unit.sh test -only-testing:cmuxTests/CJKIMEMarkedSelectionTests Not-tested: local reload/manual dogfood skipped per user request; user will reload locally
Apple Zhuyin reports plain Down during marked text as moveDown: without changing composition, so simply consuming the arrow or asking AppKit's app-candidate panel does not show the IME candidate menu. Keep the #3691 intercept exact, then replay the IME candidate expansion key into NSTextInputContext only for that unchanged Down case. This also keeps the Zhuyin candidate-arrow test cleanup symmetrical by restoring the debug expansion handler after the commit-from-interpretKeyEvents regression case. Constraint: #3691 scope is exact Apple Zhuyin, active marked text, plain Down/Up only; Up remains consume-only for candidate navigation Rejected: private AppKit candidate presentation selectors | dogfood still showed no Zhuyin candidate menu Rejected: broad IME routing/keyUp state/window reroute | reverted in #3849 after breaking other IMEs Confidence: medium Scope-risk: narrow Directive: Do not widen this beyond Apple Zhuyin marked-text Down without per-IME shell-forwarding regression guards and manual IME dogfood Tested: git diff --check Tested: ./scripts/test-unit.sh test -only-testing:cmuxTests/CJKIMEMarkedSelectionTests Tested: ./scripts/reload.sh --tag issue-3691-zhuyin-candidate-arrows Not-tested: latest local manual IME dogfood; user/maintainer should verify Apple Zhuyin Down opens the candidate window in the tagged app
Reverts #3694 ("Fix arrow key navigation in IME candidate window during composition," merged 2026-05-08).
Why
#3694 was the source of an arrow-key regression that broke navigation for any user with a CJK / Korean / Japanese / Vietnamese IME selected as the active system input source. Two follow-on PRs (#3767, #3836) extended the same framework and made the breakage worse. Both have been reverted (#3845, #3846), but the no-marked-text branch and broad
isInputMethodSourcepredicate introduced by #3694 itself are still live and still suppress arrow keys for IME users empirically — confirmed by a Korean user (yoonkeee@gmail.com, localeko-KR) who reports arrows still dead on the post-#3845/#3846 nightly (a183d44be).What this reverts
shouldSuppressGhosttyKeyForwardingAfterIMEHandling(the broadisInputMethodSource(inputSourceId)gate that suppresses any non-numpad-fallback event for any IME user when AppKit claims to have handled the event).shouldKeepIMECompositionCommandInsideTextInput(the 15-key navigation/control case list).shouldRouteTextInputKeyEquivalentToKeyDown(the window-level re-route inAppDelegate.performKeyEquivalent).shouldOpenZhuyinCandidatesWithSyntheticSpaceandshouldRememberZhuyinCandidateInteraction(the Zhuyin candidate-window synthetic-Space + interaction tracking).isTraditionalZhuyinInputSource,isInputMethodSource,shouldAllowDeferredNumpadIMEFallback(helpers).imeSuppressedKeyUpKeyCodes/zhuyinCandidateOpenRequestedIME transient state onGhosttyNSView.AppDelegate.swiftthat funneled key equivalents through the re-route.cmuxTests/CJKIMEMarkedSelectionTests.swiftplus the test changes incmuxTests/CJKIMEInputTests.swift.What this re-opens
Issue #3691 — "Chinese IME (Zhuyin/Bopomofo): arrow keys cannot navigate candidate window in terminal." Re-opening it explicitly; see the updated body there for guardrails that any future fix must satisfy so we don't re-enter this loop.
Trade
Strongly positive net trade.
Conflicts resolved
Sources/GhosttyTerminalView.swifthad a small conflict in the DEBUG test accessor block (lines 7056–7082) because the #3767 / #3836 reverts had already partially un-done the surrounding code. Resolved by taking the pre-#3694 version (single test accessor pair, noimeSuppressedKeyUpKeyCodesForTesting/zhuyinCandidateOpenRequestedForTesting/setIMETransientStateForTesting/debugTextInputEventHandler— all of those were #3694 additions).Post-revert sanity grep confirms zero residual references in
Sources/,cmuxTests/,cmuxUITests/to any of the #3694-introduced symbols.Verification target
yoonkeee@gmail.com(locale ko-KR) — the post-revert nightly cut from this branch should be the test build. Comment on #3691 (or a follow-up issue) once they confirm.Note
Medium Risk
Changes core keyboard/IME event handling by removing IME-specific suppression/rerouting paths and related transient state, which could affect shortcut and arrow-key behavior across input methods.
Overview
Reverts the prior IME candidate-navigation framework by removing IME-specific command/arrow handling that suppressed forwarding even when no marked text was active, along with the window-level
performKeyEquivalentreroute that funneled some key equivalents back intokeyDown.Simplifies IME forwarding decisions to only suppress terminal key forwarding when marked text/selection actually changes, and deletes related transient state in
GhosttyTerminalView(e.g. suppressed key-up tracking and Zhuyin candidate-open bookkeeping).Updates tests by dropping the large Zhuyin candidate/arrow navigation suite and switching CJK IME interception from a custom debug handler to a targeted
interpretKeyEventsmethod swizzle.Reviewed by Cursor Bugbot for commit ecdf3fc. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Reverts the IME arrow-key routing from #3694 to fix a regression that disabled arrow/page/home/end/space keys for users with CJK/Korean/Japanese/Vietnamese IMEs. Normal terminal navigation is restored; Zhuyin candidate-window arrows during composition remain unfixed and are tracked in issue #3691.
AppDelegatethat intercepted IME arrows.GhosttyNSView+IMECompositionandGhosttyTerminalView.Written for commit ecdf3fc. Summary will update on new commits.
Summary by CodeRabbit