Grid Picker for HID Usage#159
Conversation
✅ Deploy Preview for zmk-studio ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Example.mp4 |
650ddf2 to
b685fc4
Compare
|
Are you putting ISO keys like non-us-pound and non-us-backslash on basic? |
|
NUHS and NUBS are both under the ISO/JIS section at the moment |
|
Ah - a little cryptic so I missed them, but that's good. Thanks! |
b685fc4 to
8bc19a5
Compare
|
Would "International" be a better name for "ISO/JIS"? |
|
Show "Key Press" in a virtual keyboard may be better, like https://hodgef.com/simple-keyboard/demos/?d=fullKeyboard. That's what I did in my fork, and it works very well. |
5e0bb15 to
af6c818
Compare
I think this could be a good improvement - but I don't want to add too much into this PR. Right now, it's pretty easy to digest, but with the special-casing dropdown for the "Other" category, it's already a bit messier than I had hoped. IMO - we should consider this in a subsequent PR. I think this one already moves the experience forward incrementally, and that would be a good incremental change on top of this. |
|
Great work, any further update on this? |
|
I got some feedback from Pete which I haven’t been able to implement yet. I’m gonna do it this weekend and hopefully we can get this merged. |
feat: split Basic category into three new categories
feat(picker): Visual HID/behavior picker built on upstream PR zmkfirmware#159
| "135": { "short": "Intl1", "med": "Int1 ろ", "category": "International" }, | ||
| "136": { | ||
| "short": "Intl2", | ||
| "med": "Int2 かな", | ||
| "category": "International" | ||
| }, | ||
| "137": { "short": "Intl3", "med": "Int3 ¥", "category": "International" }, | ||
| "138": { | ||
| "short": "Intl4", | ||
| "med": "Int4 変換", | ||
| "category": "International" | ||
| }, | ||
| "139": { | ||
| "short": "Intl5", | ||
| "med": "Int5 無変換", | ||
| "category": "International" | ||
| }, | ||
| "140": { "short": "Intl6", "med": "Int6 ,", "category": "International" }, | ||
| "141": { "short": "Intl7", "category": "International" }, | ||
| "142": { "short": "Intl8", "category": "International" }, | ||
| "143": { "short": "Intl9", "category": "International" }, | ||
| "144": { | ||
| "short": "Lang1", | ||
| "med": "Lang1 한/영", | ||
| "category": "International" | ||
| }, | ||
| "145": { | ||
| "short": "Lang2", | ||
| "med": "Lang2 한자", | ||
| "category": "International" | ||
| }, | ||
| "146": { | ||
| "short": "Lang3", | ||
| "med": "Lang3 カタカナ", | ||
| "category": "International" | ||
| }, | ||
| "147": { | ||
| "short": "Lang4", | ||
| "med": "Lang4 ひらがな", | ||
| "category": "International" | ||
| }, | ||
| "148": { | ||
| "short": "Lang5", | ||
| "med": "Lang5 半角/全角", | ||
| "category": "International" | ||
| }, |
There was a problem hiding this comment.
Thanks so much for this PR @awkannan — the categorized grid is a real step up from the dropdown, and the metadata file structure made it easy to extend.
For full context: I've been using PR #159 as the base in a personal fork (numachang/zmk-studio-tweaks#4) where I layered on a few personal-preference extras (cross-tab search bar, physical-keyboard layouts inside the tabs, behavior chip grid, hold-tap preview, …). Most of those are opinionated UX choices that almost certainly don't belong in this PR as-is — I'm just leaving the link in case any of it is useful as a reference, and not asking for any of it to be taken on board.
The one thing I'd flag as a possible fit for #159 itself is the International category labels. The locale-specific glyphs in the med labels (Int1 ろ, Lang1 한/영, …) read like the HID spec definitions, but on real keyboards they often don't line up — Lang1 / Lang2 are spec'd as Hangul / Hanja but JIS layouts send them as Henkan / Muhenkan, and Lang3-5 plus most Intl* glyphs are JP-specific. Showing one region's label by default can mislead users on other layouts.
Until there's a locale-overlay mechanism, it might be cleanest to keep the neutral short labels only so no single region is privileged:
| "135": { "short": "Intl1", "med": "Int1 ろ", "category": "International" }, | |
| "136": { | |
| "short": "Intl2", | |
| "med": "Int2 かな", | |
| "category": "International" | |
| }, | |
| "137": { "short": "Intl3", "med": "Int3 ¥", "category": "International" }, | |
| "138": { | |
| "short": "Intl4", | |
| "med": "Int4 変換", | |
| "category": "International" | |
| }, | |
| "139": { | |
| "short": "Intl5", | |
| "med": "Int5 無変換", | |
| "category": "International" | |
| }, | |
| "140": { "short": "Intl6", "med": "Int6 ,", "category": "International" }, | |
| "141": { "short": "Intl7", "category": "International" }, | |
| "142": { "short": "Intl8", "category": "International" }, | |
| "143": { "short": "Intl9", "category": "International" }, | |
| "144": { | |
| "short": "Lang1", | |
| "med": "Lang1 한/영", | |
| "category": "International" | |
| }, | |
| "145": { | |
| "short": "Lang2", | |
| "med": "Lang2 한자", | |
| "category": "International" | |
| }, | |
| "146": { | |
| "short": "Lang3", | |
| "med": "Lang3 カタカナ", | |
| "category": "International" | |
| }, | |
| "147": { | |
| "short": "Lang4", | |
| "med": "Lang4 ひらがな", | |
| "category": "International" | |
| }, | |
| "148": { | |
| "short": "Lang5", | |
| "med": "Lang5 半角/全角", | |
| "category": "International" | |
| }, | |
| "135": { "short": "Intl1", "category": "International" }, | |
| "136": { "short": "Intl2", "category": "International" }, | |
| "137": { "short": "Intl3", "category": "International" }, | |
| "138": { "short": "Intl4", "category": "International" }, | |
| "139": { "short": "Intl5", "category": "International" }, | |
| "140": { "short": "Intl6", "category": "International" }, | |
| "141": { "short": "Intl7", "category": "International" }, | |
| "142": { "short": "Intl8", "category": "International" }, | |
| "143": { "short": "Intl9", "category": "International" }, | |
| "144": { "short": "Lang1", "category": "International" }, | |
| "145": { "short": "Lang2", "category": "International" }, | |
| "146": { "short": "Lang3", "category": "International" }, | |
| "147": { "short": "Lang4", "category": "International" }, | |
| "148": { "short": "Lang5", "category": "International" }, |
(This came up while using Lang1 / Lang2 on a JIS keyboard — the displayed Hangul didn't match the actual Henkan / Muhenkan behavior, which is what made me look at the rest of the category. Thanks again for the work on this PR — happy to follow up if any of the above is off-base.)
There was a problem hiding this comment.
On that topic, is there anything you'd change on https://zmk.dev/docs/keymaps/list-of-keycodes#international or https://zmk.dev/docs/keymaps/list-of-keycodes#language which is the same issue but outside Studio.
There was a problem hiding this comment.
@peterjc
The docs themselves are actually correct — the macOS footnote does
cover this, and (embarrassingly) I'd missed it on first read.
One small bit worth adding: recent Windows actually behaves the same
way as macOS for LANG1 / LANG2 — though Windows-targeted
keyboards typically don't ship with those physical keys, so it's
easy to miss in practice.
So the existing wording is fine as-is. If you wanted to make the
dual meaning more discoverable at the row level, two cheap options:
Inline:
| Names | Description |
|---|---|
LANG1 / LANG_HANGEUL / … |
한/영 (Language 1), かな (Language 1 on macOS) |
LANG2 / LANG_HANJA / … |
한자 (Language 2), 英数 (Language 2 on macOS) |
Or with a footnote marker that points back to the existing macOS
note, so the cross-reference is one step away:
| Names | Description |
|---|---|
LANG1 / … |
한/영 (Language 1) * |
LANG2 / … |
한자 (Language 2) * |
Happy to send a PR if either sounds worthwhile.
A bit of context on why this matters for the Japanese-Windows side:
the default IME toggle on Windows is the stateful 半角/全角
(Hankaku/Zenkaku) key, which flips between modes — you can't tell
from looking at the keyboard which mode you're in, which trips
people up. People who care about that often prefer the macOS-style
two-key arrangement: one key explicitly puts you in Japanese, a
different one explicitly puts you in alphabet. On a programmable
keyboard you get there by either
- binding
LANG1/LANG2(works on macOS, and on recent Windows
as well), or - binding
INT4(変換) /INT5(無変換) and remapping them to
"IME on" / "IME off" in the Windows IME settings — this used to
not be possible and still isn't the default, but it works today.
So the Japanese-Windows audience genuinely benefits from LANG1 /
LANG2's dual meaning being visible right in the table.

This changes the HidUsagePicker to a grid-of-buttons style of input, similar to what we see in VIA or VIAL.
We keep the modifier toggles so people can still add modifiers to their keys too.
Some decisions I made:
Some things I need help with: