From 003db892adadb7b760f43411d7154fe60bf3556d Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Sun, 17 Jan 2021 16:36:01 -0500 Subject: [PATCH 1/9] refactor(core): Extra position state change data struct. * Separate header and data struct for the event. * Remove duplicate struct in split code. --- .../zmk/events/position_state_changed.h | 8 ++++-- app/src/behaviors/behavior_hold_tap.c | 27 ++++++++++--------- app/src/keymap.c | 3 ++- app/src/kscan.c | 5 ++-- app/src/split/bluetooth/central.c | 16 +++-------- app/src/split_listener.c | 6 ++--- 6 files changed, 31 insertions(+), 34 deletions(-) diff --git a/app/include/zmk/events/position_state_changed.h b/app/include/zmk/events/position_state_changed.h index 0f1ac1b2..7541b475 100644 --- a/app/include/zmk/events/position_state_changed.h +++ b/app/include/zmk/events/position_state_changed.h @@ -9,11 +9,15 @@ #include #include -struct position_state_changed { - struct zmk_event_header header; +struct zmk_position_state_changed_data { uint32_t position; bool state; int64_t timestamp; }; +struct position_state_changed { + struct zmk_event_header header; + struct zmk_position_state_changed_data data; +}; + ZMK_EVENT_DECLARE(position_state_changed); \ No newline at end of file diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index 9b62eb15..43bf92cb 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -92,7 +92,7 @@ static struct position_state_changed *find_captured_keydown_event(uint32_t posit continue; } struct position_state_changed *position_event = cast_position_state_changed(eh); - if (position_event->position == position && position_event->state) { + if (position_event->data.position == position && position_event->data.state) { last_match = position_event; } } @@ -143,8 +143,9 @@ static void release_captured_events() { if (is_position_state_changed(captured_event)) { struct position_state_changed *position_event = cast_position_state_changed(captured_event); - LOG_DBG("Releasing key position event for position %d %s", position_event->position, - (position_event->state ? "pressed" : "released")); + LOG_DBG("Releasing key position event for position %d %s", + position_event->data.position, + (position_event->data.state ? "pressed" : "released")); } else { struct keycode_state_changed *modifier_event = cast_keycode_state_changed(captured_event); @@ -391,12 +392,12 @@ static int position_state_changed_listener(const struct zmk_event_header *eh) { struct position_state_changed *ev = cast_position_state_changed(eh); if (undecided_hold_tap == NULL) { - LOG_DBG("%d bubble (no undecided hold_tap active)", ev->position); + LOG_DBG("%d bubble (no undecided hold_tap active)", ev->data.position); return ZMK_EV_EVENT_BUBBLE; } - if (undecided_hold_tap->position == ev->position) { - if (ev->state) { // keydown + if (undecided_hold_tap->position == ev->data.position) { + if (ev->data.state) { // keydown LOG_ERR("hold-tap listener should be called before before most other listeners!"); return ZMK_EV_EVENT_BUBBLE; } else { // keyup @@ -408,23 +409,23 @@ static int position_state_changed_listener(const struct zmk_event_header *eh) { // If these events were queued, the timer event may be queued too late or not at all. // We make a timer decision before the other key events are handled if the timer would // have run out. - if (ev->timestamp > + if (ev->data.timestamp > (undecided_hold_tap->timestamp + undecided_hold_tap->config->tapping_term_ms)) { decide_hold_tap(undecided_hold_tap, HT_TIMER_EVENT); } - if (!ev->state && find_captured_keydown_event(ev->position) == NULL) { + if (!ev->data.state && find_captured_keydown_event(ev->data.position) == NULL) { // no keydown event has been captured, let it bubble. // we'll catch modifiers later in modifier_state_changed_listener - LOG_DBG("%d bubbling %d %s event", undecided_hold_tap->position, ev->position, - ev->state ? "down" : "up"); + LOG_DBG("%d bubbling %d %s event", undecided_hold_tap->position, ev->data.position, + ev->data.state ? "down" : "up"); return ZMK_EV_EVENT_BUBBLE; } - LOG_DBG("%d capturing %d %s event", undecided_hold_tap->position, ev->position, - ev->state ? "down" : "up"); + LOG_DBG("%d capturing %d %s event", undecided_hold_tap->position, ev->data.position, + ev->data.state ? "down" : "up"); capture_event(eh); - decide_hold_tap(undecided_hold_tap, ev->state ? HT_OTHER_KEY_DOWN : HT_OTHER_KEY_UP); + decide_hold_tap(undecided_hold_tap, ev->data.state ? HT_OTHER_KEY_DOWN : HT_OTHER_KEY_UP); return ZMK_EV_EVENT_CAPTURED; } diff --git a/app/src/keymap.c b/app/src/keymap.c index 322a9369..0af777d7 100644 --- a/app/src/keymap.c +++ b/app/src/keymap.c @@ -249,7 +249,8 @@ int zmk_keymap_sensor_triggered(uint8_t sensor_number, const struct device *sens int keymap_listener(const struct zmk_event_header *eh) { if (is_position_state_changed(eh)) { const struct position_state_changed *ev = cast_position_state_changed(eh); - return zmk_keymap_position_state_changed(ev->position, ev->state, ev->timestamp); + return zmk_keymap_position_state_changed(ev->data.position, ev->data.state, + ev->data.timestamp); #if ZMK_KEYMAP_HAS_SENSORS } else if (is_sensor_event(eh)) { const struct sensor_event *ev = cast_sensor_event(eh); diff --git a/app/src/kscan.c b/app/src/kscan.c index 6b84490a..707b4390 100644 --- a/app/src/kscan.c +++ b/app/src/kscan.c @@ -51,9 +51,8 @@ void zmk_kscan_process_msgq(struct k_work *item) { LOG_DBG("Row: %d, col: %d, position: %d, pressed: %s\n", ev.row, ev.column, position, (pressed ? "true" : "false")); pos_ev = new_position_state_changed(); - pos_ev->state = pressed; - pos_ev->position = position; - pos_ev->timestamp = k_uptime_get(); + pos_ev->data = (struct zmk_position_state_changed_data){ + .state = pressed, .position = position, .timestamp = k_uptime_get()}; ZMK_EVENT_RAISE(pos_ev); } } diff --git a/app/src/split/bluetooth/central.c b/app/src/split/bluetooth/central.c index e9dfbac5..6772869b 100644 --- a/app/src/split/bluetooth/central.c +++ b/app/src/split/bluetooth/central.c @@ -33,22 +33,14 @@ static struct bt_uuid_128 uuid = BT_UUID_INIT_128(ZMK_SPLIT_BT_SERVICE_UUID); static struct bt_gatt_discover_params discover_params; static struct bt_gatt_subscribe_params subscribe_params; -struct zmk_split_peripheral_event { - uint32_t position; - uint32_t state; - int32_t timestamp; -}; - -K_MSGQ_DEFINE(peripheral_event_msgq, sizeof(struct zmk_split_peripheral_event), +K_MSGQ_DEFINE(peripheral_event_msgq, sizeof(struct zmk_position_state_changed_data), CONFIG_ZMK_SPLIT_BLE_CENTRAL_POSITION_QUEUE_SIZE, 4); void peripheral_event_work_callback(struct k_work *work) { - struct zmk_split_peripheral_event ev; + struct zmk_position_state_changed_data ev; while (k_msgq_get(&peripheral_event_msgq, &ev, K_NO_WAIT) == 0) { struct position_state_changed *pos_ev = new_position_state_changed(); - pos_ev->position = ev.position; - pos_ev->state = ev.state; - pos_ev->timestamp = ev.timestamp; + pos_ev->data = ev; LOG_DBG("Trigger key position state change for %d", ev.position); ZMK_EVENT_RAISE(pos_ev); @@ -82,7 +74,7 @@ static uint8_t split_central_notify_func(struct bt_conn *conn, if (changed_positions[i] & BIT(j)) { uint32_t position = (i * 8) + j; bool pressed = position_state[i] & BIT(j); - struct zmk_split_peripheral_event ev = { + struct zmk_position_state_changed_data ev = { .position = position, .state = pressed, .timestamp = k_uptime_get()}; k_msgq_put(&peripheral_event_msgq, &ev, K_NO_WAIT); diff --git a/app/src/split_listener.c b/app/src/split_listener.c index f475002c..6d2ca60d 100644 --- a/app/src/split_listener.c +++ b/app/src/split_listener.c @@ -23,10 +23,10 @@ int split_listener(const struct zmk_event_header *eh) { LOG_DBG(""); if (is_position_state_changed(eh)) { const struct position_state_changed *ev = cast_position_state_changed(eh); - if (ev->state) { - return zmk_split_bt_position_pressed(ev->position); + if (ev->data.state) { + return zmk_split_bt_position_pressed(ev->data.position); } else { - return zmk_split_bt_position_released(ev->position); + return zmk_split_bt_position_released(ev->data.position); } } return ZMK_EV_EVENT_BUBBLE; From 3fe2acc2d191006fa6309191ee99b2e4e249ed08 Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Mon, 18 Jan 2021 00:35:56 -0500 Subject: [PATCH 2/9] refactor(core): Extra event payloads to own types, refactor API. * Make it easier to use *just* event payloads by defining the data, and then having event manager macros generate "wrapper structs" * Improve is_*/cast_* APIs to hide details of full event struct. * Create `zmk_event_t` typedef to pass to event handlers. * Bring event names inline w/ consistent `zmk_` prefix. --- app/include/zmk/event_manager.h | 49 +++++++------ .../zmk/events/activity_state_changed.h | 13 +--- .../zmk/events/battery_state_changed.h | 5 +- .../zmk/events/ble_active_profile_changed.h | 5 +- .../zmk/events/keycode_state_changed.h | 22 +++--- app/include/zmk/events/layer_state_changed.h | 16 ++-- .../zmk/events/modifiers_state_changed.h | 14 +--- .../zmk/events/position_state_changed.h | 10 +-- app/include/zmk/events/sensor_event.h | 6 +- .../zmk/events/usb_conn_state_changed.h | 5 +- app/src/activity.c | 11 ++- app/src/battery.c | 5 +- app/src/behaviors/behavior_hold_tap.c | 73 +++++++++---------- app/src/behaviors/behavior_key_press.c | 4 +- .../behavior_sensor_rotate_key_press.c | 4 +- app/src/behaviors/behavior_sticky_key.c | 8 +- app/src/ble.c | 7 +- app/src/combo.c | 40 +++++----- app/src/display/main.c | 6 +- app/src/display/widgets/battery_status.c | 6 +- app/src/display/widgets/layer_status.c | 4 +- app/src/display/widgets/output_status.c | 6 +- app/src/endpoints.c | 6 +- app/src/event_manager.c | 14 ++-- app/src/events/activity_state_changed.c | 2 +- app/src/events/battery_state_changed.c | 2 +- app/src/events/ble_active_profile_changed.c | 2 +- app/src/events/keycode_state_changed.c | 2 +- app/src/events/layer_state_changed.c | 2 +- app/src/events/modifiers_state_changed.c | 2 +- app/src/events/position_state_changed.c | 2 +- app/src/events/sensor_event.c | 2 +- app/src/events/usb_conn_state_changed.c | 2 +- app/src/hid_listener.c | 8 +- app/src/keymap.c | 17 ++--- app/src/kscan.c | 7 +- app/src/sensors.c | 9 +-- app/src/split/bluetooth/central.c | 11 +-- app/src/split_listener.c | 14 ++-- app/src/usb.c | 6 +- 40 files changed, 190 insertions(+), 239 deletions(-) diff --git a/app/include/zmk/event_manager.h b/app/include/zmk/event_manager.h index e5b6ed53..8fc3f197 100644 --- a/app/include/zmk/event_manager.h +++ b/app/include/zmk/event_manager.h @@ -14,16 +14,16 @@ struct zmk_event_type { const char *name; }; -struct zmk_event_header { +typedef struct { const struct zmk_event_type *event; uint8_t last_listener_index; -}; +} zmk_event_t; #define ZMK_EV_EVENT_BUBBLE 0 #define ZMK_EV_EVENT_HANDLED 1 #define ZMK_EV_EVENT_CAPTURED 2 -typedef int (*zmk_listener_callback_t)(const struct zmk_event_header *eh); +typedef int (*zmk_listener_callback_t)(const zmk_event_t *eh); struct zmk_listener { zmk_listener_callback_t callback; }; @@ -34,25 +34,29 @@ struct zmk_event_subscription { }; #define ZMK_EVENT_DECLARE(event_type) \ - struct event_type *new_##event_type(); \ - bool is_##event_type(const struct zmk_event_header *eh); \ - struct event_type *cast_##event_type(const struct zmk_event_header *eh); \ + struct event_type##_event { \ + zmk_event_t header; \ + struct event_type data; \ + }; \ + struct event_type##_event *new_##event_type(struct event_type); \ + bool is_##event_type(const zmk_event_t *eh); \ + struct event_type *cast_##event_type(const zmk_event_t *eh); \ extern const struct zmk_event_type zmk_event_##event_type; #define ZMK_EVENT_IMPL(event_type) \ const struct zmk_event_type zmk_event_##event_type = {.name = STRINGIFY(event_type)}; \ const struct zmk_event_type *zmk_event_ref_##event_type __used \ __attribute__((__section__(".event_type"))) = &zmk_event_##event_type; \ - struct event_type *new_##event_type() { \ - struct event_type *ev = (struct event_type *)k_malloc(sizeof(struct event_type)); \ + struct event_type##_event *new_##event_type(struct event_type data) { \ + struct event_type##_event *ev = \ + (struct event_type##_event *)k_malloc(sizeof(struct event_type##_event)); \ ev->header.event = &zmk_event_##event_type; \ + ev->data = data; \ return ev; \ }; \ - bool is_##event_type(const struct zmk_event_header *eh) { \ - return eh->event == &zmk_event_##event_type; \ - }; \ - struct event_type *cast_##event_type(const struct zmk_event_header *eh) { \ - return (struct event_type *)eh; \ + bool is_##event_type(const zmk_event_t *eh) { return eh->event == &zmk_event_##event_type; }; \ + struct event_type *cast_##event_type(const zmk_event_t *eh) { \ + return &((struct event_type##_event *)eh)->data; \ }; #define ZMK_LISTENER(mod, cb) const struct zmk_listener zmk_listener_##mod = {.callback = cb}; @@ -65,18 +69,19 @@ struct zmk_event_subscription { .listener = &zmk_listener_##mod, \ }; -#define ZMK_EVENT_RAISE(ev) zmk_event_manager_raise((struct zmk_event_header *)ev); +#define ZMK_EVENT_RAISE(ev) zmk_event_manager_raise((zmk_event_t *)ev); #define ZMK_EVENT_RAISE_AFTER(ev, mod) \ - zmk_event_manager_raise_after((struct zmk_event_header *)ev, &zmk_listener_##mod); + zmk_event_manager_raise_after((zmk_event_t *)ev, &zmk_listener_##mod); #define ZMK_EVENT_RAISE_AT(ev, mod) \ - zmk_event_manager_raise_at((struct zmk_event_header *)ev, &zmk_listener_##mod); + zmk_event_manager_raise_at((zmk_event_t *)ev, &zmk_listener_##mod); -#define ZMK_EVENT_RELEASE(ev) zmk_event_manager_release((struct zmk_event_header *)ev); +#define ZMK_EVENT_RELEASE(ev) zmk_event_manager_release((zmk_event_t *)ev); -int zmk_event_manager_raise(struct zmk_event_header *event); -int zmk_event_manager_raise_after(struct zmk_event_header *event, - const struct zmk_listener *listener); -int zmk_event_manager_raise_at(struct zmk_event_header *event, const struct zmk_listener *listener); -int zmk_event_manager_release(struct zmk_event_header *event); +#define ZMK_EVENT_FREE(ev) k_free((void *)ev); + +int zmk_event_manager_raise(zmk_event_t *event); +int zmk_event_manager_raise_after(zmk_event_t *event, const struct zmk_listener *listener); +int zmk_event_manager_raise_at(zmk_event_t *event, const struct zmk_listener *listener); +int zmk_event_manager_release(zmk_event_t *event); \ No newline at end of file diff --git a/app/include/zmk/events/activity_state_changed.h b/app/include/zmk/events/activity_state_changed.h index 511fbad6..998fa2d4 100644 --- a/app/include/zmk/events/activity_state_changed.h +++ b/app/include/zmk/events/activity_state_changed.h @@ -10,17 +10,8 @@ #include #include -struct activity_state_changed { - struct zmk_event_header header; +struct zmk_activity_state_changed { enum zmk_activity_state state; }; -ZMK_EVENT_DECLARE(activity_state_changed); - -static inline struct activity_state_changed * -create_activity_state_changed(enum zmk_activity_state state) { - struct activity_state_changed *ev = new_activity_state_changed(); - ev->state = state; - - return ev; -} \ No newline at end of file +ZMK_EVENT_DECLARE(zmk_activity_state_changed); \ No newline at end of file diff --git a/app/include/zmk/events/battery_state_changed.h b/app/include/zmk/events/battery_state_changed.h index 47e44ba1..6a003d8d 100644 --- a/app/include/zmk/events/battery_state_changed.h +++ b/app/include/zmk/events/battery_state_changed.h @@ -9,10 +9,9 @@ #include #include -struct battery_state_changed { - struct zmk_event_header header; +struct zmk_battery_state_changed { // TODO: Other battery channels uint8_t state_of_charge; }; -ZMK_EVENT_DECLARE(battery_state_changed); \ No newline at end of file +ZMK_EVENT_DECLARE(zmk_battery_state_changed); \ No newline at end of file diff --git a/app/include/zmk/events/ble_active_profile_changed.h b/app/include/zmk/events/ble_active_profile_changed.h index fa161266..4d3bb7ae 100644 --- a/app/include/zmk/events/ble_active_profile_changed.h +++ b/app/include/zmk/events/ble_active_profile_changed.h @@ -12,10 +12,9 @@ #include -struct ble_active_profile_changed { - struct zmk_event_header header; +struct zmk_ble_active_profile_changed { uint8_t index; struct zmk_ble_profile *profile; }; -ZMK_EVENT_DECLARE(ble_active_profile_changed); +ZMK_EVENT_DECLARE(zmk_ble_active_profile_changed); diff --git a/app/include/zmk/events/keycode_state_changed.h b/app/include/zmk/events/keycode_state_changed.h index 85b792b7..031169d0 100644 --- a/app/include/zmk/events/keycode_state_changed.h +++ b/app/include/zmk/events/keycode_state_changed.h @@ -12,8 +12,7 @@ #include #include -struct keycode_state_changed { - struct zmk_event_header header; +struct zmk_keycode_state_changed { uint16_t usage_page; uint32_t keycode; uint8_t implicit_modifiers; @@ -21,10 +20,10 @@ struct keycode_state_changed { int64_t timestamp; }; -ZMK_EVENT_DECLARE(keycode_state_changed); +ZMK_EVENT_DECLARE(zmk_keycode_state_changed); -static inline struct keycode_state_changed * -keycode_state_changed_from_encoded(uint32_t encoded, bool pressed, int64_t timestamp) { +static inline struct zmk_keycode_state_changed_event * +zmk_keycode_state_changed_from_encoded(uint32_t encoded, bool pressed, int64_t timestamp) { uint16_t page = HID_USAGE_PAGE(encoded) & 0xFF; uint16_t id = HID_USAGE_ID(encoded); zmk_mod_flags_t implicit_mods = SELECT_MODS(encoded); @@ -33,11 +32,10 @@ keycode_state_changed_from_encoded(uint32_t encoded, bool pressed, int64_t times page = HID_USAGE_KEY; } - struct keycode_state_changed *ev = new_keycode_state_changed(); - ev->usage_page = page; - ev->keycode = id; - ev->implicit_modifiers = implicit_mods; - ev->state = pressed; - ev->timestamp = timestamp; - return ev; + return new_zmk_keycode_state_changed( + (struct zmk_keycode_state_changed){.usage_page = page, + .keycode = id, + .implicit_modifiers = implicit_mods, + .state = pressed, + .timestamp = timestamp}); } diff --git a/app/include/zmk/events/layer_state_changed.h b/app/include/zmk/events/layer_state_changed.h index cf240025..33183546 100644 --- a/app/include/zmk/events/layer_state_changed.h +++ b/app/include/zmk/events/layer_state_changed.h @@ -9,20 +9,16 @@ #include #include -struct layer_state_changed { - struct zmk_event_header header; +struct zmk_layer_state_changed { uint8_t layer; bool state; int64_t timestamp; }; -ZMK_EVENT_DECLARE(layer_state_changed); +ZMK_EVENT_DECLARE(zmk_layer_state_changed); -static inline struct layer_state_changed *create_layer_state_changed(uint8_t layer, bool state) { - struct layer_state_changed *ev = new_layer_state_changed(); - ev->layer = layer; - ev->state = state; - ev->timestamp = k_uptime_get(); - - return ev; +static inline struct zmk_layer_state_changed_event *create_layer_state_changed(uint8_t layer, + bool state) { + return new_zmk_layer_state_changed((struct zmk_layer_state_changed){ + .layer = layer, .state = state, .timestamp = k_uptime_get()}); } diff --git a/app/include/zmk/events/modifiers_state_changed.h b/app/include/zmk/events/modifiers_state_changed.h index 4f40f4c9..504c2c9c 100644 --- a/app/include/zmk/events/modifiers_state_changed.h +++ b/app/include/zmk/events/modifiers_state_changed.h @@ -10,19 +10,9 @@ #include #include -struct modifiers_state_changed { - struct zmk_event_header header; +struct zmk_modifiers_state_changed { zmk_mod_flags_t modifiers; bool state; }; -ZMK_EVENT_DECLARE(modifiers_state_changed); - -inline struct modifiers_state_changed *create_modifiers_state_changed(zmk_mod_flags_t modifiers, - bool state) { - struct modifiers_state_changed *ev = new_modifiers_state_changed(); - ev->modifiers = modifiers; - ev->state = state; - - return ev; -} \ No newline at end of file +ZMK_EVENT_DECLARE(zmk_modifiers_state_changed); \ No newline at end of file diff --git a/app/include/zmk/events/position_state_changed.h b/app/include/zmk/events/position_state_changed.h index 7541b475..e2f68720 100644 --- a/app/include/zmk/events/position_state_changed.h +++ b/app/include/zmk/events/position_state_changed.h @@ -8,16 +8,10 @@ #include #include - -struct zmk_position_state_changed_data { +struct zmk_position_state_changed { uint32_t position; bool state; int64_t timestamp; }; -struct position_state_changed { - struct zmk_event_header header; - struct zmk_position_state_changed_data data; -}; - -ZMK_EVENT_DECLARE(position_state_changed); \ No newline at end of file +ZMK_EVENT_DECLARE(zmk_position_state_changed); \ No newline at end of file diff --git a/app/include/zmk/events/sensor_event.h b/app/include/zmk/events/sensor_event.h index 14fb2d3d..f579bc39 100644 --- a/app/include/zmk/events/sensor_event.h +++ b/app/include/zmk/events/sensor_event.h @@ -9,12 +9,10 @@ #include #include #include - -struct sensor_event { - struct zmk_event_header header; +struct zmk_sensor_event { uint8_t sensor_number; const struct device *sensor; int64_t timestamp; }; -ZMK_EVENT_DECLARE(sensor_event); \ No newline at end of file +ZMK_EVENT_DECLARE(zmk_sensor_event); \ No newline at end of file diff --git a/app/include/zmk/events/usb_conn_state_changed.h b/app/include/zmk/events/usb_conn_state_changed.h index b38fb9fe..b40158c3 100644 --- a/app/include/zmk/events/usb_conn_state_changed.h +++ b/app/include/zmk/events/usb_conn_state_changed.h @@ -12,9 +12,8 @@ #include #include -struct usb_conn_state_changed { - struct zmk_event_header header; +struct zmk_usb_conn_state_changed { enum zmk_usb_conn_state conn_state; }; -ZMK_EVENT_DECLARE(usb_conn_state_changed); \ No newline at end of file +ZMK_EVENT_DECLARE(zmk_usb_conn_state_changed); \ No newline at end of file diff --git a/app/src/activity.c b/app/src/activity.c index 8fe912a3..0661b270 100644 --- a/app/src/activity.c +++ b/app/src/activity.c @@ -29,7 +29,10 @@ static uint32_t activity_last_uptime; #define MAX_SLEEP_MS CONFIG_ZMK_IDLE_SLEEP_TIMEOUT #endif -int raise_event() { return ZMK_EVENT_RAISE(create_activity_state_changed(activity_state)); } +int raise_event() { + return ZMK_EVENT_RAISE(new_zmk_activity_state_changed( + (struct zmk_activity_state_changed){.state = activity_state})); +} int set_state(enum zmk_activity_state state) { if (activity_state == state) @@ -41,7 +44,7 @@ int set_state(enum zmk_activity_state state) { enum zmk_activity_state zmk_activity_get_state() { return activity_state; } -int activity_event_listener(const struct zmk_event_header *eh) { +int activity_event_listener(const zmk_event_t *eh) { activity_last_uptime = k_uptime_get(); return set_state(ZMK_ACTIVITY_ACTIVE); @@ -74,7 +77,7 @@ int activity_init() { } ZMK_LISTENER(activity, activity_event_listener); -ZMK_SUBSCRIPTION(activity, position_state_changed); -ZMK_SUBSCRIPTION(activity, sensor_event); +ZMK_SUBSCRIPTION(activity, zmk_position_state_changed); +ZMK_SUBSCRIPTION(activity, zmk_sensor_event); SYS_INIT(activity_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); diff --git a/app/src/battery.c b/app/src/battery.c index 917af9cf..5a7c57b0 100644 --- a/app/src/battery.c +++ b/app/src/battery.c @@ -45,9 +45,8 @@ static int zmk_battery_update(const struct device *battery) { return rc; } - struct battery_state_changed *ev = new_battery_state_changed(); - ev->state_of_charge = state_of_charge.val1; - return ZMK_EVENT_RAISE(ev); + return ZMK_EVENT_RAISE(new_zmk_battery_state_changed( + (struct zmk_battery_state_changed){.state_of_charge = state_of_charge.val1})); } static void zmk_battery_work(struct k_work *work) { diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index 43bf92cb..01851e91 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -69,9 +69,9 @@ struct active_hold_tap { struct active_hold_tap *undecided_hold_tap = NULL; struct active_hold_tap active_hold_taps[ZMK_BHV_HOLD_TAP_MAX_HELD] = {}; // We capture most position_state_changed events and some modifiers_state_changed events. -const struct zmk_event_header *captured_events[ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS] = {}; +const zmk_event_t *captured_events[ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS] = {}; -static int capture_event(const struct zmk_event_header *event) { +static int capture_event(const zmk_event_t *event) { for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) { if (captured_events[i] == NULL) { captured_events[i] = event; @@ -81,18 +81,18 @@ static int capture_event(const struct zmk_event_header *event) { return -ENOMEM; } -static struct position_state_changed *find_captured_keydown_event(uint32_t position) { - struct position_state_changed *last_match = NULL; +static struct zmk_position_state_changed *find_captured_keydown_event(uint32_t position) { + struct zmk_position_state_changed *last_match = NULL; for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) { - const struct zmk_event_header *eh = captured_events[i]; + const zmk_event_t *eh = captured_events[i]; if (eh == NULL) { return last_match; } - if (!is_position_state_changed(eh)) { + if (!is_zmk_position_state_changed(eh)) { continue; } - struct position_state_changed *position_event = cast_position_state_changed(eh); - if (position_event->data.position == position && position_event->data.state) { + struct zmk_position_state_changed *position_event = cast_zmk_position_state_changed(eh); + if (position_event->position == position && position_event->state) { last_match = position_event; } } @@ -132,7 +132,7 @@ static void release_captured_events() { // [k1_down, k1_up, null, null, null, ...] // now mt2 will start releasing it's own captured positions. for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) { - const struct zmk_event_header *captured_event = captured_events[i]; + const zmk_event_t *captured_event = captured_events[i]; if (captured_event == NULL) { return; } @@ -140,15 +140,14 @@ static void release_captured_events() { if (undecided_hold_tap != NULL) { k_msleep(10); } - if (is_position_state_changed(captured_event)) { - struct position_state_changed *position_event = - cast_position_state_changed(captured_event); - LOG_DBG("Releasing key position event for position %d %s", - position_event->data.position, - (position_event->data.state ? "pressed" : "released")); + if (is_zmk_position_state_changed(captured_event)) { + struct zmk_position_state_changed *position_event = + cast_zmk_position_state_changed(captured_event); + LOG_DBG("Releasing key position event for position %d %s", position_event->position, + (position_event->state ? "pressed" : "released")); } else { - struct keycode_state_changed *modifier_event = - cast_keycode_state_changed(captured_event); + struct zmk_keycode_state_changed *modifier_event = + cast_zmk_keycode_state_changed(captured_event); LOG_DBG("Releasing mods changed event 0x%02X %s", modifier_event->keycode, (modifier_event->state ? "pressed" : "released")); } @@ -388,16 +387,16 @@ static const struct behavior_driver_api behavior_hold_tap_driver_api = { .binding_released = on_hold_tap_binding_released, }; -static int position_state_changed_listener(const struct zmk_event_header *eh) { - struct position_state_changed *ev = cast_position_state_changed(eh); +static int position_state_changed_listener(const zmk_event_t *eh) { + struct zmk_position_state_changed *ev = cast_zmk_position_state_changed(eh); if (undecided_hold_tap == NULL) { - LOG_DBG("%d bubble (no undecided hold_tap active)", ev->data.position); + LOG_DBG("%d bubble (no undecided hold_tap active)", ev->position); return ZMK_EV_EVENT_BUBBLE; } - if (undecided_hold_tap->position == ev->data.position) { - if (ev->data.state) { // keydown + if (undecided_hold_tap->position == ev->position) { + if (ev->state) { // keydown LOG_ERR("hold-tap listener should be called before before most other listeners!"); return ZMK_EV_EVENT_BUBBLE; } else { // keyup @@ -409,34 +408,34 @@ static int position_state_changed_listener(const struct zmk_event_header *eh) { // If these events were queued, the timer event may be queued too late or not at all. // We make a timer decision before the other key events are handled if the timer would // have run out. - if (ev->data.timestamp > + if (ev->timestamp > (undecided_hold_tap->timestamp + undecided_hold_tap->config->tapping_term_ms)) { decide_hold_tap(undecided_hold_tap, HT_TIMER_EVENT); } - if (!ev->data.state && find_captured_keydown_event(ev->data.position) == NULL) { + if (!ev->state && find_captured_keydown_event(ev->position) == NULL) { // no keydown event has been captured, let it bubble. // we'll catch modifiers later in modifier_state_changed_listener - LOG_DBG("%d bubbling %d %s event", undecided_hold_tap->position, ev->data.position, - ev->data.state ? "down" : "up"); + LOG_DBG("%d bubbling %d %s event", undecided_hold_tap->position, ev->position, + ev->state ? "down" : "up"); return ZMK_EV_EVENT_BUBBLE; } - LOG_DBG("%d capturing %d %s event", undecided_hold_tap->position, ev->data.position, - ev->data.state ? "down" : "up"); + LOG_DBG("%d capturing %d %s event", undecided_hold_tap->position, ev->position, + ev->state ? "down" : "up"); capture_event(eh); - decide_hold_tap(undecided_hold_tap, ev->data.state ? HT_OTHER_KEY_DOWN : HT_OTHER_KEY_UP); + decide_hold_tap(undecided_hold_tap, ev->state ? HT_OTHER_KEY_DOWN : HT_OTHER_KEY_UP); return ZMK_EV_EVENT_CAPTURED; } -static inline bool only_mods(struct keycode_state_changed *ev) { +static inline bool only_mods(struct zmk_keycode_state_changed *ev) { return ev->usage_page == HID_USAGE_KEY && ev->keycode >= HID_USAGE_KEY_KEYBOARD_LEFTCONTROL && ev->keycode <= HID_USAGE_KEY_KEYBOARD_RIGHT_GUI; } -static int keycode_state_changed_listener(const struct zmk_event_header *eh) { +static int keycode_state_changed_listener(const zmk_event_t *eh) { // we want to catch layer-up events too... how? - struct keycode_state_changed *ev = cast_keycode_state_changed(eh); + struct zmk_keycode_state_changed *ev = cast_zmk_keycode_state_changed(eh); if (undecided_hold_tap == NULL) { // LOG_DBG("0x%02X bubble (no undecided hold_tap active)", ev->keycode); @@ -456,19 +455,19 @@ static int keycode_state_changed_listener(const struct zmk_event_header *eh) { return ZMK_EV_EVENT_CAPTURED; } -int behavior_hold_tap_listener(const struct zmk_event_header *eh) { - if (is_position_state_changed(eh)) { +int behavior_hold_tap_listener(const zmk_event_t *eh) { + if (is_zmk_position_state_changed(eh)) { return position_state_changed_listener(eh); - } else if (is_keycode_state_changed(eh)) { + } else if (is_zmk_keycode_state_changed(eh)) { return keycode_state_changed_listener(eh); } return ZMK_EV_EVENT_BUBBLE; } ZMK_LISTENER(behavior_hold_tap, behavior_hold_tap_listener); -ZMK_SUBSCRIPTION(behavior_hold_tap, position_state_changed); +ZMK_SUBSCRIPTION(behavior_hold_tap, zmk_position_state_changed); // this should be modifiers_state_changed, but unfrotunately that's not implemented yet. -ZMK_SUBSCRIPTION(behavior_hold_tap, keycode_state_changed); +ZMK_SUBSCRIPTION(behavior_hold_tap, zmk_keycode_state_changed); void behavior_hold_tap_timer_work_handler(struct k_work *item) { struct active_hold_tap *hold_tap = CONTAINER_OF(item, struct active_hold_tap, work); diff --git a/app/src/behaviors/behavior_key_press.c b/app/src/behaviors/behavior_key_press.c index df0828ac..8282977e 100644 --- a/app/src/behaviors/behavior_key_press.c +++ b/app/src/behaviors/behavior_key_press.c @@ -22,14 +22,14 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) { LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1); return ZMK_EVENT_RAISE( - keycode_state_changed_from_encoded(binding->param1, true, event.timestamp)); + zmk_keycode_state_changed_from_encoded(binding->param1, true, event.timestamp)); } static int on_keymap_binding_released(struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) { LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1); return ZMK_EVENT_RAISE( - keycode_state_changed_from_encoded(binding->param1, false, event.timestamp)); + zmk_keycode_state_changed_from_encoded(binding->param1, false, event.timestamp)); } static const struct behavior_driver_api behavior_key_press_driver_api = { diff --git a/app/src/behaviors/behavior_sensor_rotate_key_press.c b/app/src/behaviors/behavior_sensor_rotate_key_press.c index 1e659a15..67a2e710 100644 --- a/app/src/behaviors/behavior_sensor_rotate_key_press.c +++ b/app/src/behaviors/behavior_sensor_rotate_key_press.c @@ -45,12 +45,12 @@ static int on_sensor_binding_triggered(struct zmk_behavior_binding *binding, LOG_DBG("SEND %d", keycode); - ZMK_EVENT_RAISE(keycode_state_changed_from_encoded(keycode, true, timestamp)); + ZMK_EVENT_RAISE(zmk_keycode_state_changed_from_encoded(keycode, true, timestamp)); // TODO: Better way to do this? k_msleep(5); - return ZMK_EVENT_RAISE(keycode_state_changed_from_encoded(keycode, false, timestamp)); + return ZMK_EVENT_RAISE(zmk_keycode_state_changed_from_encoded(keycode, false, timestamp)); } static const struct behavior_driver_api behavior_sensor_rotate_key_press_driver_api = { diff --git a/app/src/behaviors/behavior_sticky_key.c b/app/src/behaviors/behavior_sticky_key.c index 15c9e21c..ee33d381 100644 --- a/app/src/behaviors/behavior_sticky_key.c +++ b/app/src/behaviors/behavior_sticky_key.c @@ -175,11 +175,11 @@ static const struct behavior_driver_api behavior_sticky_key_driver_api = { .binding_released = on_sticky_key_binding_released, }; -static int sticky_key_keycode_state_changed_listener(const struct zmk_event_header *eh) { - if (!is_keycode_state_changed(eh)) { +static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh) { + if (!is_zmk_keycode_state_changed(eh)) { return ZMK_EV_EVENT_BUBBLE; } - struct keycode_state_changed *ev = cast_keycode_state_changed(eh); + struct zmk_keycode_state_changed *ev = cast_zmk_keycode_state_changed(eh); for (int i = 0; i < ZMK_BHV_STICKY_KEY_MAX_HELD; i++) { struct active_sticky_key *sticky_key = &active_sticky_keys[i]; if (sticky_key->position == ZMK_BHV_STICKY_KEY_POSITION_FREE) { @@ -226,7 +226,7 @@ static int sticky_key_keycode_state_changed_listener(const struct zmk_event_head } ZMK_LISTENER(behavior_sticky_key, sticky_key_keycode_state_changed_listener); -ZMK_SUBSCRIPTION(behavior_sticky_key, keycode_state_changed); +ZMK_SUBSCRIPTION(behavior_sticky_key, zmk_keycode_state_changed); void behavior_sticky_key_timer_handler(struct k_work *item) { struct active_sticky_key *sticky_key = diff --git a/app/src/ble.c b/app/src/ble.c index 3a115cf4..e8d2c420 100644 --- a/app/src/ble.c +++ b/app/src/ble.c @@ -92,11 +92,8 @@ static bt_addr_le_t peripheral_addr; #endif /* IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) */ static void raise_profile_changed_event() { - struct ble_active_profile_changed *ev = new_ble_active_profile_changed(); - ev->index = active_profile; - ev->profile = &profiles[active_profile]; - - ZMK_EVENT_RAISE(ev); + ZMK_EVENT_RAISE(new_zmk_ble_active_profile_changed((struct zmk_ble_active_profile_changed){ + .index = active_profile, .profile = &profiles[active_profile]})); } static void raise_profile_changed_event_callback(struct k_work *work) { diff --git a/app/src/combo.c b/app/src/combo.c index 49638703..a08a2f57 100644 --- a/app/src/combo.c +++ b/app/src/combo.c @@ -40,7 +40,7 @@ struct active_combo { // key_positions_pressed is filled with key_positions when the combo is pressed. // The keys are removed from this array when they are released. // Once this array is empty, the behavior is released. - struct position_state_changed *key_positions_pressed[CONFIG_ZMK_COMBO_MAX_KEYS_PER_COMBO]; + const zmk_event_t *key_positions_pressed[CONFIG_ZMK_COMBO_MAX_KEYS_PER_COMBO]; }; struct combo_candidate { @@ -52,7 +52,7 @@ struct combo_candidate { }; // set of keys pressed -struct position_state_changed *pressed_keys[CONFIG_ZMK_COMBO_MAX_KEYS_PER_COMBO] = {NULL}; +const zmk_event_t *pressed_keys[CONFIG_ZMK_COMBO_MAX_KEYS_PER_COMBO] = {NULL}; // the set of candidate combos based on the currently pressed_keys struct combo_candidate candidates[CONFIG_ZMK_COMBO_MAX_COMBOS_PER_KEY]; // the last candidate that was completely pressed @@ -202,7 +202,7 @@ static int clear_candidates() { return CONFIG_ZMK_COMBO_MAX_COMBOS_PER_KEY; } -static int capture_pressed_key(struct position_state_changed *ev) { +static int capture_pressed_key(const zmk_event_t *ev) { for (int i = 0; i < CONFIG_ZMK_COMBO_MAX_COMBOS_PER_KEY; i++) { if (pressed_keys[i] != NULL) { continue; @@ -228,7 +228,7 @@ static void release_pressed_keys() { if (pressed_keys[i] == NULL) { return; } - struct position_state_changed *captured_event = pressed_keys[i]; + const zmk_event_t *captured_event = pressed_keys[i]; pressed_keys[i] = NULL; ZMK_EVENT_RAISE(captured_event); } @@ -290,7 +290,8 @@ static void activate_combo(struct combo_cfg *combo) { return; } move_pressed_keys_to_active_combo(active_combo); - press_combo_behavior(combo, active_combo->key_positions_pressed[0]->timestamp); + press_combo_behavior( + combo, cast_zmk_position_state_changed(active_combo->key_positions_pressed[0])->timestamp); } static void deactivate_combo(int active_combo_index) { @@ -314,10 +315,11 @@ static bool release_combo_key(int32_t position, int64_t timestamp) { for (int i = 0; i < active_combo->combo->key_position_len; i++) { if (active_combo->key_positions_pressed[i] == NULL) { all_keys_pressed = false; - } else if (active_combo->key_positions_pressed[i]->position != position) { + } else if (cast_zmk_position_state_changed(active_combo->key_positions_pressed[i]) + ->position != position) { all_keys_released = false; } else { // not null and position matches - k_free(active_combo->key_positions_pressed[i]); + ZMK_EVENT_FREE(active_combo->key_positions_pressed[i]); active_combo->key_positions_pressed[i] = NULL; key_released = true; } @@ -362,16 +364,16 @@ static void update_timeout_task() { } } -static int position_state_down(struct position_state_changed *ev) { +static int position_state_down(const zmk_event_t *ev, struct zmk_position_state_changed *data) { int num_candidates; if (candidates[0].combo == NULL) { - num_candidates = setup_candidates_for_first_keypress(ev->position, ev->timestamp); + num_candidates = setup_candidates_for_first_keypress(data->position, data->timestamp); if (num_candidates == 0) { return 0; } } else { - filter_timed_out_candidates(ev->timestamp); - num_candidates = filter_candidates(ev->position); + filter_timed_out_candidates(data->timestamp); + num_candidates = filter_candidates(data->position); } update_timeout_task(); @@ -395,7 +397,7 @@ static int position_state_down(struct position_state_changed *ev) { } } -static int position_state_up(struct position_state_changed *ev) { +static int position_state_up(struct zmk_position_state_changed *ev) { cleanup(); if (release_combo_key(ev->position, ev->timestamp)) { return ZMK_EV_EVENT_HANDLED; @@ -415,21 +417,21 @@ static void combo_timeout_handler(struct k_work *item) { update_timeout_task(); } -static int position_state_changed_listener(const struct zmk_event_header *eh) { - if (!is_position_state_changed(eh)) { +static int position_state_changed_listener(const zmk_event_t *ev) { + if (!is_zmk_position_state_changed(ev)) { return 0; } - struct position_state_changed *ev = cast_position_state_changed(eh); - if (ev->state) { // keydown - return position_state_down(ev); + struct zmk_position_state_changed *data = cast_zmk_position_state_changed(ev); + if (data->state) { // keydown + return position_state_down(ev, data); } else { // keyup - return position_state_up(ev); + return position_state_up(data); } } ZMK_LISTENER(combo, position_state_changed_listener); -ZMK_SUBSCRIPTION(combo, position_state_changed); +ZMK_SUBSCRIPTION(combo, zmk_position_state_changed); // todo: remove this once #506 is merged and #include #define KEY_BINDING_TO_STRUCT(idx, drv_inst) \ diff --git a/app/src/display/main.c b/app/src/display/main.c index 0bef6567..90789f94 100644 --- a/app/src/display/main.c +++ b/app/src/display/main.c @@ -75,8 +75,8 @@ int zmk_display_init() { return 0; } -int display_event_handler(const struct zmk_event_header *eh) { - struct activity_state_changed *ev = cast_activity_state_changed(eh); +int display_event_handler(const zmk_event_t *eh) { + struct zmk_activity_state_changed *ev = cast_zmk_activity_state_changed(eh); switch (ev->state) { case ZMK_ACTIVITY_ACTIVE: start_display_updates(); @@ -93,4 +93,4 @@ int display_event_handler(const struct zmk_event_header *eh) { } ZMK_LISTENER(display, display_event_handler); -ZMK_SUBSCRIPTION(display, activity_state_changed); \ No newline at end of file +ZMK_SUBSCRIPTION(display, zmk_activity_state_changed); \ No newline at end of file diff --git a/app/src/display/widgets/battery_status.c b/app/src/display/widgets/battery_status.c index f1f1c9f1..309c3e9d 100644 --- a/app/src/display/widgets/battery_status.c +++ b/app/src/display/widgets/battery_status.c @@ -75,14 +75,14 @@ lv_obj_t *zmk_widget_battery_status_obj(struct zmk_widget_battery_status *widget return widget->obj; } -int battery_status_listener(const struct zmk_event_header *eh) { +int battery_status_listener(const zmk_event_t *eh) { struct zmk_widget_battery_status *widget; SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) { set_battery_symbol(widget->obj); } return ZMK_EV_EVENT_BUBBLE; } ZMK_LISTENER(widget_battery_status, battery_status_listener) -ZMK_SUBSCRIPTION(widget_battery_status, battery_state_changed); +ZMK_SUBSCRIPTION(widget_battery_status, zmk_battery_state_changed); #if IS_ENABLED(CONFIG_USB) -ZMK_SUBSCRIPTION(widget_battery_status, usb_conn_state_changed); +ZMK_SUBSCRIPTION(widget_battery_status, zmk_usb_conn_state_changed); #endif /* IS_ENABLED(CONFIG_USB) */ diff --git a/app/src/display/widgets/layer_status.c b/app/src/display/widgets/layer_status.c index 6700bb30..9960f2a0 100644 --- a/app/src/display/widgets/layer_status.c +++ b/app/src/display/widgets/layer_status.c @@ -69,11 +69,11 @@ lv_obj_t *zmk_widget_layer_status_obj(struct zmk_widget_layer_status *widget) { return widget->obj; } -int layer_status_listener(const struct zmk_event_header *eh) { +int layer_status_listener(const zmk_event_t *eh) { struct zmk_widget_layer_status *widget; SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) { set_layer_symbol(widget->obj); } return 0; } ZMK_LISTENER(widget_layer_status, layer_status_listener) -ZMK_SUBSCRIPTION(widget_layer_status, layer_state_changed); \ No newline at end of file +ZMK_SUBSCRIPTION(widget_layer_status, zmk_layer_state_changed); \ No newline at end of file diff --git a/app/src/display/widgets/output_status.c b/app/src/display/widgets/output_status.c index 716228b7..7e37f906 100644 --- a/app/src/display/widgets/output_status.c +++ b/app/src/display/widgets/output_status.c @@ -79,7 +79,7 @@ lv_obj_t *zmk_widget_output_status_obj(struct zmk_widget_output_status *widget) return widget->obj; } -int output_status_listener(const struct zmk_event_header *eh) { +int output_status_listener(const zmk_event_t *eh) { struct zmk_widget_output_status *widget; SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) { set_status_symbol(widget->obj); } return ZMK_EV_EVENT_BUBBLE; @@ -87,8 +87,8 @@ int output_status_listener(const struct zmk_event_header *eh) { ZMK_LISTENER(widget_output_status, output_status_listener) #if defined(CONFIG_USB) -ZMK_SUBSCRIPTION(widget_output_status, usb_conn_state_changed); +ZMK_SUBSCRIPTION(widget_output_status, zmk_usb_conn_state_changed); #endif #if defined(CONFIG_ZMK_BLE) -ZMK_SUBSCRIPTION(widget_output_status, ble_active_profile_changed); +ZMK_SUBSCRIPTION(widget_output_status, zmk_ble_active_profile_changed); #endif diff --git a/app/src/endpoints.c b/app/src/endpoints.c index feff7996..93dfb817 100644 --- a/app/src/endpoints.c +++ b/app/src/endpoints.c @@ -245,17 +245,17 @@ static void update_current_endpoint() { } } -static int endpoint_listener(const struct zmk_event_header *eh) { +static int endpoint_listener(const zmk_event_t *eh) { update_current_endpoint(); return 0; } ZMK_LISTENER(endpoint_listener, endpoint_listener); #if IS_ENABLED(CONFIG_ZMK_USB) -ZMK_SUBSCRIPTION(endpoint_listener, usb_conn_state_changed); +ZMK_SUBSCRIPTION(endpoint_listener, zmk_usb_conn_state_changed); #endif #if IS_ENABLED(CONFIG_ZMK_BLE) -ZMK_SUBSCRIPTION(endpoint_listener, ble_active_profile_changed); +ZMK_SUBSCRIPTION(endpoint_listener, zmk_ble_active_profile_changed); #endif SYS_INIT(zmk_endpoints_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); diff --git a/app/src/event_manager.c b/app/src/event_manager.c index 872f5c86..0399ca80 100644 --- a/app/src/event_manager.c +++ b/app/src/event_manager.c @@ -17,7 +17,7 @@ extern struct zmk_event_type *__event_type_end[]; extern struct zmk_event_subscription __event_subscriptions_start[]; extern struct zmk_event_subscription __event_subscriptions_end[]; -int zmk_event_manager_handle_from(struct zmk_event_header *event, uint8_t start_index) { +int zmk_event_manager_handle_from(zmk_event_t *event, uint8_t start_index) { int ret = 0; uint8_t len = __event_subscriptions_end - __event_subscriptions_start; for (int i = start_index; i < len; i++) { @@ -48,12 +48,9 @@ release: return ret; } -int zmk_event_manager_raise(struct zmk_event_header *event) { - return zmk_event_manager_handle_from(event, 0); -} +int zmk_event_manager_raise(zmk_event_t *event) { return zmk_event_manager_handle_from(event, 0); } -int zmk_event_manager_raise_after(struct zmk_event_header *event, - const struct zmk_listener *listener) { +int zmk_event_manager_raise_after(zmk_event_t *event, const struct zmk_listener *listener) { uint8_t len = __event_subscriptions_end - __event_subscriptions_start; for (int i = 0; i < len; i++) { struct zmk_event_subscription *ev_sub = __event_subscriptions_start + i; @@ -68,8 +65,7 @@ int zmk_event_manager_raise_after(struct zmk_event_header *event, return -EINVAL; } -int zmk_event_manager_raise_at(struct zmk_event_header *event, - const struct zmk_listener *listener) { +int zmk_event_manager_raise_at(zmk_event_t *event, const struct zmk_listener *listener) { uint8_t len = __event_subscriptions_end - __event_subscriptions_start; for (int i = 0; i < len; i++) { struct zmk_event_subscription *ev_sub = __event_subscriptions_start + i; @@ -84,6 +80,6 @@ int zmk_event_manager_raise_at(struct zmk_event_header *event, return -EINVAL; } -int zmk_event_manager_release(struct zmk_event_header *event) { +int zmk_event_manager_release(zmk_event_t *event) { return zmk_event_manager_handle_from(event, event->last_listener_index + 1); } diff --git a/app/src/events/activity_state_changed.c b/app/src/events/activity_state_changed.c index 001e6a1a..2c27ce74 100644 --- a/app/src/events/activity_state_changed.c +++ b/app/src/events/activity_state_changed.c @@ -7,4 +7,4 @@ #include #include -ZMK_EVENT_IMPL(activity_state_changed); \ No newline at end of file +ZMK_EVENT_IMPL(zmk_activity_state_changed); \ No newline at end of file diff --git a/app/src/events/battery_state_changed.c b/app/src/events/battery_state_changed.c index ed6147a0..435fb24d 100644 --- a/app/src/events/battery_state_changed.c +++ b/app/src/events/battery_state_changed.c @@ -7,4 +7,4 @@ #include #include -ZMK_EVENT_IMPL(battery_state_changed); \ No newline at end of file +ZMK_EVENT_IMPL(zmk_battery_state_changed); \ No newline at end of file diff --git a/app/src/events/ble_active_profile_changed.c b/app/src/events/ble_active_profile_changed.c index e2d172fd..c4887f73 100644 --- a/app/src/events/ble_active_profile_changed.c +++ b/app/src/events/ble_active_profile_changed.c @@ -7,4 +7,4 @@ #include #include -ZMK_EVENT_IMPL(ble_active_profile_changed); \ No newline at end of file +ZMK_EVENT_IMPL(zmk_ble_active_profile_changed); \ No newline at end of file diff --git a/app/src/events/keycode_state_changed.c b/app/src/events/keycode_state_changed.c index d46126be..c9ef6aa7 100644 --- a/app/src/events/keycode_state_changed.c +++ b/app/src/events/keycode_state_changed.c @@ -7,4 +7,4 @@ #include #include -ZMK_EVENT_IMPL(keycode_state_changed); +ZMK_EVENT_IMPL(zmk_keycode_state_changed); diff --git a/app/src/events/layer_state_changed.c b/app/src/events/layer_state_changed.c index e7f8039c..bd6234c9 100644 --- a/app/src/events/layer_state_changed.c +++ b/app/src/events/layer_state_changed.c @@ -7,4 +7,4 @@ #include #include -ZMK_EVENT_IMPL(layer_state_changed); \ No newline at end of file +ZMK_EVENT_IMPL(zmk_layer_state_changed); \ No newline at end of file diff --git a/app/src/events/modifiers_state_changed.c b/app/src/events/modifiers_state_changed.c index 4143796e..3dfea25f 100644 --- a/app/src/events/modifiers_state_changed.c +++ b/app/src/events/modifiers_state_changed.c @@ -7,4 +7,4 @@ #include #include -ZMK_EVENT_IMPL(modifiers_state_changed); \ No newline at end of file +ZMK_EVENT_IMPL(zmk_modifiers_state_changed); \ No newline at end of file diff --git a/app/src/events/position_state_changed.c b/app/src/events/position_state_changed.c index b80314b9..bb40584e 100644 --- a/app/src/events/position_state_changed.c +++ b/app/src/events/position_state_changed.c @@ -7,4 +7,4 @@ #include #include -ZMK_EVENT_IMPL(position_state_changed); \ No newline at end of file +ZMK_EVENT_IMPL(zmk_position_state_changed); \ No newline at end of file diff --git a/app/src/events/sensor_event.c b/app/src/events/sensor_event.c index 6811e7dd..94ade947 100644 --- a/app/src/events/sensor_event.c +++ b/app/src/events/sensor_event.c @@ -7,4 +7,4 @@ #include #include -ZMK_EVENT_IMPL(sensor_event); \ No newline at end of file +ZMK_EVENT_IMPL(zmk_sensor_event); \ No newline at end of file diff --git a/app/src/events/usb_conn_state_changed.c b/app/src/events/usb_conn_state_changed.c index c299da7a..b3555569 100644 --- a/app/src/events/usb_conn_state_changed.c +++ b/app/src/events/usb_conn_state_changed.c @@ -7,4 +7,4 @@ #include #include -ZMK_EVENT_IMPL(usb_conn_state_changed); \ No newline at end of file +ZMK_EVENT_IMPL(zmk_usb_conn_state_changed); \ No newline at end of file diff --git a/app/src/hid_listener.c b/app/src/hid_listener.c index 6537ccab..c5143db7 100644 --- a/app/src/hid_listener.c +++ b/app/src/hid_listener.c @@ -70,9 +70,9 @@ static int hid_listener_keycode_released(uint16_t usage_page, uint32_t keycode, return zmk_endpoints_send_report(usage_page); } -int hid_listener(const struct zmk_event_header *eh) { - if (is_keycode_state_changed(eh)) { - const struct keycode_state_changed *ev = cast_keycode_state_changed(eh); +int hid_listener(const zmk_event_t *eh) { + if (is_zmk_keycode_state_changed(eh)) { + const struct zmk_keycode_state_changed *ev = cast_zmk_keycode_state_changed(eh); if (ev->state) { hid_listener_keycode_pressed(ev->usage_page, ev->keycode, ev->implicit_modifiers); } else { @@ -83,4 +83,4 @@ int hid_listener(const struct zmk_event_header *eh) { } ZMK_LISTENER(hid_listener, hid_listener); -ZMK_SUBSCRIPTION(hid_listener, keycode_state_changed); \ No newline at end of file +ZMK_SUBSCRIPTION(hid_listener, zmk_keycode_state_changed); \ No newline at end of file diff --git a/app/src/keymap.c b/app/src/keymap.c index 0af777d7..169cf9c4 100644 --- a/app/src/keymap.c +++ b/app/src/keymap.c @@ -246,14 +246,13 @@ int zmk_keymap_sensor_triggered(uint8_t sensor_number, const struct device *sens #endif /* ZMK_KEYMAP_HAS_SENSORS */ -int keymap_listener(const struct zmk_event_header *eh) { - if (is_position_state_changed(eh)) { - const struct position_state_changed *ev = cast_position_state_changed(eh); - return zmk_keymap_position_state_changed(ev->data.position, ev->data.state, - ev->data.timestamp); +int keymap_listener(const zmk_event_t *eh) { + if (is_zmk_position_state_changed(eh)) { + const struct zmk_position_state_changed *ev = cast_zmk_position_state_changed(eh); + return zmk_keymap_position_state_changed(ev->position, ev->state, ev->timestamp); #if ZMK_KEYMAP_HAS_SENSORS - } else if (is_sensor_event(eh)) { - const struct sensor_event *ev = cast_sensor_event(eh); + } else if (is_zmk_sensor_event(eh)) { + const struct zmk_sensor_event *ev = cast_zmk_sensor_event(eh); return zmk_keymap_sensor_triggered(ev->sensor_number, ev->sensor, ev->timestamp); #endif /* ZMK_KEYMAP_HAS_SENSORS */ } @@ -262,8 +261,8 @@ int keymap_listener(const struct zmk_event_header *eh) { } ZMK_LISTENER(keymap, keymap_listener); -ZMK_SUBSCRIPTION(keymap, position_state_changed); +ZMK_SUBSCRIPTION(keymap, zmk_position_state_changed); #if ZMK_KEYMAP_HAS_SENSORS -ZMK_SUBSCRIPTION(keymap, sensor_event); +ZMK_SUBSCRIPTION(keymap, zmk_sensor_event); #endif /* ZMK_KEYMAP_HAS_SENSORS */ diff --git a/app/src/kscan.c b/app/src/kscan.c index 707b4390..0c128b2d 100644 --- a/app/src/kscan.c +++ b/app/src/kscan.c @@ -47,13 +47,10 @@ void zmk_kscan_process_msgq(struct k_work *item) { while (k_msgq_get(&zmk_kscan_msgq, &ev, K_NO_WAIT) == 0) { bool pressed = (ev.state == ZMK_KSCAN_EVENT_STATE_PRESSED); uint32_t position = zmk_matrix_transform_row_column_to_position(ev.row, ev.column); - struct position_state_changed *pos_ev; LOG_DBG("Row: %d, col: %d, position: %d, pressed: %s\n", ev.row, ev.column, position, (pressed ? "true" : "false")); - pos_ev = new_position_state_changed(); - pos_ev->data = (struct zmk_position_state_changed_data){ - .state = pressed, .position = position, .timestamp = k_uptime_get()}; - ZMK_EVENT_RAISE(pos_ev); + ZMK_EVENT_RAISE(new_zmk_position_state_changed((struct zmk_position_state_changed){ + .state = pressed, .position = position, .timestamp = k_uptime_get()})); } } diff --git a/app/src/sensors.c b/app/src/sensors.c index 5e9ef150..dd5f4267 100644 --- a/app/src/sensors.c +++ b/app/src/sensors.c @@ -35,7 +35,6 @@ static struct sensors_data_item sensors[] = {UTIL_LISTIFY(ZMK_KEYMAP_SENSORS_LEN static void zmk_sensors_trigger_handler(const struct device *dev, struct sensor_trigger *trigger) { int err; struct sensors_data_item *item = CONTAINER_OF(trigger, struct sensors_data_item, trigger); - struct sensor_event *event; LOG_DBG("sensor %d", item->sensor_number); @@ -45,12 +44,8 @@ static void zmk_sensors_trigger_handler(const struct device *dev, struct sensor_ return; } - event = new_sensor_event(); - event->sensor_number = item->sensor_number; - event->sensor = dev; - event->timestamp = k_uptime_get(); - - ZMK_EVENT_RAISE(event); + ZMK_EVENT_RAISE(new_zmk_sensor_event((struct zmk_sensor_event){ + .sensor_number = item->sensor_number, .sensor = dev, .timestamp = k_uptime_get()})); } static void zmk_sensors_init_item(const char *node, uint8_t i, uint8_t abs_i) { diff --git a/app/src/split/bluetooth/central.c b/app/src/split/bluetooth/central.c index 6772869b..a56b0b81 100644 --- a/app/src/split/bluetooth/central.c +++ b/app/src/split/bluetooth/central.c @@ -33,17 +33,14 @@ static struct bt_uuid_128 uuid = BT_UUID_INIT_128(ZMK_SPLIT_BT_SERVICE_UUID); static struct bt_gatt_discover_params discover_params; static struct bt_gatt_subscribe_params subscribe_params; -K_MSGQ_DEFINE(peripheral_event_msgq, sizeof(struct zmk_position_state_changed_data), +K_MSGQ_DEFINE(peripheral_event_msgq, sizeof(struct zmk_position_state_changed), CONFIG_ZMK_SPLIT_BLE_CENTRAL_POSITION_QUEUE_SIZE, 4); void peripheral_event_work_callback(struct k_work *work) { - struct zmk_position_state_changed_data ev; + struct zmk_position_state_changed ev; while (k_msgq_get(&peripheral_event_msgq, &ev, K_NO_WAIT) == 0) { - struct position_state_changed *pos_ev = new_position_state_changed(); - pos_ev->data = ev; - LOG_DBG("Trigger key position state change for %d", ev.position); - ZMK_EVENT_RAISE(pos_ev); + ZMK_EVENT_RAISE(new_zmk_position_state_changed(ev)); } } @@ -74,7 +71,7 @@ static uint8_t split_central_notify_func(struct bt_conn *conn, if (changed_positions[i] & BIT(j)) { uint32_t position = (i * 8) + j; bool pressed = position_state[i] & BIT(j); - struct zmk_position_state_changed_data ev = { + struct zmk_position_state_changed ev = { .position = position, .state = pressed, .timestamp = k_uptime_get()}; k_msgq_put(&peripheral_event_msgq, &ev, K_NO_WAIT); diff --git a/app/src/split_listener.c b/app/src/split_listener.c index 6d2ca60d..54e893ed 100644 --- a/app/src/split_listener.c +++ b/app/src/split_listener.c @@ -19,18 +19,18 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include -int split_listener(const struct zmk_event_header *eh) { +int split_listener(const zmk_event_t *eh) { LOG_DBG(""); - if (is_position_state_changed(eh)) { - const struct position_state_changed *ev = cast_position_state_changed(eh); - if (ev->data.state) { - return zmk_split_bt_position_pressed(ev->data.position); + if (is_zmk_position_state_changed(eh)) { + const struct zmk_position_state_changed *ev = cast_zmk_position_state_changed(eh); + if (ev->state) { + return zmk_split_bt_position_pressed(ev->position); } else { - return zmk_split_bt_position_released(ev->data.position); + return zmk_split_bt_position_released(ev->position); } } return ZMK_EV_EVENT_BUBBLE; } ZMK_LISTENER(split_listener, split_listener); -ZMK_SUBSCRIPTION(split_listener, position_state_changed); \ No newline at end of file +ZMK_SUBSCRIPTION(split_listener, zmk_position_state_changed); \ No newline at end of file diff --git a/app/src/usb.c b/app/src/usb.c index 7900acef..c2f61a5b 100644 --- a/app/src/usb.c +++ b/app/src/usb.c @@ -55,10 +55,8 @@ int zmk_usb_hid_send_report(const uint8_t *report, size_t len) { #endif /* CONFIG_ZMK_USB */ static void raise_usb_status_changed_event() { - struct usb_conn_state_changed *ev = new_usb_conn_state_changed(); - ev->conn_state = zmk_usb_get_conn_state(); - - ZMK_EVENT_RAISE(ev); + ZMK_EVENT_RAISE(new_zmk_usb_conn_state_changed( + (struct zmk_usb_conn_state_changed){.conn_state = zmk_usb_get_conn_state()})); } enum usb_dc_status_code zmk_usb_get_status() { return usb_status; } From 3368a81057d4981aa259c5548050d95739d99d51 Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Tue, 19 Jan 2021 14:21:00 -0500 Subject: [PATCH 3/9] refactor(core): Combine `is_` and `cast_` event functions. * Use a single `as_foo` generated function to conditionally return a certain event type from a generic `zmk_event_t*` pointer. --- app/include/zmk/event_manager.h | 9 ++++----- app/src/behaviors/behavior_hold_tap.c | 24 ++++++++++++------------ app/src/behaviors/behavior_sticky_key.c | 4 ++-- app/src/combo.c | 8 ++++---- app/src/display/main.c | 6 +++++- app/src/hid_listener.c | 4 ++-- app/src/keymap.c | 20 ++++++++++++-------- app/src/split_listener.c | 4 ++-- 8 files changed, 43 insertions(+), 36 deletions(-) diff --git a/app/include/zmk/event_manager.h b/app/include/zmk/event_manager.h index 8fc3f197..5acb26eb 100644 --- a/app/include/zmk/event_manager.h +++ b/app/include/zmk/event_manager.h @@ -39,8 +39,7 @@ struct zmk_event_subscription { struct event_type data; \ }; \ struct event_type##_event *new_##event_type(struct event_type); \ - bool is_##event_type(const zmk_event_t *eh); \ - struct event_type *cast_##event_type(const zmk_event_t *eh); \ + struct event_type *as_##event_type(const zmk_event_t *eh); \ extern const struct zmk_event_type zmk_event_##event_type; #define ZMK_EVENT_IMPL(event_type) \ @@ -54,9 +53,9 @@ struct zmk_event_subscription { ev->data = data; \ return ev; \ }; \ - bool is_##event_type(const zmk_event_t *eh) { return eh->event == &zmk_event_##event_type; }; \ - struct event_type *cast_##event_type(const zmk_event_t *eh) { \ - return &((struct event_type##_event *)eh)->data; \ + struct event_type *as_##event_type(const zmk_event_t *eh) { \ + return (eh->event == &zmk_event_##event_type) ? &((struct event_type##_event *)eh)->data \ + : NULL; \ }; #define ZMK_LISTENER(mod, cb) const struct zmk_listener zmk_listener_##mod = {.callback = cb}; diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index 01851e91..de356337 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -88,10 +88,11 @@ static struct zmk_position_state_changed *find_captured_keydown_event(uint32_t p if (eh == NULL) { return last_match; } - if (!is_zmk_position_state_changed(eh)) { + struct zmk_position_state_changed *position_event = as_zmk_position_state_changed(eh); + if (position_event == NULL) { continue; } - struct zmk_position_state_changed *position_event = cast_zmk_position_state_changed(eh); + if (position_event->position == position && position_event->state) { last_match = position_event; } @@ -140,14 +141,13 @@ static void release_captured_events() { if (undecided_hold_tap != NULL) { k_msleep(10); } - if (is_zmk_position_state_changed(captured_event)) { - struct zmk_position_state_changed *position_event = - cast_zmk_position_state_changed(captured_event); + + struct zmk_position_state_changed *position_event; + struct zmk_keycode_state_changed *modifier_event; + if ((position_event = as_zmk_position_state_changed(captured_event)) != NULL) { LOG_DBG("Releasing key position event for position %d %s", position_event->position, (position_event->state ? "pressed" : "released")); - } else { - struct zmk_keycode_state_changed *modifier_event = - cast_zmk_keycode_state_changed(captured_event); + } else if ((modifier_event = as_zmk_keycode_state_changed(captured_event)) != NULL) { LOG_DBG("Releasing mods changed event 0x%02X %s", modifier_event->keycode, (modifier_event->state ? "pressed" : "released")); } @@ -388,7 +388,7 @@ static const struct behavior_driver_api behavior_hold_tap_driver_api = { }; static int position_state_changed_listener(const zmk_event_t *eh) { - struct zmk_position_state_changed *ev = cast_zmk_position_state_changed(eh); + struct zmk_position_state_changed *ev = as_zmk_position_state_changed(eh); if (undecided_hold_tap == NULL) { LOG_DBG("%d bubble (no undecided hold_tap active)", ev->position); @@ -435,7 +435,7 @@ static inline bool only_mods(struct zmk_keycode_state_changed *ev) { static int keycode_state_changed_listener(const zmk_event_t *eh) { // we want to catch layer-up events too... how? - struct zmk_keycode_state_changed *ev = cast_zmk_keycode_state_changed(eh); + struct zmk_keycode_state_changed *ev = as_zmk_keycode_state_changed(eh); if (undecided_hold_tap == NULL) { // LOG_DBG("0x%02X bubble (no undecided hold_tap active)", ev->keycode); @@ -456,9 +456,9 @@ static int keycode_state_changed_listener(const zmk_event_t *eh) { } int behavior_hold_tap_listener(const zmk_event_t *eh) { - if (is_zmk_position_state_changed(eh)) { + if (as_zmk_position_state_changed(eh) != NULL) { return position_state_changed_listener(eh); - } else if (is_zmk_keycode_state_changed(eh)) { + } else if (as_zmk_keycode_state_changed(eh) != NULL) { return keycode_state_changed_listener(eh); } return ZMK_EV_EVENT_BUBBLE; diff --git a/app/src/behaviors/behavior_sticky_key.c b/app/src/behaviors/behavior_sticky_key.c index ee33d381..fe05e067 100644 --- a/app/src/behaviors/behavior_sticky_key.c +++ b/app/src/behaviors/behavior_sticky_key.c @@ -176,10 +176,10 @@ static const struct behavior_driver_api behavior_sticky_key_driver_api = { }; static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh) { - if (!is_zmk_keycode_state_changed(eh)) { + struct zmk_keycode_state_changed *ev = as_zmk_keycode_state_changed(eh); + if (ev == NULL) { return ZMK_EV_EVENT_BUBBLE; } - struct zmk_keycode_state_changed *ev = cast_zmk_keycode_state_changed(eh); for (int i = 0; i < ZMK_BHV_STICKY_KEY_MAX_HELD; i++) { struct active_sticky_key *sticky_key = &active_sticky_keys[i]; if (sticky_key->position == ZMK_BHV_STICKY_KEY_POSITION_FREE) { diff --git a/app/src/combo.c b/app/src/combo.c index a08a2f57..82f6538f 100644 --- a/app/src/combo.c +++ b/app/src/combo.c @@ -291,7 +291,7 @@ static void activate_combo(struct combo_cfg *combo) { } move_pressed_keys_to_active_combo(active_combo); press_combo_behavior( - combo, cast_zmk_position_state_changed(active_combo->key_positions_pressed[0])->timestamp); + combo, as_zmk_position_state_changed(active_combo->key_positions_pressed[0])->timestamp); } static void deactivate_combo(int active_combo_index) { @@ -315,7 +315,7 @@ static bool release_combo_key(int32_t position, int64_t timestamp) { for (int i = 0; i < active_combo->combo->key_position_len; i++) { if (active_combo->key_positions_pressed[i] == NULL) { all_keys_pressed = false; - } else if (cast_zmk_position_state_changed(active_combo->key_positions_pressed[i]) + } else if (as_zmk_position_state_changed(active_combo->key_positions_pressed[i]) ->position != position) { all_keys_released = false; } else { // not null and position matches @@ -418,11 +418,11 @@ static void combo_timeout_handler(struct k_work *item) { } static int position_state_changed_listener(const zmk_event_t *ev) { - if (!is_zmk_position_state_changed(ev)) { + struct zmk_position_state_changed *data = as_zmk_position_state_changed(ev); + if (data == NULL) { return 0; } - struct zmk_position_state_changed *data = cast_zmk_position_state_changed(ev); if (data->state) { // keydown return position_state_down(ev, data); } else { // keyup diff --git a/app/src/display/main.c b/app/src/display/main.c index 90789f94..55dd1ce2 100644 --- a/app/src/display/main.c +++ b/app/src/display/main.c @@ -76,7 +76,11 @@ int zmk_display_init() { } int display_event_handler(const zmk_event_t *eh) { - struct zmk_activity_state_changed *ev = cast_zmk_activity_state_changed(eh); + struct zmk_activity_state_changed *ev = as_zmk_activity_state_changed(eh); + if (ev == NULL) { + return -ENOTSUP; + } + switch (ev->state) { case ZMK_ACTIVITY_ACTIVE: start_display_updates(); diff --git a/app/src/hid_listener.c b/app/src/hid_listener.c index c5143db7..cd7acc0e 100644 --- a/app/src/hid_listener.c +++ b/app/src/hid_listener.c @@ -71,8 +71,8 @@ static int hid_listener_keycode_released(uint16_t usage_page, uint32_t keycode, } int hid_listener(const zmk_event_t *eh) { - if (is_zmk_keycode_state_changed(eh)) { - const struct zmk_keycode_state_changed *ev = cast_zmk_keycode_state_changed(eh); + const struct zmk_keycode_state_changed *ev = as_zmk_keycode_state_changed(eh); + if (ev) { if (ev->state) { hid_listener_keycode_pressed(ev->usage_page, ev->keycode, ev->implicit_modifiers); } else { diff --git a/app/src/keymap.c b/app/src/keymap.c index 169cf9c4..31258e0d 100644 --- a/app/src/keymap.c +++ b/app/src/keymap.c @@ -247,16 +247,20 @@ int zmk_keymap_sensor_triggered(uint8_t sensor_number, const struct device *sens #endif /* ZMK_KEYMAP_HAS_SENSORS */ int keymap_listener(const zmk_event_t *eh) { - if (is_zmk_position_state_changed(eh)) { - const struct zmk_position_state_changed *ev = cast_zmk_position_state_changed(eh); - return zmk_keymap_position_state_changed(ev->position, ev->state, ev->timestamp); -#if ZMK_KEYMAP_HAS_SENSORS - } else if (is_zmk_sensor_event(eh)) { - const struct zmk_sensor_event *ev = cast_zmk_sensor_event(eh); - return zmk_keymap_sensor_triggered(ev->sensor_number, ev->sensor, ev->timestamp); -#endif /* ZMK_KEYMAP_HAS_SENSORS */ + const struct zmk_position_state_changed *pos_ev; + if ((pos_ev = as_zmk_position_state_changed(eh)) != NULL) { + return zmk_keymap_position_state_changed(pos_ev->position, pos_ev->state, + pos_ev->timestamp); } +#if ZMK_KEYMAP_HAS_SENSORS + const struct zmk_sensor_event *sensor_ev; + if ((sensor_ev = as_zmk_sensor_event(eh)) != NULL) { + return zmk_keymap_sensor_triggered(sensor_ev->sensor_number, sensor_ev->sensor, + sensor_ev->timestamp); + } +#endif /* ZMK_KEYMAP_HAS_SENSORS */ + return -ENOTSUP; } diff --git a/app/src/split_listener.c b/app/src/split_listener.c index 54e893ed..8ac56c9f 100644 --- a/app/src/split_listener.c +++ b/app/src/split_listener.c @@ -21,8 +21,8 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); int split_listener(const zmk_event_t *eh) { LOG_DBG(""); - if (is_zmk_position_state_changed(eh)) { - const struct zmk_position_state_changed *ev = cast_zmk_position_state_changed(eh); + const struct zmk_position_state_changed *ev = as_zmk_position_state_changed(eh); + if (ev != NULL) { if (ev->state) { return zmk_split_bt_position_pressed(ev->position); } else { From 13e46bea817bb9392bdd4922f4949c894c3673bf Mon Sep 17 00:00:00 2001 From: innovaker <66737976+innovaker@users.noreply.github.com> Date: Tue, 5 Jan 2021 19:59:35 +0000 Subject: [PATCH 4/9] docs(hold-tap): mark tapping_term_ms as code Improves readability and consistency. --- docs/docs/behaviors/hold-tap.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/docs/behaviors/hold-tap.md b/docs/docs/behaviors/hold-tap.md index f3c3c664..0cf48884 100644 --- a/docs/docs/behaviors/hold-tap.md +++ b/docs/docs/behaviors/hold-tap.md @@ -23,9 +23,9 @@ We call this the 'hold-preferred' flavor of hold-taps. While this flavor may wor #### Flavors -- The 'hold-preferred' flavor triggers the hold behavior when the tapping_term_ms has expired or another key is pressed. -- The 'balanced' flavor will trigger the hold behavior when the tapping_term_ms has expired or another key is pressed and released. -- The 'tap-preferred' flavor triggers the hold behavior when the tapping_term_ms has expired. It triggers the tap behavior when another key is pressed. +- The 'hold-preferred' flavor triggers the hold behavior when the `tapping_term_ms` has expired or another key is pressed. +- The 'balanced' flavor will trigger the hold behavior when the `tapping_term_ms` has expired or another key is pressed and released. +- The 'tap-preferred' flavor triggers the hold behavior when the `tapping_term_ms` has expired. It triggers the tap behavior when another key is pressed. When the hold-tap key is released and the hold behavior has not been triggered, the tap behavior will trigger. @@ -68,7 +68,7 @@ This example configures a hold-tap that works well for homerow mods: ``` -If this config does not work for you, try the flavor "balanced" with a medium tapping_term_ms such as 200ms. +If this config does not work for you, try the flavor "balanced" with a medium `tapping_term_ms` such as 200ms. #### Comparison to QMK From 58ad5d4e865341e736f4f80e6c3ec31d168fc509 Mon Sep 17 00:00:00 2001 From: Jay Greco Date: Tue, 19 Jan 2021 13:54:20 -0800 Subject: [PATCH 5/9] Fix offset in NIBBLE transformation and keymap The NIBBLE transformation was missing RC(0,0), which was causing some strange behavior in the kscan driver. --- app/boards/shields/nibble/nibble.keymap | 4 ++-- app/boards/shields/nibble/nibble.overlay | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/boards/shields/nibble/nibble.keymap b/app/boards/shields/nibble/nibble.keymap index 0bb625ec..bc274cd8 100644 --- a/app/boards/shields/nibble/nibble.keymap +++ b/app/boards/shields/nibble/nibble.keymap @@ -20,7 +20,7 @@ &kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp MINUS &kp EQUAL &kp BSPC &kp HOME &kp C_VOL_UP &kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp LBKT &kp RBKT &kp BSLH &kp DEL &kp C_VOL_DN &kp CLCK &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SEMI &kp SQT &kp RET &kp PG_UP -&trans &kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp FSLH &kp RSHFT &kp UP &kp PG_DN +&trans &kp LSHFT &trans &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp FSLH &kp RSHFT &kp UP &kp PG_DN &trans &kp LCTRL &kp LGUI &kp LALT &kp SPACE &mo FUNC &kp RALT &kp RCTRL &kp LEFT &kp DOWN &kp RIGHT >; }; @@ -29,7 +29,7 @@ &kp TILDE &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &trans &kp END &bt BT_CLR &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &bootloader &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans -&bt BT_PRV &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans +&bt BT_PRV &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &bt BT_NXT &trans &trans &trans &trans &trans &trans &trans &kp C_PREV &kp C_PP &kp C_NEXT >; }; diff --git a/app/boards/shields/nibble/nibble.overlay b/app/boards/shields/nibble/nibble.overlay index fd1b2f61..3b672752 100644 --- a/app/boards/shields/nibble/nibble.overlay +++ b/app/boards/shields/nibble/nibble.overlay @@ -21,7 +21,7 @@ , <&pro_micro_d 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)> , <&pro_micro_d 16 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)> , <&pro_micro_d 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)> - , <&pro_micro_d 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)> + , <&pro_micro_d 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)> ; output-gpios = <&pro_micro_a 3 GPIO_ACTIVE_HIGH> @@ -39,11 +39,11 @@ //TODO: Add a keymap graphic here map = < - RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5) RC(0,6) RC(0,7) RC(0,8) RC(0,9) RC(0,10) RC(0,11) RC(0,12) RC(0,13) RC(0,14) RC(0,15) -RC(1,0) RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5) RC(1,6) RC(1,7) RC(1,8) RC(1,9) RC(1,10) RC(1,11) RC(1,12) RC(1,13) RC(1,14) RC(1,15) -RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(2,6) RC(2,7) RC(2,8) RC(2,9) RC(2,10) RC(2,11) RC(2,12) RC(2,14) RC(2,15) -RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(3,6) RC(3,7) RC(3,8) RC(3,9) RC(3,10) RC(3,11) RC(3,12) RC(3,14) RC(3,15) -RC(4,0) RC(4,1) RC(4,2) RC(4,3) RC(4,6) RC(4,9) RC(4,10) RC(4,11) RC(4,12) RC(4,14) RC(4,15) + RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5) RC(0,6) RC(0,7) RC(0,8) RC(0,9) RC(0,10) RC(0,11) RC(0,12) RC(0,13) RC(0,14) RC(0,15) +RC(1,0) RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5) RC(1,6) RC(1,7) RC(1,8) RC(1,9) RC(1,10) RC(1,11) RC(1,12) RC(1,13) RC(1,14) RC(1,15) +RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(2,6) RC(2,7) RC(2,8) RC(2,9) RC(2,10) RC(2,11) RC(2,12) RC(2,14) RC(2,15) +RC(3,0) RC(3,1) RC(0,0) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(3,6) RC(3,7) RC(3,8) RC(3,9) RC(3,10) RC(3,11) RC(3,12) RC(3,14) RC(3,15) +RC(4,0) RC(4,1) RC(4,2) RC(4,3) RC(4,6) RC(4,9) RC(4,10) RC(4,11) RC(4,12) RC(4,14) RC(4,15) >; }; }; From 5eeb310b2f0ccf1adf91b448573001559696a1d7 Mon Sep 17 00:00:00 2001 From: Okke Formsma Date: Sat, 26 Dec 2020 14:46:56 +0100 Subject: [PATCH 6/9] feat(grave-escape): implement grave-escape closes #85 --- app/CMakeLists.txt | 1 + app/dts/behaviors.dtsi | 1 + app/dts/behaviors/gresc.dtsi | 19 ++++ .../behaviors/zmk,behavior-mod-morph.yaml | 16 +++ app/include/zmk/hid.h | 1 + app/src/behaviors/behavior_mod_morph.c | 99 +++++++++++++++++++ app/src/hid.c | 2 + .../gresc/gresc-press-release/events.patterns | 1 + .../keycode_events.snapshot | 18 ++++ .../gresc-press-release/native_posix.keymap | 49 +++++++++ .../gresc/gresc-two-instances/events.patterns | 2 + .../keycode_events.snapshot | 6 ++ .../gresc-two-instances/native_posix.keymap | 43 ++++++++ 13 files changed, 258 insertions(+) create mode 100644 app/dts/behaviors/gresc.dtsi create mode 100644 app/dts/bindings/behaviors/zmk,behavior-mod-morph.yaml create mode 100644 app/src/behaviors/behavior_mod_morph.c create mode 100644 app/tests/gresc/gresc-press-release/events.patterns create mode 100644 app/tests/gresc/gresc-press-release/keycode_events.snapshot create mode 100644 app/tests/gresc/gresc-press-release/native_posix.keymap create mode 100644 app/tests/gresc/gresc-two-instances/events.patterns create mode 100644 app/tests/gresc/gresc-two-instances/keycode_events.snapshot create mode 100644 app/tests/gresc/gresc-two-instances/native_posix.keymap diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index b217a1a1..83cf1bb8 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -45,6 +45,7 @@ if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) target_sources(app PRIVATE src/behaviors/behavior_hold_tap.c) target_sources(app PRIVATE src/behaviors/behavior_sticky_key.c) target_sources(app PRIVATE src/behaviors/behavior_momentary_layer.c) + target_sources(app PRIVATE src/behaviors/behavior_mod_morph.c) target_sources(app PRIVATE src/behaviors/behavior_outputs.c) target_sources(app PRIVATE src/behaviors/behavior_toggle_layer.c) target_sources(app PRIVATE src/behaviors/behavior_to_layer.c) diff --git a/app/dts/behaviors.dtsi b/app/dts/behaviors.dtsi index daa073f1..4333ceea 100644 --- a/app/dts/behaviors.dtsi +++ b/app/dts/behaviors.dtsi @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include diff --git a/app/dts/behaviors/gresc.dtsi b/app/dts/behaviors/gresc.dtsi new file mode 100644 index 00000000..29593880 --- /dev/null +++ b/app/dts/behaviors/gresc.dtsi @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include + +/ { + behaviors { + /omit-if-no-ref/ gresc: grave_escape { + compatible = "zmk,behavior-mod-morph"; + label = "GRAVE_ESCAPE"; + #binding-cells = <0>; + bindings = <&kp ESC>, <&kp GRAVE>; + mods = <(MOD_LGUI|MOD_LSFT|MOD_RGUI|MOD_RSFT)>; + }; + }; +}; diff --git a/app/dts/bindings/behaviors/zmk,behavior-mod-morph.yaml b/app/dts/bindings/behaviors/zmk,behavior-mod-morph.yaml new file mode 100644 index 00000000..66b452a5 --- /dev/null +++ b/app/dts/bindings/behaviors/zmk,behavior-mod-morph.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2020 The ZMK Contributors +# SPDX-License-Identifier: MIT + +description: Keyboard Reset Behavior + +compatible: "zmk,behavior-mod-morph" + +include: zero_param.yaml + +properties: + bindings: + type: phandle-array + required: true + mods: + type: int + required: true diff --git a/app/include/zmk/hid.h b/app/include/zmk/hid.h index 1ec51262..aca3cc46 100644 --- a/app/include/zmk/hid.h +++ b/app/include/zmk/hid.h @@ -166,6 +166,7 @@ struct zmk_hid_consumer_report { struct zmk_hid_consumer_report_body body; } __packed; +zmk_mod_flags_t zmk_hid_get_explicit_mods(); int zmk_hid_register_mod(zmk_mod_t modifier); int zmk_hid_unregister_mod(zmk_mod_t modifier); int zmk_hid_implicit_modifiers_press(zmk_mod_flags_t implicit_modifiers); diff --git a/app/src/behaviors/behavior_mod_morph.c b/app/src/behaviors/behavior_mod_morph.c new file mode 100644 index 00000000..36d109b8 --- /dev/null +++ b/app/src/behaviors/behavior_mod_morph.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_behavior_mod_morph + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) + +struct behavior_mod_morph_config { + struct zmk_behavior_binding normal_binding; + struct zmk_behavior_binding morph_binding; + zmk_mod_flags_t mods; +}; + +struct behavior_mod_morph_data { + struct zmk_behavior_binding *pressed_binding; +}; + +static int on_mod_morph_binding_pressed(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + const struct device *dev = device_get_binding(binding->behavior_dev); + const struct behavior_mod_morph_config *cfg = dev->config; + struct behavior_mod_morph_data *data = dev->data; + + if (data->pressed_binding != NULL) { + LOG_ERR("Can't press the same mod-morph twice"); + return -ENOTSUP; + } + + if (zmk_hid_get_explicit_mods() & cfg->mods) { + data->pressed_binding = (struct zmk_behavior_binding *)&cfg->morph_binding; + } else { + data->pressed_binding = (struct zmk_behavior_binding *)&cfg->normal_binding; + } + return behavior_keymap_binding_pressed(data->pressed_binding, event); +} + +static int on_mod_morph_binding_released(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + const struct device *dev = device_get_binding(binding->behavior_dev); + struct behavior_mod_morph_data *data = dev->data; + + if (data->pressed_binding == NULL) { + LOG_ERR("Mod-morph already released"); + return -ENOTSUP; + } + + struct zmk_behavior_binding *pressed_binding = data->pressed_binding; + data->pressed_binding = NULL; + return behavior_keymap_binding_released(pressed_binding, event); +} + +static const struct behavior_driver_api behavior_mod_morph_driver_api = { + .binding_pressed = on_mod_morph_binding_pressed, + .binding_released = on_mod_morph_binding_released, +}; + +static int behavior_mod_morph_init(const struct device *dev) { return 0; } + +#define _TRANSFORM_ENTRY(idx, node) \ + { \ + .behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(node, bindings, idx)), \ + .param1 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param1), (0), \ + (DT_INST_PHA_BY_IDX(node, bindings, idx, param1))), \ + .param2 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param2), (0), \ + (DT_INST_PHA_BY_IDX(node, bindings, idx, param2))), \ + } + +#define KP_INST(n) \ + static struct behavior_mod_morph_config behavior_mod_morph_config_##n = { \ + .normal_binding = _TRANSFORM_ENTRY(0, n), \ + .morph_binding = _TRANSFORM_ENTRY(1, n), \ + .mods = DT_INST_PROP(n, mods), \ + }; \ + static struct behavior_mod_morph_data behavior_mod_morph_data_##n = {}; \ + DEVICE_AND_API_INIT(behavior_mod_morph_##n, DT_INST_LABEL(n), behavior_mod_morph_init, \ + &behavior_mod_morph_data_##n, &behavior_mod_morph_config_##n, APPLICATION, \ + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_mod_morph_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(KP_INST) + +#endif \ No newline at end of file diff --git a/app/src/hid.c b/app/src/hid.c index b9ddfc52..65eabd9c 100644 --- a/app/src/hid.c +++ b/app/src/hid.c @@ -26,6 +26,8 @@ static zmk_mod_flags_t explicit_modifiers = 0; LOG_DBG("Modifiers set to 0x%02X", keyboard_report.body.modifiers); \ } +zmk_mod_flags_t zmk_hid_get_explicit_mods() { return explicit_modifiers; } + int zmk_hid_register_mod(zmk_mod_t modifier) { explicit_modifier_counts[modifier]++; LOG_DBG("Modifier %d count %d", modifier, explicit_modifier_counts[modifier]); diff --git a/app/tests/gresc/gresc-press-release/events.patterns b/app/tests/gresc/gresc-press-release/events.patterns new file mode 100644 index 00000000..b1342af4 --- /dev/null +++ b/app/tests/gresc/gresc-press-release/events.patterns @@ -0,0 +1 @@ +s/.*hid_listener_keycode_//p diff --git a/app/tests/gresc/gresc-press-release/keycode_events.snapshot b/app/tests/gresc/gresc-press-release/keycode_events.snapshot new file mode 100644 index 00000000..ebeba596 --- /dev/null +++ b/app/tests/gresc/gresc-press-release/keycode_events.snapshot @@ -0,0 +1,18 @@ +pressed: usage_page 0x07 keycode 0x29 mods 0x00 +released: usage_page 0x07 keycode 0x29 mods 0x00 +pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +pressed: usage_page 0x07 keycode 0x35 mods 0x00 +released: usage_page 0x07 keycode 0x35 mods 0x00 +released: usage_page 0x07 keycode 0xe1 mods 0x00 +pressed: usage_page 0x07 keycode 0xe3 mods 0x00 +pressed: usage_page 0x07 keycode 0x35 mods 0x00 +released: usage_page 0x07 keycode 0x35 mods 0x00 +released: usage_page 0x07 keycode 0xe3 mods 0x00 +pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +pressed: usage_page 0x07 keycode 0x35 mods 0x00 +released: usage_page 0x07 keycode 0xe1 mods 0x00 +released: usage_page 0x07 keycode 0x35 mods 0x00 +pressed: usage_page 0x07 keycode 0xe3 mods 0x00 +pressed: usage_page 0x07 keycode 0x35 mods 0x00 +released: usage_page 0x07 keycode 0xe3 mods 0x00 +released: usage_page 0x07 keycode 0x35 mods 0x00 diff --git a/app/tests/gresc/gresc-press-release/native_posix.keymap b/app/tests/gresc/gresc-press-release/native_posix.keymap new file mode 100644 index 00000000..7ca3d77d --- /dev/null +++ b/app/tests/gresc/gresc-press-release/native_posix.keymap @@ -0,0 +1,49 @@ +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &gresc &none + &kp LEFT_SHIFT &kp LEFT_GUI + >; + }; + }; +}; + +&kscan { + events = < + /* esc */ + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + + /* ~ */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(1,0,10) + + /* LGUI+` */ + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(1,1,10) + + /* ~ */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + + /* LGUI+` */ + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/gresc/gresc-two-instances/events.patterns b/app/tests/gresc/gresc-two-instances/events.patterns new file mode 100644 index 00000000..ef7b7955 --- /dev/null +++ b/app/tests/gresc/gresc-two-instances/events.patterns @@ -0,0 +1,2 @@ +s/.*hid_listener_keycode_//p +s/.*on_mod_morph_binding_/morph_binding_/p \ No newline at end of file diff --git a/app/tests/gresc/gresc-two-instances/keycode_events.snapshot b/app/tests/gresc/gresc-two-instances/keycode_events.snapshot new file mode 100644 index 00000000..170e0cb1 --- /dev/null +++ b/app/tests/gresc/gresc-two-instances/keycode_events.snapshot @@ -0,0 +1,6 @@ +pressed: usage_page 0x07 keycode 0x29 mods 0x00 +released: usage_page 0x07 keycode 0x29 mods 0x00 +pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +pressed: usage_page 0x07 keycode 0x35 mods 0x00 +released: usage_page 0x07 keycode 0xe1 mods 0x00 +released: usage_page 0x07 keycode 0x35 mods 0x00 diff --git a/app/tests/gresc/gresc-two-instances/native_posix.keymap b/app/tests/gresc/gresc-two-instances/native_posix.keymap new file mode 100644 index 00000000..0c38721d --- /dev/null +++ b/app/tests/gresc/gresc-two-instances/native_posix.keymap @@ -0,0 +1,43 @@ +#include +#include +#include + +/* +This test checks nothing breaks if two grave-escapes are pressed at the same time. +If someone ever really needs two, they can make a second behavior definition. + +The second gresc that is pressed is ignored. +The first gresc that is released releases the key. +*/ + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &gresc &gresc + &kp LEFT_SHIFT &kp LEFT_GUI + >; + }; + }; +}; + +&kscan { + events = < + /* esc */ + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(0,1,10) /* the second gresc is ignored */ + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) /* the second gresc is ignored */ + + /* ~ */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_PRESS(0,0,10) /* the second gresc is ignored */ + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_RELEASE(0,0,10) /* the second gresc is ignored */ + >; +}; \ No newline at end of file From c0cab57c2d4d1fd4a7db4e7d6edda7bdc6549619 Mon Sep 17 00:00:00 2001 From: Jeff Rizzo Date: Thu, 21 Jan 2021 12:05:30 -0800 Subject: [PATCH 7/9] run-test.sh: use the POSIX '-L 1' for xargs This allows tests to be run on platforms where '-l' isn't implemented, like MacOS. --- app/run-test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/run-test.sh b/app/run-test.sh index dd3c752b..47089323 100755 --- a/app/run-test.sh +++ b/app/run-test.sh @@ -17,7 +17,7 @@ testcases=$(find $path -name native_posix.keymap -exec dirname \{\} \;) num_cases=$(echo "$testcases" | wc -l) if [ $num_cases -gt 1 ]; then echo "" > ./build/tests/pass-fail.log - echo "$testcases" | xargs -l -P 4 ./run-test.sh + echo "$testcases" | xargs -L 1 -P 4 ./run-test.sh err=$? sort -k2 ./build/tests/pass-fail.log exit $err @@ -45,4 +45,4 @@ else echo "PASS: $testcase" >> ./build/tests/pass-fail.log exit 0 fi -fi \ No newline at end of file +fi From a4aaa73f06939417a911c5213480efe78aa70fab Mon Sep 17 00:00:00 2001 From: Ally Parker Date: Fri, 22 Jan 2021 16:23:21 +0000 Subject: [PATCH 8/9] feat: Add WPM calculator and display widget --- app/CMakeLists.txt | 2 + app/Kconfig | 4 + app/include/zmk/display/widgets/wpm_status.h | 18 ++++ app/include/zmk/events/wpm_state_changed.h | 17 ++++ app/include/zmk/wpm.h | 9 ++ app/src/display/status_screen.c | 10 +++ app/src/display/widgets/CMakeLists.txt | 1 + app/src/display/widgets/Kconfig | 7 ++ app/src/display/widgets/wpm_status.c | 67 +++++++++++++++ app/src/events/wpm_state_changed.c | 10 +++ app/src/wpm.c | 86 +++++++++++++++++++ .../wpm/1-single_keypress/events.patterns | 2 + .../1-single_keypress/keycode_events.snapshot | 7 ++ .../wpm/1-single_keypress/native_posix.conf | 9 ++ .../wpm/1-single_keypress/native_posix.keymap | 10 +++ .../wpm/2-multiple_keypress/events.patterns | 2 + .../keycode_events.snapshot | 4 + .../wpm/2-multiple_keypress/native_posix.conf | 9 ++ .../2-multiple_keypress/native_posix.keymap | 15 ++++ app/tests/wpm/behavior_keymap.dtsi | 17 ++++ 20 files changed, 306 insertions(+) create mode 100644 app/include/zmk/display/widgets/wpm_status.h create mode 100644 app/include/zmk/events/wpm_state_changed.h create mode 100644 app/include/zmk/wpm.h create mode 100644 app/src/display/widgets/wpm_status.c create mode 100644 app/src/events/wpm_state_changed.c create mode 100644 app/src/wpm.c create mode 100644 app/tests/wpm/1-single_keypress/events.patterns create mode 100644 app/tests/wpm/1-single_keypress/keycode_events.snapshot create mode 100644 app/tests/wpm/1-single_keypress/native_posix.conf create mode 100644 app/tests/wpm/1-single_keypress/native_posix.keymap create mode 100644 app/tests/wpm/2-multiple_keypress/events.patterns create mode 100644 app/tests/wpm/2-multiple_keypress/keycode_events.snapshot create mode 100644 app/tests/wpm/2-multiple_keypress/native_posix.conf create mode 100644 app/tests/wpm/2-multiple_keypress/native_posix.keymap create mode 100644 app/tests/wpm/behavior_keymap.dtsi diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 83cf1bb8..e283487f 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -28,6 +28,7 @@ target_sources(app PRIVATE src/kscan.c) target_sources(app PRIVATE src/matrix_transform.c) target_sources(app PRIVATE src/hid.c) target_sources(app PRIVATE src/sensors.c) +target_sources_ifdef(CONFIG_ZMK_WPM app PRIVATE src/wpm.c) target_sources(app PRIVATE src/event_manager.c) target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/ext_power_generic.c) target_sources(app PRIVATE src/events/activity_state_changed.c) @@ -36,6 +37,7 @@ target_sources(app PRIVATE src/events/layer_state_changed.c) target_sources(app PRIVATE src/events/keycode_state_changed.c) target_sources(app PRIVATE src/events/modifiers_state_changed.c) target_sources(app PRIVATE src/events/sensor_event.c) +target_sources_ifdef(CONFIG_ZMK_WPM app PRIVATE src/events/wpm_state_changed.c) target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/events/ble_active_profile_changed.c) target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/events/battery_state_changed.c) target_sources_ifdef(CONFIG_USB app PRIVATE src/events/usb_conn_state_changed.c) diff --git a/app/Kconfig b/app/Kconfig index df00f1db..737895c7 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -417,6 +417,10 @@ config REBOOT config USB default y if HAS_HW_NRF_USBD +config ZMK_WPM + bool "Calculate WPM" + default n + module = ZMK module-str = zmk source "subsys/logging/Kconfig.template.log_config" diff --git a/app/include/zmk/display/widgets/wpm_status.h b/app/include/zmk/display/widgets/wpm_status.h new file mode 100644 index 00000000..0592299e --- /dev/null +++ b/app/include/zmk/display/widgets/wpm_status.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include +#include + +struct zmk_widget_wpm_status { + sys_snode_t node; + lv_obj_t *obj; +}; + +int zmk_widget_wpm_status_init(struct zmk_widget_wpm_status *widget, lv_obj_t *parent); +lv_obj_t *zmk_widget_wpm_status_obj(struct zmk_widget_wpm_status *widget); \ No newline at end of file diff --git a/app/include/zmk/events/wpm_state_changed.h b/app/include/zmk/events/wpm_state_changed.h new file mode 100644 index 00000000..3d1a3695 --- /dev/null +++ b/app/include/zmk/events/wpm_state_changed.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include +#include +#include + +struct zmk_wpm_state_changed { + int state; +}; + +ZMK_EVENT_DECLARE(zmk_wpm_state_changed); diff --git a/app/include/zmk/wpm.h b/app/include/zmk/wpm.h new file mode 100644 index 00000000..6db100a0 --- /dev/null +++ b/app/include/zmk/wpm.h @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +int zmk_wpm_get_state(); \ No newline at end of file diff --git a/app/src/display/status_screen.c b/app/src/display/status_screen.c index 0c88717a..6f32b283 100644 --- a/app/src/display/status_screen.c +++ b/app/src/display/status_screen.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -24,6 +25,10 @@ static struct zmk_widget_output_status output_status_widget; static struct zmk_widget_layer_status layer_status_widget; #endif +#if IS_ENABLED(CONFIG_ZMK_WIDGET_WPM_STATUS) +static struct zmk_widget_wpm_status wpm_status_widget; +#endif + lv_obj_t *zmk_display_status_screen() { lv_obj_t *screen; @@ -47,5 +52,10 @@ lv_obj_t *zmk_display_status_screen() { 0, 0); #endif +#if IS_ENABLED(CONFIG_ZMK_WIDGET_WPM_STATUS) + zmk_widget_wpm_status_init(&wpm_status_widget, screen); + lv_obj_align(zmk_widget_wpm_status_obj(&wpm_status_widget), NULL, LV_ALIGN_IN_BOTTOM_RIGHT, -12, + 0); +#endif return screen; } diff --git a/app/src/display/widgets/CMakeLists.txt b/app/src/display/widgets/CMakeLists.txt index ad7e132a..1d115dcc 100644 --- a/app/src/display/widgets/CMakeLists.txt +++ b/app/src/display/widgets/CMakeLists.txt @@ -4,3 +4,4 @@ target_sources_ifdef(CONFIG_ZMK_WIDGET_BATTERY_STATUS app PRIVATE battery_status.c) target_sources_ifdef(CONFIG_ZMK_WIDGET_OUTPUT_STATUS app PRIVATE output_status.c) target_sources_ifdef(CONFIG_ZMK_WIDGET_LAYER_STATUS app PRIVATE layer_status.c) +target_sources_ifdef(CONFIG_ZMK_WIDGET_WPM_STATUS app PRIVATE wpm_status.c) diff --git a/app/src/display/widgets/Kconfig b/app/src/display/widgets/Kconfig index bdb3024e..f12d99a3 100644 --- a/app/src/display/widgets/Kconfig +++ b/app/src/display/widgets/Kconfig @@ -22,5 +22,12 @@ config ZMK_WIDGET_OUTPUT_STATUS default y if BT select LVGL_USE_LABEL select LVGL_FONT_MONTSERRAT_16 + +config ZMK_WIDGET_WPM_STATUS + bool "Widget for displaying typed words per minute" + depends on !ZMK_SPLIT || ZMK_SPLIT_BLE_ROLE_CENTRAL + select LVGL_USE_LABEL + select LVGL_FONT_MONTSERRAT_16 + select ZMK_WPM endmenu diff --git a/app/src/display/widgets/wpm_status.c b/app/src/display/widgets/wpm_status.c new file mode 100644 index 00000000..41ee3685 --- /dev/null +++ b/app/src/display/widgets/wpm_status.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#include +#include +#include +#include +#include + +static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets); +static lv_style_t label_style; + +static bool style_initialized = false; + +void wpm_status_init() { + if (style_initialized) { + return; + } + + style_initialized = true; + lv_style_init(&label_style); + lv_style_set_text_color(&label_style, LV_STATE_DEFAULT, LV_COLOR_BLACK); + lv_style_set_text_font(&label_style, LV_STATE_DEFAULT, &lv_font_montserrat_12); + lv_style_set_text_letter_space(&label_style, LV_STATE_DEFAULT, 1); + lv_style_set_text_line_space(&label_style, LV_STATE_DEFAULT, 1); +} + +void set_wpm_symbol(lv_obj_t *label, int wpm) { + char text[4] = {}; + + LOG_DBG("WPM changed to %i", wpm); + sprintf(text, "%i ", wpm); + + lv_label_set_text(label, text); +} + +int zmk_widget_wpm_status_init(struct zmk_widget_wpm_status *widget, lv_obj_t *parent) { + wpm_status_init(); + widget->obj = lv_label_create(parent, NULL); + lv_obj_add_style(widget->obj, LV_LABEL_PART_MAIN, &label_style); + lv_label_set_align(widget->obj, LV_LABEL_ALIGN_RIGHT); + + lv_obj_set_size(widget->obj, 40, 15); + set_wpm_symbol(widget->obj, 0); + + sys_slist_append(&widgets, &widget->node); + + return 0; +} + +lv_obj_t *zmk_widget_wpm_status_obj(struct zmk_widget_wpm_status *widget) { return widget->obj; } + +int wpm_status_listener(const zmk_event_t *eh) { + struct zmk_wpm_state_changed *ev = as_zmk_wpm_state_changed(eh); + struct zmk_widget_wpm_status *widget; + SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) { set_wpm_symbol(widget->obj, ev->state); } + return 0; +} + +ZMK_LISTENER(widget_wpm_status, wpm_status_listener) +ZMK_SUBSCRIPTION(widget_wpm_status, zmk_wpm_state_changed); \ No newline at end of file diff --git a/app/src/events/wpm_state_changed.c b/app/src/events/wpm_state_changed.c new file mode 100644 index 00000000..3d9830bf --- /dev/null +++ b/app/src/events/wpm_state_changed.c @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +ZMK_EVENT_IMPL(zmk_wpm_state_changed); \ No newline at end of file diff --git a/app/src/wpm.c b/app/src/wpm.c new file mode 100644 index 00000000..bcabf377 --- /dev/null +++ b/app/src/wpm.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include + +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#include +#include +#include + +#include + +#define WPM_UPDATE_INTERVAL_SECONDS 1 +#define WPM_RESET_INTERVAL_SECONDS 5 + +// See https://en.wikipedia.org/wiki/Words_per_minute +// "Since the length or duration of words is clearly variable, for the purpose of measurement of +// text entry, the definition of each "word" is often standardized to be five characters or +// keystrokes long in English" +#define CHARS_PER_WORD 5.0 + +static uint8_t wpm_state = -1; +static uint8_t last_wpm_state; +static uint8_t wpm_update_counter; +static uint32_t key_pressed_count; + +int zmk_wpm_get_state() { return wpm_state; } + +int wpm_event_listener(const zmk_event_t *eh) { + const struct zmk_keycode_state_changed *ev = as_zmk_keycode_state_changed(eh); + if (ev) { + // count only key up events + if (!ev->state) { + key_pressed_count++; + LOG_DBG("key_pressed_count %d keycode %d", key_pressed_count, ev->keycode); + } + } + return 0; +} + +void wpm_work_handler(struct k_work *work) { + wpm_update_counter++; + wpm_state = (key_pressed_count / CHARS_PER_WORD) / + (wpm_update_counter * WPM_UPDATE_INTERVAL_SECONDS / 60.0); + + if (last_wpm_state != wpm_state) { + LOG_DBG("Raised WPM state changed %d wpm_update_counter %d", wpm_state, wpm_update_counter); + + ZMK_EVENT_RAISE( + new_zmk_wpm_state_changed((struct zmk_wpm_state_changed){.state = wpm_state})); + + last_wpm_state = wpm_state; + } + + if (wpm_update_counter >= WPM_RESET_INTERVAL_SECONDS) { + wpm_update_counter = 0; + key_pressed_count = 0; + } +} + +K_WORK_DEFINE(wpm_work, wpm_work_handler); + +void wpm_expiry_function() { k_work_submit(&wpm_work); } + +K_TIMER_DEFINE(wpm_timer, wpm_expiry_function, NULL); + +int wpm_init() { + wpm_state = 0; + wpm_update_counter = 0; + k_timer_start(&wpm_timer, K_SECONDS(WPM_UPDATE_INTERVAL_SECONDS), + K_SECONDS(WPM_UPDATE_INTERVAL_SECONDS)); + return 0; +} + +ZMK_LISTENER(wpm, wpm_event_listener); +ZMK_SUBSCRIPTION(wpm, zmk_keycode_state_changed); + +SYS_INIT(wpm_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); diff --git a/app/tests/wpm/1-single_keypress/events.patterns b/app/tests/wpm/1-single_keypress/events.patterns new file mode 100644 index 00000000..c49e6c00 --- /dev/null +++ b/app/tests/wpm/1-single_keypress/events.patterns @@ -0,0 +1,2 @@ +s/.*wpm_work_handler: //p +s/.*wpm_event_listener: //p \ No newline at end of file diff --git a/app/tests/wpm/1-single_keypress/keycode_events.snapshot b/app/tests/wpm/1-single_keypress/keycode_events.snapshot new file mode 100644 index 00000000..c86f323b --- /dev/null +++ b/app/tests/wpm/1-single_keypress/keycode_events.snapshot @@ -0,0 +1,7 @@ +key_pressed_count 1 keycode 5 +Raised WPM state changed 12 wpm_update_counter 1 +Raised WPM state changed 6 wpm_update_counter 2 +Raised WPM state changed 4 wpm_update_counter 3 +Raised WPM state changed 3 wpm_update_counter 4 +Raised WPM state changed 2 wpm_update_counter 5 +Raised WPM state changed 0 wpm_update_counter 1 diff --git a/app/tests/wpm/1-single_keypress/native_posix.conf b/app/tests/wpm/1-single_keypress/native_posix.conf new file mode 100644 index 00000000..360e77d5 --- /dev/null +++ b/app/tests/wpm/1-single_keypress/native_posix.conf @@ -0,0 +1,9 @@ +CONFIG_KSCAN=n +CONFIG_ZMK_KSCAN_MOCK_DRIVER=y +CONFIG_ZMK_KSCAN_GPIO_DRIVER=n +CONFIG_GPIO=n +CONFIG_ZMK_BLE=n +CONFIG_LOG=y +CONFIG_LOG_BACKEND_SHOW_COLOR=n +CONFIG_ZMK_LOG_LEVEL_DBG=y +CONFIG_ZMK_WPM=y \ No newline at end of file diff --git a/app/tests/wpm/1-single_keypress/native_posix.keymap b/app/tests/wpm/1-single_keypress/native_posix.keymap new file mode 100644 index 00000000..ec12a286 --- /dev/null +++ b/app/tests/wpm/1-single_keypress/native_posix.keymap @@ -0,0 +1,10 @@ +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + /* Wait for the worker to trigger and reset after 5 seconds, followed by a 0 at 6 seconds */ + ZMK_MOCK_PRESS(0,0,6000) + >; +}; \ No newline at end of file diff --git a/app/tests/wpm/2-multiple_keypress/events.patterns b/app/tests/wpm/2-multiple_keypress/events.patterns new file mode 100644 index 00000000..c49e6c00 --- /dev/null +++ b/app/tests/wpm/2-multiple_keypress/events.patterns @@ -0,0 +1,2 @@ +s/.*wpm_work_handler: //p +s/.*wpm_event_listener: //p \ No newline at end of file diff --git a/app/tests/wpm/2-multiple_keypress/keycode_events.snapshot b/app/tests/wpm/2-multiple_keypress/keycode_events.snapshot new file mode 100644 index 00000000..a0e8f7a8 --- /dev/null +++ b/app/tests/wpm/2-multiple_keypress/keycode_events.snapshot @@ -0,0 +1,4 @@ +key_pressed_count 1 keycode 5 +Raised WPM state changed 12 wpm_update_counter 1 +key_pressed_count 2 keycode 5 +Raised WPM state changed 8 wpm_update_counter 3 diff --git a/app/tests/wpm/2-multiple_keypress/native_posix.conf b/app/tests/wpm/2-multiple_keypress/native_posix.conf new file mode 100644 index 00000000..f0e1a480 --- /dev/null +++ b/app/tests/wpm/2-multiple_keypress/native_posix.conf @@ -0,0 +1,9 @@ +CONFIG_KSCAN=n +CONFIG_ZMK_KSCAN_MOCK_DRIVER=y +CONFIG_ZMK_KSCAN_GPIO_DRIVER=n +CONFIG_GPIO=n +CONFIG_ZMK_BLE=n +CONFIG_LOG=y +CONFIG_LOG_BACKEND_SHOW_COLOR=n +CONFIG_ZMK_LOG_LEVEL_DBG=y +CONFIG_ZMK_WPM=y diff --git a/app/tests/wpm/2-multiple_keypress/native_posix.keymap b/app/tests/wpm/2-multiple_keypress/native_posix.keymap new file mode 100644 index 00000000..f4ba2dfe --- /dev/null +++ b/app/tests/wpm/2-multiple_keypress/native_posix.keymap @@ -0,0 +1,15 @@ +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + //1st WPM worker call - 12wpm - 1 key press in 1 second + ZMK_MOCK_PRESS(0,0,1000) + ZMK_MOCK_RELEASE(0,0,10) + // 2nd WPM worker call - 12wpm - 2 key press in 2 second + // note there is no event for this as WPM hasn't changed + // 3rd WPM worker call - 8wpm - 2 key press in 3 seconds + ZMK_MOCK_PRESS(0,0,2000) + >; +}; \ No newline at end of file diff --git a/app/tests/wpm/behavior_keymap.dtsi b/app/tests/wpm/behavior_keymap.dtsi new file mode 100644 index 00000000..f0c5d0c2 --- /dev/null +++ b/app/tests/wpm/behavior_keymap.dtsi @@ -0,0 +1,17 @@ +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &kp B &none + &none &none + >; + }; + }; +}; From e8aa576781532e883308bf2aec3a77f68ae3f545 Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Sat, 23 Jan 2021 23:50:30 -0500 Subject: [PATCH 9/9] refactor(docs): Move combos under Features. * Since combos aren't a behavior, but a new high level keymap feature, move under Features section. --- docs/docs/{behaviors => features}/combos.md | 5 ++--- docs/docs/intro.md | 2 +- docs/sidebars.js | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) rename docs/docs/{behaviors => features}/combos.md (92%) diff --git a/docs/docs/behaviors/combos.md b/docs/docs/features/combos.md similarity index 92% rename from docs/docs/behaviors/combos.md rename to docs/docs/features/combos.md index e9b01761..845bb018 100644 --- a/docs/docs/behaviors/combos.md +++ b/docs/docs/features/combos.md @@ -1,6 +1,5 @@ --- -title: Combo Behavior -sidebar_label: Combos +title: Combos --- ## Summary @@ -9,7 +8,7 @@ Combo keys are a way to combine multiple keypresses to output a different key. F ### Configuration -Combos are specified like this: +Combos configured in your `.keymap` file, but are separate from the `keymap` node found there, since they are processed before the normal keymap. They are specified like this: ``` / { diff --git a/docs/docs/intro.md b/docs/docs/intro.md index 2215291c..45aadfdd 100644 --- a/docs/docs/intro.md +++ b/docs/docs/intro.md @@ -26,7 +26,7 @@ ZMK is currently missing some features found in other popular firmware. This tab | [Display Support](features/displays)[^2] | 🚧 | 🚧 | ✅ | | [RGB Underglow](features/underglow) | ✅ | ✅ | ✅ | | One Shot Keys | ✅ | ✅ | ✅ | -| [Combo Keys](behaviors/combos) | ✅ | | ✅ | +| [Combo Keys](features/combos) | ✅ | | ✅ | | Macros | 🚧 | ✅ | ✅ | | Mouse Keys | 💡 | ✅ | ✅ | | Low Active Power Usage | ✅ | | | diff --git a/docs/sidebars.js b/docs/sidebars.js index d095a47e..56de3eb8 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -10,6 +10,7 @@ module.exports = { ], Features: [ "features/keymaps", + "features/combos", "features/displays", "features/encoders", "features/underglow", @@ -20,7 +21,6 @@ module.exports = { "behaviors/misc", "behaviors/hold-tap", "behaviors/mod-tap", - "behaviors/combos", "behaviors/reset", "behaviors/bluetooth", "behaviors/outputs",