Ubuntu で Copilot キーを Ctrl 化する
Copilot キーを evsieve で evdev 層から横取りして Ctrl 化・無効化し、systemd で永続化する手順を紹介します。
目次
はじめに
最近 Copilot キー(AI アシスタントキー)を購入しました。以前使っていた Copilot キー非搭載のキーボードでもキーの割当てを変更していたので、今回も同じ要領で行けるかと思いましたが、少し手こずったので手順をメモします。
この記事のゴールは次の通りです。
- Copilotキー単押し → 単一の
RightCtrlとして認識される - Ctrl + C / Ctrl + V などのショートカットが全アプリで使える
- 再起動後も自動で有効になる
- 失敗しても元に戻せる
この記事では右 Ctrl に割当てる手順を紹介しますが、完全に無効化することもできます。
前提
- Linux + GNOME 環境であること(X11 で動作確認しています)
- Copilot キー搭載キーボードを使っていること
- 例: ELECOM Leggero シリーズ (新モデルは「AIアシスタントキー搭載」を公式に謳っています)
まず自分の環境が前提を満たすか確認します。
# x11 か wayland かを確認します。
echo "$XDG_SESSION_TYPE"
# 2つともパスが出ることを確認してください。出なければ sudo apt install x11-utils xinput です。
which xev xinput読み替え表
以降の手順では、環境依存の値を変数で表します。最初にあなたの値を調べて、この表を埋めてから読み進めてください。
| 変数表記 | 意味 | 著者の例 | あなたの値の調べ方 |
|---|---|---|---|
$KEYREMAP_DIR |
作業ディレクトリー | ~/Documents/apps/keyremap |
任意の空き場所で良いです。手順では ~/Documents/apps/keyremap を使います。 |
$DEVICE_LINK |
キーボードのデバイス | /dev/input/by-id/usb-ELECOM_ELECOM_Leggero-event-kbd |
ls -l /dev/input/by-id/ | grep -i kbd で特定します。 |
$YOUR_USER |
ユーザー名 | taikun |
id -un で確認します。 |
$EVSIEVE_DIR |
evsieve のビルド場所 | ~/Documents/apps/evsieve |
任意です。$KEYREMAP_DIR と分けると管理しやすいと思います。 |
id -un
ls -l /dev/input/by-id/ | grep -i kbd
# 例:
# usb-ELECOM_ELECOM_Leggero-event-kbd -> ../event5
# usb-ELECOM_ELECOM_Leggero-if01-event-kbd -> ../event6
# → event-kbd 側 (if01 が付かない方) を使うのが一般的?なぜ普通の方法ではできないのか
結論だけ知りたい方は 手順1 まで読み飛ばして構いません。
なぜ普通の方法ではできないのか
Copilotキーは1つのキーではない
Copilot キーは単一のスキャンコードを送りません。左 Shift + Win + F23 の 3 キーを同時押しすることがハードウェアレベルで実装される仕様です。ハードウェアレベルでの実装なので、ソフトウェア側での制御は簡単ではありません。
xev -event keyboardCopilot キーを 1 回押すと、以下が 2〜3 ms 間隔でほぼ同時に発火します。
keycode 133 (Super_L) ← Win 部分
keycode 50 (Shift_L) ← ゴースト (仕様)
keycode 201 (F23 相当) ← F23 部分。XKB 上は XF86TouchpadOff と表示されることがあるようです。ゴースト Shift が Ctrl+C を壊す
133 番に Ctrl を割当てても、押すたびに Shift が混ざるため、コピペなどのショートカットが成立しません。ゴーストの Shift は本物の左 Shift と同一 keycode のため、ソフトウェア側では分離できません。よってキーマップの書き換えによる修飾子化は断念する必要があります。
evdev層での横取りが必要
X より下の evdev 層で LeftMeta → LeftShift → F23 の順序(デバイスによっては順番が異なるかも?)を検出して飲み込み、代わりに単一の RightCtrl を合成します。使うのは evsieve です。
全体像
処理の流れは次の通りです。
- Copilotキー押下: Shift + Win + F23 発火
- evsieve: evdev層で横取り
- 仮想デバイス kbd-no-copilot: 単一の RightCtrl を合成
- アプリ: Ctrl+C などが効く
evsieve が物理デバイスを grab し、仮想デバイス kbd-no-copilot を常駐させます。常駐化は root の systemd サービス 1 つで行い、ログイン後の追加設定は不要です。
手順1: デバイスと環境を確認する
ls -l /dev/input/by-id/ | grep -i kbd
# $DEVICE_LINK をメモします。
# 例: /dev/input/by-id/usb-ELECOM_ELECOM_Leggero-event-kbd複数の event-kbd が出る場合は、if01 が付かない方から試します。確実に特定したい場合は、次のコマンドで実際にキーを押して反応する方を選びます。
sudo evtest
# 一覧から候補を選び、Copilotキーや通常キーを押して反応を見ます。
# Ctrl+C で抜けます。作業ディレクトリーを用意します。
mkdir -p ~/Documents/apps/keyremap
ls -ld ~/Documents/apps/keyremap手順2: evsieveをビルドする
--hook ... sequential ... send-key 方式は安定版 v1.4.0 に無いため、main ブランチをビルドします。Rust と libevdev が必要です。
mkdir -p ~/Documents/apps/evsieve
cd ~/Documents/apps/evsieve
git clone --depth 1 https://github.com/KarsMulder/evsieve.git srccargo --version
rustc --version
# 出なければ https://rustup.rs/ から rustup を入れてください。libevdev の dev ファイルが無ければ、システムに入れず局所的な展開で済ませます (ランタイムの libevdev2 は通常存在します)。
mkdir -p debs sysroot
apt-get download libevdev-dev
mv *.deb debs/
dpkg-deb -x debs/libevdev-dev_*.deb sysroot/
LIBRARY_PATH="$PWD/sysroot/usr/lib/x86_64-linux-gnu" cargo build --release --manifest-path src/Cargo.toml
# → src/target/release/evsieve ができます。機能確認をします。
./src/target/release/evsieve --help | grep -E "hook|withhold|delay|sequential|send-key"
# 何も出なければ、古いタグを拾っている可能性があります。git pull して再ビルドしてください。手順3: ファイルを配置する
$KEYREMAP_DIR (例: ~/Documents/apps/keyremap/) に以下を置きます。
- keyremap
- evsieve
- remap.sh
- keyremap-evsieve.service
| ファイル | 内容 |
|---|---|
evsieve |
ビルド済みバイナリ (コピー) |
remap.sh |
手動テスト用 |
keyremap-evsieve.service |
systemd unit |
cp ~/Documents/apps/evsieve/src/target/release/evsieve ~/Documents/apps/keyremap/evsieve
chmod +x ~/Documents/apps/keyremap/evsieve
chmod +x ~/Documents/apps/keyremap/remap.shremap.sh
./remap.sh start|stop で使います。
start:sudo evsieve ... &で起動 → 仮想デバイス出現待ち。二重 grab 防止のために起動中はstartを拒否します。stop: evsieve を停止します。
#!/bin/bash
set -eu
DIR="$(cd "$(dirname "$0")" && pwd)"
EVSIEVE="$DIR/evsieve"
# ▼ デバイス名に置き換えます。
DEVICE="/dev/input/by-id/usb-ELECOM_ELECOM_Leggero-event-kbd"
usage() {
echo "Usage: $0 start|stop" >&2
}
wait_for_output() {
local i=0
while ! xinput list --name-only 2>/dev/null | grep -qx "kbd-no-copilot"; do
i=$((i + 1))
if [ "$i" -ge 100 ]; then
echo "timed out waiting for kbd-no-copilot" >&2
return 1
fi
sleep 0.2
done
}
cmd_start() {
if pgrep -af "[e]vsieve.*kbd-no-copilot" >/dev/null; then
echo "evsieve is already running. Refusing double grab." >&2
exit 1
fi
# RightCtrl 化する場合です。Copilot キーを完全に無効化するなら --hook の send-key と --delay オプションを外します。
sudo "$EVSIEVE" \
--input "$DEVICE" grab \
--hook key:leftmeta key:leftshift key:f23 sequential period=0.1 send-key=key:rightctrl \
--withhold \
--delay key:rightctrl:0 period=0.3 \
--output name="kbd-no-copilot" create-link="kbd-no-copilot" &
wait_for_output
echo "started. Copilot key should now act as RightCtrl."
}
cmd_stop() {
sudo pkill -f "[e]vsieve.*kbd-no-copilot" || true
sleep 0.5
echo "stopped."
}
case "${1:-}" in
start) cmd_start ;;
stop) cmd_stop ;;
*) usage; exit 2 ;;
esac--hook の period=0.1 というのは、0.1 秒の間に 3 キー(leftmeta, leftshift, f23)が入力された場合にフックを発動するという意味です。xev などで実際に Copilot キーを押して time を計測し、3 キーが(ほぼ)同時入力される期間を調べてください。0.1 秒もあれば十分だと思います。
--delay の period=0.3 というのは、フックが発動した場合、キーを最低でも 0.3 秒間維持するという意味です。
手順4: 手動でテストする
いきなり自動起動はせず、まず手動で動作確認します。
cd ~/Documents/apps/keyremap
./remap.sh start
# 別ターミナルで:
xinput list | grep -i copilot
# 期待値: kbd-no-copilot が見えるはずです。xev -event keyboard
# Copilot キー単押しで Control_R の KeyPress/KeyRelease が出れば成功です。
# Super_L / Shift_L / F23 が出なくなっていることも確認します。成功したら、エディターやブラウザーで Ctrl + C / Ctrl + V を試します。
戻すときは次の通りです。
./remap.sh stop手順5: 自動起動を登録する
手動テストが通ったら、再起動しても有効になるよう systemd サービスとして登録します。
[Unit]
Description=keyremap: convert Copilot key chord to RightCtrl via evsieve
After=multi-user.target
[Service]
Type=simple
ExecStart=/home/YOUR_USER/Documents/apps/keyremap/evsieve --input /dev/input/by-id/DEVICE grab --hook key:leftmeta key:leftshift key:f23 sequential period=0.1 send-key=key:rightctrl --withhold --delay key:rightctrl:0 period=0.3 --output name=kbd-no-copilot create-link=kbd-no-copilot
Restart=on-failure
RestartSec=2
[Install]
WantedBy=multi-user.targetYOUR_USER と DEVICE の 2 か所を、自身の環境を確認して置き換えてください。ExecStart に ~ や $HOME は使えません。絶対パスで書きます。
# YOUR_USER と DEVICE を置換済みか確認します。
grep -n "ExecStart" ~/Documents/apps/keyremap/keyremap-evsieve.service
sudo install -m 644 ~/Documents/apps/keyremap/keyremap-evsieve.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now keyremap-evsieve.service
systemctl is-active keyremap-evsieve.service
# 期待値: active手順6: 検証する
systemctl is-active keyremap-evsieve.service
# 期待値: active
xinput list | grep -i copilot
# 期待値: kbd-no-copilot が見える
xev -event keyboard
# Copilotキー単押しが Control_R に見えること
# (Super_L / Shift_L / F23 が出ないこと)その後、Copilotキーを使った Ctrl ショートカット (例: Ctrl + C、Ctrl + Tab) が効くことを確認します。
Copilot キーを無効化だけしたい場合
「Ctrl 化ではなく、誤爆防止で無効化したい」場合は、--hook から send-key=key:rightctrl を外し、末尾の --delay ... も外します。
sudo ./evsieve \
--input /dev/input/by-id/DEVICE grab \
--hook key:leftmeta key:leftshift key:f23 sequential period=0.1 \
--withhold \
--output name="kbd-no-copilot" create-link="kbd-no-copilot"remap.sh と .service の両方を同じ形に揃えてください。片方だけ変えると、手動テストと自動起動で挙動が食い違います。
RightCtrl がアプリで効かないときの代替案
アプリ側が Control_R を受け付けない場合があります。その場合は send-key=key:rightctrl を send-key=key:leftctrl に変えて試してください。それでもダメなら、いったん無効化だけにして、アプリ側の問題か切り分けます。
トラブルシューティング
RightCtrl がアプリで効かない
アプリ側が Control_R を受け付けない場合があります。その場合は Control_L で代用するか、Copilot キーを無効化のみにします (無効化だけしたい場合 参照)。
xev -event keyboard
# Copilotキー単押しで Control_R が出るか確認します。
# Super_L / Shift_L / F23 が残っていたら hook の period を調整します。タッチパッドが勝手に切り替わるかも(未検証)
Copilot キーの F23 部分がタッチパッドトグル (XF86TouchpadOff) として解釈される場合があります。この手順では --withhold で3キー同時押しを飲み込んでいるため、通常は起きません。
それでも起きる場合は、--hook の period=0.1 を少し大きめ (例: period=0.2) にして取りこぼしを減らしてください。remap.sh と .service の両方を同じ値に揃えます。
デバイスが見つからない
USB差込口を変えたら by-path が変わります。by-id を使ってください。それでも無い場合は、カーネルが別名で認識していないか確認します。
ls -l /dev/input/by-id/ | grep -i kbd
ls -l /dev/input/by-path/ | grep -i kbd
sudo dmesg | tail -30
# キーボードを抜き差しして、どの名前で認識されるか見る入力不能になった
sudo systemctl stop keyremap-evsieve.service
# または再起動マウスも効かない場合は、電源ボタン長押しの前に Ctrl + Alt + F3 で TTY に切り替えられるか試します。ダメなら再起動が最速です。再起動すれば grab は解けるため、予備キーボードが無くても復旧できます。ただし自動起動を有効化済みだと再発するため、復旧後はサービスを disable して原因切り分けをしてください。
sudo systemctl disable --now keyremap-evsieve.serviceおわりに
- Copilot キーは 3 キー同時押しなので、キーマップの書き換えだけでは修飾子化できません。
evdev層でevsieveに横取りさせ、単一のRightCtrlを合成します。- systemd サービスとして常駐させれば、再起動後も有効になります。
Copilot キーの仕様を知ったときはマイクロソフトやってくれたな…と思いました。今回は Copilot キー搭載のキーボードを買ってしまった人向けの記事になりましたが、そもそも Copilot キー搭載キーボードを買わなければこのような苦労をする必要もありません。
よほどの理由がない限り、Copilot キー搭載キーボードを買うべきではないでしょう。