fix: adding option to separate implicit mod release from key release

This adds a new config value `ZMK_HID_SEPARATE_MOD_RELEASE_REPORT`
where, if enabled, the report for a key release is sent separately to
the accompanying modifier release signals, which are then sent in a
second report.

This fixes an issue where certain applications are unable to work with
implicitly modified keys (e.g. colon) due to them registering the
modifier release prior to the actual key release.

Have tested this on my personal keyboard and `wev` now shows the signals
in the correct order.

=> **Previously:** ```LSHIFT (pressed) -> colon (pressed) -> LSHIFT
(released) -> **semi**colon (released)```

=> **Now:** ```LSHIFT (pressed) -> colon (pressed) -> colon (released)
-> LSHIFT (released)```

(This time without accidental files)
This commit is contained in:
Timoyoungster 2024-06-14 02:28:49 +02:00 committed by Pete Johanson
parent 4dce096161
commit 10d03ca46c
3 changed files with 23 additions and 5 deletions

View file

@ -113,6 +113,12 @@ config ZMK_HID_INDICATORS
Enable HID indicators, used for detecting state of Caps/Scroll/Num Lock,
Kata, and Compose.
config ZMK_HID_SEPARATE_MOD_RELEASE_REPORT
bool "Release Modifiers Separately"
help
Send a separate release event for the modifiers, to make sure the release
of the modifier doesn't get recognized before the actual key's release event.
menu "Output Types"
config ZMK_USB

View file

@ -66,6 +66,17 @@ static int hid_listener_keycode_released(const struct zmk_keycode_state_changed
return err;
}
#if IS_ENABLED(CONFIG_ZMK_HID_SEPARATE_MOD_RELEASE_REPORT)
// send report of normal key release early to fix the issue
// of some programs recognizing the implicit_mod release before the actual key release
err = zmk_endpoints_send_report(ev->usage_page);
if (err < 0) {
LOG_ERR("Failed to send key report for the released keycode (%d)", err);
}
#endif // IS_ENABLED(CONFIG_ZMK_HID_SEPARATE_MOD_RELEASE_REPORT)
explicit_mods_changed = zmk_hid_unregister_mods(ev->explicit_modifiers);
// There is a minor issue with this code.
// If LC(A) is pressed, then LS(B), then LC(A) is released, the shift for B will be released
@ -73,7 +84,7 @@ static int hid_listener_keycode_released(const struct zmk_keycode_state_changed
// Solving this would require keeping track of which key's implicit modifiers are currently
// active and only releasing modifiers at that time.
implicit_mods_changed = zmk_hid_implicit_modifiers_release();
;
if (ev->usage_page != HID_USAGE_KEY &&
(explicit_mods_changed > 0 || implicit_mods_changed > 0)) {
err = zmk_endpoints_send_report(HID_USAGE_KEY);

View file

@ -30,9 +30,10 @@ Making changes to any of the settings in this section modifies the HID report de
:::
| Config | Type | Description | Default |
| ------------------------------------- | ---- | -------------------------------------------------------------- | ------- |
| -------------------------------------------- | ---- | -------------------------------------------------------------- | ------- |
| `CONFIG_ZMK_HID_INDICATORS` | bool | Enable receipt of HID/LED indicator state from connected hosts | n |
| `CONFIG_ZMK_HID_CONSUMER_REPORT_SIZE` | int | Number of consumer keys simultaneously reportable | 6 |
| `CONFIG_ZMK_HID_SEPARATE_MOD_RELEASE_REPORT` | bool | Release the Modifiers separate from and after the modified key | n |
Exactly zero or one of the following options may be set to `y`. The first is used if none are set.