How the Shift Key Toggles Smart and Traditional English Mode in Hallelujah IM
Pressing and releasing the Right Shift key toggles Hallelujah IM between Smart English mode, which passes keystrokes directly to macOS, and Traditional Chinese mode, which buffers characters for conversion.
The hallelujahim input method for macOS implements a dedicated Right Shift shortcut that allows users to instantly switch between input behaviors without changing system input sources. This mechanism is controlled by the _defaultEnglishMode boolean flag in src/InputController.mm, determining whether the IME intercepts alphabetic keys or lets the operating system handle them directly.
The Toggle Logic in InputController.mm
The shift toggle is implemented inside the -handleEvent:client: method in src/InputController.mm. This method receives both key-down events and modifier-flag-changed events, monitoring specifically for the release of the Right Shift key to trigger the mode switch.
The code validates a precise sequence of conditions before flipping the state:
// src/InputController.mm, lines 39-44
if (modifiers == 0 &&
_lastEventTypes[1] == NSEventTypeFlagsChanged &&
_lastModifiers[1] == NSEventModifierFlagShift &&
event.keyCode == KEY_RIGHT_SHIFT &&
!(_lastModifiers[0] & NSEventModifierFlagShift)) {
_defaultEnglishMode = !_defaultEnglishMode; // toggle flag
The logic verifies that:
- The current event reports no active modifiers (
modifiers == 0) - The previous event was a Shift press (
_lastModifiers[1] == NSEventModifierFlagShift) - The keyCode matches Right Shift (
KEY_RIGHT_SHIFT, defined as60) - Left Shift is not currently held (
!(_lastModifiers[0] & NSEventModifierFlagShift))
When all conditions are satisfied, the _defaultEnglishMode boolean is inverted. A value of YES activates Smart English mode, while NO restores Traditional Chinese conversion.
Committing Pending Text When Enabling Smart English
When the toggle switches to Smart English mode (_defaultEnglishMode becomes YES), the IME immediately commits any pending Chinese composition to prevent data loss:
if (_defaultEnglishMode) {
NSString *bufferedText = [self originalBuffer];
if (bufferedText && bufferedText.length > 0) {
[self cancelComposition];
[self commitComposition:sender]; // flush pending Chinese text
}
}
This ensures that buffered characters are inserted into the document before the IME stops intercepting subsequent keystrokes.
How the Mode Flag Controls Input Processing
Later in the same -handleEvent:client: method, the _defaultEnglishMode flag determines processing for alphabetic key-down events:
// src/InputController.mm, lines 53-56
case NSEventTypeKeyDown:
if (_defaultEnglishMode) {
break; // bypass the conversion pipeline
}
- Smart English mode (
YES): Execution hits thebreakstatement immediately, returning control to macOS. Characters appear directly without triggering candidate windows. - Traditional mode (
NO): Execution continues into the conversion pipeline, where the IME buffers keystrokes and displays Chinese/English candidate suggestions.
Why Only the Right Shift Key Works
The implementation explicitly restricts this shortcut to the Right Shift key only by checking event.keyCode == KEY_RIGHT_SHIFT. Left Shift uses a different keyCode and is intentionally excluded to prevent accidental toggles during normal typing when users hold Shift for capitalization.
This design choice ensures that standard capitalization habits (Left Shift) do not trigger unwanted mode switches, while keeping the toggle accessible via the less frequently used Right Shift key.
Practical Usage and Mode Detection
When using Hallelujah IM, the Right Shift toggle operates as follows:
| Action | Result |
|---|---|
| Press Right Shift (release) | Switches to Smart English – alphabetic keys pass through directly. |
| Press Right Shift again | Switches back to Traditional – Chinese conversion resumes. |
| Type while in Smart English | Characters appear immediately without candidate windows. |
| Type while in Traditional | Characters buffer and trigger candidate selection. |
To programmatically check the current mode from within the controller, inspect the _defaultEnglishMode property:
- (void)checkCurrentMode {
BOOL isSmartEnglish = _defaultEnglishMode;
NSLog(@"Current mode: %@", isSmartEnglish ? @"Smart English" : @"Traditional Chinese");
}
Summary
- Right Shift release toggles the
_defaultEnglishModeflag insrc/InputController.mmvia the-handleEvent:client:method. - Smart English mode bypasses the conversion pipeline entirely, letting macOS handle keystrokes directly without IME interception.
- Traditional mode activates the full IME pipeline with character buffering and candidate selection.
- The toggle specifically requires Right Shift (keyCode 60) to avoid conflicts with standard capitalization using Left Shift.
- When switching to Smart English, any pending Chinese text in the composition buffer is automatically committed before passthrough begins.
Frequently Asked Questions
What happens to unfinished Chinese text when I press Right Shift?
When you toggle into Smart English mode, Hallelujah IM automatically commits any pending composition. The code calls [self commitComposition:sender] to flush the buffer, ensuring your typed Chinese characters are inserted before the IME stops intercepting keys.
Why doesn't Left Shift toggle the input mode?
The implementation explicitly checks for event.keyCode == KEY_RIGHT_SHIFT (value 60). Left Shift uses a different keyCode and is intentionally excluded to prevent accidental mode switches during normal typing when users hold Shift for capitalization.
How do I know which mode I'm currently in?
There is no built-in visual indicator in the provided source code, but you can detect the mode programmatically by checking the _defaultEnglishMode boolean in InputController. When YES, you are in Smart English mode; when NO, you are in Traditional Chinese conversion mode.
Can I disable the Shift toggle functionality?
According to the source implementation in src/InputController.mm, the Shift toggle is hardcoded in the -handleEvent:client: method. To disable it, you would need to modify the source code and remove or comment out the conditional block that checks for KEY_RIGHT_SHIFT and toggles _defaultEnglishMode.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →