diff --git a/app/Kconfig b/app/Kconfig index b21d7bb7..a5e0cf5a 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -325,6 +325,9 @@ config ZMK_RGB_UNDERGLOW_ON_START bool "RGB underglow starts on by default" default y +config ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE + bool "Turn off RGB underglow when keyboard goes into idle state" + #ZMK_RGB_UNDERGLOW endif diff --git a/app/src/rgb_underglow.c b/app/src/rgb_underglow.c index 427552fa..a9439f73 100644 --- a/app/src/rgb_underglow.c +++ b/app/src/rgb_underglow.c @@ -17,6 +17,9 @@ #include #include +#include +#include + #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -287,7 +290,8 @@ int zmk_rgb_underglow_get_state(bool *on_off) { return 0; } -int zmk_rgb_underglow_on() { +// Enables underglow LEDs and underglow_tick, but doesn't update state +int zmk_rgb_underglow_resume() { if (!led_strip) return -ENODEV; @@ -300,14 +304,22 @@ int zmk_rgb_underglow_on() { } #endif + k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50)); + + return 0; +} + +int zmk_rgb_underglow_on() { + zmk_rgb_underglow_resume(); + state.on = true; state.animation_step = 0; - k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50)); return zmk_rgb_underglow_save_state(); } -int zmk_rgb_underglow_off() { +// Disables underglow LEDs and underglow_tick, but doesn't update state +int zmk_rgb_underglow_pause() { if (!led_strip) return -ENODEV; @@ -327,11 +339,47 @@ int zmk_rgb_underglow_off() { led_strip_update_rgb(led_strip, pixels, STRIP_NUM_PIXELS); k_timer_stop(&underglow_tick); + + return 0; +} + +int zmk_rgb_underglow_off() { + zmk_rgb_underglow_pause(); + state.on = false; return zmk_rgb_underglow_save_state(); } +#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE) +static int zmk_rgb_underglow_event_listener(const zmk_event_t *eh) { + + if (state.on == true) { + struct zmk_activity_state_changed *ev = as_zmk_activity_state_changed(eh); + if (ev == NULL) { + return -ENOTSUP; + } + + switch (ev->state) { + case ZMK_ACTIVITY_ACTIVE: + zmk_rgb_underglow_resume(); + break; + case ZMK_ACTIVITY_IDLE: + case ZMK_ACTIVITY_SLEEP: + zmk_rgb_underglow_pause(); + break; + default: + LOG_WRN("Unhandled activity state: %d", ev->state); + return -EINVAL; + } + } + return 0; +} + +ZMK_LISTENER(rgb_underglow, zmk_rgb_underglow_event_listener); +ZMK_SUBSCRIPTION(rgb_underglow, zmk_activity_state_changed); +#endif // IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE) + int zmk_rgb_underglow_calc_effect(int direction) { return (state.current_effect + UNDERGLOW_EFFECT_NUMBER + direction) % UNDERGLOW_EFFECT_NUMBER; }