Merge 59d468e19d
into b8846cf635
This commit is contained in:
commit
029cbc5534
4 changed files with 73 additions and 13 deletions
|
@ -28,8 +28,6 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
#define ZMK_BHV_STICKY_KEY_MAX_HELD 10
|
#define ZMK_BHV_STICKY_KEY_MAX_HELD 10
|
||||||
|
|
||||||
#define ZMK_BHV_STICKY_KEY_POSITION_FREE UINT32_MAX
|
|
||||||
|
|
||||||
struct behavior_sticky_key_config {
|
struct behavior_sticky_key_config {
|
||||||
uint32_t release_after_ms;
|
uint32_t release_after_ms;
|
||||||
bool quick_release;
|
bool quick_release;
|
||||||
|
@ -38,6 +36,7 @@ struct behavior_sticky_key_config {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct active_sticky_key {
|
struct active_sticky_key {
|
||||||
|
bool is_active;
|
||||||
uint32_t position;
|
uint32_t position;
|
||||||
uint32_t param1;
|
uint32_t param1;
|
||||||
uint32_t param2;
|
uint32_t param2;
|
||||||
|
@ -59,10 +58,10 @@ static struct active_sticky_key *store_sticky_key(uint32_t position, uint32_t pa
|
||||||
const struct behavior_sticky_key_config *config) {
|
const struct behavior_sticky_key_config *config) {
|
||||||
for (int i = 0; i < ZMK_BHV_STICKY_KEY_MAX_HELD; i++) {
|
for (int i = 0; i < ZMK_BHV_STICKY_KEY_MAX_HELD; i++) {
|
||||||
struct active_sticky_key *const sticky_key = &active_sticky_keys[i];
|
struct active_sticky_key *const sticky_key = &active_sticky_keys[i];
|
||||||
if (sticky_key->position != ZMK_BHV_STICKY_KEY_POSITION_FREE ||
|
if (sticky_key->is_active || sticky_key->timer_cancelled) {
|
||||||
sticky_key->timer_cancelled) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
sticky_key->is_active = true;
|
||||||
sticky_key->position = position;
|
sticky_key->position = position;
|
||||||
sticky_key->param1 = param1;
|
sticky_key->param1 = param1;
|
||||||
sticky_key->param2 = param2;
|
sticky_key->param2 = param2;
|
||||||
|
@ -78,12 +77,13 @@ static struct active_sticky_key *store_sticky_key(uint32_t position, uint32_t pa
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_sticky_key(struct active_sticky_key *sticky_key) {
|
static void clear_sticky_key(struct active_sticky_key *sticky_key) {
|
||||||
sticky_key->position = ZMK_BHV_STICKY_KEY_POSITION_FREE;
|
sticky_key->is_active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct active_sticky_key *find_sticky_key(uint32_t position) {
|
static struct active_sticky_key *find_sticky_key(uint32_t param1) {
|
||||||
for (int i = 0; i < ZMK_BHV_STICKY_KEY_MAX_HELD; i++) {
|
for (int i = 0; i < ZMK_BHV_STICKY_KEY_MAX_HELD; i++) {
|
||||||
if (active_sticky_keys[i].position == position && !active_sticky_keys[i].timer_cancelled) {
|
if (active_sticky_keys[i].is_active && active_sticky_keys[i].param1 == param1 &&
|
||||||
|
!active_sticky_keys[i].timer_cancelled) {
|
||||||
return &active_sticky_keys[i];
|
return &active_sticky_keys[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ static int on_sticky_key_binding_pressed(struct zmk_behavior_binding *binding,
|
||||||
const struct device *dev = zmk_behavior_get_binding(binding->behavior_dev);
|
const struct device *dev = zmk_behavior_get_binding(binding->behavior_dev);
|
||||||
const struct behavior_sticky_key_config *cfg = dev->config;
|
const struct behavior_sticky_key_config *cfg = dev->config;
|
||||||
struct active_sticky_key *sticky_key;
|
struct active_sticky_key *sticky_key;
|
||||||
sticky_key = find_sticky_key(event.position);
|
sticky_key = find_sticky_key(binding->param1);
|
||||||
if (sticky_key != NULL) {
|
if (sticky_key != NULL) {
|
||||||
stop_timer(sticky_key);
|
stop_timer(sticky_key);
|
||||||
release_sticky_key_behavior(sticky_key, event.timestamp);
|
release_sticky_key_behavior(sticky_key, event.timestamp);
|
||||||
|
@ -146,14 +146,14 @@ static int on_sticky_key_binding_pressed(struct zmk_behavior_binding *binding,
|
||||||
return ZMK_BEHAVIOR_OPAQUE;
|
return ZMK_BEHAVIOR_OPAQUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG_DBG("new sticky_key 0x%x", binding->param1);
|
||||||
press_sticky_key_behavior(sticky_key, event.timestamp);
|
press_sticky_key_behavior(sticky_key, event.timestamp);
|
||||||
LOG_DBG("%d new sticky_key", event.position);
|
|
||||||
return ZMK_BEHAVIOR_OPAQUE;
|
return ZMK_BEHAVIOR_OPAQUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int on_sticky_key_binding_released(struct zmk_behavior_binding *binding,
|
static int on_sticky_key_binding_released(struct zmk_behavior_binding *binding,
|
||||||
struct zmk_behavior_binding_event event) {
|
struct zmk_behavior_binding_event event) {
|
||||||
struct active_sticky_key *sticky_key = find_sticky_key(event.position);
|
struct active_sticky_key *sticky_key = find_sticky_key(binding->param1);
|
||||||
if (sticky_key == NULL) {
|
if (sticky_key == NULL) {
|
||||||
LOG_ERR("ACTIVE STICKY KEY CLEARED TOO EARLY");
|
LOG_ERR("ACTIVE STICKY KEY CLEARED TOO EARLY");
|
||||||
return ZMK_BEHAVIOR_OPAQUE;
|
return ZMK_BEHAVIOR_OPAQUE;
|
||||||
|
@ -200,7 +200,7 @@ static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh) {
|
||||||
|
|
||||||
for (int i = 0; i < ZMK_BHV_STICKY_KEY_MAX_HELD; i++) {
|
for (int i = 0; i < ZMK_BHV_STICKY_KEY_MAX_HELD; i++) {
|
||||||
struct active_sticky_key *sticky_key = &active_sticky_keys[i];
|
struct active_sticky_key *sticky_key = &active_sticky_keys[i];
|
||||||
if (sticky_key->position == ZMK_BHV_STICKY_KEY_POSITION_FREE) {
|
if (!sticky_key->is_active) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh) {
|
||||||
void behavior_sticky_key_timer_handler(struct k_work *item) {
|
void behavior_sticky_key_timer_handler(struct k_work *item) {
|
||||||
struct active_sticky_key *sticky_key =
|
struct active_sticky_key *sticky_key =
|
||||||
CONTAINER_OF(item, struct active_sticky_key, release_timer);
|
CONTAINER_OF(item, struct active_sticky_key, release_timer);
|
||||||
if (sticky_key->position == ZMK_BHV_STICKY_KEY_POSITION_FREE) {
|
if (!sticky_key->is_active) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (sticky_key->timer_cancelled) {
|
if (sticky_key->timer_cancelled) {
|
||||||
|
@ -280,7 +280,8 @@ static int behavior_sticky_key_init(const struct device *dev) {
|
||||||
for (int i = 0; i < ZMK_BHV_STICKY_KEY_MAX_HELD; i++) {
|
for (int i = 0; i < ZMK_BHV_STICKY_KEY_MAX_HELD; i++) {
|
||||||
k_work_init_delayable(&active_sticky_keys[i].release_timer,
|
k_work_init_delayable(&active_sticky_keys[i].release_timer,
|
||||||
behavior_sticky_key_timer_handler);
|
behavior_sticky_key_timer_handler);
|
||||||
active_sticky_keys[i].position = ZMK_BHV_STICKY_KEY_POSITION_FREE;
|
active_sticky_keys[i].is_active = false;
|
||||||
|
active_sticky_keys[i].timer_cancelled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
init_first_run = false;
|
init_first_run = false;
|
||||||
|
|
1
app/tests/sticky-keys/11-sl-sk-macro/events.patterns
Normal file
1
app/tests/sticky-keys/11-sl-sk-macro/events.patterns
Normal file
|
@ -0,0 +1 @@
|
||||||
|
s/.*hid_listener_keycode_//p
|
|
@ -0,0 +1,4 @@
|
||||||
|
pressed: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00
|
||||||
|
pressed: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
|
||||||
|
released: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00
|
||||||
|
released: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
|
54
app/tests/sticky-keys/11-sl-sk-macro/native_posix_64.keymap
Normal file
54
app/tests/sticky-keys/11-sl-sk-macro/native_posix_64.keymap
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
|
||||||
|
&sl {
|
||||||
|
ignore-modifiers;
|
||||||
|
};
|
||||||
|
|
||||||
|
/ {
|
||||||
|
macros {
|
||||||
|
sls: sls {
|
||||||
|
label = "sticky_layer_shift";
|
||||||
|
compatible = "zmk,behavior-macro";
|
||||||
|
#binding-cells = <0>;
|
||||||
|
wait-ms = <0>;
|
||||||
|
tap-ms = <1>;
|
||||||
|
bindings
|
||||||
|
= <&sl 1 &sk LSHFT>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
keymap {
|
||||||
|
compatible = "zmk,keymap";
|
||||||
|
label ="Default keymap";
|
||||||
|
|
||||||
|
default_layer {
|
||||||
|
bindings = <
|
||||||
|
&sls &kp A
|
||||||
|
&sl 1 &sk LSHFT
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
|
||||||
|
second_layer {
|
||||||
|
bindings = <
|
||||||
|
&trans &kp B
|
||||||
|
&trans &trans
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,10) // macro should produce same as sl followd by sk
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
// ZMK_MOCK_PRESS(1,0,10)
|
||||||
|
// ZMK_MOCK_RELEASE(1,0,10)
|
||||||
|
// ZMK_MOCK_PRESS(1,1,10)
|
||||||
|
// ZMK_MOCK_RELEASE(1,1,10)
|
||||||
|
ZMK_MOCK_PRESS(0,1,10)
|
||||||
|
ZMK_MOCK_RELEASE(0,1,10)
|
||||||
|
>;
|
||||||
|
};
|
Loading…
Add table
Reference in a new issue