From 6689912bcd090a06d690e869d8af3c20aeba84ab Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 4 Jan 2020 14:36:21 +0100 Subject: [PATCH] LEDControl: Add disable/enable functions, and a toggle key This adds `LEDControl.disable()` and `LEDControl.enable()` which disable and enable LED operations, respectively. These are meant to replace the current `LEDControl.paused` property (which is getting deprecated with this change), and do some additional work on top of just disabling or re-enabling future updates and sync. Namely, `disable()` will also turn LEDs off, while `enable()` will refresh them all, too. We also add a dedicated `Key_LEDToggle` key to disable/enable LEDs. This is useful when one wants to turn LEDs off, without changing active LED mode to `LEDOff`. Signed-off-by: Gergely Nagy --- docs/NEWS.md | 17 +++++--- docs/UPGRADING.md | 39 ++++++++++++++++++ examples/Devices/Keyboardio/Imago/Imago.ino | 9 ++-- .../HostPowerManagement.ino | 9 ++-- src/kaleidoscope/plugin/IdleLEDs.cpp | 14 +++---- src/kaleidoscope/plugin/LEDControl.cpp | 25 +++++++++-- src/kaleidoscope/plugin/LEDControl.h | 41 +++++++++++++++++-- src/kaleidoscope_internal/deprecations.h | 9 +++- 8 files changed, 129 insertions(+), 34 deletions(-) diff --git a/docs/NEWS.md b/docs/NEWS.md index 1e4abe33..67bfa980 100644 --- a/docs/NEWS.md +++ b/docs/NEWS.md @@ -161,17 +161,24 @@ The [FirmwareDump](doc/plugin/FirmwareDump.md) plugin makes it possible to dump Type `Key` was originally implemented as a C++ union. For technical reasons it had to be converted to a C++ class. This implies that the double usage of the original union, holding either raw data (member `raw`) or key code/key flags -data (members `keyCode` and `flags`) is no more possible. +data (members `keyCode` and `flags`) is no more possible. -Direct use of member `raw` will -emit a diagnostic compiler message but will cause the firmware linking +Direct use of member `raw` will +emit a diagnostic compiler message but will cause the firmware linking process to fail. For a deprecation -periode `keyCode` and `flags` keep on being supported but will cause -deprecation warnings during compile. +periode `keyCode` and `flags` keep on being supported but will cause +deprecation warnings during compile. Please see the [relevant upgrade notes](UPGRADING.md##implementation-of-type-key-internally-changed-from-union-to-class) for information about how to upgrade legacy code. +### `LEDControl.paused` has been deprecated + +The `.paused` property of `LEDControl` has been deprecated in favour of the new +`LEDControl.disable()` and `LEDControl.enable()` methods. These two will turn +off or refresh the LEDs, respectively, along with disabling or re-enabling +future updates and syncs. + ### The `NumPad` plugin no longer toggles `NumLock` The `NumPad` plugin used to toggle `NumLock` when switching to the NumPad layer. This caused issues on OSX where `NumLock` is interpreted as `Clear`. For this reason, the plugin no longer does this. As a consequence, everyone's encouraged to update their keymap so that the numpad layer uses normal number keys instead of the keypad numbers. See [Model01-Firmware#79](https://github.com/keyboardio/Model01-Firmware/pull/79) for an example about how to do this. diff --git a/docs/UPGRADING.md b/docs/UPGRADING.md index d26aa354..6762407a 100644 --- a/docs/UPGRADING.md +++ b/docs/UPGRADING.md @@ -13,6 +13,7 @@ If any of this does not make sense to you, or you have trouble updating your .in - [Consistent timing](#consistent-timing) + [Breaking changes](#breaking-changes) - [Implementation of type Key internally changed from C++ union to class](#implementation-of-type-key-internally-changed-from-union-to-class) + - [`LEDControl.paused` has been deprecated](#ledcontrolpaused-has-been-deprecated) - [The `RxCy` macros and peeking into the keyswitch state](#the-rxcy-macros-and-peeking-into-the-keyswitch-state) - [HostOS](#hostos) - [MagicCombo](#magiccombo) @@ -353,6 +354,44 @@ k.setKeyCode(Key_A.getKeyCode()); k.setFlags(Key_A.getFlags()); ``` +### `LEDControl.paused` has been deprecated + +Wherever we used `LEDControl.paused`, we'll need to use one of +`LEDControl.disable()`, `LEDControl.enable()`, or `LEDControl.isEnabled()` +instead. `LEDControl.paused` will still compile, but will emit deprecation +warnings, and will be removed after **2020-03-15**. + +Keep in mind that `.enable()` and `.disable()` do more than what `paused` did: +they will refresh and turn off LEDs too, respectively. + +A few examples to show how to transition to the new APIs follow, old use first, new second. + +```c++ +if (someCondition) { + LEDControl.set_all_leds_to({0, 0, 0}); + LEDControl.syncLeds(); + LEDControl.paused = true; +} else if (someOtherCondition) { + LEDControl.paused = false; + LEDControl.refreshAll(); +} + +if (LEDControl.paused) { + // do things... +} +``` + +```c++ +if (someCondition) { + LEDControl.disable(); +} else if (someOtherCondition) { + LEDControl.enable(); +} +if (!LEDControl.isEnabled()) { + // do things... +} +``` + ### The `RxCy` macros and peeking into the keyswitch state The `RxCy` macros changed from being indexes into a per-hand bitmap to being an diff --git a/examples/Devices/Keyboardio/Imago/Imago.ino b/examples/Devices/Keyboardio/Imago/Imago.ino index 6142a15c..f76df8ad 100644 --- a/examples/Devices/Keyboardio/Imago/Imago.ino +++ b/examples/Devices/Keyboardio/Imago/Imago.ino @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Imago.ino -- Example sketch for the Keyboardio Imago - * Copyright (C) 2018, 2019 Keyboard.io, Inc + * Copyright (C) 2018, 2019, 2020 Keyboard.io, Inc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -91,13 +91,10 @@ static kaleidoscope::plugin::LEDSolidColor solidViolet(130, 0, 120); void toggleLedsOnSuspendResume(kaleidoscope::plugin::HostPowerManagement::Event event) { switch (event) { case kaleidoscope::plugin::HostPowerManagement::Suspend: - LEDControl.set_all_leds_to({0, 0, 0}); - LEDControl.syncLeds(); - LEDControl.paused = true; + LEDControl.disable(); break; case kaleidoscope::plugin::HostPowerManagement::Resume: - LEDControl.paused = false; - LEDControl.refreshAll(); + LEDControl.enable(); break; case kaleidoscope::plugin::HostPowerManagement::Sleep: break; diff --git a/examples/Features/HostPowerManagement/HostPowerManagement.ino b/examples/Features/HostPowerManagement/HostPowerManagement.ino index 065d6696..cb5c9f49 100644 --- a/examples/Features/HostPowerManagement/HostPowerManagement.ino +++ b/examples/Features/HostPowerManagement/HostPowerManagement.ino @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-HostPowerManagement -- Host power management support plugin. - * Copyright (C) 2017, 2018 Gergely Nagy + * Copyright (C) 2017, 2018, 2020 Keyboard.io, Inc * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -46,13 +46,10 @@ KEYMAPS( void hostPowerManagementEventHandler(kaleidoscope::plugin::HostPowerManagement::Event event) { switch (event) { case kaleidoscope::plugin::HostPowerManagement::Suspend: - LEDControl.paused = true; - LEDControl.set_all_leds_to({0, 0, 0}); - LEDControl.syncLeds(); + LEDControl.disable(); break; case kaleidoscope::plugin::HostPowerManagement::Resume: - LEDControl.paused = false; - LEDControl.refreshAll(); + LEDControl.enable(); break; case kaleidoscope::plugin::HostPowerManagement::Sleep: break; diff --git a/src/kaleidoscope/plugin/IdleLEDs.cpp b/src/kaleidoscope/plugin/IdleLEDs.cpp index 8cac7e2e..6094d6de 100644 --- a/src/kaleidoscope/plugin/IdleLEDs.cpp +++ b/src/kaleidoscope/plugin/IdleLEDs.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-Idle-LEDs -- Turn off the LEDs when the keyboard's idle - * Copyright (C) 2018, 2019 Keyboard.io, Inc + * Copyright (C) 2018, 2019, 2020 Keyboard.io, Inc * Copyright (C) 2019 Dygma, Inc * * This program is free software: you can redistribute it and/or modify it under @@ -36,12 +36,9 @@ void IdleLEDs::setIdleTimeoutSeconds(uint32_t new_limit) { } EventHandlerResult IdleLEDs::beforeEachCycle() { - if (!::LEDControl.paused && + if (::LEDControl.isEnabled() && Runtime.hasTimeExpired(start_time_, idle_time_limit)) { - ::LEDControl.set_all_leds_to(CRGB(0, 0, 0)); - ::LEDControl.syncLeds(); - - ::LEDControl.paused = true; + ::LEDControl.disable(); } return EventHandlerResult::OK; @@ -49,9 +46,8 @@ EventHandlerResult IdleLEDs::beforeEachCycle() { EventHandlerResult IdleLEDs::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) { - if (::LEDControl.paused) { - ::LEDControl.paused = false; - ::LEDControl.refreshAll(); + if (!::LEDControl.isEnabled()) { + ::LEDControl.enable(); } start_time_ = Runtime.millisAtCycleStart(); diff --git a/src/kaleidoscope/plugin/LEDControl.cpp b/src/kaleidoscope/plugin/LEDControl.cpp index 8e8f668a..dbc10cb9 100644 --- a/src/kaleidoscope/plugin/LEDControl.cpp +++ b/src/kaleidoscope/plugin/LEDControl.cpp @@ -1,5 +1,5 @@ /* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope - * Copyright (C) 2017-2018 Keyboard.io, Inc. + * Copyright (C) 2017-2020 Keyboard.io, Inc. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software @@ -31,7 +31,7 @@ uint8_t LEDControl::num_led_modes_ = LEDModeManager::numLEDModes(); LEDMode *LEDControl::cur_led_mode_; uint8_t LEDControl::syncDelay = 32; uint16_t LEDControl::syncTimer = 0; -bool LEDControl::paused = false; +bool LEDControl::enabled_ = true; LEDControl::LEDControl(void) { } @@ -120,7 +120,7 @@ cRGB LEDControl::getCrgbAt(KeyAddr key_addr) { } void LEDControl::syncLeds(void) { - if (paused) + if (!enabled_) return; Runtime.device().syncLeds(); @@ -138,6 +138,18 @@ kaleidoscope::EventHandlerResult LEDControl::onSetup() { return EventHandlerResult::OK; } +void LEDControl::disable() { + set_all_leds_to(CRGB(0, 0, 0)); + Runtime.device().syncLeds(); + enabled_ = false; +} + +void LEDControl::enable() { + enabled_ = true; + refreshAll(); + Runtime.device().syncLeds(); +} + kaleidoscope::EventHandlerResult LEDControl::onKeyswitchEvent(Key &mappedKey, KeyAddr key_addr, uint8_t keyState) { if (mappedKey.getFlags() != (SYNTHETIC | IS_INTERNAL | LED_TOGGLE)) return kaleidoscope::EventHandlerResult::OK; @@ -147,6 +159,11 @@ kaleidoscope::EventHandlerResult LEDControl::onKeyswitchEvent(Key &mappedKey, Ke next_mode(); } else if (mappedKey == Key_LEDEffectPrevious) { prev_mode(); + } else if (mappedKey == Key_LEDToggle) { + if (enabled_) + disable(); + else + enable(); } } @@ -154,7 +171,7 @@ kaleidoscope::EventHandlerResult LEDControl::onKeyswitchEvent(Key &mappedKey, Ke } kaleidoscope::EventHandlerResult LEDControl::beforeReportingState(void) { - if (paused) + if (!enabled_) return kaleidoscope::EventHandlerResult::OK; if (Runtime.hasTimeExpired(syncTimer, syncDelay)) { diff --git a/src/kaleidoscope/plugin/LEDControl.h b/src/kaleidoscope/plugin/LEDControl.h index 1636b8f2..3034a9bc 100644 --- a/src/kaleidoscope/plugin/LEDControl.h +++ b/src/kaleidoscope/plugin/LEDControl.h @@ -1,5 +1,5 @@ /* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope - * Copyright (C) 2017-2018 Keyboard.io, Inc. + * Copyright (C) 2017-2020 Keyboard.io, Inc. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software @@ -23,6 +23,7 @@ #define Key_LEDEffectNext Key(0, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE) #define Key_LEDEffectPrevious Key(1, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE) +#define Key_LEDToggle Key(2, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE) #define _DEPRECATED_MESSAGE_LED_CONTROL_MODE_ADD \ "LEDControl::mode_add(LEDMode *mode) is deprecated. LEDModes are now \n" \ @@ -73,7 +74,7 @@ class LEDControl : public kaleidoscope::Plugin { if (!Runtime.has_leds) return; - if (paused) + if (!enabled_) return; set_all_leds_to({0, 0, 0}); @@ -108,17 +109,51 @@ class LEDControl : public kaleidoscope::Plugin { static void activate(LEDModeInterface *plugin); static uint8_t syncDelay; - static bool paused; kaleidoscope::EventHandlerResult onSetup(); kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mappedKey, KeyAddr key_addr, uint8_t keyState); kaleidoscope::EventHandlerResult beforeReportingState(); + static void disable(); + static void enable(); + static bool isEnabled() { + return enabled_; + } + + // The data proxy objects are required to only emit deprecation + // messages when the `paused` property is accessed directly. + // + // Once the deprecation period elapsed, the proxy class and the proxied + // `paused` property can be safely removed. + class DataProxy { + public: + DataProxy() = default; + + //constexpr DataProxy(bool value) : value_{value} {} + + DEPRECATED(DIRECT_LEDCONTROL_PAUSED_ACCESS) + DataProxy &operator=(bool value) { + if (value) + disable(); + else + enable(); + return *this; + } + + DEPRECATED(DIRECT_LEDCONTROL_PAUSED_ACCESS) + operator bool () const { + return !isEnabled(); + } + }; + + DataProxy paused; + private: static uint16_t syncTimer; static uint8_t mode_id; static uint8_t num_led_modes_; static LEDMode *cur_led_mode_; + static bool enabled_; }; class FocusLEDCommand : public Plugin { diff --git a/src/kaleidoscope_internal/deprecations.h b/src/kaleidoscope_internal/deprecations.h index 9e6ee4b9..43a96c86 100644 --- a/src/kaleidoscope_internal/deprecations.h +++ b/src/kaleidoscope_internal/deprecations.h @@ -1,5 +1,5 @@ /* Kaleidoscope - Firmware for computer input devices - * Copyright (C) 2013-2018 Keyboard.io, Inc. + * Copyright (C) 2013-2020 Keyboard.io, Inc. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software @@ -66,6 +66,13 @@ "For further information and examples on how to do that, \n" \ "please see UPGRADING.md." +#define _DEPRECATED_MESSAGE_DIRECT_LEDCONTROL_PAUSED_ACCESS \ + "Direct access to `LEDControl.paused` is deprecated.\n" \ + "Please use `LEDControl.disable()` and `LEDControl.enable()` instead.\n" \ + "\n" \ + "For further information and examples on how to do that, please see\n" \ + "UPGRADING.md" + #define _DEPRECATED_MESSAGE_KEY_MEMBER_RAW_ACCESS \ "The member variable `raw` of class Key had to be removed. Please \n" \ "use `Key::setRaw()`/`Key::getRaw()` to set and get raw data.\n" \