Skip to content

fix: ⌘ tap switches IME even while Shift/other modifiers are held (regression from 2.4.11)#126

Merged
kazukinakai merged 1 commit into
mainfrom
fix/modifier-tap-with-held-modifiers
Jul 6, 2026
Merged

fix: ⌘ tap switches IME even while Shift/other modifiers are held (regression from 2.4.11)#126
kazukinakai merged 1 commit into
mainfrom
fix/modifier-tap-with-held-modifiers

Conversation

@kazukinakai

Copy link
Copy Markdown
Member

Problem

Since v2.4.11 (#122), tapping a Command key while any other modifier is held no longer switches the input source. Holding Shift and tapping left ⌘ — e.g. committing a kana conversion and dropping to eisu — does nothing.

Causes (three defects in the tap gesture path)

  1. Chord-cancel from fix(keyevent): tear down old event tap on rebuild, cancel lone-modifier gesture on chords, post keyUp for media-key remaps #122: modifierKeyDown cancelled the lone-press gesture whenever a second modifier was physically held, making every Shift/Option/Control+⌘ tap a no-op.
  2. Residual flags leak: even when a tap fired, the synthesized Eisu/Kana event inherited the still-held modifier flags, so the IME saw Shift+英数 and ignored it.
  3. keyUp cancel: a regular key's up-stroke cancelled the pending gesture, so pressing ⌘ to commit while the last typed character key was still physically depressed (routine in fast typing) misfired.

Fix

Tests

swift test: 51 tests, 0 failures. New coverage: Shift-held taps (both press orders), residual-flag stripping, independent sibling-command taps, keyDown-cancel, keyUp-no-cancel, disable-mapping.

Releases as 2.5.0 (manifest + CHANGELOG updated).

🤖 Generated with Claude Code

…trip residual flags from the synthesized tap

Regression from the 2.4.11 chord-cancel (#122): holding Shift (or any other
modifier) and tapping ⌘ no longer switched the input source, breaking
"commit kana conversion with left ⌘". Three defects in the tap gesture path:

- modifierKeyDown cancelled the lone-press gesture whenever a second
  modifier was physically held, so every Shift/Option/Control+⌘ tap was a
  no-op. Replaced the single tracked-keyCode slot + downModifierKeyCodes
  chord-cancel with per-modifier pending taps (`pendingModifierTaps`): a
  modifier release fires its mapping iff nothing but modifier activity
  happened since its own press, regardless of press/release order. This
  also removes the inconsistent re-arm hole #122 was closing — taps now
  fire consistently instead of never.
- The synthesized Eisu/Kana event inherited residual held-modifier flags
  (convertedEvent keeps event.flags), so even when a tap fired with Shift
  held the IME saw Shift+英数 and ignored it. modifierKeyUp now posts the
  bare output shortcut (output keyCode + output flags only) through a
  postModifierTap seam (injectable for tests).
- keyUp of a regular key unconditionally cancelled the pending gesture, so
  pressing ⌘ to commit while the last typed character key was still
  physically depressed (routine in fast typing) misfired. Only keyDown,
  mouse events, and media keys cancel now.

Reworks the modifier-gesture unit tests around the new semantics and the
capture seam: taps with Shift held (both orders), independent sibling
taps, keyDown-cancel, keyUp-no-cancel, disable-mapping, and residual-flag
stripping.

Release 2.5.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kazukinakai kazukinakai enabled auto-merge July 6, 2026 00:25
@kazukinakai kazukinakai merged commit d5823a7 into main Jul 6, 2026
2 checks passed
@kazukinakai kazukinakai deleted the fix/modifier-tap-with-held-modifiers branch July 6, 2026 00:26
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