Skip to content

Grid Picker for HID Usage#159

Open
awkannan wants to merge 4 commits into
zmkfirmware:mainfrom
awkannan:202511/feat/key-press-grid-picker
Open

Grid Picker for HID Usage#159
awkannan wants to merge 4 commits into
zmkfirmware:mainfrom
awkannan:202511/feat/key-press-grid-picker

Conversation

@awkannan

@awkannan awkannan commented Nov 25, 2025

Copy link
Copy Markdown
Contributor

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:

  • I'm changing "src/hid-usage-name-overrides.json" to "src/hid-usage-metadata.json". We have to categorize keys manually - so instead of making a 2nd json for categorization which basically had the same shape, I decided to just make the name overrides json a bit more generic. The idea is if we need to add anything else, i.e. icons - it can go in this file, which isn't just limited to name overrides
  • On top of that - if something is going to be categorized in a way that shows it on the grid, we should consider how we want it to be shown on the grid. We should probably define a short name or medium name for these.
  • We have 5 categories - Basic, Numpad, Apps/Media, ISO/JIS, and Other
  • I used the categorization in the ZMK Docs

Some things I need help with:

  • I used Gemini to help me with the CSS. I'm not great at tailwind, so I would love someone with more experience there to review the CSS. It all seems sensible to me, though.

@netlify

netlify Bot commented Nov 25, 2025

Copy link
Copy Markdown

Deploy Preview for zmk-studio ready!

Name Link
🔨 Latest commit 330ded3
🔍 Latest deploy log https://app.netlify.com/projects/zmk-studio/deploys/698d8640bbc0468382547f06
😎 Deploy Preview https://deploy-preview-159.preview.zmk.studio
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@awkannan awkannan marked this pull request as ready for review November 26, 2025 01:28
@awkannan awkannan changed the title WIP: Grid Picker for Key Presses Grid Picker for Key Presses Nov 26, 2025
@awkannan

Copy link
Copy Markdown
Contributor Author
Example.mp4

@awkannan awkannan changed the title Grid Picker for Key Presses Grid Picker for HID Usage Nov 26, 2025
@awkannan awkannan force-pushed the 202511/feat/key-press-grid-picker branch from 650ddf2 to b685fc4 Compare November 26, 2025 03:29
@peterjc

peterjc commented Nov 26, 2025

Copy link
Copy Markdown
Contributor

Are you putting ISO keys like non-us-pound and non-us-backslash on basic?

@awkannan

Copy link
Copy Markdown
Contributor Author

NUHS and NUBS are both under the ISO/JIS section at the moment

@peterjc

peterjc commented Nov 26, 2025

Copy link
Copy Markdown
Contributor

Ah - a little cryptic so I missed them, but that's good. Thanks!

@awkannan awkannan force-pushed the 202511/feat/key-press-grid-picker branch from b685fc4 to 8bc19a5 Compare November 26, 2025 19:48
@joelspadin

Copy link
Copy Markdown
Contributor

Would "International" be a better name for "ISO/JIS"?

@adminhxx

Copy link
Copy Markdown

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.

@awkannan awkannan force-pushed the 202511/feat/key-press-grid-picker branch from 5e0bb15 to af6c818 Compare December 1, 2025 15:47
@awkannan

awkannan commented Dec 1, 2025

Copy link
Copy Markdown
Contributor Author

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.

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.

@alt-0191

Copy link
Copy Markdown

Great work, any further update on this?

@awkannan

Copy link
Copy Markdown
Contributor Author

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.

@petejohanson

Copy link
Copy Markdown
Collaborator

Improved, IMHO!

A few thoughts:

image
  1. I think we should consistently do / separated, .e.g. "Numbers/Punctuation". Also, I think the third tab should include "Mods" or "Modifiers" in the label, since those are there.
  2. With this "pulled out" the implicit modifiers are left on top with a label of "Key" (from the behavior metadata, IIRC), which is confusing. I think there should be some additional label/indicator that those are "Implicit" or "Automatic" modifiers to help users understand what they're doing.
  3. When selecting a new key/reloading the display, we should probably auto-select the tab that contains that key, so it's easy to see "Here's the key that's selected" or maybe add some indicator to the tab for the tab that holds the selected key?

Thanks for working on this!

Comment on lines +206 to +251
"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"
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

Suggested change
"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.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants