以前、画面共有中に英数/かなキー1発で、ローカルとリモートのIMEを同時に揃える Karabiner-Elements の設定をClaude Codeを使って記事にしました。
(元記事へのリンク: 画面共有のIME切り替え【Karabiner-Elements】英数/かなキー1発でローカルとリモートを同時に揃える)
その後、画面共有アプリを Apple 標準の「画面共有.app」から Screens 5 に乗り換えた。
そうしたら、この仕組みが動かなくなりまして。
英数キー、かなキーを押しても、ローカルだけ切り替わって、リモートは反応しないんですよね。
Claude CodeのFable5で色々と試して、わかったのが、原因は2つ。
Screens 5(VNCベース)は、英数/かなキーをリモートまで運ばない様子。そして、リモート側では「セキュア入力」が F18 などの通常キーを握りつぶしていたこと。
最終的に「英数 = fn+左Control、かな = fn+左Option」という修飾キーの組み合わせを送り、リモート側は Hammerspoon で受ける方式にしたらバッチリでした。
1つのキー操作で両方のIMEがバチッと揃う。快適です。(iPadでのリモートアクセスだと、これができないので、Macからやるのが良いんだろうな、そうなると、MacBookNeo がリモートアクセスのマシンとして最高な気がしています)
bundle ID を足すだけでは動かなかった
最初は簡単に終わると思っていた。詳細はClaude Codeに任せているけど、アプリのIDを変更するだけでいいと思っていました。
Karabiner の既存ルールは frontmost_application_if で画面共有アプリを判定しているので、そこに Screens 5 の bundle ID を足せばいいはず。
"bundle_identifiers": [
"^com\\.apple\\.ScreenSharing$",
"^com\\.apple\\.RemoteDesktop$",
"^com\\.edovia\\.screens\\.5$"
]
Screens 5 の bundle ID は com.edovia.screens.5。ターミナルで確認できる。
osascript -e 'id of app "Screens 5"'
で、ルールは発火するようになった。ローカルのIMEは切り替わる。
が、
リモートが切り替わらないんですよね、ここからが長かったです。
原因その1は、VNC
標準の画面共有.app は、Apple 独自の拡張で Mac の生のキーコード(japanese_eisuu / japanese_kana)をそのままリモートへ運んでくれているんですよね。さすがapple 純正。独自の拡張があるんですよね。だから元記事の方式が成立していた。
Screens 5 は VNC プロトコルで接続する。VNC はキーを「文字」ベースで運ぶ仕組みなので、JIS の英数/かなキーのような特殊キーは、そもそも転送されない様子。
ここから、色々とトライした。
Apple 日本語IMEの標準ショートカット(Ctrl+Shift+J でひらがな、Ctrl+Shift+; で英字)に変換して送る作戦。ダメ。
Screens 5 の接続設定「詳細」にある入力モード(キーストローク / ユニコード / レガシー)を全部切り替えてみる。全滅。orz
かなり四苦八苦したけど、この方向では解決せず。発想を変えることにした。
リモート側で受ける。でも Karabiner では受けられない
リモートも Mac なんだから、届いたキーをリモート側で変換すればいい。リモートにも Karabiner を入れて、送りやすいキー(F18/F19 あたり)を英数/かなに変換する作戦だ。
ところが、ここにも落とし穴がありました。
画面共有で届くキーは、リモートの macOS 上では「ソフトウェアが注入したイベント」になる。Karabiner-Elements が見張っているのは物理キーボード(HID層)だけなので、画面共有経由のキーは Karabiner に見えないらしい。まーそうですよね。キー入力が1つも見えない。
Claudeが、リモート側の受け手は Hammerspoon にすると言い出しまして、僕はまったく知らなかったんですが、これが救世主に。
Hammerspoon の eventtap は、注入されたイベントも見える場所で動いている。
F18 が消える。犯人は、セキュア入力
これで行けると思ったら、まだ動かない。
F18 を送っても、リモートの Hammerspoon まで届いていない。
調べていくと、原因は macOS のセキュア入力(Secure Keyboard Entry)だった。
リモートの loginwindow がセキュア入力を保持したままになっていて、F18/F19 のような通常キーの押下イベントは、イベントタップに届く前に null イベント化されて消えていた。
Claude Codeが、リモート側のキーイベントを収集するプログラムを作り、色々なキーを押して、問題を切り分けていく、すると、
見つけた抜け道があった。
修飾キー(Ctrl や Option)の状態変化イベント(flagsChanged)は、セキュア入力の影響を受けずに届く。
なので、送るキーを「fn+左Control(英数)」「fn+左Option(かな)」という修飾キーだけの組み合わせに変更した。
これなら VNC も通り抜けるし、セキュア入力にも消されない。
最終形の設定
操作側(手元の Mac)の Karabiner は、Screens 5 用のルールを別に作り、リモート向けの送出キーをこうする。
英数: { "key_code": "left_control", "modifiers": ["fn"] }
かな: { "key_code": "left_option", "modifiers": ["fn"] }
たとえば「左Cmd 単押しで両方を英数に揃える」ルールなら、こうなる。
{
"description": "Screens 5: 左Cmd 単押し → ローカルとリモートを両方 英数 に同期",
"manipulators": [
{
"type": "basic",
"conditions": [
{
"type": "frontmost_application_if",
"bundle_identifiers": ["^com\\.edovia\\.screens\\.5$"]
}
],
"from": {
"key_code": "left_command",
"modifiers": { "optional": ["any"] }
},
"to": [{ "key_code": "left_command", "lazy": true }],
"to_if_alone": [
{ "key_code": "left_control", "modifiers": ["fn"] },
{
"select_input_source": [
{ "input_source_id": "com.apple.keylayout.ABC" }
]
}
]
}
]
}
ローカル側の切り替えは元記事と同じ select_input_source。リモート向けの送出キーだけが変わった形だ。
標準の画面共有.app 用の元のルールはそのまま残してあるので、アプリによって送り方が自動で切り替わる。
karabiner.json をいじる前には、必ずバックアップを取ってください。
リモート側は、Hammerspoon をインストールして、~/.hammerspoon/init.lua にこれを書く。
-- 画面共有から届く fn+ctrl / fn+option で入力ソースを切り替える
local JA_IDS = {
"com.apple.inputmethod.Kotoeri.RomajiTyping.Japanese", -- Apple 日本語IME
"com.google.inputmethod.Japanese.base", -- Google 日本語入力
}
local function setJapanese()
for _, id in ipairs(JA_IDS) do
if hs.keycodes.currentSourceID(id) then return true end
end
return false
end
local function setEisuu()
hs.keycodes.currentSourceID("com.apple.keylayout.ABC")
end
local lastFlagTrigger = 0
imeFlagTap = hs.eventtap.new({ hs.eventtap.event.types.flagsChanged }, function(e)
local f = e:getFlags()
local now = hs.timer.secondsSinceEpoch()
if now - lastFlagTrigger < 0.3 then return false end
if f.fn and f.ctrl and not (f.alt or f.cmd or f.shift) then
lastFlagTrigger = now; setEisuu(); hs.alert.show("英数", 0.4)
elseif f.fn and f.alt and not (f.ctrl or f.cmd or f.shift) then
lastFlagTrigger = now; setJapanese(); hs.alert.show("かな", 0.4)
end
return false
end)
imeFlagTap:start()
hs.alert.show("IME 切替設定 読み込み完了", 1)
日本語入力ソースのIDは環境で違うので、リモートで確認して JA_IDS を合わせる。
defaults read com.apple.HIToolbox AppleEnabledInputSources
そして、ここが重要。Hammerspoon に与える権限は、システム設定の「アクセシビリティ」と「入力監視」の2つとも必要になる。
アクセシビリティだけだと、イベントタップは「有効」と報告されるのにキーが1つも届かない、という無言の失敗になる。ここで悩む時間がもったいないので、最初から両方許可してください。
これで、Screens 5 の画面越しに英数キーを押すと、リモートの画面に「英数」とポップアップが出て、両方のIMEが揃う。かなキーなら「かな」。ポップアップが出るので、届いているかどうかが目に見えるのも安心感がある。
ちなみに、動作確認が済んだあとは、このポップアップは、切り替えのたびに表示が出るのが煩わしくなってきたので、hs.alert.show("英数", 0.4) と hs.alert.show("かな", 0.4) の2行を削除(かコメントアウト)して、Reload Config をClaude Codeに依頼した。
まとめ
Screens 5 での画面共有IME同期、整理すると以下の感じに。
操作側の Karabiner が「英数 = fn+左Control、かな = fn+左Option」を送出。
VNC とセキュア入力を通り抜けた修飾キーイベントを、リモートの Hammerspoon が受けて入力ソースを切り替える。ローカル側は従来どおり select_input_source で同時に切り替え。
原因が「VNC の仕様」と「セキュア入力」の二段構えだったので、切り分けにはだいぶ時間がかかった。
実は、今回の調査は、操作側とリモート側、それぞれの Mac で動かしている Claude Code に手伝ってもらった。というより、1行もコードは書いていない、全部、話言葉で指示を出しただけ。すごい時代になったと痛感する。
操作側の Claude Code にリモート用の指示プロンプトを書いてもらい、それをリモートの Claude Code に貼る、という伝言ゲームをやっただけ。
セキュア入力が通常キーを null イベント化している、という核心はリモート側の解析で見つかった。二人三脚ならぬ、二AI三脚。
動いた瞬間は、ホッとしたというより、嬉しかった。
Screens 5 に乗り換えて英数/かなキーの同期が効かなくなって困っている方は(かなりニッチだと思うけれど)、お試しください。






