feat(hid): Dynamic nkro#3402
Open
t3dodson wants to merge 4 commits into
Open
Conversation
Restructure the single zmk_hid_report_desc[] initializer into composable macros (ZMK_HID_REPORT_DESC_COMMON_PREFIX/_COMMON_SUFFIX, the per-mode _NKRO/_HKRO_KEYBOARD_ITEMS, and the ZMK_HID_REPORT_DESC() combiner) so the descriptor body can be instantiated more than once. No functional change: for the static NKRO and HKRO configurations the generated report descriptor is byte-for-byte identical to before, verified across indicators / pointing / smooth-scrolling and consumer BASIC/FULL permutations.
Factor the per-usage press/release/is-pressed/boot-report loops out of the static NKRO and HKRO report-type arms into buffer-parameterized static inline primitives (nkro_*/hkro_*). Each arm becomes a thin binding of those primitives to keyboard_report.body.keys; keys_held bookkeeping stays in the arms so its ordering is unchanged. Pure refactor of existing code, no behavior change.
Compile in both the HKRO and NKRO HID report descriptors/report bodies and pick between them at boot from a flash-persisted mode. The &dyn_nkro behavior flips the active mode and warm-reboots (descriptors cannot change after enumeration). The HID Report Type choice selects the first-boot default (HKRO at ZMK's own default). Leverages the shared key primitives and the reusable report-descriptor macros from the preceding refactor commits: the dynamic arm just binds those primitives to body.nkro_keys/body.hkro_keys per the boot-resolved mode.
Add a Dynamic NKRO behavior page covering &dyn_nkro and its command defines, and document CONFIG_ZMK_HID_REPORT_TYPE_DYNAMIC in the system config reference.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3395 curious to get feedback, as I had mentioned in the issue I think this is a widely useful feature suitable for upstream zmk.
With this fix I can finally switch into my bios with the same keyboard and make my edits.
PR check-list
I manually validated the following scenarios
Dynamic NKRO — Test Scenarios
Critical test matrix for the dynamic HKRO/NKRO feature. Columns are the relevant
Kconfig settings; rows are the build/runtime scenarios we care about. The first
two are regression baselines (feature absent → behavior must be unchanged); the
rest exercise the dynamic path.
HKRO/NKRO=CONFIG_ZMK_HID_REPORT_TYPE_HKRO/_NKRO(the report-typechoice).
DYNAMIC=CONFIG_ZMK_HID_REPORT_TYPE_DYNAMIC.EXT=CONFIG_ZMK_HID_KEYBOARD_NKRO_EXTENDED_REPORT.BOOT=CONFIG_ZMK_USB_BOOT.&dyn_nkrounavailable&dyn_nkrokeys inert as expected. Build dropped 1536 B.&dyn_nkro DYN_NKRO_TOG→ reboot → HKRO; toggle back → NKRO; mode survives power cycleDYN_NKRO_NKRO→ reboot → NKRO;DYN_NKRO_HKROwhen already HKRO is a no-op (no reboot)Bluetooth
I also validated behavior using bluetooth on an iphone
I connect, if I toggle to a different mode, I have to reconnect bluetooth then it does behave as expected. I understand some devices may not handle this gracefully, but I would hope using multiple profiles would be sufficient for that use case.