Android でも言語切替をトグルではなく直接指定にできないか (ユーザー補助サービスの検討)
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 48/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- android, c
- Domain
- embedded-iot, mobile
Research direction
First test Key Mapper’s “Switch keyboard” action on a real device, then use a key tester to check which dedicated key codes Android can distinguish. If both tests succeed, inspect the Android branch of td_tap_confirm() in firmware/windmill.c and determine which dedicated keys it should send. Done means the Android mode can select Japanese and English directly; otherwise, leave Android using the toggle.
Written by the indexing model from the issue text.
Description
背景
issue #53 / PR #54 で、Ctrlタップの言語切替をトグルにした。Windows は KC_LNG1 (かな) / KC_LNG2 (英数) を交互に送るので、IME側とずれてももう一度タップすれば揃う。
Android だけがトグル (Ctrl+Space) のままで、IME側を別の手段で切り替えてずれると、キーボードのベースレイヤーと食い違ったまま自力では戻せない。
Android で KC_LNG1/KC_LNG2 自体は効くが、日本語IMEが入力欄を移るたびに既定のかなへ戻ってしまい、英数を保てない。そのため、IMEそのもの (日本語⇔英語) を切り替える形にしてある。
このissueは、Android でもモードを直接指定できないか調べた結果のメモ。実機では何も試しておらず、以下はすべて公開ドキュメントを読んだ範囲の話。
分かったこと
- Android 11 (API 30) 以降、ユーザー補助 (アクセシビリティ) サービスは
SoftKeyboardController.switchToInputMethod(imeId)で IMEを名指しで切り替えられる。条件はその IME がインストール済みかつ有効なこと。戻り値で成否が分かる - ユーザー補助サービスは、物理キーのイベントを IME やアプリより先に受け取れる (
FLAG_REQUEST_FILTER_KEY_EVENTS)。握りつぶすこともできる - つまり、キーボードが「日本語へ」「英語へ」の専用キーを送り、常駐するサービスがそれを受けて IME を切り替えれば、Windows と同じくモードを直接指定する形にできる。ずれてもタップし直せば揃う
制約
- 切り替えられるのは IME 単位。 Gboard の中の日本語と英語は同じ IME の中の「サブタイプ」で、これを外部のアプリから選ぶ公開APIは無さそう (
setCurrentInputMethodSubtype/setInputMethodAndSubtypeは非推奨か、IME自身・システム専用) - したがって 英語側を別の IME にする必要がある。 Key Mapper の "Basic Input Method" は画面キーボードを持たない IME なので、物理キーボード専用なら足りそう
- 物理キーボードの配列 (英語(US)) は IME ごとの設定。 英語用の IME にも設定し直す必要があるかもしれない
まずコードを書かずに試す
Key Mapper (オープンソース) がまさにこの仕組みで動いていて、アクション一覧に Switch keyboard がある。
- 専用キーA → Gboard (日本語)
- 専用キーB → 英語用の IME
これで想定どおり動けば、自作アプリはほぼ同じことをするだけで、ユーザー補助サービスと設定XMLで数十行程度に収まるはず。
ただし Switch keyboard が Android 11 以降で追加の権限なしに特定の IME を選べるかは、ドキュメントに書かれておらず未確認。
気をつけること
- 専用キーは新しく用意する。
KC_LNG1/KC_LNG2は Symレイヤーの数字・記号と、かなの「も」の Shift+タップ (半角?) で一時的な切り替えに使っているので、サービスが横取りすると壊れる - そのキーが Android に区別できる形で届くか要確認。 Android の
KeyEventは F1〜F12 までで、F13以降は「不明なキー」扱いになる可能性がある。キーテスターのアプリで先に確かめる - Android 13以降、ストア外から入れたアプリのユーザー補助を有効にするには「制限付き設定を許可」の手順が要る
- 機種によっては省電力機能でサービスが止められることがある
- すべてのキー入力がサービスを通る。自作なら問題ないが、他人のアプリを使うなら信頼できるかの話になる
- 別の方法として、adb で
WRITE_SECURE_SETTINGSを与えて既定のIMEの設定を書き換えるやり方もあるが、公式に用意された手段であるユーザー補助のほうが素直
ファームウェア側に要ること
Android モードのとき、Ctrl+Space の代わりに専用キーを切り替え先に応じて送るよう、firmware/windmill.c の td_tap_confirm() の Android 分岐を変えるだけ。PR #54 の作りにそのまま載る。
進め方
- Key Mapper で
Switch keyboardが期待どおり動くか実機で確認する - 専用キーに使えるキーコードを実機で探す
- 動けばファームウェア側を直し、常駐アプリを自作するか Key Mapper に任せるかを決める
1と2が通らなければ、Android はトグルのままにする。
アイデア: 英語用の IME を自作する
Android で専用の英語用 IME を作り、英語モードにするときはその IME を強制的にアクティブにしてモードを揃える。特定の IME を強制的にアクティブにできるかを、実現性として探る。
調査結果: ソースから分かったこと (2026-11-03)
AOSP、Linux、Key Mapper のソースを読んで分かったこと。実機では確かめていない。
専用キーの候補
キーボードから送ったキーは、Linux の hid-input.c でキーコードに変わり、AOSP の Generic.kl で Android の KEYCODE_* になる。
| QMK | HID | Linux | Android |
|---|---|---|---|
KC_INT2 |
0x88 | KEY_KATAKANAHIRAGANA (93) |
KATAKANA_HIRAGANA |
KC_INT4 |
0x8A | KEY_HENKAN (92) |
HENKAN |
KC_INT5 |
0x8B | KEY_MUHENKAN (94) |
MUHENKAN |
KC_LNG5 |
0x94 | KEY_ZENKAKUHANKAKU (85) |
ZENKAKU_HANKAKU |
KC_LNG3 / KC_LNG4 |
0x92 / 0x93 | KEY_KATAKANA / KEY_HIRAGANA |
対応なし (Generic.kl でコメントアウト) |
KC_F13〜KC_F24 |
0x68〜0x73 | KEY_F13〜KEY_F24 |
F13〜F24。KEYCODE_F13 以降は 2025年Q2 の新しいキーコードで、それより前の Android では不明なキー |
- 候補は
KC_INT4(変換) とKC_INT5(無変換) の組。どの Android でも別々のキーコードで届き、windmill はどちらもまだ使っていない。日本語へ = 変換、英語へ = 無変換で、意味も合う - サービスが動いていないときは、変換・無変換がそのまま IME に届く。F13 以降なら何も起きないが、古い Android ではキーコードで区別できない
- Key Mapper は、キーコードが不明なキーをスキャンコードで見分ける (CHANGELOG #1276、#761)。F13 以降でも Key Mapper なら使える
Key Mapper の Switch keyboard
SwitchImeAsyncImpl.kt と BaseAccessibilityService.kt を読んだ。
- Android 11 以降は、ユーザー補助サービスの
switchToInputMethod(imeId)で切り替える。追加の権限は要らない - 失敗したときだけ、
WRITE_SECURE_SETTINGS(adb で付与) があればDEFAULT_INPUT_METHODを書き換える - 切り替え先の IME は、あらかじめ有効にしておく必要がある
自作する場合の形
- 1つのアプリに、英語用の IME とユーザー補助サービスを同梱する
- Android 13 以降、ユーザー補助サービスは同じパッケージの IME を、ユーザーの操作なしで有効にできる (
setInputMethodEnabled。Key Mapper も同じ制約で使っている)。英語用 IME を設定画面で有効にする手順が要らない - 英語用 IME は、画面キーボードを持たない
InputMethodServiceの派生だけで足りる。キーは処理せず、アプリへ素通しする。Key Mapper のKeyMapperImeService.ktが参考になる - ユーザー補助サービスは、
onKeyEventで変換・無変換を受けて握りつぶし、switchToInputMethodを呼ぶだけ - 規模は、Kotlin のコードが2クラスで100行前後、ほかに manifest と設定の XML が2つ
実機で確かめること
- 変換・無変換を送ったとき、キーテスターに
KEYCODE_HENKAN/KEYCODE_MUHENKANで届くか - Key Mapper で、変換 → Gboard、無変換 → 英語用 IME の切り替えが効くか
- 英語用 IME に切り替えたとき、物理キーボードの配列 (英語(US)) がそのまま効くか
進め方の更新 (2026-11-03)
Key Mapper は機能が多すぎるので、試さずに自作へ進む。
- アプリ: cognitom/windmill-android (#1 アプリ本体、#2 ビルド環境)
- ファームウェア: #105 (アプリが実機で動いてから)
- Dominant language
- C++
- Stars
- 4
- Forks
- 0
- Avg merge
- 1h 56m
- Merged PRs (30d)
- 15
Getting set up
- Ships a Dockerfile or Docker Compose file
- No pull request template
- No contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from cognitom/windmill
-
md ファイルの段落途中の改行をなくすOpen
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 22/100
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 15/100
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 12/100
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 25/100
Maintainers usually reply within 1 day
All issues in cognitom/windmill
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
arvidn/libtorrent#9149 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Niko1221/Strata#5560 · 2 comments ·
Maintainers usually reply within 4 days
-
NVIDIA windows
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
要トリアージ 辞書
Difficulty 1/5 1-3 hours Newbie friendliness 86/100
yksr-melt/Meltype#1625 · 1 reaction ·
Maintainers usually reply within 1 day