diff --git a/app/dts/behaviors/homerow_tap.dtsi b/app/dts/behaviors/homerow_tap.dtsi index 21c1531f..4162c288 100644 --- a/app/dts/behaviors/homerow_tap.dtsi +++ b/app/dts/behaviors/homerow_tap.dtsi @@ -2,7 +2,7 @@ behaviors { ht: behavior_homerow_mod { compatible = "zmk,behavior-hold-tap"; - label = "homerow_mod"; + label = "HOMEROW_MOD"; #binding-cells = <2>; flavor = "balanced"; tapping_term_ms = <200>; diff --git a/app/dts/bindings/behaviors/zmk,behavior-tap-hold.yaml b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml similarity index 100% rename from app/dts/bindings/behaviors/zmk,behavior-tap-hold.yaml rename to app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml diff --git a/app/include/zmk/event-manager.h b/app/include/zmk/event-manager.h index 07c0aa98..d9a56a4f 100644 --- a/app/include/zmk/event-manager.h +++ b/app/include/zmk/event-manager.h @@ -75,13 +75,14 @@ struct zmk_event_subscription { #define ZMK_EVENT_RAISE_AFTER(ev, mod) \ zmk_event_manager_raise_after((struct zmk_event_header *)ev, &zmk_listener_##mod); + +#define ZMK_EVENT_RAISE_AT(ev, mod) \ + zmk_event_manager_raise_at((struct zmk_event_header *)ev, &zmk_listener_##mod); + #define ZMK_EVENT_RELEASE(ev) \ zmk_event_manager_release((struct zmk_event_header *)ev); -#define ZMK_EVENT_RELEASE_AGAIN(ev) \ - zmk_event_manager_release_again((struct zmk_event_header *)ev); - int zmk_event_manager_raise(struct zmk_event_header *event); int zmk_event_manager_raise_after(struct zmk_event_header *event, const struct zmk_listener *listener); +int zmk_event_manager_raise_at(struct zmk_event_header *event, const struct zmk_listener *listener); int zmk_event_manager_release(struct zmk_event_header *event); -int zmk_event_manager_release_again(struct zmk_event_header *event); diff --git a/app/run-test-debug.sh b/app/run-test-debug.sh deleted file mode 100755 index f6696a1d..00000000 --- a/app/run-test-debug.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2020 Peter Johanson; Cody McGinnis; Okke Formsma -# -# SPDX-License-Identifier: MIT -# -set -e -set -x - -if [ -z "$1" ]; then - echo "Usage: ./run-test.sh " - exit 1 -elif [ "$1" = "all" ]; then - echo "" > ./build/tests/pass-fail.log - find tests -name native_posix.keymap -exec dirname \{\} \; | xargs -l -P 4 ./run-test.sh - err=$? - sort -k2 ./build/tests/pass-fail.log - exit $err -fi - -testcase="$1" -echo "Running $testcase:" - -west build -d build/$testcase -b native_posix --pristine -- -DZMK_CONFIG=$testcase -if [ $? -gt 0 ]; then - echo "FAIL: $testcase did not build" -else - ./build/$testcase/zephyr/zmk.exe | sed -e "s/.*> //" | tee build/$testcase/keycode_events_full.log | sed -n -f $testcase/events.patterns > build/$testcase/keycode_events.log - cat build/$testcase/keycode_events_full.log - cat build/$testcase/keycode_events.log - diff -au $testcase/keycode_events.snapshot build/$testcase/keycode_events.log - if [ $? -gt 0 ]; then - if [ -f $testcase/pending ]; then - echo "PEND: $testcase" - exit 0 - else - echo "FAIL: $testcase" - exit 1 - fi - else - echo "PASS: $testcase" - exit 0 - fi -fi \ No newline at end of file diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index 08fa1397..cd788f75 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -23,7 +23,6 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #if DT_NODE_EXISTS(DT_DRV_INST(0)) -/************************************************************ DATA SETUP */ #define ZMK_BHV_HOLD_TAP_MAX_HELD 10 #define ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS 40 @@ -40,7 +39,7 @@ typedef k_timeout_t (*timer_func)(); struct behavior_hold_tap_config { timer_func tapping_term_ms; struct behavior_hold_tap_behaviors *behaviors; - char *flavor; + int flavor; }; // this data is specific for each hold-tap @@ -65,7 +64,6 @@ struct active_hold_tap active_hold_taps[ZMK_BHV_HOLD_TAP_MAX_HELD] = {}; // We capture most position_state_changed events and some modifiers_state_changed events. const struct zmk_event_header *captured_events[ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS] = {}; -/************************************************************ CAPTURED POSITION HELPER FUNCTIONS */ static int capture_event(const struct zmk_event_header *event) { for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) { @@ -96,6 +94,8 @@ static struct position_state_changed *find_captured_keydown_event(u32_t position return last_match; } +const struct zmk_listener zmk_listener_behavior_hold_tap; + static void release_captured_events() { if (undecided_hold_tap != NULL) { @@ -143,13 +143,10 @@ static void release_captured_events() struct keycode_state_changed *modifier_event = cast_keycode_state_changed(captured_event); LOG_DBG("Releasing mods changed event 0x%02X %s", modifier_event->keycode, (modifier_event->state ? "pressed" : "released")); } - ZMK_EVENT_RELEASE_AGAIN(captured_event); + ZMK_EVENT_RAISE_AT(captured_event, behavior_hold_tap); } } - -/************************************************************ ACTIVE TAP HOLD HELPER FUNCTIONS */ - static struct active_hold_tap *find_hold_tap(u32_t position) { for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_HELD; i++) { @@ -256,12 +253,12 @@ static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_mome return; } - char *flavor = hold_tap->config->flavor; - if (strcmp(flavor, "balanced") == 0) { + int flavor = hold_tap->config->flavor; + if (flavor == 1) { decide_balanced(hold_tap, event); - } else if (strcmp(flavor, "tap-preferred") == 0) { + } else if (flavor == 2) { decide_tap_preferred(hold_tap, event); - } else if (strcmp(flavor, "hold-preferred") == 0) { + } else if (flavor == 0) { decide_hold_preferred(hold_tap, event); } @@ -269,7 +266,11 @@ static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_mome return; } - LOG_DBG("%d decided %s (%s event %d)", hold_tap->position, hold_tap->is_hold ? "hold" : "tap", flavor, event); + LOG_DBG("%d decided %s (%s event %d)", + hold_tap->position, + hold_tap->is_hold ? "hold" : "tap", + flavor == 0 ? "hold-preferred" : flavor == 1 ? "balanced": "tap-preferred", + event); undecided_hold_tap = NULL; struct zmk_behavior_binding *behavior; @@ -285,7 +286,6 @@ static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_mome release_captured_events(); } -/************************************************************ hold_tap_binding and key handlers */ static int on_hold_tap_binding_pressed(struct device *dev, u32_t position, u32_t param_hold, u32_t param_tap) { const struct behavior_hold_tap_config *cfg = dev->config_info; @@ -430,7 +430,6 @@ ZMK_SUBSCRIPTION(behavior_hold_tap, position_state_changed); // this should be modifiers_state_changed, but unfrotunately that's not implemented yet. ZMK_SUBSCRIPTION(behavior_hold_tap, keycode_state_changed); -/************************************************************ TIMER FUNCTIONS */ void behavior_hold_tap_timer_work_handler(struct k_work *item) { struct active_hold_tap *hold_tap = CONTAINER_OF(item, struct active_hold_tap, work); @@ -459,7 +458,6 @@ static int behavior_hold_tap_init(struct device *dev) struct behavior_hold_tap_data {}; static struct behavior_hold_tap_data behavior_hold_tap_data; -/************************************************************ NODE CONFIG */ #define _TRANSFORM_ENTRY(idx, node) \ { \ .behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(node, bindings, idx)), \ @@ -476,7 +474,7 @@ static struct behavior_hold_tap_data behavior_hold_tap_data; static struct behavior_hold_tap_config behavior_hold_tap_config_##n = { \ .behaviors = &behavior_hold_tap_behaviors_##n, \ .tapping_term_ms = &behavior_hold_tap_config_##n##_gettime, \ - .flavor = DT_INST_PROP(n, flavor), \ + .flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \ }; \ DEVICE_AND_API_INIT( \ behavior_hold_tap_##n, DT_INST_LABEL(n), behavior_hold_tap_init, \ diff --git a/app/src/event_manager.c b/app/src/event_manager.c index 2f423fc5..47ad6b73 100644 --- a/app/src/event_manager.c +++ b/app/src/event_manager.c @@ -71,13 +71,23 @@ int zmk_event_manager_raise_after(struct zmk_event_header *event, const struct z return -EINVAL; } -int zmk_event_manager_release(struct zmk_event_header *event) +int zmk_event_manager_raise_at(struct zmk_event_header *event, const struct zmk_listener *listener) { - return zmk_event_manager_handle_from(event, event->last_listener_index + 1); -} + u8_t len = __event_subscriptions_end - __event_subscriptions_start; + for (int i = 0; i < len; i++) { + struct zmk_event_subscription *ev_sub = __event_subscriptions_start + i; + + if (ev_sub->event_type == event->event && ev_sub->listener == listener) { + return zmk_event_manager_handle_from(event, i); + } + } + LOG_WRN("Unable to find where to raise this event"); + + return -EINVAL; +} -int zmk_event_manager_release_again(struct zmk_event_header *event) +int zmk_event_manager_release(struct zmk_event_header *event) { - return zmk_event_manager_handle_from(event, event->last_listener_index); -} \ No newline at end of file + return zmk_event_manager_handle_from(event, event->last_listener_index + 1); +} diff --git a/app/tests/hold-tap/README.md b/app/tests/hold-tap/README.md new file mode 100644 index 00000000..0630132d --- /dev/null +++ b/app/tests/hold-tap/README.md @@ -0,0 +1 @@ +Refer to the pdf/open document "zmk-modtap-proposal.{pdf,odt}" in this directory for a visual representation of the numbered tests for hold-tap. diff --git a/docs/docs/behavior/mod-tap.md b/docs/docs/behavior/mod-tap.md index cbe95e42..dcac4920 100644 --- a/docs/docs/behavior/mod-tap.md +++ b/docs/docs/behavior/mod-tap.md @@ -22,7 +22,7 @@ The Mod-Tap behavior either acts as a held modifier, or as a tapped keycode. Example: ``` -&mt MOD_LSFT A +&mt LSFT A ``` ### Configuration