aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNicolas Munnich <[email protected]>2024-12-13 00:13:56 +0000
committerGitHub <[email protected]>2024-12-12 19:13:56 -0500
commit4ef231f4bba87151acfbd1cf3babd83b69813e45 (patch)
tree4f8ed2da58aa8284d6fdc010983279140819f73a
parent7013158a6715d94b34e8c471ce25bb5005f3bb49 (diff)
downloadzmk-4ef231f4bba87151acfbd1cf3babd83b69813e45.tar.gz
zmk-4ef231f4bba87151acfbd1cf3babd83b69813e45.zip
feat: Added `toggle-mode`, allowing toggle-on and toggle-off (#2555)
feat: added toggle mode to key and layer toggles docs: documented toggle mode changes
-rw-r--r--app/dts/bindings/behaviors/zmk,behavior-key-toggle.yaml10
-rw-r--r--app/dts/bindings/behaviors/zmk,behavior-toggle-layer.yaml10
-rw-r--r--app/src/behaviors/behavior_key_toggle.c35
-rw-r--r--app/src/behaviors/behavior_toggle_layer.c37
-rw-r--r--app/tests/keytoggle/kt-off/events.patterns1
-rw-r--r--app/tests/keytoggle/kt-off/keycode_events.snapshot4
-rw-r--r--app/tests/keytoggle/kt-off/native_posix_64.keymap29
-rw-r--r--app/tests/keytoggle/kt-on/events.patterns1
-rw-r--r--app/tests/keytoggle/kt-on/keycode_events.snapshot6
-rw-r--r--app/tests/keytoggle/kt-on/native_posix_64.keymap30
-rw-r--r--app/tests/toggle-layer/behavior_keymap.dtsi2
-rw-r--r--app/tests/toggle-layer/early-key-release/native_posix_64.keymap10
-rw-r--r--app/tests/toggle-layer/normal/keycode_events.snapshot4
-rw-r--r--app/tests/toggle-layer/normal/native_posix_64.keymap11
-rw-r--r--app/tests/toggle-layer/toggle-mode-off/events.patterns4
-rw-r--r--app/tests/toggle-layer/toggle-mode-off/keycode_events.snapshot14
-rw-r--r--app/tests/toggle-layer/toggle-mode-off/native_posix_64.keymap25
-rw-r--r--app/tests/toggle-layer/toggle-mode-on/events.patterns2
-rw-r--r--app/tests/toggle-layer/toggle-mode-on/keycode_events.snapshot8
-rw-r--r--app/tests/toggle-layer/toggle-mode-on/native_posix_64.keymap21
-rw-r--r--docs/docs/config/behaviors.md54
-rw-r--r--docs/docs/keymaps/behaviors/key-toggle.md22
-rw-r--r--docs/docs/keymaps/behaviors/layers.md22
23 files changed, 346 insertions, 16 deletions
diff --git a/app/dts/bindings/behaviors/zmk,behavior-key-toggle.yaml b/app/dts/bindings/behaviors/zmk,behavior-key-toggle.yaml
index e3ec86f7a1..7e465e88b6 100644
--- a/app/dts/bindings/behaviors/zmk,behavior-key-toggle.yaml
+++ b/app/dts/bindings/behaviors/zmk,behavior-key-toggle.yaml
@@ -6,3 +6,13 @@ description: Key toggle behavior
compatible: "zmk,behavior-key-toggle"
include: one_param.yaml
+
+properties:
+ toggle-mode:
+ type: string
+ required: false
+ default: "flip"
+ enum:
+ - "on"
+ - "off"
+ - "flip"
diff --git a/app/dts/bindings/behaviors/zmk,behavior-toggle-layer.yaml b/app/dts/bindings/behaviors/zmk,behavior-toggle-layer.yaml
index 0a9723f7bc..1ab0179c49 100644
--- a/app/dts/bindings/behaviors/zmk,behavior-toggle-layer.yaml
+++ b/app/dts/bindings/behaviors/zmk,behavior-toggle-layer.yaml
@@ -6,3 +6,13 @@ description: Toggle Layer
compatible: "zmk,behavior-toggle-layer"
include: one_param.yaml
+
+properties:
+ toggle-mode:
+ type: string
+ required: false
+ default: "flip"
+ enum:
+ - "on"
+ - "off"
+ - "flip"
diff --git a/app/src/behaviors/behavior_key_toggle.c b/app/src/behaviors/behavior_key_toggle.c
index 72f2570b4d..355f4e465d 100644
--- a/app/src/behaviors/behavior_key_toggle.c
+++ b/app/src/behaviors/behavior_key_toggle.c
@@ -17,18 +17,41 @@
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
+enum toggle_mode {
+ ON,
+ OFF,
+ FLIP,
+};
+
+struct behavior_key_toggle_config {
+ enum toggle_mode toggle_mode;
+};
+
static int behavior_key_toggle_init(const struct device *dev) { return 0; }
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);
- bool pressed = zmk_hid_is_pressed(binding->param1);
- return raise_zmk_keycode_state_changed_from_encoded(binding->param1, !pressed, event.timestamp);
+ const struct behavior_key_toggle_config *cfg =
+ zmk_behavior_get_binding(binding->behavior_dev)->config;
+ switch (cfg->toggle_mode) {
+ case ON:
+ return raise_zmk_keycode_state_changed_from_encoded(binding->param1, true, event.timestamp);
+ case OFF:
+ return raise_zmk_keycode_state_changed_from_encoded(binding->param1, false,
+ event.timestamp);
+ case FLIP:
+ bool pressed = zmk_hid_is_pressed(binding->param1);
+ return raise_zmk_keycode_state_changed_from_encoded(binding->param1, !pressed,
+ event.timestamp);
+ default:
+ return -ENOTSUP;
+ };
}
static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) {
- return 0;
+ return ZMK_BEHAVIOR_OPAQUE;
}
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
@@ -61,7 +84,11 @@ static const struct behavior_driver_api behavior_key_toggle_driver_api = {
};
#define KT_INST(n) \
- BEHAVIOR_DT_INST_DEFINE(n, behavior_key_toggle_init, NULL, NULL, NULL, POST_KERNEL, \
+ static const struct behavior_key_toggle_config behavior_key_toggle_config_##n = { \
+ .toggle_mode = DT_ENUM_IDX(DT_DRV_INST(n), toggle_mode), \
+ }; \
+ BEHAVIOR_DT_INST_DEFINE(n, behavior_key_toggle_init, NULL, NULL, \
+ &behavior_key_toggle_config_##n, POST_KERNEL, \
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_key_toggle_driver_api);
DT_INST_FOREACH_STATUS_OKAY(KT_INST)
diff --git a/app/src/behaviors/behavior_toggle_layer.c b/app/src/behaviors/behavior_toggle_layer.c
index ea46c79faa..c804f5844c 100644
--- a/app/src/behaviors/behavior_toggle_layer.c
+++ b/app/src/behaviors/behavior_toggle_layer.c
@@ -17,15 +17,33 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
-struct behavior_tog_config {};
-struct behavior_tog_data {};
+enum toggle_mode {
+ ON,
+ OFF,
+ FLIP,
+};
+
+struct behavior_tog_config {
+ enum toggle_mode toggle_mode;
+};
static int behavior_tog_init(const struct device *dev) { return 0; };
static int tog_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_toggle(binding->param1);
+
+ const struct behavior_tog_config *cfg = zmk_behavior_get_binding(binding->behavior_dev)->config;
+ switch (cfg->toggle_mode) {
+ case ON:
+ return zmk_keymap_layer_activate(binding->param1);
+ case OFF:
+ return zmk_keymap_layer_deactivate(binding->param1);
+ case FLIP:
+ return zmk_keymap_layer_toggle(binding->param1);
+ default:
+ return -ENOTSUP;
+ };
}
static int tog_keymap_binding_released(struct zmk_behavior_binding *binding,
@@ -63,11 +81,14 @@ static const struct behavior_driver_api behavior_tog_driver_api = {
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
};
-static const struct behavior_tog_config behavior_tog_config = {};
-
-static struct behavior_tog_data behavior_tog_data;
+#define KT_INST(n) \
+ static const struct behavior_tog_config behavior_tog_config_##n = { \
+ .toggle_mode = DT_ENUM_IDX(DT_DRV_INST(n), toggle_mode), \
+ }; \
+ BEHAVIOR_DT_INST_DEFINE(n, behavior_tog_init, NULL, NULL, &behavior_tog_config_##n, \
+ POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
+ &behavior_tog_driver_api);
-BEHAVIOR_DT_INST_DEFINE(0, behavior_tog_init, NULL, &behavior_tog_data, &behavior_tog_config,
- POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_tog_driver_api);
+DT_INST_FOREACH_STATUS_OKAY(KT_INST)
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
diff --git a/app/tests/keytoggle/kt-off/events.patterns b/app/tests/keytoggle/kt-off/events.patterns
new file mode 100644
index 0000000000..833100f6ac
--- /dev/null
+++ b/app/tests/keytoggle/kt-off/events.patterns
@@ -0,0 +1 @@
+s/.*hid_listener_keycode_//p \ No newline at end of file
diff --git a/app/tests/keytoggle/kt-off/keycode_events.snapshot b/app/tests/keytoggle/kt-off/keycode_events.snapshot
new file mode 100644
index 0000000000..2440460586
--- /dev/null
+++ b/app/tests/keytoggle/kt-off/keycode_events.snapshot
@@ -0,0 +1,4 @@
+released: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
+pressed: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
+released: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
+released: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00 \ No newline at end of file
diff --git a/app/tests/keytoggle/kt-off/native_posix_64.keymap b/app/tests/keytoggle/kt-off/native_posix_64.keymap
new file mode 100644
index 0000000000..4abf6ee99d
--- /dev/null
+++ b/app/tests/keytoggle/kt-off/native_posix_64.keymap
@@ -0,0 +1,29 @@
+#include "../behavior_keymap.dtsi"
+
+&kt {
+ toggle-mode = "off";
+};
+
+&kscan {
+ events = <
+ ZMK_MOCK_PRESS(0,0,10)
+ ZMK_MOCK_RELEASE(0,0,10)
+ ZMK_MOCK_PRESS(1,1,10)
+ ZMK_MOCK_PRESS(0,0,10)
+ ZMK_MOCK_RELEASE(1,1,10)
+ ZMK_MOCK_RELEASE(0,0,10)
+ >;
+};
+
+/ {
+ keymap {
+ compatible = "zmk,keymap";
+
+ default_layer {
+ bindings = <
+ &kt B &trans
+ &trans &kp B
+ >;
+ };
+ };
+}; \ No newline at end of file
diff --git a/app/tests/keytoggle/kt-on/events.patterns b/app/tests/keytoggle/kt-on/events.patterns
new file mode 100644
index 0000000000..833100f6ac
--- /dev/null
+++ b/app/tests/keytoggle/kt-on/events.patterns
@@ -0,0 +1 @@
+s/.*hid_listener_keycode_//p \ No newline at end of file
diff --git a/app/tests/keytoggle/kt-on/keycode_events.snapshot b/app/tests/keytoggle/kt-on/keycode_events.snapshot
new file mode 100644
index 0000000000..6954f3daa9
--- /dev/null
+++ b/app/tests/keytoggle/kt-on/keycode_events.snapshot
@@ -0,0 +1,6 @@
+pressed: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
+pressed: unregistering usage_page 0x07 keycode 0x05 since it was already pressed
+pressed: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
+pressed: unregistering usage_page 0x07 keycode 0x05 since it was already pressed
+pressed: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
+released: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00 \ No newline at end of file
diff --git a/app/tests/keytoggle/kt-on/native_posix_64.keymap b/app/tests/keytoggle/kt-on/native_posix_64.keymap
new file mode 100644
index 0000000000..964aa93bb8
--- /dev/null
+++ b/app/tests/keytoggle/kt-on/native_posix_64.keymap
@@ -0,0 +1,30 @@
+#include "../behavior_keymap.dtsi"
+
+&kt {
+ toggle-mode = "on";
+};
+
+
+&kscan {
+ events = <
+ ZMK_MOCK_PRESS(0,0,10)
+ ZMK_MOCK_RELEASE(0,0,10)
+ ZMK_MOCK_PRESS(1,1,10)
+ ZMK_MOCK_PRESS(0,0,10)
+ ZMK_MOCK_RELEASE(1,1,10)
+ ZMK_MOCK_RELEASE(0,0,10)
+ >;
+};
+
+/ {
+ keymap {
+ compatible = "zmk,keymap";
+
+ default_layer {
+ bindings = <
+ &kt B &trans
+ &trans &kp B
+ >;
+ };
+ };
+}; \ No newline at end of file
diff --git a/app/tests/toggle-layer/behavior_keymap.dtsi b/app/tests/toggle-layer/behavior_keymap.dtsi
index 1ff4a81f3e..7c712a874f 100644
--- a/app/tests/toggle-layer/behavior_keymap.dtsi
+++ b/app/tests/toggle-layer/behavior_keymap.dtsi
@@ -9,7 +9,7 @@
default_layer {
bindings = <
&kp B &tog 1
- &kp D &kp G>;
+ &kp D &to 1>;
};
lower_layer {
diff --git a/app/tests/toggle-layer/early-key-release/native_posix_64.keymap b/app/tests/toggle-layer/early-key-release/native_posix_64.keymap
index 0a0c88ea84..dfdbe1724c 100644
--- a/app/tests/toggle-layer/early-key-release/native_posix_64.keymap
+++ b/app/tests/toggle-layer/early-key-release/native_posix_64.keymap
@@ -4,6 +4,12 @@
#include "../behavior_keymap.dtsi"
&kscan {
- events = <ZMK_MOCK_PRESS(0,0,10) ZMK_MOCK_PRESS(0,1,10) ZMK_MOCK_RELEASE(0,0,10) ZMK_MOCK_RELEASE(0,1,10)
- ZMK_MOCK_PRESS(0,0,10) ZMK_MOCK_RELEASE(0,0,10)>;
+ events = <
+ ZMK_MOCK_PRESS(0,0,10)
+ ZMK_MOCK_PRESS(0,1,10)
+ ZMK_MOCK_RELEASE(0,0,10)
+ ZMK_MOCK_RELEASE(0,1,10)
+ ZMK_MOCK_PRESS(0,0,10)
+ ZMK_MOCK_RELEASE(0,0,10)
+ >;
}; \ No newline at end of file
diff --git a/app/tests/toggle-layer/normal/keycode_events.snapshot b/app/tests/toggle-layer/normal/keycode_events.snapshot
index 515772a4d1..1d28c7f98a 100644
--- a/app/tests/toggle-layer/normal/keycode_events.snapshot
+++ b/app/tests/toggle-layer/normal/keycode_events.snapshot
@@ -2,3 +2,7 @@ tog_pressed: position 1 layer 1
tog_released: position 1 layer 1
kp_pressed: usage_page 0x0C keycode 0xB5 implicit_mods 0x00 explicit_mods 0x00
kp_released: usage_page 0x0C keycode 0xB5 implicit_mods 0x00 explicit_mods 0x00
+tog_pressed: position 1 layer 1
+tog_released: position 1 layer 1
+kp_pressed: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
+kp_released: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00 \ No newline at end of file
diff --git a/app/tests/toggle-layer/normal/native_posix_64.keymap b/app/tests/toggle-layer/normal/native_posix_64.keymap
index 97bdd17993..8f0124db34 100644
--- a/app/tests/toggle-layer/normal/native_posix_64.keymap
+++ b/app/tests/toggle-layer/normal/native_posix_64.keymap
@@ -4,5 +4,14 @@
#include "../behavior_keymap.dtsi"
&kscan {
- events = <ZMK_MOCK_PRESS(0,1,10) ZMK_MOCK_RELEASE(0,1,10) ZMK_MOCK_PRESS(0,0,10) ZMK_MOCK_RELEASE(0,0,10)>;
+ events = <
+ ZMK_MOCK_PRESS(0,1,10)
+ ZMK_MOCK_RELEASE(0,1,10)
+ ZMK_MOCK_PRESS(0,0,10)
+ ZMK_MOCK_RELEASE(0,0,10)
+ ZMK_MOCK_PRESS(0,1,10)
+ ZMK_MOCK_RELEASE(0,1,10)
+ ZMK_MOCK_PRESS(0,0,10)
+ ZMK_MOCK_RELEASE(0,0,10)
+ >;
}; \ No newline at end of file
diff --git a/app/tests/toggle-layer/toggle-mode-off/events.patterns b/app/tests/toggle-layer/toggle-mode-off/events.patterns
new file mode 100644
index 0000000000..30996ad02d
--- /dev/null
+++ b/app/tests/toggle-layer/toggle-mode-off/events.patterns
@@ -0,0 +1,4 @@
+s/.*hid_listener_keycode/kp/p
+s/.*to_keymap_binding/to/p
+s/.*layer_changed/layer_changed/p
+s/.*tog_keymap_binding/tog/p \ No newline at end of file
diff --git a/app/tests/toggle-layer/toggle-mode-off/keycode_events.snapshot b/app/tests/toggle-layer/toggle-mode-off/keycode_events.snapshot
new file mode 100644
index 0000000000..94b7b3607e
--- /dev/null
+++ b/app/tests/toggle-layer/toggle-mode-off/keycode_events.snapshot
@@ -0,0 +1,14 @@
+tog_pressed: position 1 layer 1
+tog_released: position 1 layer 1
+kp_pressed: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
+kp_released: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
+to_pressed: position 3 layer 1
+layer_changed: layer 1 state 1
+to_released: position 3 layer 1
+kp_pressed: usage_page 0x0C keycode 0xB5 implicit_mods 0x00 explicit_mods 0x00
+kp_released: usage_page 0x0C keycode 0xB5 implicit_mods 0x00 explicit_mods 0x00
+tog_pressed: position 1 layer 1
+layer_changed: layer 1 state 0
+tog_released: position 1 layer 1
+kp_pressed: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
+kp_released: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00 \ No newline at end of file
diff --git a/app/tests/toggle-layer/toggle-mode-off/native_posix_64.keymap b/app/tests/toggle-layer/toggle-mode-off/native_posix_64.keymap
new file mode 100644
index 0000000000..a89182fcc2
--- /dev/null
+++ b/app/tests/toggle-layer/toggle-mode-off/native_posix_64.keymap
@@ -0,0 +1,25 @@
+#include <dt-bindings/zmk/keys.h>
+#include <behaviors.dtsi>
+#include <dt-bindings/zmk/kscan_mock.h>
+#include "../behavior_keymap.dtsi"
+
+&tog {
+ toggle-mode = "off";
+};
+
+&kscan {
+ events = <
+ ZMK_MOCK_PRESS(0,1,10)
+ ZMK_MOCK_RELEASE(0,1,10)
+ ZMK_MOCK_PRESS(0,0,10)
+ ZMK_MOCK_RELEASE(0,0,10)
+ ZMK_MOCK_PRESS(1,1,10)
+ ZMK_MOCK_RELEASE(1,1,10)
+ ZMK_MOCK_PRESS(0,0,10)
+ ZMK_MOCK_RELEASE(0,0,10)
+ ZMK_MOCK_PRESS(0,1,10)
+ ZMK_MOCK_RELEASE(0,1,10)
+ ZMK_MOCK_PRESS(0,0,10)
+ ZMK_MOCK_RELEASE(0,0,10)
+ >;
+}; \ No newline at end of file
diff --git a/app/tests/toggle-layer/toggle-mode-on/events.patterns b/app/tests/toggle-layer/toggle-mode-on/events.patterns
new file mode 100644
index 0000000000..397fef4f31
--- /dev/null
+++ b/app/tests/toggle-layer/toggle-mode-on/events.patterns
@@ -0,0 +1,2 @@
+s/.*hid_listener_keycode/kp/p
+s/.*tog_keymap_binding/tog/p \ No newline at end of file
diff --git a/app/tests/toggle-layer/toggle-mode-on/keycode_events.snapshot b/app/tests/toggle-layer/toggle-mode-on/keycode_events.snapshot
new file mode 100644
index 0000000000..3dd5f27e06
--- /dev/null
+++ b/app/tests/toggle-layer/toggle-mode-on/keycode_events.snapshot
@@ -0,0 +1,8 @@
+tog_pressed: position 1 layer 1
+tog_released: position 1 layer 1
+kp_pressed: usage_page 0x0C keycode 0xB5 implicit_mods 0x00 explicit_mods 0x00
+kp_released: usage_page 0x0C keycode 0xB5 implicit_mods 0x00 explicit_mods 0x00
+tog_pressed: position 1 layer 1
+tog_released: position 1 layer 1
+kp_pressed: usage_page 0x0C keycode 0xB5 implicit_mods 0x00 explicit_mods 0x00
+kp_released: usage_page 0x0C keycode 0xB5 implicit_mods 0x00 explicit_mods 0x00 \ No newline at end of file
diff --git a/app/tests/toggle-layer/toggle-mode-on/native_posix_64.keymap b/app/tests/toggle-layer/toggle-mode-on/native_posix_64.keymap
new file mode 100644
index 0000000000..690787eb77
--- /dev/null
+++ b/app/tests/toggle-layer/toggle-mode-on/native_posix_64.keymap
@@ -0,0 +1,21 @@
+#include <dt-bindings/zmk/keys.h>
+#include <behaviors.dtsi>
+#include <dt-bindings/zmk/kscan_mock.h>
+#include "../behavior_keymap.dtsi"
+
+&tog {
+ toggle-mode = "on";
+};
+
+&kscan {
+ events = <
+ ZMK_MOCK_PRESS(0,1,10)
+ ZMK_MOCK_RELEASE(0,1,10)
+ ZMK_MOCK_PRESS(0,0,10)
+ ZMK_MOCK_RELEASE(0,0,10)
+ ZMK_MOCK_PRESS(0,1,10)
+ ZMK_MOCK_RELEASE(0,1,10)
+ ZMK_MOCK_PRESS(0,0,10)
+ ZMK_MOCK_RELEASE(0,0,10)
+ >;
+}; \ No newline at end of file
diff --git a/docs/docs/config/behaviors.md b/docs/docs/config/behaviors.md
index e528325aeb..7df6d17660 100644
--- a/docs/docs/config/behaviors.md
+++ b/docs/docs/config/behaviors.md
@@ -17,6 +17,14 @@ See the [zmk/app/dts/behaviors/](https://github.com/zmkfirmware/zmk/tree/main/ap
| --------------------------------- | ---- | ------------------------------------------------------------------------------------ | ------- |
| `CONFIG_ZMK_BEHAVIORS_QUEUE_SIZE` | int | Maximum number of behaviors to allow queueing from a macro or other complex behavior | 64 |
+### Devicetree
+
+Definition file: [zmk/app/dts/bindings/behaviors/behavior-metadata.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/behavior-metadata.yaml)
+
+| Property | Type | Description | Default |
+| -------------- | ------ | -------------------------------------------------------------------------------- | ------- |
+| `display-name` | string | Name of the layer, for use with a display or [ZMK Studio](../features/studio.md) | |
+
## Caps Word
Creates a custom behavior that behaves similar to a caps lock but deactivates when any key not in a continue list is pressed.
@@ -123,6 +131,52 @@ You can use the following nodes to tweak the default behaviors:
| ------------- | ------------------------------------------------ |
| `&key_repeat` | [Key repeat](../keymaps/behaviors/key-repeat.md) |
+## Key Toggle
+
+Creates a custom behavior that toggles a key code on, off, or switches between the two states.
+
+See the [key toggle behavior](../keymaps/behaviors/key-toggle.md) documentation for more details and examples.
+
+### Devicetree
+
+Definition file: [zmk/app/dts/bindings/behaviors/zmk,behavior-key-toggle.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-key-toggle.yaml)
+
+Applies to: `compatible = "zmk,behavior-key-toggle"`
+
+| Property | Type | Description | Default |
+| ---------------- | ---- | ------------------------------ | ------- |
+| `#binding-cells` | int | Must be `<1>` | |
+| `toggle-mode` | | One of `on`, `off`, and `flip` | `flip` |
+
+You can use the following node to tweak the default behavior:
+
+| Node | Behavior |
+| ----- | ------------------------------------------------ |
+| `&kt` | [Key toggle](../keymaps/behaviors/key-toggle.md) |
+
+## Layer Toggle
+
+Creates a custom behavior that toggles a layer on, off, or switches between the two states.
+
+See the [layer toggle behavior](../keymaps/behaviors/layers.md#toggle-layer) documentation for more details and examples.
+
+### Devicetree
+
+Definition file: [zmk/app/dts/bindings/behaviors/zmk,behavior-layer-toggle.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-layer-toggle.yaml)
+
+Applies to: `compatible = "zmk,behavior-layer-toggle"`
+
+| Property | Type | Description | Default |
+| ---------------- | ---- | ------------------------------ | ------- |
+| `#binding-cells` | int | Must be `<1>` | |
+| `toggle-mode` | | One of `on`, `off`, and `flip` | `flip` |
+
+You can use the following node to tweak the default behavior:
+
+| Node | Behavior |
+| ------ | ----------------------------------------------------------- |
+| `&tog` | [Layer toggle](../keymaps/behaviors/layers.md#toggle-layer) |
+
## Macro
Creates a custom behavior which triggers a sequence of other behaviors.
diff --git a/docs/docs/keymaps/behaviors/key-toggle.md b/docs/docs/keymaps/behaviors/key-toggle.md
index 8200b455da..173087cad4 100644
--- a/docs/docs/keymaps/behaviors/key-toggle.md
+++ b/docs/docs/keymaps/behaviors/key-toggle.md
@@ -24,3 +24,25 @@ Example:
You can use any keycode that works for `&kp` as parameter to `&kt`, however, [modified keys](../modifiers.mdx#modifier-functions) such as `LA(A)` will be toggled based on the status of the base keycode (in this case `A`).
In other words, modifiers are ignored when determining whether or not the key is currently pressed.
+
+### Configuration
+
+#### Toggle mode
+
+If you wish to ensure that a key is pressed or released, rather than merely toggling, then you can do so with the `toggle-mode` property.
+Define a new behavior and assign `"on"` or `"off"` to `toggle-mode`:
+
+```dts
+/ {
+ behaviors {
+ kt_on: key_toggle_on_only {
+ compatible = "zmk,behavior-key-toggle";
+ #binding-cells = <1>;
+ display-name = "Key Toggle On";
+ toggle-mode = "on";
+ };
+ };
+};
+```
+
+You can then use `&kt_on` in place of `&kt` whenever you wish to only toggle a key on, and not toggle it off. An `"off"` version of the behavior can be defined similarly.
diff --git a/docs/docs/keymaps/behaviors/layers.md b/docs/docs/keymaps/behaviors/layers.md
index 4a944dfbe4..162a433755 100644
--- a/docs/docs/keymaps/behaviors/layers.md
+++ b/docs/docs/keymaps/behaviors/layers.md
@@ -103,6 +103,28 @@ Example:
&tog 3
```
+### Configuration
+
+#### Toggle mode
+
+If you wish to ensure that a layer is toggled on or off specifically, rather than switching between the two states, then you can do so with the `toggle-mode` property.
+Define a new behavior and assign `"on"` or `"off"` to `toggle-mode`:
+
+```dts
+/ {
+ behaviors {
+ tog_on: toggle_layer_on_only {
+ compatible = "zmk,behavior-toggle-layer";
+ #binding-cells = <1>;
+ display-name = "Toggle Layer On";
+ toggle-mode = "on";
+ };
+ };
+};
+```
+
+You can then use `&tog_on` in place of `&tog` whenever you wish to only toggle a layer on, and not toggle it off. An `"off"` version of the behavior can be defined similarly.
+
## Conditional Layers
The "conditional layers" feature enables a particular layer when all layers in a specified set are active.