IDX: キー番号の正本としてIDXレイヤーを確定し、MAPの参照をPHYへ移す
キー番号はPHYの幾何からもELCの配線からも導出できない決めごとなので、IDXが正本を持つ。 公開した基板のキー番号は他人のキーマップが依存する公開インターフェースであり、 出力のたびに生成し直さず固定する。 「最も重要な抽象化層」「最も欠けている層」という位置づけは誤りだったので落とした。 QMKのLAYOUTマクロの引数順、ZMKのmatrix transformのmap、KMKのcoord_mappingとして 既に存在していて、形式化されていないだけである。 あわせて2点。MAPはキー番号ではなくPHYのキーIDを参照する(IDXへの挿入でMAPがずれないため)。 IDXの保存形式は order: string[] とし、ELCのLEDChain.orderと同じく並びの位置を番号とする。 phase1-json-schema.md の P-1 を解消。 Journal: journal/2026-09-21-idx-necessity.md Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
# IDXレイヤーは必要か (schema P-1解消)
|
||||
|
||||
## 結論
|
||||
|
||||
必要。ただし「最も重要な抽象化層」「エコシステムで最も欠けている層」という位置づけは誤りで、
|
||||
ドキュメントから落とす。
|
||||
|
||||
IDXの中身は「どのキーに、どの順で番号を振るか」という順列だけ。情報ではなく決めごとで、
|
||||
PHYからもELCからも導出できない。導出できないから正本として置く。
|
||||
|
||||
あわせて2点決めた。
|
||||
|
||||
- MAPはキー番号ではなくPHYのキーIDを参照する
|
||||
- IDXの保存形式は `order: string[]` (並びの位置が番号)
|
||||
|
||||
## 発端
|
||||
|
||||
ユーザーの指摘: 「PHYのidやELCの接続がそのままキー番号になってしまうのでは?
|
||||
わざわざIDXを振る意味が薄れてきている」。
|
||||
|
||||
薄く見える原因は特定できた。IDXが持つと思われていたものが順次出ていったため。
|
||||
|
||||
| 元々IDXが持つとされたもの | 現在の置き場 | コミット |
|
||||
| --- | --- | --- |
|
||||
| row / col | ELCの配線から出力時に導出 | 5bba75d |
|
||||
| LEDの識別番号 | ELC (チェーン順序) | eb96ff0 |
|
||||
|
||||
引き算の結果、キー番号との対応だけが残った。薄いという認識自体は正しい。
|
||||
|
||||
## 案の比較
|
||||
|
||||
| 案 | キー番号の出どころ | 判定 |
|
||||
| --- | --- | --- |
|
||||
| IDXが正本として持つ | 設計者が決める並び順 | 採用 |
|
||||
| PHYのツリー順 | 幾何の編集順 | reparentで番号が動きキーマップがずれる |
|
||||
| ELCのマトリクス順 | row/col | 分割で並びが一致しない。欠番がある。再配線で動く |
|
||||
| そもそも番号を持たない | (MAPがPHYのキーIDを参照) | 公開インターフェースが固定できない |
|
||||
|
||||
最後の案が一番惜しかった。row/colを出力時に割り当てる判断と揃えるなら、キー番号も
|
||||
Firmware Generatorが生成する派生情報にできそうに見える。しかし番号が再生成のたびに動くと、
|
||||
公開した基板に対して他人が書いたキーマップが別のキーを指す。公開インターフェースは固定が要る。
|
||||
|
||||
結果として、MAPの参照だけをPHYのキーIDに移し、番号の並びはIDXに残す形にした。
|
||||
番号がずれてもMAPは無傷で、番号は固定される。
|
||||
|
||||
## 根拠: 3つの処理系はどれもこの順列を手書きしている
|
||||
|
||||
- QMK: `LAYOUT` マクロの引数順 / `keyboard.json` の `layouts.<NAME>.layout[]` の配列順
|
||||
- ZMK: matrix transform の `map` の並び順
|
||||
- KMK: `coord_mapping` の並び順
|
||||
|
||||
QMK Configuratorの説明:
|
||||
> The Configurator's API uses the layout macro and the JSON file we've given it to create a visual
|
||||
> representation of the keyboard that has each visual object tied to a specific key, in sequence.
|
||||
> When a user selects the top-left key in the Configurator, and assigns Num Lock to it, the
|
||||
> Configurator builds a keymap file with `KC_NUM` as the first key, and so on as the keymap is built.
|
||||
|
||||
> The names themselves actually don't matter, as long as they match between the top section, which
|
||||
> receives the keycodes from the keymap, and the bottom half which designates where each key is in the matrix.
|
||||
|
||||
ZMKの matrix transform `map`:
|
||||
> It should have one item per logical position in the keymap. Each item should list the physical row
|
||||
> and column that trigger the key in that position.
|
||||
|
||||
つまりIDXは「欠けている層」ではない。Cのマクロの引数順として存在していて、形式化されていないだけ。
|
||||
引数の数え間違いでキーが1つずれるのが定番のバグであることも、この層が手書きである傍証になる。
|
||||
|
||||
出典:
|
||||
- https://docs.qmk.fm/reference_configurator_support
|
||||
- https://docs.qmk.fm/reference_info_json
|
||||
- https://zmk.dev/docs/config/layout
|
||||
- https://github.com/KMKfw/kmk_firmware/blob/main/docs/en/porting_to_kmk.md
|
||||
|
||||
## 根拠: マトリクス順 ≠ キー番号順 の実物
|
||||
|
||||
KMKのCorne向け `coord_mapping`。
|
||||
|
||||
```python
|
||||
coord_mapping = [
|
||||
0, 1, 2, 3, 4, 5, 24, 25, 26, 27, 28, 29,
|
||||
6, 7, 8, 9, 10, 11, 30, 31, 32, 33, 34, 35,
|
||||
12, 13, 14, 15, 16, 17, 36, 37, 38, 39, 40, 41,
|
||||
21, 22, 23, 42, 43, 44,
|
||||
]
|
||||
```
|
||||
|
||||
配列の位置がキー番号、値がマトリクス上の通し番号。左半身が0〜23、右半身が24〜47。
|
||||
キー番号の並びは視覚的な行ごとに左右交互で、マトリクス順とは一致しない。18〜20は欠番。
|
||||
1つの例で「並びが違う」と「穴がある」の両方が出ている。
|
||||
|
||||
KMKの説明:
|
||||
> Split keyboards count as the total keyboard, not per side, the right side being offset by the
|
||||
> number of keys on the left side, as if the rows were stacked.
|
||||
|
||||
QMKの分割も同じ構造。
|
||||
> Since the matrix scanning procedure operates on entire rows, it first populates the left half's rows,
|
||||
> then the right half's. Thus, the matrix as QMK views it has double the rows instead of double the columns.
|
||||
|
||||
出典: https://docs.qmk.fm/features/split_keyboard
|
||||
|
||||
## 保存形式を `order: string[]` にした理由
|
||||
|
||||
旧案 `keyMap: [{keyId, index}]` は、欠番・重複・非連続をスキーマが許してしまう。
|
||||
`{k-a, 0}, {k-b, 0}` が通る。
|
||||
|
||||
ELCの `LEDChain.order` で既に「並びの位置が番号」の形を採っている (eb96ff0)。同じ形に揃えた。
|
||||
不変条件が構造として保証され、バリデーションが不要になる。
|
||||
|
||||
## 捨てた仮説
|
||||
|
||||
- 「IDXはdecal/ghostの区別を持つべきではないか」。decalはPHYが `decal` フラグを持っているので
|
||||
そこから分かる。ghostは何を意味するかがKLE由来で曖昧なので、IDXの側で規定しない。
|
||||
`order` に挙げたキーだけが番号を持つ、で足りる
|
||||
- 「VIAとの往復でキー番号が要るのでは」。VIAのプロトコルはrow/col指定なので、キー番号は出てこない。
|
||||
ただし裏取りしていないので、ドキュメントには書かなかった
|
||||
Reference in New Issue
Block a user