Karabiner-ElementsでSandS設定時にIME切り替え(control+space)が遅延する問題と解決方法
前提条件
この記事は、以下の条件に該当する人向けの内容である。
- macOSを使用している
- Karabiner-Elements v15.0.0以降を使用している
- IME切り替えに
control + spaceを使用している(macOSのデフォルト設定) - Karabiner-ElementsでSandS(Space and Shift)を設定している
SandS(Space and Shift)とは
SandSとは、spaceキーに2つの役割を持たせるキーマッピング手法である。
- spaceキーを単独で押して離す → 通常のspace入力
- spaceキーを押しながら他のキーを押す → Shiftキーとして機能
Karabiner-Elementsでは、以下のような設定で実現できる。
{ "description": "Change spacebar to left_shift. (Post spacebar if pressed alone)", "manipulators": [ { "from": { "key_code": "spacebar", "modifiers": { "optional": ["any"] } }, "to": [{ "key_code": "left_shift" }], "to_if_alone": [{ "key_code": "spacebar" }], "type": "basic" } ] }
この設定は事前定義済みであるため、以下の手順でマウスクリックするだけで設定可能である。
- Karabiner-Elementsを起動する
- 左側のメニューで [Complex Modifications] をクリックする
- [Add predefined rule] ボタンをクリックする
- [Change spacebar to left_shift. (Post spacebar if pressed alone)] の右側にある [Enable] ボタンをクリックする

事象
上記のSandS設定を使用している状態でcontrol + spaceを押してIMEを切り替えると、以下の問題が発生する。
- IME切り替えに遅延が発生する
- 1文字目の入力が意図と反対のIMEで行われてしまう
原因
SandSの設定では、spaceキーを押した瞬間にleft_shiftが送信される。そのため、control + spaceを押すとcontrol + left_shiftとして処理されてしまい、IME切り替えのショートカットが正常に認識されない。

解決方法
control + spacebarの組み合わせをSandS変換の対象から除外するルールを追加する。
{ "description": "Change spacebar to left_shift. (Post spacebar if pressed alone, pass through with control)", "manipulators": [ { "type": "basic", "from": { "key_code": "spacebar", "modifiers": { "mandatory": ["control"], "optional": ["caps_lock"] } }, "to": [ { "key_code": "spacebar", "modifiers": ["control"] } ] }, { "from": { "key_code": "spacebar", "modifiers": { "optional": ["any"] } }, "to": [{ "key_code": "left_shift" }], "to_if_alone": [{ "key_code": "spacebar" }], "type": "basic" } ] }
ポイント
- 最初のルールが
control + spacebarを検出し、そのままcontrol + spacebarを送信する(SandS変換をバイパス) - 2番目のルールは既存のSandS設定で、control以外の場合にShift変換を行う
- Karabiner-Elementsはルールを上から順に評価するため、
control + spaceのルールを先に配置する必要がある
補足:他のモディファイアキーも除外したい場合
command + spaceなど他の組み合わせも除外したい場合は、以下のように追加できる。
{ "description": "Change spacebar to left_shift. (Post spacebar if pressed alone, pass through with modifiers)", "manipulators": [ { "type": "basic", "from": { "key_code": "spacebar", "modifiers": { "mandatory": ["control"], "optional": ["caps_lock"] } }, "to": [{ "key_code": "spacebar", "modifiers": ["control"] }] }, { "type": "basic", "from": { "key_code": "spacebar", "modifiers": { "mandatory": ["command"], "optional": ["caps_lock"] } }, "to": [{ "key_code": "spacebar", "modifiers": ["command"] }] }, { "from": { "key_code": "spacebar", "modifiers": { "optional": ["any"] } }, "to": [{ "key_code": "left_shift" }], "to_if_alone": [{ "key_code": "spacebar" }], "type": "basic" } ] }