Track momentary layers activation

This commit is contained in:
Cem Aksoylar 2021-12-30 22:54:00 -08:00 committed by hannah
parent 310ff449d8
commit 9ef1605b7c
4 changed files with 27 additions and 10 deletions

View file

@ -17,8 +17,10 @@ typedef uint32_t zmk_keymap_layers_state_t;
uint8_t zmk_keymap_layer_default();
zmk_keymap_layers_state_t zmk_keymap_layer_state();
bool zmk_keymap_layer_active(uint8_t layer);
bool zmk_keymap_layer_momentary(uint8_t layer);
bool zmk_keymap_layers_any_momentary(zmk_keymap_layers_state_t layers_mask);
uint8_t zmk_keymap_highest_layer_active();
int zmk_keymap_layer_activate(uint8_t layer);
int zmk_keymap_layer_activate(uint8_t layer, bool momentary);
int zmk_keymap_layer_deactivate(uint8_t layer);
int zmk_keymap_layer_toggle(uint8_t layer);
int zmk_keymap_layer_to(uint8_t layer);

View file

@ -23,7 +23,7 @@ static int behavior_mo_init(const struct device *dev) { return 0; };
static int mo_keymap_binding_pressed(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) {
LOG_DBG("position %d layer %d", event.position, binding->param1);
return zmk_keymap_layer_activate(binding->param1);
return zmk_keymap_layer_activate(binding->param1, true);
}
static int mo_keymap_binding_released(struct zmk_behavior_binding *binding,

View file

@ -49,12 +49,12 @@ static const struct conditional_layer_cfg CONDITIONAL_LAYER_CFGS[] = {
static const int32_t NUM_CONDITIONAL_LAYER_CFGS =
sizeof(CONDITIONAL_LAYER_CFGS) / sizeof(*CONDITIONAL_LAYER_CFGS);
static void conditional_layer_activate(int8_t layer) {
static void conditional_layer_activate(int8_t layer, bool momentary) {
// This may trigger another event that could, in turn, activate additional then-layers. However,
// the process will eventually terminate (at worst, when every layer is active).
if (!zmk_keymap_layer_active(layer)) {
LOG_DBG("layer %d", layer);
zmk_keymap_layer_activate(layer);
zmk_keymap_layer_activate(layer, momentary);
}
}
@ -84,6 +84,7 @@ static int layer_state_changed_listener(const zmk_event_t *ev) {
int8_t max_then_layer = -1;
uint32_t then_layers = 0;
uint32_t then_layer_state = 0;
uint32_t momentariness_state = 0;
conditional_layer_updates_needed = false;
@ -100,13 +101,17 @@ static int layer_state_changed_listener(const zmk_event_t *ev) {
// also trigger activation of another.
if ((zmk_keymap_layer_state() & mask) == mask) {
then_layer_state |= BIT(cfg->then_layer);
if (zmk_keymap_layers_any_momentary(mask)) {
momentariness_state |= BIT(cfg->then_layer);
}
}
}
for (uint8_t layer = 0; layer <= max_then_layer; layer++) {
if ((BIT(layer) & then_layers) != 0U) {
if ((BIT(layer) & then_layer_state) != 0U) {
conditional_layer_activate(layer);
bool momentary = BIT(layer) & momentariness_state;
conditional_layer_activate(layer, momentary);
} else {
conditional_layer_deactivate(layer);
}

View file

@ -27,6 +27,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/events/sensor_event.h>
static zmk_keymap_layers_state_t _zmk_keymap_layer_state = 0;
static zmk_keymap_layers_state_t _zmk_keymap_layer_momentary = 0;
static uint8_t _zmk_keymap_layer_default = 0;
#define DT_DRV_COMPAT zmk_keymap
@ -78,7 +79,7 @@ static struct zmk_behavior_binding zmk_sensor_keymap[ZMK_KEYMAP_LAYERS_LEN]
#endif /* ZMK_KEYMAP_HAS_SENSORS */
static inline int set_layer_state(uint8_t layer, bool state) {
static inline int set_layer_state(uint8_t layer, bool state, bool momentary) {
if (layer >= ZMK_KEYMAP_LAYERS_LEN) {
return -EINVAL;
}
@ -93,6 +94,7 @@ static inline int set_layer_state(uint8_t layer, bool state) {
// Don't send state changes unless there was an actual change
if (old_state != _zmk_keymap_layer_state) {
LOG_DBG("layer_changed: layer %d state %d", layer, state);
WRITE_BIT(_zmk_keymap_layer_momentary, layer, momentary);
ZMK_EVENT_RAISE(create_layer_state_changed(layer, state));
}
@ -113,6 +115,14 @@ bool zmk_keymap_layer_active(uint8_t layer) {
return zmk_keymap_layer_active_with_state(layer, _zmk_keymap_layer_state);
};
bool zmk_keymap_layer_momentary(uint8_t layer) {
return layer != _zmk_keymap_layer_default && (_zmk_keymap_layer_momentary & (BIT(layer))) == (BIT(layer));
};
bool zmk_keymap_layers_any_momentary(zmk_keymap_layers_state_t layers_mask) {
return (_zmk_keymap_layer_momentary & layers_mask) > 0;
};
uint8_t zmk_keymap_highest_layer_active() {
for (uint8_t layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer > 0; layer--) {
if (zmk_keymap_layer_active(layer)) {
@ -122,16 +132,16 @@ uint8_t zmk_keymap_highest_layer_active() {
return zmk_keymap_layer_default();
}
int zmk_keymap_layer_activate(uint8_t layer) { return set_layer_state(layer, true); };
int zmk_keymap_layer_activate(uint8_t layer, bool momentary) { return set_layer_state(layer, true, momentary); };
int zmk_keymap_layer_deactivate(uint8_t layer) { return set_layer_state(layer, false); };
int zmk_keymap_layer_deactivate(uint8_t layer) { return set_layer_state(layer, false, false); };
int zmk_keymap_layer_toggle(uint8_t layer) {
if (zmk_keymap_layer_active(layer)) {
return zmk_keymap_layer_deactivate(layer);
}
return zmk_keymap_layer_activate(layer);
return zmk_keymap_layer_activate(layer, false);
};
int zmk_keymap_layer_to(uint8_t layer) {
@ -139,7 +149,7 @@ int zmk_keymap_layer_to(uint8_t layer) {
zmk_keymap_layer_deactivate(i);
}
zmk_keymap_layer_activate(layer);
zmk_keymap_layer_activate(layer, false);
return 0;
}