Skip to content

Commit

Permalink
Add debouncing for layer change
Browse files Browse the repository at this point in the history
Fixes #1
  • Loading branch information
caksoylar committed Jul 16, 2024
1 parent a8f5b02 commit e5909fb
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 12 deletions.
8 changes: 8 additions & 0 deletions Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,16 @@ config RGBLED_WIDGET_BATTERY_LEVEL_CRITICAL
config RGBLED_WIDGET_SHOW_LAYER_CHANGE
bool "Indicate highest active layer on each layer change with a sequence of blinks"

if RGBLED_WIDGET_SHOW_LAYER_CHANGE

config RGBLED_WIDGET_LAYER_BLINK_MS
int "Blink and wait duration for layer indicator"
default 100

config RGBLED_WIDGET_LAYER_DEBOUNCE_MS
int "Wait duration after a layer change before showing the highest active layer"
default 100

endif # RGBLED_WIDGET_SHOW_LAYER_CHANGE

endif
30 changes: 18 additions & 12 deletions leds.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);

#define LED_GPIO_NODE_ID DT_COMPAT_GET_ANY_STATUS_OKAY(gpio_leds)

#define SHOW_LAYER_CHANGE \
(IS_ENABLED(CONFIG_RGBLED_WIDGET_SHOW_LAYER_CHANGE)) && \
(!IS_ENABLED(CONFIG_ZMK_SPLIT) || IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL))

BUILD_ASSERT(DT_NODE_EXISTS(DT_ALIAS(led_red)),
"An alias for a red LED is not found for RGBLED_WIDGET");
BUILD_ASSERT(DT_NODE_EXISTS(DT_ALIAS(led_green)),
Expand Down Expand Up @@ -130,18 +134,18 @@ ZMK_LISTENER(led_battery_listener, led_battery_listener_cb);
ZMK_SUBSCRIPTION(led_battery_listener, zmk_battery_state_changed);
#endif // IS_ENABLED(CONFIG_ZMK_BATTERY_REPORTING)

#if IS_ENABLED(CONFIG_RGBLED_WIDGET_SHOW_LAYER_CHANGE)
#if !IS_ENABLED(CONFIG_ZMK_SPLIT) || IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
static int led_layer_listener_cb(const zmk_event_t *eh) {
if (!initialized) {
return 0;
}
#if SHOW_LAYER_CHANGE
static struct k_work_delayable layer_indicate_work;

// ignore layer off events
if (!as_zmk_layer_state_changed(eh)->state) {
return 0;
static int led_layer_listener_cb(const zmk_event_t *eh) {
// ignore if not initialized yet or layer off events
if (initialized && as_zmk_layer_state_changed(eh)->state) {
k_work_reschedule(&layer_indicate_work, K_MSEC(CONFIG_RGBLED_WIDGET_LAYER_DEBOUNCE_MS));
}
return 0;
}

static void indicate_layer(struct k_work *work) {
uint8_t index = zmk_keymap_highest_layer_active();
static const struct blink_item blink = {.duration_ms = CONFIG_RGBLED_WIDGET_LAYER_BLINK_MS,
.color = LED_CYAN,
Expand All @@ -155,19 +159,21 @@ static int led_layer_listener_cb(const zmk_event_t *eh) {
k_msgq_put(&led_msgq, &last_blink, K_NO_WAIT);
}
}
return 0;
}

ZMK_LISTENER(led_layer_listener, led_layer_listener_cb);
ZMK_SUBSCRIPTION(led_layer_listener, zmk_layer_state_changed);
#endif
#endif // IS_ENABLED(CONFIG_RGBLED_WIDGET_SHOW_LAYER_CHANGE)
#endif // SHOW_LAYER_CHANGE

extern void led_process_thread(void *d0, void *d1, void *d2) {
ARG_UNUSED(d0);
ARG_UNUSED(d1);
ARG_UNUSED(d2);

#if SHOW_LAYER_CHANGE
k_work_init_delayable(&layer_indicate_work, indicate_layer);
#endif

while (true) {
// wait until a blink item is received and process it
struct blink_item blink;
Expand Down

0 comments on commit e5909fb

Please sign in to comment.