Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 2 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 12 additions & 1 deletion app/src/hid_listener.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,25 @@ 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
// prematurely. This causes if LS(B) to repeat like Bbbbbbbb when pressed for a long time.
// 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);
Expand Down
9 changes: 5 additions & 4 deletions docs/docs/config/system.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ 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 | 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 | Send modifier release event **after** non-modifier release event | n |

Exactly zero or one of the following options may be set to `y`. The first is used if none are set.

Expand Down
Loading