Skip to content

Commit

Permalink
Apply on-release positional hold-tap PR zmkfirmware#1423
Browse files Browse the repository at this point in the history
  • Loading branch information
urob authored and caksoylar committed Jan 22, 2023
1 parent 4b75791 commit 395ffdc
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 2 deletions.
2 changes: 2 additions & 0 deletions app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ properties:
type: array
required: false
default: []
hold-trigger-on-release:
type: boolean
7 changes: 5 additions & 2 deletions app/src/behaviors/behavior_hold_tap.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ struct behavior_hold_tap_config {
int global_quick_tap_ms;
enum flavor flavor;
bool retro_tap;
bool hold_trigger_on_release;
int32_t hold_trigger_key_positions_len;
int32_t hold_trigger_key_positions[];
};
Expand Down Expand Up @@ -590,9 +591,10 @@ static int position_state_changed_listener(const zmk_event_t *eh) {
}

// Store the position of pressed key for positional hold-tap purposes.
if ((ev->state) // i.e. key pressed (not released)
if (((!undecided_hold_tap->config->hold_trigger_on_release && ev->state) // key pressed
|| (undecided_hold_tap->config->hold_trigger_on_release && !ev->state)) // key released
&& (undecided_hold_tap->position_of_first_other_key_pressed ==
-1) // i.e. no other key has been pressed yet
-1) // no other key has been pressed yet
) {
undecided_hold_tap->position_of_first_other_key_pressed = ev->position;
}
Expand Down Expand Up @@ -708,6 +710,7 @@ static int behavior_hold_tap_init(const struct device *dev) {
: DT_INST_PROP(n, global_quick_tap_ms), \
.flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \
.retro_tap = DT_INST_PROP(n, retro_tap), \
.hold_trigger_on_release = DT_INST_PROP(n, hold_trigger_on_release), \
.hold_trigger_key_positions = DT_INST_PROP(n, hold_trigger_key_positions), \
.hold_trigger_key_positions_len = DT_INST_PROP_LEN(n, hold_trigger_key_positions), \
}; \
Expand Down
3 changes: 3 additions & 0 deletions docs/docs/behaviors/hold-tap.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ See the following example, which uses a hold-tap behavior definition, configured
- The sequence `(pht_down, W_down, W_up, pht_up)` produces `W`. The normal hold behavior (LEFT_SHIFT) **is NOT** modified into a tap behavior (Q) by positional hold-tap because the first key pressed after the hold-tap key is the `W key`, which is in position 1, which **IS** included in `hold-trigger-key-positions`.
- If the `LEFT_SHIFT / Q key` is held by itself for longer than `tapping-term-ms`, a hold behavior is produced. This is because positional hold-tap only modifies the behavior of a hold-tap if another key is pressed before the `tapping-term-ms` period expires.

By default, `hold-trigger-key-positions` are evaluated upon the first _key press_ after
the hold-tap. For homerow mods, this is not always ideal, because it prevents combining multiple modifiers unless they are included in `hold-trigger-key-positions`. To overwrite this behavior, one can set `hold-trigger-on-release`. If set to true, the evaluation of `hold-trigger-key-positions` gets delayed until _key release_. This allows combining multiple modifiers when the next key is _held_, while still deciding the hold-tap in favor of a tap when the next key is _tapped_.

### Example Use-Cases

<Tabs
Expand Down

0 comments on commit 395ffdc

Please sign in to comment.