
Waydroidで英語のときだけテンキーが効かない原因を、AndroidとWaydroidのソースから調べた
LinuxでAndroidを動かすWaydroidの中で、テンキーの数字が打てなくなった。キーボードをGboardの「日本語」にすると打てて、「English (US)」にすると打てない。上段の数字キーは、どちらでも打てる。ホスト(Arch Linux、sway)でテンキーを打つと、数字が出る。 swayの設定に input * xkb_numlock enabled を足したが、直らなかった。なぜ効かないのかを、ソースと実測で調べた。 先に結論 ホストのNumLockの状態は、Waydroidの中のAndroidに渡らない。swayの設定は、Waydroidには効かない。 AndroidのNumLockは、Waydroidの中で、入った直後に消されている可能性が高い。ソースの読みと実測が合っているが、消す判定の値そのものは、見ていない。 Androidのアプリで、テンキーを数字に割り当てるキーレイアウトを足したら、英語のままテンキーが打てた。 ソースで分かったこと 読んだのは、WaydroidのHWC(android_hardware_waydroidのhwcomposer/wayland-hwc.cpp)と、Android 13(android13-release)の入力まわり、Waydroidが当てるパッチ(android_vendor_waydroid)。 1. ホストのキーは、キーコードのまま渡される。修飾キーの状態は渡されない。 HWCは、Waydroidのウィンドウに入ったキー入力を、キーコードの形で、Android側のパイプ(/dev/input/wl_keyboard_events)に書く。Waylandの修飾キーの状態を受け取る関数 keyboard_handle_modifiers は、中身が空になっている。ホストのNumLockがオンでも、Androidはそれを知らない。 2. テンキーの数字は、AndroidのNumLockがオンのときだけ出る。 Android 13の Generic.kcm では、NUMPAD_1 は、base: fallback MOVE_END、numlock: '1' と定義されている。NumLockがオフなら、Endキーになる。 3. NumLockの状態は、キーを離したときに切り替わる。 Keyboard.cpp の toggleLockedMetaState は、キーを押したときは何もせず、離したときに、状態を反転する。 4. Waydroidが作る入力機器は、出せるキーを2つしか登録していない。 WaydroidのEventHubのパッチ(Android 13用の 0004-EventHub-Add-wayland-inputs-support.patch)は、wayland_keyboard の keyBitmask に、BTN_MISC と KEY_OK だけを登録する。 AndroidのEventHubの markSupportedKeyCodes は、キーレイアウトにそのキーがあっても、この登録に無いキーは、「機器に無いキー」と判定する。KeyboardInputMapper::updateLedState は、NumLockのキーが無い機器について、NumLockの状態を消す。 NumLock(コード69)は、この登録に入っていない。 実測 dumpsys input で、入力機器の状態を取った。キー入力の履歴を含まない部分だけを、次のように取り出せる。 sudo waydroid shell dumpsys input | sed -n '/Input Reader State/,/Input Dispatcher State/p' > out-1.txt Copy wayland_keyboard の項目の、MetaState(修飾キーとロックの状態)と、DownTime(最後にキーが押された時刻)を、見た。 ...

