Merge d4e656b4a2
into 6fe13c9565
This commit is contained in:
commit
e0f017f873
36 changed files with 1258 additions and 0 deletions
|
@ -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)
|
||||
|
|
|
@ -21,3 +21,4 @@
|
|||
#include <behaviors/macros.dtsi>
|
||||
#include <behaviors/mouse_key_press.dtsi>
|
||||
#include <behaviors/soft_off.dtsi>
|
||||
#include <behaviors/non_overlap.dtsi>
|
||||
|
|
18
app/dts/behaviors/non_overlap.dtsi
Normal file
18
app/dts/behaviors/non_overlap.dtsi
Normal 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";
|
||||
};
|
||||
};
|
||||
};
|
17
app/dts/bindings/behaviors/zmk,behavior-non-overlap.yaml
Normal file
17
app/dts/bindings/behaviors/zmk,behavior-non-overlap.yaml
Normal 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
|
278
app/src/behaviors/behavior_non_overlap.c
Normal file
278
app/src/behaviors/behavior_non_overlap.c
Normal 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) */
|
1
app/tests/non-overlap/basic/events.patterns
Normal file
1
app/tests/non-overlap/basic/events.patterns
Normal file
|
@ -0,0 +1 @@
|
|||
s/.*hid_listener_keycode_//p
|
6
app/tests/non-overlap/basic/keycode_events.snapshot
Normal file
6
app/tests/non-overlap/basic/keycode_events.snapshot
Normal 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
|
19
app/tests/non-overlap/basic/native_posix_64.keymap
Normal file
19
app/tests/non-overlap/basic/native_posix_64.keymap
Normal 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)
|
||||
>;
|
||||
};
|
21
app/tests/non-overlap/behavior_keymap.dtsi
Normal file
21
app/tests/non-overlap/behavior_keymap.dtsi
Normal 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>;
|
||||
};
|
||||
};
|
||||
};
|
1
app/tests/non-overlap/keep-active-size/events.patterns
Normal file
1
app/tests/non-overlap/keep-active-size/events.patterns
Normal file
|
@ -0,0 +1 @@
|
|||
s/.*hid_listener_keycode_//p
|
|
@ -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
|
|
@ -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
|
||||
>;
|
||||
};
|
1
app/tests/non-overlap/linked-list/events.patterns
Normal file
1
app/tests/non-overlap/linked-list/events.patterns
Normal file
|
@ -0,0 +1 @@
|
|||
s/.*hid_listener_keycode_//p
|
48
app/tests/non-overlap/linked-list/keycode_events.snapshot
Normal file
48
app/tests/non-overlap/linked-list/keycode_events.snapshot
Normal 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
|
65
app/tests/non-overlap/linked-list/native_posix_64.keymap
Normal file
65
app/tests/non-overlap/linked-list/native_posix_64.keymap
Normal 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 ___
|
||||
>;
|
||||
};
|
1
app/tests/non-overlap/no-active/events.patterns
Normal file
1
app/tests/non-overlap/no-active/events.patterns
Normal file
|
@ -0,0 +1 @@
|
|||
s/.*hid_listener_keycode_//p
|
4
app/tests/non-overlap/no-active/keycode_events.snapshot
Normal file
4
app/tests/non-overlap/no-active/keycode_events.snapshot
Normal 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
|
25
app/tests/non-overlap/no-active/native_posix_64.keymap
Normal file
25
app/tests/non-overlap/no-active/native_posix_64.keymap
Normal 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)
|
||||
>;
|
||||
};
|
1
app/tests/non-overlap/release-backward/events.patterns
Normal file
1
app/tests/non-overlap/release-backward/events.patterns
Normal file
|
@ -0,0 +1 @@
|
|||
s/.*hid_listener_keycode_//p
|
|
@ -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
|
|
@ -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
|
||||
>;
|
||||
};
|
1
app/tests/non-overlap/release-random/events.patterns
Normal file
1
app/tests/non-overlap/release-random/events.patterns
Normal file
|
@ -0,0 +1 @@
|
|||
s/.*hid_listener_keycode_//p
|
230
app/tests/non-overlap/release-random/keycode_events.snapshot
Normal file
230
app/tests/non-overlap/release-random/keycode_events.snapshot
Normal 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
|
236
app/tests/non-overlap/release-random/native_posix_64.keymap
Normal file
236
app/tests/non-overlap/release-random/native_posix_64.keymap
Normal 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
|
||||
>;
|
||||
};
|
1
app/tests/non-overlap/release/events.patterns
Normal file
1
app/tests/non-overlap/release/events.patterns
Normal file
|
@ -0,0 +1 @@
|
|||
s/.*hid_listener_keycode_//p
|
4
app/tests/non-overlap/release/keycode_events.snapshot
Normal file
4
app/tests/non-overlap/release/keycode_events.snapshot
Normal 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
|
20
app/tests/non-overlap/release/native_posix_64.keymap
Normal file
20
app/tests/non-overlap/release/native_posix_64.keymap
Normal 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
|
||||
>;
|
||||
};
|
1
app/tests/non-overlap/tap/events.patterns
Normal file
1
app/tests/non-overlap/tap/events.patterns
Normal file
|
@ -0,0 +1 @@
|
|||
s/.*hid_listener_keycode_//p
|
2
app/tests/non-overlap/tap/keycode_events.snapshot
Normal file
2
app/tests/non-overlap/tap/keycode_events.snapshot
Normal 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
|
14
app/tests/non-overlap/tap/native_posix_64.keymap
Normal file
14
app/tests/non-overlap/tap/native_posix_64.keymap
Normal 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)
|
||||
>;
|
||||
};
|
1
app/tests/non-overlap/wasd/events.patterns
Normal file
1
app/tests/non-overlap/wasd/events.patterns
Normal file
|
@ -0,0 +1 @@
|
|||
s/.*hid_listener_keycode_//p
|
8
app/tests/non-overlap/wasd/keycode_events.snapshot
Normal file
8
app/tests/non-overlap/wasd/keycode_events.snapshot
Normal 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
|
31
app/tests/non-overlap/wasd/native_posix_64.keymap
Normal file
31
app/tests/non-overlap/wasd/native_posix_64.keymap
Normal 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)
|
||||
>;
|
||||
};
|
|
@ -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
|
||||
|
||||
|
|
101
docs/docs/behaviors/non-overlap.mdx
Normal file
101
docs/docs/behaviors/non-overlap.mdx
Normal 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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
|
@ -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",
|
||||
|
|
Loading…
Add table
Reference in a new issue