From a19a17f72e6986fe7c562fe47fe1d4ac3ec8020d Mon Sep 17 00:00:00 2001 From: urob <978080+urob@users.noreply.github.com> Date: Thu, 6 Apr 2023 07:47:22 -0400 Subject: [PATCH] Smart-word: original PR (#1451), updated to Zephyr-3.2 --- app/dts/behaviors/caps_word.dtsi | 15 ++++++++ .../behaviors/zmk,behavior-caps-word.yaml | 8 +++++ app/src/behaviors/behavior_caps_word.c | 31 +++++++++++++--- .../deactivate-by-mod/events.patterns | 3 ++ .../deactivate-by-mod/keycode_events.snapshot | 13 +++++++ .../deactivate-by-mod/native_posix_64.keymap | 35 +++++++++++++++++++ docs/docs/behaviors/caps-word.md | 12 +++++++ 7 files changed, 112 insertions(+), 5 deletions(-) create mode 100644 app/tests/caps-word/deactivate-by-mod/events.patterns create mode 100644 app/tests/caps-word/deactivate-by-mod/keycode_events.snapshot create mode 100644 app/tests/caps-word/deactivate-by-mod/native_posix_64.keymap diff --git a/app/dts/behaviors/caps_word.dtsi b/app/dts/behaviors/caps_word.dtsi index ac04e26b2d6..262ed601d40 100644 --- a/app/dts/behaviors/caps_word.dtsi +++ b/app/dts/behaviors/caps_word.dtsi @@ -12,7 +12,22 @@ compatible = "zmk,behavior-caps-word"; label = "CAPS_WORD"; #binding-cells = <0>; + mods = ; continue-list = ; + ignore-alphas; + ignore-numbers; + ignore-modifiers; + }; + }; + + behaviors { + /omit-if-no-ref/ num_word: behavior_num_word { + compatible = "zmk,behavior-caps-word"; + label = "NUM_WORD"; + #binding-cells = <0>; + // layers = ; // to be specified in user config using "&num_word { layers = ; };" + continue-list = ; + ignore-numbers; }; }; }; diff --git a/app/dts/bindings/behaviors/zmk,behavior-caps-word.yaml b/app/dts/bindings/behaviors/zmk,behavior-caps-word.yaml index cc1dda01370..eb67a2032fb 100644 --- a/app/dts/bindings/behaviors/zmk,behavior-caps-word.yaml +++ b/app/dts/bindings/behaviors/zmk,behavior-caps-word.yaml @@ -13,3 +13,11 @@ properties: required: true mods: type: int + layers: + type: int + ignore-alphas: + type: boolean + ignore-numbers: + type: boolean + ignore-modifiers: + type: boolean diff --git a/app/src/behaviors/behavior_caps_word.c b/app/src/behaviors/behavior_caps_word.c index 4c9fd71186d..5e31dcd3bcc 100644 --- a/app/src/behaviors/behavior_caps_word.c +++ b/app/src/behaviors/behavior_caps_word.c @@ -32,6 +32,10 @@ struct caps_word_continue_item { struct behavior_caps_word_config { zmk_mod_flags_t mods; + int8_t layers; + bool ignore_alphas; + bool ignore_numbers; + bool ignore_modifiers; uint8_t index; uint8_t continuations_count; struct caps_word_continue_item continuations[]; @@ -44,12 +48,22 @@ struct behavior_caps_word_data { static void activate_caps_word(const struct device *dev) { struct behavior_caps_word_data *data = dev->data; + const struct behavior_caps_word_config *config = dev->config; + + if (config->layers > -1) { + zmk_keymap_layer_activate(config->layers); + } data->active = true; } static void deactivate_caps_word(const struct device *dev) { struct behavior_caps_word_data *data = dev->data; + const struct behavior_caps_word_config *config = dev->config; + + if (config->layers > -1) { + zmk_keymap_layer_deactivate(config->layers); + } data->active = false; } @@ -120,8 +134,10 @@ static void caps_word_enhance_usage(const struct behavior_caps_word_config *conf return; } - LOG_DBG("Enhancing usage 0x%02X with modifiers: 0x%02X", ev->keycode, config->mods); - ev->implicit_modifiers |= config->mods; + if (config->mods != 0) { + LOG_DBG("Enhancing usage 0x%02X with modifiers: 0x%02X", ev->keycode, config->mods); + ev->implicit_modifiers |= config->mods; + } } static int caps_word_keycode_state_changed_listener(const zmk_event_t *eh) { @@ -145,8 +161,9 @@ static int caps_word_keycode_state_changed_listener(const zmk_event_t *eh) { caps_word_enhance_usage(config, ev); - if (!caps_word_is_alpha(ev->keycode) && !caps_word_is_numeric(ev->keycode) && - !is_mod(ev->usage_page, ev->keycode) && + if ((!caps_word_is_alpha(ev->keycode) || !config->ignore_alphas) && + (!caps_word_is_numeric(ev->keycode) || !config->ignore_numbers) && + (!is_mod(ev->usage_page, ev->keycode) || !config->ignore_modifiers) && !caps_word_is_caps_includelist(config, ev->usage_page, ev->keycode, ev->implicit_modifiers)) { LOG_DBG("Deactivating caps_word for 0x%02X - 0x%02X", ev->usage_page, ev->keycode); @@ -177,7 +194,11 @@ static int behavior_caps_word_init(const struct device *dev) { static struct behavior_caps_word_data behavior_caps_word_data_##n = {.active = false}; \ static struct behavior_caps_word_config behavior_caps_word_config_##n = { \ .index = n, \ - .mods = DT_INST_PROP_OR(n, mods, MOD_LSFT), \ + .mods = DT_INST_PROP_OR(n, mods, 0), \ + .layers = DT_INST_PROP_OR(n, layers, -1), \ + .ignore_alphas = DT_INST_PROP(n, ignore_alphas), \ + .ignore_numbers = DT_INST_PROP(n, ignore_numbers), \ + .ignore_modifiers = DT_INST_PROP(n, ignore_modifiers), \ .continuations = {LISTIFY(DT_INST_PROP_LEN(n, continue_list), BREAK_ITEM, (, ), n)}, \ .continuations_count = DT_INST_PROP_LEN(n, continue_list), \ }; \ diff --git a/app/tests/caps-word/deactivate-by-mod/events.patterns b/app/tests/caps-word/deactivate-by-mod/events.patterns new file mode 100644 index 00000000000..e9b216a8b02 --- /dev/null +++ b/app/tests/caps-word/deactivate-by-mod/events.patterns @@ -0,0 +1,3 @@ +s/.*hid_listener_keycode_//p +s/.*hid_implicit_modifiers_//p +s/.*caps_word_enhance_usage/enhance_usage/p diff --git a/app/tests/caps-word/deactivate-by-mod/keycode_events.snapshot b/app/tests/caps-word/deactivate-by-mod/keycode_events.snapshot new file mode 100644 index 00000000000..4f27b89fe6d --- /dev/null +++ b/app/tests/caps-word/deactivate-by-mod/keycode_events.snapshot @@ -0,0 +1,13 @@ +enhance_usage: Enhancing usage 0x04 with modifiers: 0x02 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x02 explicit_mods 0x00 +press: Modifiers set to 0x02 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +release: Modifiers set to 0x00 +pressed: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00 +press: Modifiers set to 0x02 +released: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00 +release: Modifiers set to 0x00 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +press: Modifiers set to 0x00 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +release: Modifiers set to 0x00 diff --git a/app/tests/caps-word/deactivate-by-mod/native_posix_64.keymap b/app/tests/caps-word/deactivate-by-mod/native_posix_64.keymap new file mode 100644 index 00000000000..c77f5d471d0 --- /dev/null +++ b/app/tests/caps-word/deactivate-by-mod/native_posix_64.keymap @@ -0,0 +1,35 @@ +#include +#include +#include + +&caps_word { + /delete-property/ ignore-modifiers; +}; + +/ { + keymap { + compatible = "zmk,keymap"; + label = "Default keymap"; + + default_layer { + bindings = < + &caps_word &kp A + &kp LSHFT &none + >; + }; + }; +}; + + +&kscan { + events = < + 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(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; diff --git a/docs/docs/behaviors/caps-word.md b/docs/docs/behaviors/caps-word.md index e85d7ecae98..86613ed7420 100644 --- a/docs/docs/behaviors/caps-word.md +++ b/docs/docs/behaviors/caps-word.md @@ -37,6 +37,18 @@ By default, the caps word will remain active when any alphanumeric character or }; ``` +#### Continue on modifiers + +By default, the caps word will remain active when any modifiers are pressed. If you +would like to deactivate caps word when modifiers are pressed, you can delete the +`ignored-modifiers` property in your keymap: + +``` +&caps_word { + /delete-property/ ignore-modifiers; +}; +``` + #### Applied Modifier(s) In addition, if you would like _multiple_ modifiers, instead of just `MOD_LSFT`, you can override the `mods` property: