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

@@ -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);