Skip to content

Commit

Permalink
urob/improve-caps-word zmkfirmware#1451
Browse files Browse the repository at this point in the history
  • Loading branch information
johnm committed Nov 6, 2022
1 parent 0193f0b commit 0579331
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 5 deletions.
15 changes: 15 additions & 0 deletions app/dts/behaviors/caps_word.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,22 @@
compatible = "zmk,behavior-caps-word";
label = "CAPS_WORD";
#binding-cells = <0>;
mods = <MOD_LSFT>;
continue-list = <UNDERSCORE BACKSPACE DELETE>;
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 = <xx>; // to be specified in user config using "&num_word { layers = <xx>; };"
continue-list = <BACKSPACE DELETE DOT COMMA>;
ignore-numbers;
};
};
};
Expand Down
8 changes: 8 additions & 0 deletions app/dts/bindings/behaviors/zmk,behavior-caps-word.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
31 changes: 26 additions & 5 deletions app/src/behaviors/behavior_caps_word.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
Expand All @@ -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;
}

Expand Down Expand Up @@ -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) {
Expand All @@ -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);
Expand Down Expand Up @@ -176,7 +193,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 = {UTIL_LISTIFY(DT_INST_PROP_LEN(n, continue_list), BREAK_ITEM, n)}, \
.continuations_count = DT_INST_PROP_LEN(n, continue_list), \
}; \
Expand Down
3 changes: 3 additions & 0 deletions app/tests/caps-word/deactivate-by-mod/events.patterns
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
s/.*hid_listener_keycode_//p
s/.*hid_implicit_modifiers_//p
s/.*caps_word_enhance_usage/enhance_usage/p
13 changes: 13 additions & 0 deletions app/tests/caps-word/deactivate-by-mod/keycode_events.snapshot
Original file line number Diff line number Diff line change
@@ -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
35 changes: 35 additions & 0 deletions app/tests/caps-word/deactivate-by-mod/native_posix_64.keymap
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>

&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)
>;
};
12 changes: 12 additions & 0 deletions docs/docs/behaviors/caps-word.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 0579331

Please sign in to comment.