some fixes based on feedback
This commit is contained in:
parent
f6a9c1ee57
commit
c5ca664411
8 changed files with 38 additions and 72 deletions
|
@ -2,7 +2,7 @@
|
||||||
behaviors {
|
behaviors {
|
||||||
ht: behavior_homerow_mod {
|
ht: behavior_homerow_mod {
|
||||||
compatible = "zmk,behavior-hold-tap";
|
compatible = "zmk,behavior-hold-tap";
|
||||||
label = "homerow_mod";
|
label = "HOMEROW_MOD";
|
||||||
#binding-cells = <2>;
|
#binding-cells = <2>;
|
||||||
flavor = "balanced";
|
flavor = "balanced";
|
||||||
tapping_term_ms = <200>;
|
tapping_term_ms = <200>;
|
||||||
|
|
|
@ -75,13 +75,14 @@ struct zmk_event_subscription {
|
||||||
#define ZMK_EVENT_RAISE_AFTER(ev, mod) \
|
#define ZMK_EVENT_RAISE_AFTER(ev, mod) \
|
||||||
zmk_event_manager_raise_after((struct zmk_event_header *)ev, &zmk_listener_##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) \
|
#define ZMK_EVENT_RELEASE(ev) \
|
||||||
zmk_event_manager_release((struct zmk_event_header *)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(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_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(struct zmk_event_header *event);
|
||||||
int zmk_event_manager_release_again(struct zmk_event_header *event);
|
|
||||||
|
|
|
@ -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 <path to testcase>"
|
|
||||||
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
|
|
|
@ -23,7 +23,6 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
#if DT_NODE_EXISTS(DT_DRV_INST(0))
|
#if DT_NODE_EXISTS(DT_DRV_INST(0))
|
||||||
|
|
||||||
/************************************************************ DATA SETUP */
|
|
||||||
#define ZMK_BHV_HOLD_TAP_MAX_HELD 10
|
#define ZMK_BHV_HOLD_TAP_MAX_HELD 10
|
||||||
#define ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS 40
|
#define ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS 40
|
||||||
|
|
||||||
|
@ -40,7 +39,7 @@ typedef k_timeout_t (*timer_func)();
|
||||||
struct behavior_hold_tap_config {
|
struct behavior_hold_tap_config {
|
||||||
timer_func tapping_term_ms;
|
timer_func tapping_term_ms;
|
||||||
struct behavior_hold_tap_behaviors *behaviors;
|
struct behavior_hold_tap_behaviors *behaviors;
|
||||||
char *flavor;
|
int flavor;
|
||||||
};
|
};
|
||||||
|
|
||||||
// this data is specific for each hold-tap
|
// 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.
|
// 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] = {};
|
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)
|
static int capture_event(const struct zmk_event_header *event)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) {
|
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;
|
return last_match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct zmk_listener zmk_listener_behavior_hold_tap;
|
||||||
|
|
||||||
static void release_captured_events()
|
static void release_captured_events()
|
||||||
{
|
{
|
||||||
if (undecided_hold_tap != NULL) {
|
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);
|
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"));
|
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)
|
static struct active_hold_tap *find_hold_tap(u32_t position)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_HELD; i++) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *flavor = hold_tap->config->flavor;
|
int flavor = hold_tap->config->flavor;
|
||||||
if (strcmp(flavor, "balanced") == 0) {
|
if (flavor == 1) {
|
||||||
decide_balanced(hold_tap, event);
|
decide_balanced(hold_tap, event);
|
||||||
} else if (strcmp(flavor, "tap-preferred") == 0) {
|
} else if (flavor == 2) {
|
||||||
decide_tap_preferred(hold_tap, event);
|
decide_tap_preferred(hold_tap, event);
|
||||||
} else if (strcmp(flavor, "hold-preferred") == 0) {
|
} else if (flavor == 0) {
|
||||||
decide_hold_preferred(hold_tap, event);
|
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;
|
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;
|
undecided_hold_tap = NULL;
|
||||||
|
|
||||||
struct zmk_behavior_binding *behavior;
|
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();
|
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)
|
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;
|
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.
|
// this should be modifiers_state_changed, but unfrotunately that's not implemented yet.
|
||||||
ZMK_SUBSCRIPTION(behavior_hold_tap, keycode_state_changed);
|
ZMK_SUBSCRIPTION(behavior_hold_tap, keycode_state_changed);
|
||||||
|
|
||||||
/************************************************************ TIMER FUNCTIONS */
|
|
||||||
void behavior_hold_tap_timer_work_handler(struct k_work *item)
|
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);
|
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 {};
|
struct behavior_hold_tap_data {};
|
||||||
static struct behavior_hold_tap_data behavior_hold_tap_data;
|
static struct behavior_hold_tap_data behavior_hold_tap_data;
|
||||||
|
|
||||||
/************************************************************ NODE CONFIG */
|
|
||||||
#define _TRANSFORM_ENTRY(idx, node) \
|
#define _TRANSFORM_ENTRY(idx, node) \
|
||||||
{ \
|
{ \
|
||||||
.behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(node, bindings, idx)), \
|
.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 = { \
|
static struct behavior_hold_tap_config behavior_hold_tap_config_##n = { \
|
||||||
.behaviors = &behavior_hold_tap_behaviors_##n, \
|
.behaviors = &behavior_hold_tap_behaviors_##n, \
|
||||||
.tapping_term_ms = &behavior_hold_tap_config_##n##_gettime, \
|
.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( \
|
DEVICE_AND_API_INIT( \
|
||||||
behavior_hold_tap_##n, DT_INST_LABEL(n), behavior_hold_tap_init, \
|
behavior_hold_tap_##n, DT_INST_LABEL(n), behavior_hold_tap_init, \
|
||||||
|
|
|
@ -71,13 +71,23 @@ int zmk_event_manager_raise_after(struct zmk_event_header *event, const struct z
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int zmk_event_manager_raise_at(struct zmk_event_header *event, const struct zmk_listener *listener)
|
||||||
|
{
|
||||||
|
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(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 + 1);
|
return zmk_event_manager_handle_from(event, event->last_listener_index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int zmk_event_manager_release_again(struct zmk_event_header *event)
|
|
||||||
{
|
|
||||||
return zmk_event_manager_handle_from(event, event->last_listener_index);
|
|
||||||
}
|
|
1
app/tests/hold-tap/README.md
Normal file
1
app/tests/hold-tap/README.md
Normal file
|
@ -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.
|
|
@ -22,7 +22,7 @@ The Mod-Tap behavior either acts as a held modifier, or as a tapped keycode.
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```
|
```
|
||||||
&mt MOD_LSFT A
|
&mt LSFT A
|
||||||
```
|
```
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
Loading…
Reference in a new issue