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(); uint8_t zmk_keymap_layer_default();
zmk_keymap_layers_state_t zmk_keymap_layer_state(); zmk_keymap_layers_state_t zmk_keymap_layer_state();
bool zmk_keymap_layer_active(uint8_t layer); 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(); 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_deactivate(uint8_t layer);
int zmk_keymap_layer_toggle(uint8_t layer); int zmk_keymap_layer_toggle(uint8_t layer);
int zmk_keymap_layer_to(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, static int mo_keymap_binding_pressed(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) { struct zmk_behavior_binding_event event) {
LOG_DBG("position %d layer %d", event.position, binding->param1); 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, 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 = static const int32_t NUM_CONDITIONAL_LAYER_CFGS =
sizeof(CONDITIONAL_LAYER_CFGS) / sizeof(*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, // 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). // the process will eventually terminate (at worst, when every layer is active).
if (!zmk_keymap_layer_active(layer)) { if (!zmk_keymap_layer_active(layer)) {
LOG_DBG("layer %d", 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; int8_t max_then_layer = -1;
uint32_t then_layers = 0; uint32_t then_layers = 0;
uint32_t then_layer_state = 0; uint32_t then_layer_state = 0;
uint32_t momentariness_state = 0;
conditional_layer_updates_needed = false; 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. // also trigger activation of another.
if ((zmk_keymap_layer_state() & mask) == mask) { if ((zmk_keymap_layer_state() & mask) == mask) {
then_layer_state |= BIT(cfg->then_layer); 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++) { for (uint8_t layer = 0; layer <= max_then_layer; layer++) {
if ((BIT(layer) & then_layers) != 0U) { if ((BIT(layer) & then_layers) != 0U) {
if ((BIT(layer) & then_layer_state) != 0U) { if ((BIT(layer) & then_layer_state) != 0U) {
conditional_layer_activate(layer); bool momentary = BIT(layer) & momentariness_state;
conditional_layer_activate(layer, momentary);
} else { } else {
conditional_layer_deactivate(layer); conditional_layer_deactivate(layer);
} }

View file

@ -27,6 +27,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/events/sensor_event.h> #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_state = 0;
static zmk_keymap_layers_state_t _zmk_keymap_layer_momentary = 0;
static uint8_t _zmk_keymap_layer_default = 0; static uint8_t _zmk_keymap_layer_default = 0;
#define DT_DRV_COMPAT zmk_keymap #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 */ #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) { if (layer >= ZMK_KEYMAP_LAYERS_LEN) {
return -EINVAL; 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 // Don't send state changes unless there was an actual change
if (old_state != _zmk_keymap_layer_state) { if (old_state != _zmk_keymap_layer_state) {
LOG_DBG("layer_changed: layer %d state %d", 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)); 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); 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() { uint8_t zmk_keymap_highest_layer_active() {
for (uint8_t layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer > 0; layer--) { for (uint8_t layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer > 0; layer--) {
if (zmk_keymap_layer_active(layer)) { if (zmk_keymap_layer_active(layer)) {
@ -122,16 +132,16 @@ uint8_t zmk_keymap_highest_layer_active() {
return zmk_keymap_layer_default(); 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) { int zmk_keymap_layer_toggle(uint8_t layer) {
if (zmk_keymap_layer_active(layer)) { if (zmk_keymap_layer_active(layer)) {
return zmk_keymap_layer_deactivate(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) { 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_deactivate(i);
} }
zmk_keymap_layer_activate(layer); zmk_keymap_layer_activate(layer, false);
return 0; return 0;
} }