Skip to content

Commit

Permalink
Leader key
Browse files Browse the repository at this point in the history
  • Loading branch information
nickconway committed Jun 3, 2023
1 parent b276a3b commit f3edd06
Show file tree
Hide file tree
Showing 64 changed files with 1,089 additions and 1 deletion.
2 changes: 2 additions & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
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_macro.c)
target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_LEADER_KEY app PRIVATE src/behaviors/behavior_leader_key.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)
Expand All @@ -55,6 +56,7 @@ if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_SENSOR_ROTATE_VAR app PRIVATE src/behaviors/behavior_sensor_rotate_var.c)
target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_SENSOR_ROTATE_COMMON app PRIVATE src/behaviors/behavior_sensor_rotate_common.c)
target_sources(app PRIVATE src/combo.c)
target_sources_ifdef(CONFIG_ZMK_LEADER app PRIVATE src/leader.c)
target_sources(app PRIVATE src/behaviors/behavior_tap_dance.c)
target_sources(app PRIVATE src/behavior_queue.c)
target_sources(app PRIVATE src/conditional_layer.c)
Expand Down
25 changes: 25 additions & 0 deletions app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,19 @@ config ZMK_COMBO_MAX_KEYS_PER_COMBO
#Combo options
endmenu

menu "Leader Options"

config ZMK_LEADER_MAX_KEYS_PER_SEQUENCE
int "Maximum number of key presses in a leader sequence"
default 4

config ZMK_LEADER_MAX_SEQUENCES_PER_KEY
int "Maximum number of leader sequences that a key can belong to"
default 5

#Leader options
endmenu

menu "Behavior Options"

config ZMK_BEHAVIORS_QUEUE_SIZE
Expand All @@ -365,6 +378,18 @@ config ZMK_MACRO_DEFAULT_TAP_MS
int "Default time to wait (in milliseconds) between the press and release events of a tapped behavior in macros"
default 30

DT_COMPAT_ZMK_LEADER := zmk,leader-sequences

config ZMK_LEADER
bool
default $(dt_compat_enabled,$(DT_COMPAT_ZMK_LEADER))

DT_COMPAT_ZMK_BEHAVIOR_LEADER_KEY := zmk,behavior-leader-key

config ZMK_BEHAVIOR_LEADER_KEY
bool
default $(dt_compat_enabled,$(DT_COMPAT_ZMK_BEHAVIOR_LEADER_KEY))

endmenu

menu "Advanced"
Expand Down
3 changes: 2 additions & 1 deletion app/dts/behaviors.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@
#include <behaviors/caps_word.dtsi>
#include <behaviors/key_repeat.dtsi>
#include <behaviors/backlight.dtsi>
#include <behaviors/macros.dtsi>
#include <behaviors/macros.dtsi>
#include <behaviors/leader_key.dtsi>
15 changes: 15 additions & 0 deletions app/dts/behaviors/leader_key.dtsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2022 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

/ {
behaviors {
/omit-if-no-ref/ leader: leader_key {
compatible = "zmk,behavior-leader-key";
label = "LEADER";
#binding-cells = <0>;
};
};
};
15 changes: 15 additions & 0 deletions app/dts/bindings/behaviors/zmk,behavior-leader-key.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright (c) 2022 The ZMK Contributors
# SPDX-License-Identifier: MIT

description: Leader key behavior

compatible: "zmk,behavior-leader-key"

include: zero_param.yaml

properties:
timerless:
type: boolean
timeout-ms:
type: int
default: 200
22 changes: 22 additions & 0 deletions app/dts/bindings/zmk,leader-sequences.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright (c) 2022, The ZMK Contributors
# SPDX-License-Identifier: MIT

description: Leader sequence container

compatible: "zmk,leader-sequences"

child-binding:
description: "A leader sequence"

properties:
bindings:
type: phandle-array
required: true
key-positions:
type: array
required: true
layers:
type: array
default: [-1]
immediate-trigger:
type: boolean
11 changes: 11 additions & 0 deletions app/include/zmk/leader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright (c) 2022 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#pragma once

void zmk_leader_activate(int32_t timeout, bool timeout_on_activation, uint32_t position);
void zmk_leader_deactivate();
bool zmk_leader_get_status();
54 changes: 54 additions & 0 deletions app/src/behaviors/behavior_leader_key.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2022 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#define DT_DRV_COMPAT zmk_behavior_leader_key

#include <zephyr/device.h>
#include <drivers/behavior.h>
#include <zephyr/logging/log.h>

#include <zmk/hid.h>
#include <zmk/event_manager.h>
#include <zmk/events/keycode_state_changed.h>
#include <zmk/behavior.h>
#include <zmk/leader.h>

LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);

struct behavior_leader_key_config {
int32_t timeout_ms;
bool timerless;
};

static int behavior_leader_key_init(const struct device *dev) { return 0; }

static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) {
const struct device *dev = device_get_binding(binding->behavior_dev);
const struct behavior_leader_key_config *cfg = dev->config;

zmk_leader_activate(cfg->timeout_ms, cfg->timerless, event.position);
return ZMK_BEHAVIOR_OPAQUE;
}

static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) {
return 0;
}

static const struct behavior_driver_api behavior_leader_key_driver_api = {
.binding_pressed = on_keymap_binding_pressed,
.binding_released = on_keymap_binding_released,
};

#define LEAD_INST(n) \
static struct behavior_leader_key_config behavior_leader_key_config_##n = { \
.timerless = DT_INST_PROP(n, timerless), .timeout_ms = DT_INST_PROP(n, timeout_ms)}; \
DEVICE_DT_INST_DEFINE(n, behavior_leader_key_init, NULL, NULL, \
&behavior_leader_key_config_##n, APPLICATION, \
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_leader_key_driver_api);

DT_INST_FOREACH_STATUS_OKAY(LEAD_INST)
Loading

0 comments on commit f3edd06

Please sign in to comment.