This commit is contained in:
nguyendown 2024-08-15 15:28:28 +01:00 committed by GitHub
commit e0f017f873
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 1258 additions and 0 deletions

View file

@ -59,6 +59,7 @@ if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
target_sources(app PRIVATE src/behaviors/behavior_to_layer.c)
target_sources(app PRIVATE src/behaviors/behavior_transparent.c)
target_sources(app PRIVATE src/behaviors/behavior_none.c)
target_sources(app PRIVATE src/behaviors/behavior_non_overlap.c)
target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_SENSOR_ROTATE app PRIVATE src/behaviors/behavior_sensor_rotate.c)
target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_SENSOR_ROTATE_VAR app PRIVATE src/behaviors/behavior_sensor_rotate_var.c)
target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_SENSOR_ROTATE_COMMON app PRIVATE src/behaviors/behavior_sensor_rotate_common.c)

View file

@ -21,3 +21,4 @@
#include <behaviors/macros.dtsi>
#include <behaviors/mouse_key_press.dtsi>
#include <behaviors/soft_off.dtsi>
#include <behaviors/non_overlap.dtsi>

View file

@ -0,0 +1,18 @@
/*
* Copyright (c) 2024 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/
#include <dt-bindings/zmk/keys.h>
/ {
behaviors {
/omit-if-no-ref/ nkp: non_overlap_key_press {
compatible = "zmk,behavior-non-overlap";
#binding-cells = <1>;
bindings = <&kp>;
display-name = "Non-overlap";
};
};
};

View file

@ -0,0 +1,17 @@
# Copyright (c) 2024 The ZMK Contributors
# SPDX-License-Identifier: MIT
description: Non-overlap behavior
compatible: "zmk,behavior-non-overlap"
include: one_param.yaml
properties:
bindings:
type: phandles
required: true
keep-active-size:
type: int
no-active:
type: boolean

View file

@ -0,0 +1,278 @@
/*
* Copyright (c) 2024 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/
#define DT_DRV_COMPAT zmk_behavior_non_overlap
#include <zephyr/device.h>
#include <drivers/behavior.h>
#include <zephyr/logging/log.h>
#include <zmk/behavior.h>
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
struct active_non_overlap {
struct active_non_overlap *previous;
struct active_non_overlap *next;
bool is_pressed;
uint32_t position;
struct zmk_behavior_binding binding;
};
struct behavior_non_overlap_config {
const char *behavior_dev;
};
struct behavior_non_overlap_data {
struct active_non_overlap *head;
struct active_non_overlap *tail;
struct active_non_overlap *actives;
const size_t keep_active_size;
};
/*
* Non-overlap key presses are kept in a static array of `struct active_non_overlap`.
* The array size defaults to 10 if `keep-active-size` is not specified.
* The array size limits the number of key presses that non-overlap behavior can remember.
* Each instance of non-overlap behavior has its own array.
*
* Non-overlap behavior must preserve the order of key presses.
* Linked list is implemented to allow efficient queue operations.
* When the number of key presses reaches its limit,
* previous key presses will be deleted to accommodate new key presses in a FIFO manner.
*/
static inline struct active_non_overlap *find_empty_slot(struct behavior_non_overlap_data *data) {
const size_t keep_active_size = data->keep_active_size;
struct active_non_overlap *actives = data->actives;
for (int i = 0; i < keep_active_size; i++) {
struct active_non_overlap *active = &actives[i];
if (!active->is_pressed) {
return active;
}
}
return NULL;
}
static inline bool matches_params(const struct zmk_behavior_binding *this,
const struct zmk_behavior_binding *that) {
return this->param1 == that->param1 && this->param2 == that->param2;
}
static inline bool matches_active(struct zmk_behavior_binding *binding, uint32_t position,
const struct active_non_overlap *active) {
return position == active->position && matches_params(binding, &active->binding);
}
static inline struct active_non_overlap *find_active(struct zmk_behavior_binding *binding,
uint32_t position,
struct active_non_overlap *tail) {
for (struct active_non_overlap *active = tail; active != NULL; active = active->previous) {
if (matches_active(binding, position, active)) {
return active;
}
}
return NULL;
}
static inline void release_binding(struct active_non_overlap *active, int64_t timestamp) {
struct zmk_behavior_binding_event event = {
.position = active->position,
.timestamp = timestamp,
};
behavior_keymap_binding_released(&active->binding, event);
}
static inline void press_binding(struct active_non_overlap *active, int64_t timestamp) {
struct zmk_behavior_binding_event event = {
.position = active->position,
.timestamp = timestamp,
};
behavior_keymap_binding_pressed(&active->binding, event);
}
static int behavior_non_overlap_init(const struct device *dev) { return 0; };
static int on_non_overlap_binding_pressed(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) {
LOG_DBG("position = %d, param1 = 0x%02X.", event.position, binding->param1);
const struct device *dev = zmk_behavior_get_binding(binding->behavior_dev);
struct behavior_non_overlap_data *data = dev->data;
struct active_non_overlap *least_recent_active = data->head;
struct active_non_overlap *most_recent_active = data->tail;
struct active_non_overlap *new_active;
if (most_recent_active == NULL) {
LOG_DBG("First active.");
new_active = data->actives;
data->head = new_active;
} else {
LOG_DBG("New active. Release the previous active.");
release_binding(most_recent_active, event.timestamp);
new_active = find_empty_slot(data);
if (new_active == NULL) {
new_active = least_recent_active;
most_recent_active->next = least_recent_active;
data->head = least_recent_active->next;
data->head->previous = NULL;
}
most_recent_active->next = new_active;
}
if (new_active == NULL) {
LOG_ERR("New active is not available for some reason.");
return ZMK_BEHAVIOR_OPAQUE;
}
new_active->is_pressed = true;
new_active->position = event.position;
new_active->binding.param1 = binding->param1;
new_active->binding.param2 = binding->param2;
press_binding(new_active, event.timestamp);
if (new_active != most_recent_active) {
new_active->previous = most_recent_active;
}
new_active->next = NULL;
data->tail = new_active;
return ZMK_BEHAVIOR_OPAQUE;
}
static int on_non_overlap_binding_released(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) {
LOG_DBG("position = %d, param1 = 0x%02X.", event.position, binding->param1);
const struct device *dev = zmk_behavior_get_binding(binding->behavior_dev);
struct behavior_non_overlap_data *data = dev->data;
struct active_non_overlap *least_recent_active = data->head;
struct active_non_overlap *most_recent_active = data->tail;
struct active_non_overlap *active = find_active(binding, event.position, most_recent_active);
const int64_t timestamp = event.timestamp;
if (active == NULL) {
LOG_DBG("No existing active. Nothing to do here.");
return ZMK_BEHAVIOR_OPAQUE;
}
active->is_pressed = false;
if (active == most_recent_active) {
LOG_DBG("This is the most recent active. Release it.");
release_binding(most_recent_active, timestamp);
most_recent_active = most_recent_active->previous;
if (most_recent_active != NULL) {
LOG_DBG("Previous active exists. Re-press it.");
press_binding(most_recent_active, timestamp);
most_recent_active->next = NULL;
}
data->tail = most_recent_active;
return ZMK_BEHAVIOR_OPAQUE;
}
active->next->previous = active->previous;
if (active == least_recent_active) {
data->head = least_recent_active->next;
} else {
active->previous->next = active->next;
}
LOG_DBG("Matched active deleted.");
return ZMK_BEHAVIOR_OPAQUE;
}
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
static int non_overlap_parameter_metadata(const struct device *non_overlap,
struct behavior_parameter_metadata *param_metadata) {
const struct behavior_non_overlap_config *cfg = non_overlap->config;
struct behavior_parameter_metadata child_metadata;
int err = behavior_get_parameter_metadata(zmk_behavior_get_binding(cfg->behavior_dev),
&child_metadata);
if (err < 0) {
LOG_WRN("Failed to get the non-overlap behavior parameter: %d", err);
return err;
}
for (int s = 0; s < child_metadata.sets_len; s++) {
const struct behavior_parameter_metadata_set *set = &child_metadata.sets[s];
if (set->param2_values_len > 0) {
return -ENOTSUP;
}
}
*param_metadata = child_metadata;
return 0;
}
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
static struct behavior_driver_api behavior_non_overlap_driver_api = {
.binding_pressed = on_non_overlap_binding_pressed,
.binding_released = on_non_overlap_binding_released,
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
.get_parameter_metadata = non_overlap_parameter_metadata,
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
};
#define _SET_NULL(i, inst) \
{ \
.previous = NULL, \
.next = NULL, \
.is_pressed = false, \
.position = 0, \
.binding = \
{ \
.behavior_dev = behavior_non_overlap_config_##inst.behavior_dev, \
.param1 = 0, \
.param2 = 0, \
}, \
}
#define _KEEP_ACTIVE_SIZE(inst) \
COND_CODE_1(DT_INST_PROP(inst, no_active), (1), (DT_INST_PROP_OR(inst, keep_active_size, 10)))
#define _SET_ACTIVES(inst) {LISTIFY(_KEEP_ACTIVE_SIZE(inst), _SET_NULL, (, ), inst)}
#define KP_INST(inst) \
static const struct behavior_non_overlap_config behavior_non_overlap_config_##inst = { \
.behavior_dev = DEVICE_DT_NAME(DT_INST_PHANDLE_BY_IDX(inst, bindings, 0)), \
}; \
static struct active_non_overlap actives_##inst[] = _SET_ACTIVES(inst); \
static struct behavior_non_overlap_data behavior_non_overlap_data_##inst = { \
.head = NULL, \
.tail = NULL, \
.actives = actives_##inst, \
.keep_active_size = _KEEP_ACTIVE_SIZE(inst), \
}; \
BEHAVIOR_DT_INST_DEFINE( \
inst, behavior_non_overlap_init, NULL, &behavior_non_overlap_data_##inst, \
&behavior_non_overlap_config_##inst, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
&behavior_non_overlap_driver_api);
DT_INST_FOREACH_STATUS_OKAY(KP_INST)
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */

View file

@ -0,0 +1 @@
s/.*hid_listener_keycode_//p

View file

@ -0,0 +1,6 @@
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00

View file

@ -0,0 +1,19 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
#include "../behavior_keymap.dtsi"
/* Basic non-overlap test. */
&kscan {
events = <
// Press &nkp A
ZMK_MOCK_PRESS(0,0,10)
// Tap &nkp D
ZMK_MOCK_PRESS(1,0,10)
ZMK_MOCK_RELEASE(1,0,10)
// &kp A is re-pressed after releasing &nkp D
// &kp A remains pressed until &nkp A is released
ZMK_MOCK_RELEASE(0,0,10)
>;
};

View file

@ -0,0 +1,21 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
/ {
keymap {
compatible = "zmk,keymap";
default_layer {
bindings = <
&nkp A &kp W
&nkp D &mo 1>;
};
lower_layer {
bindings = <
&kp LEFT_SHIFT &kp LEFT_CONTROL
&kp Y &kp Z>;
};
};
};

View file

@ -0,0 +1 @@
s/.*hid_listener_keycode_//p

View file

@ -0,0 +1,10 @@
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00

View file

@ -0,0 +1,37 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
/*
* Press in sequence WASD, then release backward DSAW.
* Only keep track of the few most recent key presses.
*/
&nkp {
keep-active-size = <2>;
};
/ {
keymap {
compatible = "zmk,keymap";
default_layer {
bindings = <
&nkp A &nkp W
&nkp D &nkp S>;
};
};
};
&kscan {
events = <
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(0,1,10) // W
>;
};

View file

@ -0,0 +1 @@
s/.*hid_listener_keycode_//p

View file

@ -0,0 +1,48 @@
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00

View file

@ -0,0 +1,65 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
/*
* Queue operations should work correctly within a limited space linked list.
*
* This test barely validates that the linked list is implemented correctly.
* Further work should provide a way to generate and evaluate all possible cases.
*/
&nkp {
keep-active-size = <3>;
};
/ {
keymap {
compatible = "zmk,keymap";
default_layer {
bindings = <
&nkp A &nkp W
&nkp D &nkp S>;
};
};
};
&kscan {
events = <
ZMK_MOCK_PRESS(0,1,10) // W W__ These 3 characters represent how
ZMK_MOCK_PRESS(0,0,10) // A WA_ the array should look like.
ZMK_MOCK_RELEASE(0,0,10) // A W__ _ represents an empty space.
ZMK_MOCK_PRESS(0,0,10) // A WA_ 130 These numbers show the order of
ZMK_MOCK_PRESS(1,1,10) // S WAS 123 each key press.
ZMK_MOCK_RELEASE(1,1,10) // S WA_ 130 0 means empty.
ZMK_MOCK_PRESS(1,1,10) // S WAS 123 1 is head. 2 is mid. 3 is tail.
ZMK_MOCK_PRESS(1,0,10) // D DAS 312 Limit reached. First in first out.
ZMK_MOCK_RELEASE(1,0,10) // D _AS 013 Test release tail.
ZMK_MOCK_PRESS(1,0,10) // D DAS 312
ZMK_MOCK_RELEASE(1,1,10) // S DA_ 310 Test release mid.
ZMK_MOCK_PRESS(1,1,10) // S DAS 213
ZMK_MOCK_RELEASE(0,0,10) // A D_S 103 Test release head.
ZMK_MOCK_PRESS(0,0,10) // A DAS 132
ZMK_MOCK_RELEASE(1,1,10) // S DA_ 130 Test release mid
ZMK_MOCK_RELEASE(0,0,10) // A D__ 100 and then tail.
ZMK_MOCK_PRESS(1,1,10) // S DS_ 130
ZMK_MOCK_PRESS(0,0,10) // A DSA 123
ZMK_MOCK_RELEASE(1,0,10) // D _SA 013 Test release head
ZMK_MOCK_RELEASE(1,1,10) // S __A 001 twice.
ZMK_MOCK_PRESS(1,1,10) // S S_A 301
ZMK_MOCK_PRESS(1,0,10) // D SDA 231
ZMK_MOCK_RELEASE(1,1,10) // S _DA 031 Test release mid
ZMK_MOCK_RELEASE(0,0,10) // A _D_ 010 and then head.
ZMK_MOCK_PRESS(0,0,10) // A AD_ 310
ZMK_MOCK_PRESS(1,1,10) // S ADS 213
ZMK_MOCK_RELEASE(1,0,10) // D A_S 103 Test release head
ZMK_MOCK_RELEASE(1,1,10) // S A__ 100 and then tail.
ZMK_MOCK_PRESS(1,1,10) // S AS_
ZMK_MOCK_PRESS(1,0,10) // D ASD
ZMK_MOCK_RELEASE(1,0,10) // D AS_ Test release all tails.
ZMK_MOCK_RELEASE(1,1,10) // S A__
ZMK_MOCK_RELEASE(0,0,10) // A ___
ZMK_MOCK_RELEASE(0,1,10) // W ___
>;
};

