feat: lock a momentary layer
This commit is contained in:
parent
40adb3858d
commit
832f490ca2
7 changed files with 108 additions and 9 deletions
|
@ -49,6 +49,7 @@ if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
|
|||
target_sources(app PRIVATE src/behaviors/behavior_key_repeat.c)
|
||||
target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_MACRO app PRIVATE src/behaviors/behavior_macro.c)
|
||||
target_sources(app PRIVATE src/behaviors/behavior_momentary_layer.c)
|
||||
target_sources(app PRIVATE src/behaviors/behavior_momentary_layer_lock.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)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <behaviors/gresc.dtsi>
|
||||
#include <behaviors/sticky_key.dtsi>
|
||||
#include <behaviors/momentary_layer.dtsi>
|
||||
#include <behaviors/momentary_layer_lock.dtsi>
|
||||
#include <behaviors/toggle_layer.dtsi>
|
||||
#include <behaviors/to_layer.dtsi>
|
||||
#include <behaviors/reset.dtsi>
|
||||
|
|
15
app/dts/behaviors/momentary_layer_lock.dtsi
Normal file
15
app/dts/behaviors/momentary_layer_lock.dtsi
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (c) 2023 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/ {
|
||||
behaviors {
|
||||
/omit-if-no-ref/ molock: behavior_momentary_layer_lock {
|
||||
compatible = "zmk,behavior-momentary-layer-lock";
|
||||
label = "MO_LOCK";
|
||||
#binding-cells = <1>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
# Copyright (c) 2023 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
description: Momentary layer on press/release behavior
|
||||
|
||||
compatible: "zmk,behavior-momentary-layer-lock"
|
||||
|
||||
include: one_param.yaml
|
15
app/include/zmk/momentary_layer.h
Normal file
15
app/include/zmk/momentary_layer.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (c) 2023 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <zmk/keymap.h>
|
||||
|
||||
// Locks all active momentary layers so they are not disabled when the key is
|
||||
// released.
|
||||
//
|
||||
// Returns a set of the layers that were locked.
|
||||
zmk_keymap_layers_state_t zmk_lock_active_momentary_layers();
|
|
@ -12,32 +12,51 @@
|
|||
|
||||
#include <zmk/keymap.h>
|
||||
#include <zmk/behavior.h>
|
||||
#include <zmk/momentary_layer.h>
|
||||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
struct behavior_mo_config {};
|
||||
struct behavior_mo_data {};
|
||||
struct behavior_mo_data {
|
||||
zmk_keymap_layers_state_t active_momentary_layers;
|
||||
zmk_keymap_layers_state_t ignore_on_release;
|
||||
};
|
||||
|
||||
static const struct behavior_mo_config behavior_mo_config = {};
|
||||
static struct behavior_mo_data behavior_mo_data;
|
||||
|
||||
zmk_keymap_layers_state_t zmk_lock_active_momentary_layers() {
|
||||
return behavior_mo_data.ignore_on_release = behavior_mo_data.active_momentary_layers;
|
||||
}
|
||||
|
||||
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);
|
||||
int layer = binding->param1;
|
||||
LOG_DBG("position %d layer %d", event.position, layer);
|
||||
WRITE_BIT(behavior_mo_data.active_momentary_layers, layer, true);
|
||||
return zmk_keymap_layer_activate(layer);
|
||||
}
|
||||
|
||||
static int mo_keymap_binding_released(struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
LOG_DBG("position %d layer %d", event.position, binding->param1);
|
||||
int layer = binding->param1;
|
||||
LOG_DBG("position %d layer %d", event.position, layer);
|
||||
WRITE_BIT(behavior_mo_data.active_momentary_layers, layer, false);
|
||||
|
||||
// If the layer is locked, don't deactivate it. Instead clear the
|
||||
// ignore_on_release flag so the next press/release will.
|
||||
if (behavior_mo_data.ignore_on_release & BIT(layer)) {
|
||||
WRITE_BIT(behavior_mo_data.ignore_on_release, layer, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return zmk_keymap_layer_deactivate(binding->param1);
|
||||
}
|
||||
|
||||
static const struct behavior_driver_api behavior_mo_driver_api = {
|
||||
.binding_pressed = mo_keymap_binding_pressed, .binding_released = mo_keymap_binding_released};
|
||||
|
||||
static const struct behavior_mo_config behavior_mo_config = {};
|
||||
|
||||
static struct behavior_mo_data behavior_mo_data;
|
||||
|
||||
BEHAVIOR_DT_INST_DEFINE(0, behavior_mo_init, NULL, &behavior_mo_data, &behavior_mo_config,
|
||||
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_mo_driver_api);
|
40
app/src/behaviors/behavior_momentary_layer_lock.c
Normal file
40
app/src/behaviors/behavior_momentary_layer_lock.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2023 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT zmk_behavior_momentary_layer_lock
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <drivers/behavior.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
#include <zmk/keymap.h>
|
||||
#include <zmk/behavior.h>
|
||||
#include <zmk/momentary_layer.h>
|
||||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
|
||||
static int behavior_mo_lock_init(const struct device *dev) { return 0; };
|
||||
|
||||
static int mo_lock_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
int fallback_layer = binding->param1;
|
||||
zmk_keymap_layers_state_t locked = zmk_lock_active_momentary_layers();
|
||||
if (!locked && fallback_layer >= 0) {
|
||||
return zmk_keymap_layer_to(fallback_layer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct behavior_driver_api behavior_mo_lock_driver_api = {
|
||||
.binding_pressed = mo_lock_keymap_binding_pressed};
|
||||
|
||||
DEVICE_DT_INST_DEFINE(0, behavior_mo_lock_init, NULL, NULL, NULL, APPLICATION,
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_mo_lock_driver_api);
|
||||
|
||||
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
|
Loading…
Add table
Reference in a new issue