Skip to content

Fix Shift+Space IME toggle inserting a space (#641) - #670

Merged
austinywang merged 2 commits into
mainfrom
fix-issue-641
Mar 1, 2026
Merged

austinywang merged 2 commits into
mainfrom
fix-issue-641

Conversation

@austinywang

@austinywang austinywang commented Feb 28, 2026 •

Copy link
Copy Markdown
Contributor

Summary\n- suppress fallback text injection for Shift+Space when AppKit/IME consumes the event for input-source switching\n- keep key event dispatch intact (only avoid synthesized space text)\n- add regression tests for Shift+Space fallback suppression\n\n## Validation\n- ./scripts/setup.sh\n- xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug -destination 'platform=macOS' build\n- ./scripts/reload.sh --tag fix-issue-641\n- xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux-unit -configuration Debug -destination 'platform=macOS' -only-testing:cmuxTests/CJKIMEShiftSpaceFallbackTests test\n\nCloses #641

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Resolved unintended space character insertion when pressing Shift+Space during CJK input method editing.
  • Tests

    • Added test coverage for Shift+Space behavior during IME input and verified it doesn't affect regular space key behavior.

@vercel

vercel Bot commented Feb 28, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Mar 1, 2026 5:05am

@coderabbitai

coderabbitai Bot commented Feb 28, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This pull request adds runtime logic to suppress Shift+Space fallback text during IME (Input Method Editor) handling in Ghostty's terminal view. A private suppression detection method is integrated into key event processing, with a public test helper variant and two new test cases validating the behavior.

Changes

Cohort / File(s) Summary
IME Shift+Space Suppression
Sources/GhosttyTerminalView.swift
Added private method shouldSuppressShiftSpaceFallbackText() to detect when AppKit consumes Shift+Space for IME switching, preventing erroneous space synthesis. Integrated suppression check into key processing path. Added public test helper method. Refactored accumulated text handling to use accumulatedText variable consistently.
Shift+Space Fallback Tests
cmuxTests/CJKIMEInputTests.swift
New test suite CJKIMEShiftSpaceFallbackTests with two test cases verifying that Shift+Space fallback suppression activates correctly when no marked text exists, and does not affect regular Space input.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Poem

🐰 A hop-skip through IME flows,

Where Shift and Space no longer pose,

A duplicate woe! The rabbit did see,

Suppression logic, crisp and clean and free,

One space wins the race! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix Shift+Space IME toggle inserting a space (#641)' directly and specifically describes the main change—preventing unwanted space insertion when Shift+Space is used for IME toggling.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-issue-641

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

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

🧹 Nitpick comments (1)
Sources/GhosttyTerminalView.swift (1)

3145-3147: Use the original event for suppression checks to avoid modifier-translation coupling.

Right now the predicate evaluates translationEvent. Passing the original event keeps this strictly tied to the physical Shift+Space shortcut and avoids config-dependent false positives/negatives.

Suggested diff
-            let suppressShiftSpaceFallbackText =
-                shouldSuppressShiftSpaceFallbackText(
-                    event: translationEvent,
-                    markedTextBefore: markedTextBefore
-                )
+            let suppressShiftSpaceFallbackText =
+                shouldSuppressShiftSpaceFallbackText(
+                    event: event,
+                    markedTextBefore: markedTextBefore
+                )

Also applies to: 3265-3269

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

In `@Sources/GhosttyTerminalView.swift` around lines 3145 - 3147, The suppression
predicate should use the original NSEvent rather than the translated/modified
translationEvent to avoid coupling modifier checks to input-method translations:
update calls to shouldSuppressShiftSpaceFallbackText(...) to pass the original
event (the parameter named event) instead of translationEvent so the function
evaluates the physical Shift+Space modifier state; adjust both occurrences
around shouldSuppressShiftSpaceFallbackText and any related logic that currently
forwards translationEvent (also at the second occurrence indicated) to maintain
correct suppression behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@Sources/GhosttyTerminalView.swift`:
- Around line 3145-3147: The suppression predicate should use the original
NSEvent rather than the translated/modified translationEvent to avoid coupling
modifier checks to input-method translations: update calls to
shouldSuppressShiftSpaceFallbackText(...) to pass the original event (the
parameter named event) instead of translationEvent so the function evaluates the
physical Shift+Space modifier state; adjust both occurrences around
shouldSuppressShiftSpaceFallbackText and any related logic that currently
forwards translationEvent (also at the second occurrence indicated) to maintain
correct suppression behavior.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1392bd1 and 755831c.

📒 Files selected for processing (2)
  • Sources/GhosttyTerminalView.swift
  • cmuxTests/CJKIMEInputTests.swift

@greptile-apps

greptile-apps Bot commented Feb 28, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Fixed Shift+Space IME toggle inserting unwanted space characters into the terminal. The fix adds targeted suppression logic that detects when AppKit/IME consumes Shift+Space for input-source switching (indicated by no insertText call and no marked text) and prevents the fallback space character from being synthesized. The key event itself still gets dispatched to allow IME handling, only the text injection is suppressed.

  • Added shouldSuppressShiftSpaceFallbackText() method that checks for Shift+Space (keyCode 49) with no other modifiers and no active IME composition
  • Integrated suppression check into keyDown() fallback path when keyTextAccumulator is empty
  • Added test-only exposure method for unit testing
  • Added comprehensive regression tests covering both the suppression case and ensuring regular Space input works normally

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The fix is narrowly scoped to a specific edge case (Shift+Space IME toggle), uses precise conditional checks (keyCode, modifiers, marked text state), and includes comprehensive regression tests. The logic only suppresses fallback text injection in the specific scenario where AppKit consumes the event for IME switching, while preserving normal key event dispatch. Regular Space input and other key combinations remain unaffected.
  • No files require special attention

Important Files Changed

Filename Overview
Sources/GhosttyTerminalView.swift Added logic to suppress space character when Shift+Space is used for IME input-source switching, preventing unwanted space insertion while preserving IME toggle functionality
cmuxTests/CJKIMEInputTests.swift Added regression tests for Shift+Space fallback suppression, covering both the IME toggle case and ensuring regular Space input remains unaffected

Last reviewed commit: 755831c

This branch was successfully deployed

1 active deployment
Preview — 42968e35 Deployed Mar 1, 2026 by vercel[bot]
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