View file

@ -0,0 +1 @@
s/.*hid_listener_keycode_//p

View file

@ -0,0 +1,4 @@
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00

View file

@ -0,0 +1,25 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
#include "../behavior_keymap.dtsi"
/*
* Keep no record of previous key presses.
* Previous non-overlap key presses will not be re-pressed.
*/
&nkp {
no-active;
};
&kscan {
events = <
// Press &nkp A
ZMK_MOCK_PRESS(0,0,10)
// Tap &nkp D
ZMK_MOCK_PRESS(1,0,10)
ZMK_MOCK_RELEASE(1,0,10)
// &kp A is not re-pressed
ZMK_MOCK_RELEASE(0,0,10)
>;
};

View file

@ -0,0 +1 @@
s/.*hid_listener_keycode_//p

View file

@ -0,0 +1,14 @@
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00

View file

@ -0,0 +1,37 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
/*
* Press and release in sequence WASD, then DSAW.
* Non-overlap keys that remain pressed should be re-pressed in the correct order.
*/
&nkp {
keep-active-size = <4>;
};
/ {
keymap {
compatible = "zmk,keymap";
default_layer {
bindings = <
&nkp A &nkp W
&nkp D &nkp S>;
};
};
};
&kscan {
events = <
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(0,1,10) // W
>;
};

View file

@ -0,0 +1 @@
s/.*hid_listener_keycode_//p

View file

@ -0,0 +1,230 @@
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x16 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00

View file

@ -0,0 +1,236 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
/*
* Press in sequence WASD. Release in every possible way.
* Non-overlap keys that remain pressed should be re-pressed in the correct order.
*/
&nkp {
keep-active-size = <4>;
};
/ {
keymap {
compatible = "zmk,keymap";
default_layer {
bindings = <
&nkp A &nkp W
&nkp D &nkp S>;
};
};
};
&kscan {
events = <
// Release DSWA. Re-press SA.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(0,0,10) // A
// Release DASW. Re-press SW.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(0,1,10) // W
// Release DAWS. Re-press S.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(1,1,10) // S
// Release DWSA. Re-press SA.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(0,0,10) // A
// Release DWAS. Re-press S.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(1,1,10) // S
// Release SDAW. Re-press AW.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(0,1,10) // W
// Release SDWA. Re-press A.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(0,0,10) // A
// Release SADW. Re-press W.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(0,1,10) // W
// Release SAWD. No re-press.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(1,0,10) // D
// Release SWDA. Re-press A.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(0,0,10) // A
// Release SWAD. No re-press.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(1,0,10) // D
// Release ADSW. Re-press SW.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(0,1,10) // W
// Release ADWS. Re-press S.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(1,1,10) // S
// Release ASDW. Re-press W.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(0,1,10) // W
// Release ASWD. No re-press.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(1,0,10) // D
// Release AWDS. Re-press S.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(1,1,10) // S
// Release AWSD. No re-press.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(1,0,10) // D
// Release WDSA. Re-press SA.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(0,0,10) // A
// Release WDAS. Re-press S.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(1,1,10) // S
// Release WSDA. Re-press A.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(0,0,10) // A
// Release WSAD. No re-press.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(1,0,10) // D
// Release WADS. Re-press S.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(1,0,10) // D
ZMK_MOCK_RELEASE(1,1,10) // S
// Release WASD. No re-press.
ZMK_MOCK_PRESS(0,1,10) // W
ZMK_MOCK_PRESS(0,0,10) // A
ZMK_MOCK_PRESS(1,1,10) // S
ZMK_MOCK_PRESS(1,0,10) // D
ZMK_MOCK_RELEASE(0,1,10) // W
ZMK_MOCK_RELEASE(0,0,10) // A
ZMK_MOCK_RELEASE(1,1,10) // S
ZMK_MOCK_RELEASE(1,0,10) // D
>;
};

View file

@ -0,0 +1 @@
s/.*hid_listener_keycode_//p

View file

@ -0,0 +1,4 @@
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00

View file

@ -0,0 +1,20 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
#include "../behavior_keymap.dtsi"
/* Release &nkp A before releasing &nkp D */
&kscan {
events = <
// Press &nkp A
ZMK_MOCK_PRESS(0,0,10)
// Press &nkp D
ZMK_MOCK_PRESS(1,0,10)
// Release &nkp A
ZMK_MOCK_RELEASE(0,0,10)
// Release &nkp D
ZMK_MOCK_RELEASE(1,0,10)
// &kp A is not re-pressed after releasing &nkp D
>;
};

View file

@ -0,0 +1 @@
s/.*hid_listener_keycode_//p

View file

@ -0,0 +1,2 @@
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00

View file

@ -0,0 +1,14 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
#include "../behavior_keymap.dtsi"
/* Non-overlap key press should behave like a normal key press. */
&kscan {
events = <
// Tap &nkp A
ZMK_MOCK_PRESS(0,0,10)
ZMK_MOCK_RELEASE(0,0,10)
>;
};

View file

@ -0,0 +1 @@
s/.*hid_listener_keycode_//p

View file

@ -0,0 +1,8 @@
pressed: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x1A implicit_mods 0x00 explicit_mods 0x00

View file

@ -0,0 +1,31 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
/* Non-overlap keys and normal keys do not interfere with one another. */
/ {
keymap {
compatible = "zmk,keymap";
default_layer {
bindings = <
&nkp A &kp W
&nkp D &kp S>;
};
};
};
&kscan {
events = <
// Hold &kp W
ZMK_MOCK_PRESS(0,1,10)
// Basic non-overlap test
ZMK_MOCK_PRESS(0,0,10)
ZMK_MOCK_PRESS(1,0,10)
ZMK_MOCK_RELEASE(1,0,10)
ZMK_MOCK_RELEASE(0,0,10)
// Release &kp W
ZMK_MOCK_RELEASE(0,1,10)
>;
};

View file

@ -20,6 +20,7 @@ Below is a summary of pre-defined behavior bindings and user-definable behaviors
| `&gresc` | [Grave Escape](mod-morph.md#behavior-binding) | Sends Grave Accent `` ` `` keycode if shift or GUI is held, sends Escape keycode otherwise |
| `&caps_word` | [Caps Word](caps-word.md) | Behaves similar to caps lock, but automatically deactivates when any key not in a continue list is pressed, or if the caps word key is pressed again |
| `&key_repeat` | [Key Repeat](key-repeat.md) | Sends again whatever keycode was last sent |
| `&nkp` | [Non-overlap](non-overlap.mdx) | Allows only one key to be pressed at a time |
## Miscellaneous Behaviors

View file

@ -0,0 +1,101 @@
---
title: Non-overlap Behavior
sidebar_label: Non-overlap
---
## Summary
This behavior allows only one key to be pressed at a time.
### Behavior Binding
The default non-overlap `&nkp` uses [key press](key-press.md) binding `&kp`.
Any [keycode](../codes/index.mdx) from the usage page should work.
The following keymap prevents `A` and `D` from overlapping each other.
```dts
/ {
keymap {
default_layer {
bindings = <
&kp Q &kp W &kp E
&nkp A &kp S &nkp D>;
};
};
};
```
When `&nkp A` is being pressed, pressing `&nkp D` will release `&kp A` (the binding of `&nkp A`).
After `&nkp D` is released, `&kp A` will be pressed again.
### Configuration
#### `keep-active-size`
Non-overlap behavior tries to re-press any remaining active keys
in the exact order they were pressed.
`keep-active-size` limits the number of active keys this behavior can handle.
The default is 10.
In this example, when you press and release keys in sequence ASDF-FDSA, only F is re-pressed
as the behavior only keeps track of the two most recent key presses, D and F.
```dts
&nkp {
keep-active-size = <2>;
};
/ {
keymap {
default_layer {
bindings = <
&nkp A &nkp S
&nkp D &nkp F>;
};
};
};
```
#### `no-active`
When `no-active` is enabled, the behavior will not track pressed keys and no re-press will be made.
`no-active` is disabled by default.
```dts
&nkp {
no-active;
};
/ {
keymap {
...
};
};
```
You can also set `keep-active-size = <1>` to achieve the same effect.
### Multiple instances
The following example creates a new non-overlap group that works separately from the default `&nkp`.
```dts
/ {
behaviors {
nkp2: non_overlap_key_press_2 {
compatible = "zmk,behavior-non-overlap";
#binding-cells = <1>;
bindings = <&kp>;
};
};
keymap {
default_layer {
bindings = <
&kp Q &nkp2 W &kp E
&nkp A &nkp2 S &nkp D>;
};
};
};
```

View file

@ -68,6 +68,7 @@ module.exports = {
"behaviors/tap-dance",
"behaviors/caps-word",
"behaviors/key-repeat",
"behaviors/non-overlap",
"behaviors/sensor-rotate",
"behaviors/mouse-emulation",
"behaviors/reset",