KMK Firmware(CircuitPython) でinternational キーコードが送られない件について
Raspberry Pi Pico に改造キーボードのマトリックスを接続して、一通りのキー入力は確認できたのですが、一部のキーが認識されません。
正確には、KMK Firmware 側では正常にキーコードを送っているようなのですが、Mac側には届いていないようです。
karabiner-element の EventViewer で見ると、当該キーだけ down/up のイベントが来ていないもよう。
確認したのはJP配列の以下のキーです。ほかにもあるでしょうが、割り振ったキーだけです。
キーコードはこのページの情報を参考にしました。
-
¥
|
キー - International3 キーコード 0x89(137)
-
_
キー- International1 キーコード 0x87(135)
-
無変換
- International5 キーコード 0x8B(139)
-
変換
- International4 キーコード 0x8A(138)
ほかにもあるだろけど、まずはこれを解決したい。
まずは問題切り分けで Mac 側の確認をします。
USBの抜き差しや、設定のキーボードでレイアウトの変更
レイアウトの認識をさせようとすると、右Shitfキーのすぐ左のキーが押しても反応がないのでやむなく?
キーを押すと、ANSIキーボードと判定される。JIS配列を選択し直しても、INT1, INT3 などは反応なし。
karabiner-element の EventViewer で見ると、そのキーを押したときだけイベントが飛んでこない。
Mac 側での問題ではなさそうです。
次は、KMK Firmware でのキーレイアウトの確認です。
- キーに別のキーコードを割り当てる
-
KC.INT3
→KC.A
に変更- 正しく
a
が入力される
- 正しく
-
- ほかのキーに
KC.INT3
を割り当ててみる- 入力されず、イベントも飛ばない
KMK Firmware のドキュメントを確認
シンプルなことしか書いていない
International extension adds keys for non US layouts. It can simply be added to the extensions list.
from kmk.extensions.international import International
keyboard.extensions.append(International())
一応ほかのLayoutやLEDモジュールをコメントアウトして、上記の通りのコードにしてみる。
変化なし
keyboard.debug_enabled = True
を追加して、ログを表示させてみる。
>>>
soft reboot
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
main.py output:
KMKInit(release=copied-from-git)
KMKKeyboard(debug_enabled=True diode_orientation=1 matrix_scanner=<class 'MatrixScanner'> unicode_mode=0 tap_time=300 _hid_helper=USBHID(REPORT_BYTES=9) keys_pressed=set() coordkeys_pressed={} hid_pending=False active_layers=[0] timeouts={} tapping=False tap_dance_counts={} tap_side_effects={})
MatrixChange(col=7 row=7 pressed=1)
KeyResolution(key=Key(code=135, has_modifiers=None))
KMKKeyboard(debug_enabled=True diode_orientation=1 matrix_scanner=<class 'MatrixScanner'> unicode_mode=0 tap_time=300 _hid_helper=USBHID(REPORT_BYTES=9) keys_pressed={Key(code=135, has_modifiers=None)} coordkeys_pressed={1799: Key(code=135, has_modifiers=None)} hid_pending=False active_layers=[0] timeouts={} tapping=False tap_dance_counts={} tap_side_effects={})
MatrixChange(col=7 row=7 pressed=0)
KeyResolution(key=Key(code=135, has_modifiers=None))
KMKKeyboard(debug_enabled=True diode_orientation=1 matrix_scanner=<class 'MatrixScanner'> unicode_mode=0 tap_time=300 _hid_helper=USBHID(REPORT_BYTES=9) keys_pressed=set() coordkeys_pressed={1799: None} hid_pending=False active_layers=[0] timeouts={} tapping=False tap_dance_counts={} tap_side_effects={})
確かにキーコード 135 の UP/DOWN イベントを送ってはいるようだ。どこで消えているのだろう。
考えられるのは、
- KMK Firmware の深いところでマスクされている
- CircuitPython が送れていない
- やっぱりMac側に問題がある
かなあ。
キーコードが0x80以上のがダメなのか?
日本語入力の切替ができないのはストレスなので、それぞれ適当なキーコードに割り振り直して、karabiner-element で 英数 かな キーに変換するようにした。私は現在は変換・無変換キーで日本語変換のオンオフをする派です。
さて、0x80(128)以上のキーコード送信に問題があるのかもという仮定を検証するために、簡単なコード送信のプログラムを実行してみる。
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
import time
kbd = Keyboard(usb_hid.devices)
for keyCode in range(0x00, 0x10):
kbd.press(keyCode)
time.sleep(.05)
kbd.release(keyCode)
time.sleep(.05)
これで、結果がでる
type:down HID usage:0x07,0x04 name:{"key_code":"a"} misc:
type:down HID usage:0x07,0x05 name:{"key_code":"b"} misc:
type:down HID usage:0x07,0x06 name:{"key_code":"c"} misc:
type:down HID usage:0x07,0x07 name:{"key_code":"d"} misc:
type:down HID usage:0x07,0x08 name:{"key_code":"e"} misc:
type:down HID usage:0x07,0x09 name:{"key_code":"f"} misc:
type:down HID usage:0x07,0x0a name:{"key_code":"g"} misc:
type:down HID usage:0x07,0x0b name:{"key_code":"h"} misc:
type:down HID usage:0x07,0x0c name:{"key_code":"i"} misc:
type:down HID usage:0x07,0x0d name:{"key_code":"j"} misc:
type:down HID usage:0x07,0x0e name:{"key_code":"k"} misc:
type:down HID usage:0x07,0x0f name:{"key_code":"l"} misc:
0x00〜0x0f で実際に振られているのは 0x04:a 〜 0x0e:k なので、きちんと送信されている。
upイベントは省略しました。
同じように範囲を変えて調べた結果、0x01〜0x7f の範囲は正常送信されました。一方、0x80〜0xff の範囲では、以下の 0xe0〜0xe7 の修飾キーのイベントだけが確認できました。
type:down HID usage:0x07,0xe0 name:{"key_code":"left_control"} misc:flags left_control
type:down HID usage:0x07,0xe1 name:{"key_code":"left_shift"} misc:flags left_shift
type:down HID usage:0x07,0xe2 name:{"key_code":"left_option"} misc:flags left_option
type:down HID usage:0x07,0xe3 name:{"key_code":"left_command"} misc:flags left_command
type:down HID usage:0x07,0xe4 name:{"key_code":"right_control"} misc:flags right_control
type:down HID usage:0x07,0xe5 name:{"key_code":"right_shift"} misc:flags right_shift
type:down HID usage:0x07,0xe6 name:{"key_code":"right_option"} misc:flags right_option
type:down HID usage:0x07,0xe7 name:{"key_code":"right_command"} misc:flags right_command
これはCircuitPythonで直接送信した結果なので、やはりCircuitPythonでマスクされているのかな。
CircuitPython のソースを調べてみることにします。
Windows PC につないだらちゃんとキーコード送信されているようでした。ではMac側の問題か。振り出しに戻る
今のところ
- Mac mini 2020 BigSur ×
- MacbookPro 2020 BigSur ×
- Window10 21H1 ◯
Macだとうまくいかないっぽいので、Github の Adafruit_CircuitPython_HID に issue だしてみた。
issue が Adafruit_CircuitPython本体に転送された
HIDライブラリではなくCircuitPythonのバグっぽい。macOSだと起こりやすいとか。