zmk/docs/docs/config/behaviors.md
Joel Spadin 76ffce6779 feat(behaviors): Add a send string behavior
This adds the following:

- A character map driver API, which maps Unicode code points to behavior
  bindings.

- A zmk,character-map driver which implements this API. This driver is
  designed for ROM efficiency, so it sends every value defined in the
  map to one behavior and passes any code point not in the map through
  to another. (A more flexible implementation that allows for a unique
  behavior binding per character could be added later if necessary.)

- A zmk,send-string behavior, which users can define and bind to their
  keymaps to send strings.

- A zmk_send_string() function, which queues the necessary behaviors
  to type a UTF-8 string. This is separated from the send string
  behavior since it could be used for other features such as Unicode
  key sequences, behaviors that print dynamic messages, etc.
2024-04-07 15:05:06 -05:00

329 lines
23 KiB
Markdown

---
title: Behavior Configuration
sidebar_label: Behaviors
---
Some behaviors have properties to adjust how they behave. These can also be used as templates to create custom behaviors when none of the built-in behaviors do what you want.
See [Configuration Overview](index.md) for instructions on how to change these settings.
See the [zmk/app/dts/behaviors/](https://github.com/zmkfirmware/zmk/tree/main/app/dts/behaviors) folder for all default behaviors.
## Common
### Kconfig
| Config | Type | Description | Default |
| --------------------------------- | ---- | ------------------------------------------------------------------------------------ | --------------------------------------------------- |
| `CONFIG_ZMK_BEHAVIORS_QUEUE_SIZE` | int | Maximum number of behaviors to allow queueing from a macro or other complex behavior | 256 if [send string](#send-string) is used, else 64 |
### Devicetree
Applies to: [`/chosen` node](https://docs.zephyrproject.org/latest/guides/dts/intro.html#aliases-and-chosen-nodes)
| Property | Type | Description |
| ------------- | ---- | -------------------------------------------------------------------------------------------- |
| `zmk,charmap` | path | The default [character map](#character-map) to use for [send string](#send-string) behaviors |
## 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.
See the [caps word behavior](../behaviors/caps-word.md) documentation for more details and examples.
### Devicetree
Definition file: [zmk/app/dts/bindings/behaviors/zmk,behavior-caps-word.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-caps-word.yaml)
Applies to: `compatible = "zmk,behavior-caps-word"`
| Property | Type | Description | Default |
| ---------------- | ----- | ------------------------------------------------------------------ | ------------------------------- |
| `#binding-cells` | int | Must be `<0>` | |
| `continue-list` | array | List of [key codes](/docs/codes) which do not deactivate caps lock | `<UNDERSCORE BACKSPACE DELETE>` |
| `mods` | int | A bit field of modifiers to apply | `<MOD_LSFT>` |
`continue-list` is treated as if it always includes alphanumeric characters (A-Z, 0-9).
See [dt-bindings/zmk/modifiers.h](https://github.com/zmkfirmware/zmk/blob/main/app/include/dt-bindings/zmk/modifiers.h) for a list of modifiers.
You can use the following nodes to tweak the default behaviors:
| Node | Behavior |
| ------------ | -------------------------------------- |
| `&caps_word` | [Caps Word](../behaviors/caps-word.md) |
## Hold-Tap
Creates a custom behavior that triggers one behavior when a key is held or a different one when the key is tapped.
See the [hold-tap behavior](../behaviors/hold-tap.mdx) documentation for more details and examples.
### Devicetree
Definition file: [zmk/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-hold-tap.yaml)
Applies to: `compatible = "zmk,behavior-hold-tap"`
| Property | Type | Description | Default |
| ----------------------------- | -------- | -------------------------------------------------------------------------------------------------------------- | ------------------ |
| `#binding-cells` | int | Must be `<2>` | |
| `bindings` | phandles | A list of two behaviors (without parameters): one for hold and one for tap | |
| `flavor` | string | Adjusts how the behavior chooses between hold and tap | `"hold-preferred"` |
| `tapping-term-ms` | int | How long in milliseconds the key must be held to trigger a hold | |
| `quick-tap-ms` | int | Tap twice within this period (in milliseconds) to trigger a tap, even when held | -1 (disabled) |
| `require-prior-idle-ms` | int | Triggers a tap immediately if any non-modifier key was pressed within `require-prior-idle-ms` of the hold-tap. | -1 (disabled) |
| `retro-tap` | bool | Triggers the tap behavior on release if no other key was pressed during a hold | false |
| `hold-while-undecided` | bool | Triggers the hold behavior immediately on press and releases before a tap | false |
| `hold-while-undecided-linger` | bool | Continues to hold the hold behavior until after the tap is released | false |
| `hold-trigger-key-positions` | array | If set, pressing the hold-tap and then any key position _not_ in the list triggers a tap. | |
This behavior forwards the first parameter it receives to the parameter of the first behavior specified in `bindings`, and second parameter to the parameter of the second behavior.
The `flavor` property may be one of:
- `"hold-preferred"`
- `"balanced"`
- `"tap-preferred"`
- `"tap-unless-interrupted"`
See the [hold-tap behavior documentation](../behaviors/hold-tap.mdx) for an explanation of each flavor.
`hold-trigger-key-positions` is an array of zero-based key position indices.
You can use the following nodes to tweak the default behaviors:
| Node | Behavior |
| ----- | --------------------------------------------- |
| `&lt` | [Layer-tap](../behaviors/layers.md#layer-tap) |
| `&mt` | [Mod-tap](../behaviors/mod-tap.md) |
## Key Repeat
Creates a custom behavior that repeats the whatever key code was last sent.
See the [key repeat behavior](../behaviors/key-repeat.md) documentation for more details and examples.
### Devicetree
Definition file: [zmk/app/dts/bindings/behaviors/zmk,behavior-key-repeat.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-key-repeat.yaml)
Applies to: `compatible = "zmk,behavior-key-repeat"`
| Property | Type | Description | Default |
| ---------------- | ----- | -------------------------------- | ----------------- |
| `#binding-cells` | int | Must be `<0>` | |
| `usage-pages` | array | List of HID usage pages to track | `<HID_USAGE_KEY>` |
For the `usage-pages` property, use the `HID_USAGE_*` defines from [dt-bindings/zmk/hid_usage_pages.h](https://github.com/zmkfirmware/zmk/blob/main/app/include/dt-bindings/zmk/hid_usage_pages.h).
You can use the following nodes to tweak the default behaviors:
| Node | Behavior |
| ------------- | ---------------------------------------- |
| `&key_repeat` | [Key repeat](../behaviors/key-repeat.md) |
## Macro
Creates a custom behavior which triggers a sequence of other behaviors.
See the [macro behavior](../behaviors/macros.md) documentation for more details and examples.
### Kconfig
| Config | Type | Description | Default |
| ---------------------------------- | ---- | -------------------------------------- | ------- |
| `CONFIG_ZMK_MACRO_DEFAULT_WAIT_MS` | int | Default value for `wait-ms` in macros. | 15 |
| `CONFIG_ZMK_MACRO_DEFAULT_TAP_MS` | int | Default value for `tap-ms` in macros. | 30 |
### Devicetree
Definition files:
- [zmk/app/dts/bindings/behaviors/zmk,behavior-macro.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-macro.yaml)
- [zmk/app/dts/bindings/behaviors/zmk,behavior-macro-one-param.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-macro-one-param.yaml)
- [zmk/app/dts/bindings/behaviors/zmk,behavior-macro-two-param.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-macro-two-param.yaml)
| Property | Type | Description | Default |
| ---------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
| `compatible` | string | Macro type, **must be _one_ of**:<ul><li>`"zmk,behavior-macro"`</li><li>`"zmk,behavior-macro-one-param"`</li><li>`"zmk,behavior-macro-two-param"`</li></ul> | |
| `#binding-cells` | int | Must be <ul><li>`<0>` if `compatible = "zmk,behavior-macro"`</li><li>`<1>` if `compatible = "zmk,behavior-macro-one-param"`</li><li>`<2>` if `compatible = "zmk,behavior-macro-two-param"`</li></ul> | |
| `bindings` | phandle array | List of behaviors to trigger | |
| `wait-ms` | int | The default time to wait (in milliseconds) before triggering the next behavior. | `CONFIG_ZMK_MACRO_DEFAULT_WAIT_MS` |
| `tap-ms` | int | The default time to wait (in milliseconds) between the press and release events of a tapped behavior. | `CONFIG_ZMK_MACRO_DEFAULT_TAP_MS` |
With `compatible = "zmk,behavior-macro-one-param"` or `compatible = "zmk,behavior-macro-two-param"`, this behavior forwards the parameters it receives according to the `&macro_param_*` control behaviors noted below.
### Macro Control Behaviors
The following macro-specific behaviors can be added at any point in the `bindings` list to change how the macro triggers subsequent behaviors.
| Behavior | Description |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `&macro_tap` | Switches to tap mode |
| `&macro_press` | Switches to press mode |
| `&macro_release` | Switches to release mode |
| `&macro_pause_for_release` | Pauses the macro until the macro key itself is released |
| `&macro_wait_time TIME` | Changes the time to wait (in milliseconds) before triggering the next behavior. |
| `&macro_tap_time TIME` | Changes the time to wait (in milliseconds) between the press and release events of a tapped behavior. |
| `&macro_param_1to1` | Forward the first parameter received by the macro to the first parameter of the next (non-macro control) behavior. |
| `&macro_param_1to2` | Forward the first parameter received by the macro to the second parameter of the next (non-macro control) behavior. |
| `&macro_param_2to1` | Forward the second parameter received by the macro to the first parameter of the next (non-macro control) behavior. |
| `&macro_param_2to2` | Forward the second parameter received by the macro to the second parameter of the next (non-macro control) behavior. |
## Mod-Morph
Creates a custom behavior that triggers one of two behaviors depending on whether certain modifiers are held.
See the [mod-morph behavior](../behaviors/mod-morph.md) documentation for more details and examples.
### Devicetree
Definition file: [zmk/app/dts/bindings/behaviors/zmk,behavior-mod-morph.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-mod-morph.yaml)
Applies to: `compatible = "zmk,behavior-mod-morph"`
| Property | Type | Description |
| ---------------- | ------------- | --------------------------------------------------------------------------------- |
| `#binding-cells` | int | Must be `<0>` |
| `bindings` | phandle array | A list of two behaviors: one for normal press and one for mod morphed press |
| `mods` | int | A bit field of modifiers. The morph behavior is used if any of these are pressed. |
See [dt-bindings/zmk/modifiers.h](https://github.com/zmkfirmware/zmk/blob/main/app/include/dt-bindings/zmk/modifiers.h) for a list of modifiers.
You can use the following nodes to tweak the default behaviors:
| Node | Behavior |
| -------- | ----------------------------------------- |
| `&gresc` | [Grave escape](../behaviors/mod-morph.md) |
## Send String
Creates a custom behavior that types a text string.
See the [send string behavior](../behaviors/send-string.md) documentation for more details and examples.
### Kconfig
| Config | Type | Description | Default |
| ---------------------------------------- | ---- | ----------------------------------------------------- | ------- |
| `CONFIG_ZMK_SEND_STRING_DEFAULT_WAIT_MS` | int | Default value for `wait-ms` in send string behaviors. | 0 |
| `CONFIG_ZMK_SEND_STRING_DEFAULT_TAP_MS` | int | Default value for `tap-ms` in send string behaviors. | 5 |
### Devicetree
Definition file: [zmk/app/dts/bindings/behaviors/zmk,behavior-send-string.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-send-string.yaml)
Applies to: `compatible = "zmk,send-string"`
| Property | Type | Description | Default |
| ---------------- | ------- | ---------------------------------------------------------------------------------------- | ---------------------------------------- |
| `#binding-cells` | int | Must be `<0>` | |
| `text` | string | The text to send | |
| `charmap` | phandle | The [character map](#character-map) to use | `zmk,charmap` chosen node. |
| `wait-ms` | int | The time to wait (in milliseconds) before pressing the next key in the text | `CONFIG_ZMK_SEND_STRING_DEFAULT_WAIT_MS` |
| `tap-ms` | int | The time to wait (in milliseconds) between the press and release of each key in the text | `CONFIG_ZMK_SEND_STRING_DEFAULT_TAP_MS` |
### Character Map
Maps Unicode code points to key codes for [send string behaviors](#send-string).
See the [send string behavior](../behaviors/send-string.md#character-maps) documentation for more details and examples.
#### Devicetree
Definition file: [zmk/app/drivers/zephyr/dts/bindings/character_map/zmk,character-map.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/character_map/zmk%2Ccharacter-map.yaml)
Applies to: `compatible = "zmk,character-map"`
| Property | Type | Description |
| ------------------- | ------- | -------------------------------------------------------------------------------------------------------------------- |
| `behavior` | phandle | Behavior to use for a code point in the map (typically should be `<&kp>`) |
| `fallback-behavior` | phandle | Optional behavior which will be sent any code points not in the map |
| `map` | array | List of `<codepoint keycode>` pairs which give the [key code](../codes/index.mdx) to use for each Unicode code point |
You can use the following nodes to tweak the default behaviors:
| Node | Description |
| ------------- | ------------------------------------ |
| `&charmap_us` | Character map for US keyboard layout |
## Sensor Rotation
Creates a custom behavior which sends a tap of other behaviors when a sensor is rotated.
Has two variants: with `compatible = "zmk,behavior-sensor-rotate"` it accepts no parameters when used, whereas with `compatible = "zmk,behavior-sensor-rotate-var"` it accepts two parameters.
See the [sensor rotation behavior](../behaviors/sensor-rotate.md) documentation for more details and examples.
### Devicetree
Definition files:
- [zmk/app/dts/bindings/behaviors/zmk,behavior-sensor-rotate.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-sensor-rotate.yaml)
- [zmk/app/dts/bindings/behaviors/zmk,behavior-sensor-rotate-var.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-sensor-rotate-var.yaml)
Applies to: `compatible = "zmk,behavior-sensor-rotate"`
| Property | Type | Description | Default |
| ----------------------- | -------- | ------------------------------------------------------------------------------------------------------ | ------- |
| `#sensor-binding-cells` | int | Must be `<0>` | |
| `bindings` | phandles | A list of two behaviors to trigger for each rotation direction, must _include_ any behavior parameters | |
| `tap-ms` | int | The tap duration (between press and release events) in milliseconds for behaviors in `bindings` | 5 |
Applies to: `compatible = "zmk,behavior-sensor-rotate-var"`
| Property | Type | Description | Default |
| ----------------------- | ------------- | ------------------------------------------------------------------------------------------------------ | ------- |
| `#sensor-binding-cells` | int | Must be `<2>` | |
| `bindings` | phandle array | A list of two behaviors to trigger for each rotation direction, must _exclude_ any behavior parameters | |
| `tap-ms` | int | The tap duration (between press and release events) in milliseconds for behaviors in `bindings` | 5 |
With `compatible = "zmk,behavior-sensor-rotate-var"`, this behavior forwards the first parameter it receives to the parameter of the first behavior specified in `bindings`, and second parameter to the parameter of the second behavior.
## Sticky Key
Creates a custom behavior that triggers a behavior and keeps it pressed it until another key is pressed and released.
See the [sticky key behavior](../behaviors/sticky-key.md) and [sticky layer behavior](../behaviors/sticky-layer.md) documentation for more details and examples.
### Devicetree
Definition file: [zmk/app/dts/bindings/behaviors/zmk,behavior-sticky-key.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-sticky-key.yaml)
Applies to: `compatible = "zmk,behavior-sticky-key"`
| Property | Type | Description | Default |
| ------------------ | -------- | ------------------------------------------------------------------------ | ------- |
| `#binding-cells` | int | Must be `<1>` | |
| `bindings` | phandles | A behavior (without parameters) to trigger | |
| `release-after-ms` | int | Releases the key after this many milliseconds if no other key is pressed | 1000 |
| `quick-release` | bool | Release the sticky key on the next key press instead of release | false |
| `lazy` | bool | Wait until the next key press to activate the sticky key behavior | false |
| `ignore-modifiers` | bool | If enabled, pressing a modifier key does not cancel the sticky key | true |
This behavior forwards the one parameter it receives to the parameter of the behavior specified in `bindings`.
You can use the following nodes to tweak the default behaviors:
| Node | Behavior |
| ----- | -------------------------------------------- |
| `&sk` | [Sticky key](../behaviors/sticky-key.md) |
| `&sl` | [Sticky layer](../behaviors/sticky-layer.md) |
## Tap Dance
Creates a custom behavior that triggers a different behavior corresponding to the number of times the key is tapped.
See the [tap dance behavior](../behaviors/tap-dance.mdx) documentation for more details and examples.
### Devicetree
Definition file: [zmk/app/dts/bindings/behaviors/zmk,behavior-tap-dance.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-tap-dance.yaml)
Applies to: `compatible = "zmk,behavior-tap-dance"`
| Property | Type | Description | Default |
| ----------------- | ------------- | -------------------------------------------------------------------------------------------- | ------- |
| `#binding-cells` | int | Must be `<0>` | |
| `bindings` | phandle array | A list of behaviors from which to select | |
| `tapping-term-ms` | int | The maximum time (in milliseconds) between taps before an item from `bindings` is triggered. | 200 |