From b3c482e8453b95553c8c67f0d81a8e582a644c2b Mon Sep 17 00:00:00 2001 From: Bryan Forbes Date: Tue, 9 Jan 2024 17:46:30 -0600 Subject: [PATCH] Tweaks and update docs --- app/Kconfig.behaviors | 11 ++-- app/src/behaviors/behavior_mouse_key_press.c | 4 -- docs/docs/development/new-behavior.mdx | 58 +++++++++++--------- 3 files changed, 36 insertions(+), 37 deletions(-) diff --git a/app/Kconfig.behaviors b/app/Kconfig.behaviors index 289c7e914cb..9e55f977615 100644 --- a/app/Kconfig.behaviors +++ b/app/Kconfig.behaviors @@ -4,13 +4,12 @@ config ZMK_BEHAVIOR_BACKLIGHT bool default y - depends on DT_HAS_ZMK_BEHAVIOR_BACKLIGHT_ENABLED - imply ZMK_BACKLIGHT + depends on DT_HAS_ZMK_BEHAVIOR_BACKLIGHT_ENABLED && ZMK_BACKLIGHT config ZMK_BEHAVIOR_BLUETOOTH bool default y - depends on DT_HAS_ZMK_BEHAVIOR_BLUETOOTH_ENABLED + depends on DT_HAS_ZMK_BEHAVIOR_BLUETOOTH_ENABLED && ZMK_BLE config ZMK_BEHAVIOR_CAPS_WORD bool @@ -20,8 +19,7 @@ config ZMK_BEHAVIOR_CAPS_WORD config ZMK_BEHAVIOR_EXT_POWER bool default y - depends on DT_HAS_ZMK_BEHAVIOR_EXT_POWER_ENABLED - imply ZMK_EXT_POWER + depends on DT_HAS_ZMK_BEHAVIOR_EXT_POWER_ENABLED && ZMK_EXT_POWER config ZMK_BEHAVIOR_HOLD_TAP bool @@ -82,8 +80,7 @@ config ZMK_BEHAVIOR_RESET config ZMK_BEHAVIOR_RGB_UNDERGLOW bool default y - depends on DT_HAS_ZMK_BEHAVIOR_RGB_UNDERGLOW_ENABLED - imply ZMK_RGB_UNDERGLOW + depends on DT_HAS_ZMK_BEHAVIOR_RGB_UNDERGLOW_ENABLED && ZMK_RGB_UNDERGLOW config ZMK_BEHAVIOR_SENSOR_ROTATE_COMMON bool diff --git a/app/src/behaviors/behavior_mouse_key_press.c b/app/src/behaviors/behavior_mouse_key_press.c index 9064a1aa5c8..fb15eaf1466 100644 --- a/app/src/behaviors/behavior_mouse_key_press.c +++ b/app/src/behaviors/behavior_mouse_key_press.c @@ -16,8 +16,6 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); -#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) - static int behavior_mouse_key_press_init(const struct device *dev) { return 0; }; static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, @@ -44,5 +42,3 @@ static const struct behavior_driver_api behavior_mouse_key_press_driver_api = { &behavior_mouse_key_press_driver_api); DT_INST_FOREACH_STATUS_OKAY(MKP_INST) - -#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ diff --git a/docs/docs/development/new-behavior.mdx b/docs/docs/development/new-behavior.mdx index cabc417f8d3..6f5d0b127fb 100644 --- a/docs/docs/development/new-behavior.mdx +++ b/docs/docs/development/new-behavior.mdx @@ -17,6 +17,7 @@ The general process for developing behaviors is: 1. [Create the behavior](#creating-the-behavior) 1. [Create the devicetree binding (`.yaml`)](#creating-the-devicetree-binding-yaml) 1. [Create the driver (`.c`)](#creating-the-driver-c) + 1. [Update `app/Kconfig.behavior`](#updating-appkconfigbehavior) 1. [Update `app/CmakeLists.txt` to include the new driver](#updating-appcmakeliststxt-to-include-the-new-driver) 1. [Define common use-cases for the behavior (`.dtsi`) (Optional)](#defining-common-use-cases-for-the-behavior-dtsi-optional) 1. [Test changes locally](#testing-changes-locally) @@ -145,8 +146,6 @@ The code snippet below shows the essential components of a new driver. LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); -#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) - // Instance-Unique Data Struct (Optional) struct behavior__data { bool example_data_param1; @@ -178,8 +177,6 @@ BEHAVIOR_DT_INST_DEFINE(0, // POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, // Initialization Level, Device Priority &_driver_api); // API Structure -#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ - ``` #### `DT_DRV_COMPAT` @@ -320,38 +317,47 @@ The fifth cell of `BEHAVIOR_DT_INST_DEFINE` can be set to `NULL` instead if inst Remember that `.c` files should be formatted according to `clang-format` to ensure that checks run smoothly once the pull request is submitted. ::: +### Updating `app/Kconfig.behaviors` + +In order to compile the behavior only when a user includes it in their keymap, an entry needs to be added to `app/Kconfig.behaviors` similar to the entry for hold-tap, which is shown below as a reference: + +```txt title="app/Kconfig.behaviors" +config ZMK_BEHAVIOR_HOLD_TAP + bool + default y + depends on DT_HAS_ZMK_BEHAVIOR_HOLD_TAP_ENABLED +``` + +In the case of a new behavior, replace `HOLD_TAP` with the upper-snake-cased name. If the inclusion of the behavior in a keyboard's keymap should enable a Kconfig option, append `imply ZMK_` to the entry. If the behavior requires a certain condition in a keyboard's `.conf` file to be met, append `&& ZMK_` to the `depends on` line. + ### Updating `app/CmakeLists.txt` to include the new driver -Most behavior drivers' are invoked according to the central half's [locality](#api-structure), and are therefore stored after the line `if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL)` in the form, `target_sources(app PRIVATE src/behaviors/.c)`, as shown below. +Most behavior drivers are invoked according to the central half's [locality](#api-structure), and are therefore stored after the line `if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL)` in the form, `target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_ app PRIVATE src/behaviors/.c)`, as shown below. ```txt title="app/CmakeLists.txt" if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL) - target_sources(app PRIVATE src/behaviors/behavior_key_press.c) - target_sources(app PRIVATE src/behaviors/behavior_hold_tap.c) - target_sources(app PRIVATE src/behaviors/behavior_sticky_key.c) - target_sources(app PRIVATE src/behaviors/behavior_caps_word.c) - target_sources(app PRIVATE src/behaviors/behavior_key_repeat.c) - target_sources(app PRIVATE src/behaviors/behavior_momentary_layer.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_tap_dance.c) - target_sources(app PRIVATE src/behaviors/behavior_toggle_layer.c) - target_sources(app PRIVATE src/behaviors/behavior_to_layer.c) - target_sources(app PRIVATE src/behaviors/behavior_transparent.c) - target_sources(app PRIVATE src/behaviors/behavior_none.c) - target_sources(app PRIVATE src/behaviors/behavior_sensor_rotate_key_press.c) - target_sources(app PRIVATE src/combo.c) - target_sources(app PRIVATE src/conditional_layer.c) - target_sources(app PRIVATE src/keymap.c) + target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_KEY_PRESS app PRIVATE src/behaviors/behavior_key_press.c) + target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_KEY_TOGGLE app PRIVATE src/behaviors/behavior_key_toggle.c) + target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_HOLD_TAP app PRIVATE src/behaviors/behavior_hold_tap.c) + target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_STICKY_KEY app PRIVATE src/behaviors/behavior_sticky_key.c) + target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_CAPS_WORD app PRIVATE src/behaviors/behavior_caps_word.c) + target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_KEY_REPEAT app PRIVATE src/behaviors/behavior_key_repeat.c) + target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_MACRO app PRIVATE src/behaviors/behavior_macro.c) + target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_MOMENTARY_LAYER app PRIVATE src/behaviors/behavior_momentary_layer.c) + target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_MOD_MORPH app PRIVATE src/behaviors/behavior_mod_morph.c) + target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_OUTPUTS app PRIVATE src/behaviors/behavior_outputs.c) + target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_TOGGLE_LAYER app PRIVATE src/behaviors/behavior_toggle_layer.c) + target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_TO_LAYER app PRIVATE src/behaviors/behavior_to_layer.c) + target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_TRANSPARENT app PRIVATE src/behaviors/behavior_transparent.c) + target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_NONE app PRIVATE src/behaviors/behavior_none.c) endif() ``` For behaviors that do not require central locality, the following options for updating `app/CmakeLists.txt` also exist: -- Behavior applies to unibody, or central or peripheral half of keyboard: place `target_sources(app PRIVATE .c)` line _before_ `if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL)` -- Behavior applies to _only_ central half of split keyboard: place `target_sources(app PRIVATE .c)` after `if (CONFIG_ZMK_SPLIT AND CONFIG_ZMK_SPLIT_ROLE_CENTRAL)` -- Behavior applies to _only_ peripheral half of split keyboard: place `target_sources(app PRIVATE .c)` after `if (CONFIG_ZMK_SPLIT AND (NOT CONFIG_ZMK_SPLIT_ROLE_CENTRAL))` -- Behavior requires certain condition in a keyboard's `.conf` file to be met: use `target_sources_ifdef(CONFIG_ app PRIVATE .c)` instead of `target_sources(.c)` +- Behavior applies to unibody, or central or peripheral half of keyboard: place `target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_ app PRIVATE src/behaviors/.c)` line _before_ `if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL)` +- Behavior applies to _only_ central half of split keyboard: place `target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_ app PRIVATE src/behaviors/.c)` after `if (CONFIG_ZMK_SPLIT AND CONFIG_ZMK_SPLIT_ROLE_CENTRAL)` +- Behavior applies to _only_ peripheral half of split keyboard: place `target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_ app PRIVATE src/behaviors/.c)` after `if (CONFIG_ZMK_SPLIT AND (NOT CONFIG_ZMK_SPLIT_ROLE_CENTRAL))` ### Defining common use-cases for the behavior (`.dtsi`) (Optional)