You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Kaleidoscope/plugins/Kaleidoscope-OneShot/src/kaleidoscope/plugin/OneShot.cpp

470 lines
15 KiB

/* -*- mode: c++ -*-
* Kaleidoscope-OneShot -- One-shot modifiers and layers
* Copyright (C) 2016-2021 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
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope-OneShot.h>
#include <Kaleidoscope-FocusSerial.h>
#include "kaleidoscope/keyswitch_state.h"
#include "kaleidoscope/key_events.h"
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
#include "kaleidoscope/layers.h"
namespace kaleidoscope {
namespace plugin {
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
// ----------------------------------------------------------------------------
// Configuration variables
8 years ago
uint16_t OneShot::timeout_ = 2500;
uint16_t OneShot::hold_timeout_ = 250;
int16_t OneShot::double_tap_timeout_ = -1;
// Deprecated
uint16_t OneShot::time_out = 2500;
uint16_t OneShot::hold_time_out = 250;
int16_t OneShot::double_tap_time_out = -1;
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
// ----------------------------------------------------------------------------
// State variables
uint16_t OneShot::stickable_keys_ = -1;
KeyAddrBitfield OneShot::temp_addrs_;
KeyAddrBitfield OneShot::glue_addrs_;
uint16_t OneShot::start_time_ = 0;
KeyAddr OneShot::prev_key_addr_ = OneShot::invalid_key_addr;
uint8_t OneShot::release_countdown_ = 0;
// ============================================================================
// Public interface
// ----------------------------------------------------------------------------
// Configuration functions
void OneShot::enableStickability(Key key) {
uint8_t n = getKeyIndex(key);
stickable_keys_ |= (1 << n);
}
void OneShot::disableStickability(Key key) {
uint8_t n = getKeyIndex(key);
stickable_keys_ &= ~(1 << n);
}
void OneShot::enableStickabilityForModifiers() {
stickable_keys_ |= stickable_modifiers_mask;
}
void OneShot::disableStickabilityForModifiers() {
stickable_keys_ &= ~stickable_modifiers_mask;
}
void OneShot::enableStickabilityForLayers() {
stickable_keys_ |= stickable_layers_mask;
}
void OneShot::disableStickabilityForLayers() {
stickable_keys_ &= ~stickable_layers_mask;
}
// ----------------------------------------------------------------------------
// Global tests for any OneShot key
bool OneShot::isActive() {
for (KeyAddr key_addr __attribute__((unused)) : temp_addrs_) {
return true;
}
for (KeyAddr key_addr __attribute__((unused)) : glue_addrs_) {
return true;
}
return false;
}
bool OneShot::isSticky() {
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
for (KeyAddr key_addr : glue_addrs_) {
if (! temp_addrs_.read(key_addr)) {
return true;
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
}
}
return false;
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
// ----------------------------------------------------------------------------
// Key-specific OneShot key tests
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
// These functions are particularly useful for ActiveModColor, which
// could potentially use three different color values for the three
// states (sticky | active && !sticky | pressed && !active).
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
bool OneShot::isModifier(Key key) {
// Returns `true` if `key` is a modifier key, including modifiers
// with extra mod flags applied (e.g. `Key_Meh`).
if ((key.getFlags() & (SYNTHETIC | RESERVED)) != 0) {
return false;
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
return (key.getKeyCode() >= Key_LeftControl.getKeyCode() &&
key.getKeyCode() <= Key_RightGui.getKeyCode());
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
bool OneShot::isLayerShift(Key key) {
// Returns `true` if `key` is a layer-shift key.
return (key.getFlags() == (SYNTHETIC | SWITCH_TO_KEYMAP) &&
key.getKeyCode() >= LAYER_SHIFT_OFFSET &&
key.getKeyCode() < LAYER_MOVE_OFFSET);
8 years ago
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
bool OneShot::isStickable(Key key) {
int8_t n;
if (isModifier(key)) {
n = key.getKeyCode() - Key_LeftControl.getKeyCode();
return bitRead(stickable_keys_, n);
} else if (isLayerShift(key)) {
n = oneshot_mod_count + key.getKeyCode() - LAYER_SHIFT_OFFSET;
if (n < oneshot_key_count) {
return bitRead(stickable_keys_, n);
}
}
return false;
8 years ago
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
bool OneShot::isTemporary(KeyAddr key_addr) {
return temp_addrs_.read(key_addr);
8 years ago
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
bool OneShot::isSticky(KeyAddr key_addr) {
return (glue_addrs_.read(key_addr) && !temp_addrs_.read(key_addr));
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
bool OneShot::isActive(KeyAddr key_addr) {
return (isTemporary(key_addr) || glue_addrs_.read(key_addr));
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
// ----------------------------------------------------------------------------
// Other functions
8 years ago
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
// Cancel all active OneShot keys (if `cancel_stickies` is true) or
// just non-sticky active OneShot keys. This function is called by
// Escape-OneShot to release active OneShot keys.
void OneShot::cancel(bool cancel_stickies) {
if (cancel_stickies) {
for (KeyAddr key_addr : glue_addrs_) {
releaseKey(key_addr);
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
}
for (KeyAddr key_addr : temp_addrs_) {
if (glue_addrs_.read(key_addr)) {
releaseKey(key_addr);
} else {
temp_addrs_.clear(key_addr);
}
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
// ----------------------------------------------------------------------------
// Plugin hook functions
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
EventHandlerResult OneShot::onNameQuery() {
return ::Focus.sendName(F("OneShot"));
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
EventHandlerResult OneShot::onKeyswitchEvent(
Key &key, KeyAddr key_addr, uint8_t key_state) {
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
// Ignore injected key events. This prevents re-processing events
// that the hook functions generate (by calling `injectNormalKey()`
// via one of the `*OneShot()` functions). There are more robust
// ways to do this, but since OneShot is intended to react to only
// physical keypresses, this is adequate.
if (key_state & INJECTED)
return EventHandlerResult::OK;
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
bool temp = temp_addrs_.read(key_addr);
bool glue = glue_addrs_.read(key_addr);
if (keyToggledOn(key_state)) {
if (!temp && !glue) {
// This key_addr is not in a OneShot state.
if (isOneShotKey(key)) {
// Replace the OneShot key with its corresponding normal key.
pressKey(key_addr, key);
return EventHandlerResult::ABORT;
} else if (!isModifier(key) && !isLayerShift(key)) {
// Only trigger release of temporary OneShot keys if the
// pressed key is neither a modifier nor a layer shift.
release_countdown_ = (1 << 1);
}
// return EventHandlerResult::OK;
} else if (temp && glue) {
// This key_addr is in the temporary OneShot state.
if (key_addr == prev_key_addr_) {
// The same OneShot key has been pressed twice in a row. It
// will either become sticky (if it has been double-tapped),
// or it will be become a normal key. Either way, its `temp`
// state will be cleared.
temp_addrs_.clear(key_addr);
// Derive the true double-tap timeout value if we're using the default.
uint16_t dtto = (double_tap_timeout_ < 0) ? timeout_ : double_tap_timeout_;
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
// If the key is not stickable, or the double-tap timeout has
// expired, clear the `glue` state, as well; this OneShot key
// has been cancelled, and will become a normal key.
if (!isStickable(key) || hasTimedOut(dtto)) {
glue_addrs_.clear(key_addr);
} else {
return EventHandlerResult::ABORT;
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
} else {
// This is a temporary OneShot key, but has not been pressed
// twice in a row, so we need to clear its state.
temp_addrs_.clear(key_addr);
glue_addrs_.clear(key_addr);
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
} else if (!temp && glue) {
// This is a sticky OneShot key that has been pressed. Clear
// state now, so it will become a normal key.
glue_addrs_.clear(key_addr);
} else { // (temp && !glue)
// A key has been pressed that is in the "pending" OneShot
// state. Since this key should have entered the "temporary"
// OneShot state as soon as it was released (from its first
// press), it should only be possible to release a key that's in
// this state.
}
// Always record the address of a keypress. It might be useful for
// other plugins, so this could perhaps be tracked in the
// Kaleidoscope core.
prev_key_addr_ = key_addr;
} else if (keyToggledOff(key_state)) {
if (temp || glue) {
// Any key in the "pending" OneShot state needs its `glue` state
// bit set to make it "temporary". If it's in the "sticky"
// OneShot state, this is redundant, but we're trading time
// efficiency to get smaller binary size.
glue_addrs_.set(key_addr);
// This is an active OneShot key that has just been released. We
// need to stop that event from sending a report, and instead
// send a "hold" event. This is handled in the
// `beforeReportingState()` hook below.
//Layer.updateLiveCompositeKeymap(key_addr, key);
return EventHandlerResult::ABORT;
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
} else {
// This key is being held.
if (temp && !glue) {
// This key is in the "pending" OneShot state. We need to check
// its hold timeout, and turn it back into a normal key if it
// has timed out.
if (hasTimedOut(hold_timeout_)) {
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
temp_addrs_.clear(key_addr);
}
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
if (isOneShotKey(key)) {
// whoops! someone cancelled a oneshot key while it was being
// held; reactivate it, but set it as a normal modifier
// instead. Or better yet, mask it, in case of a layer change.
}
}
return EventHandlerResult::OK;
8 years ago
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
// For any active OneShot modifier keys, keep those modifiers active
// in the keyboard HID report.
EventHandlerResult OneShot::beforeReportingState() {
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
for (KeyAddr key_addr : glue_addrs_) {
holdKey(key_addr);
}
return EventHandlerResult::OK;
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
EventHandlerResult OneShot::afterEachCycle() {
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
// If a normal, non-modifier key has been pressed, or if active,
// non-sticky OneShot keys have timed out, this is where they get
// released. Release is triggered when `release_countdown_` gets to
// 1, not 0, because most of the time it will be 0 (see below). It
// gets set to 2 on the press of a normal key when there are any
// active OneShot keys; that way, the OneShot keys will stay active
// long enough to apply to the newly-pressed key.
if ((release_countdown_ == 1) || hasTimedOut(timeout_)) {
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
for (KeyAddr key_addr : temp_addrs_) {
if (glue_addrs_.read(key_addr)) {
releaseKey(key_addr);
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
temp_addrs_.clear(key_addr);
}
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
// Also, advance the counter for OneShot keys that have been
// cancelled by the press of a non-OneShot, non-modifier key. An
// unconditional bit shift should be more efficient than checking
// for zero to avoid underflow.
release_countdown_ >>= 1;
// Temporary fix for deprecated variables
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
timeout_ = time_out;
hold_timeout_ = hold_time_out;
double_tap_timeout_ = double_tap_time_out;
#pragma GCC diagnostic pop
return EventHandlerResult::OK;
8 years ago
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
// ============================================================================
// Private functions, not exposed to other plugins
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
// ----------------------------------------------------------------------------
// Helper functions for acting on OneShot key events
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
uint8_t OneShot::getOneShotKeyIndex(Key oneshot_key) {
// The calling function is responsible for verifying that
// `oneshot_key` is an actual OneShot key (i.e. call
// `isOneShotKey(oneshot_key)` first).
uint8_t index = oneshot_key.getRaw() - ranges::OS_FIRST;
return index;
8 years ago
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
uint8_t OneShot::getKeyIndex(Key key) {
// Default to returning a value that's out of range. This should be
// harmless because we only use the returned index to reference a
// bit in a bitfield, not as a memory address.
uint8_t n{oneshot_key_count};
if (isOneShotKey(key)) {
n = getOneShotKeyIndex(key);
} else if (isModifier(key)) {
n = key.getKeyCode() - Key_LeftControl.getKeyCode();
} else if (isLayerShift(key)) {
n = oneshot_mod_count + key.getKeyCode() - LAYER_SHIFT_OFFSET;
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
return n;
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
Key OneShot::decodeOneShotKey(Key oneshot_key) {
// The calling function is responsible for verifying that
// `oneshot_key` is an actual OneShot key (i.e. call
// `isOneShotKey(oneshot_key)` first).
uint8_t n = getOneShotKeyIndex(oneshot_key);
if (n < oneshot_mod_count) {
return Key(Key_LeftControl.getKeyCode() + n,
Key_LeftControl.getFlags());
} else {
return Key(LAYER_SHIFT_OFFSET + n - oneshot_mod_count,
KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP);
}
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
// ------------------------------------------------------------------------------
// Helper functions for sending key events for keys in OneShot states
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
void OneShot::pressKey(KeyAddr key_addr, Key oneshot_key) {
Key key = decodeOneShotKey(oneshot_key);
prev_key_addr_ = key_addr;
start_time_ = Runtime.millisAtCycleStart();
temp_addrs_.set(key_addr);
handleKeyswitchEvent(key, key_addr, IS_PRESSED | INJECTED);
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
void OneShot::holdKey(KeyAddr key_addr) {
handleKeyswitchEvent(Key_NoKey, key_addr, WAS_PRESSED | IS_PRESSED | INJECTED);
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
void OneShot::releaseKey(KeyAddr key_addr) {
glue_addrs_.clear(key_addr);
temp_addrs_.clear(key_addr);
handleKeyswitchEvent(Key_NoKey, key_addr, WAS_PRESSED | INJECTED);
}
// ------------------------------------------------------------------------------
// Deprecated functions
void OneShot::inject(Key key, uint8_t key_state) {
if (! isOneShotKey(key)) {
return;
}
// Find an idle keyswitch to use for the injected OneShot key and activate
// it. This is an ugly hack, but it will work. It does mean that whatever key
// is used will be unavailable for its normal function until the injected
// OneShot key is deactivated, so use of `inject()` is strongly discouraged.
for (KeyAddr key_addr : KeyAddr::all()) {
if (live_keys[key_addr] == Key_Transparent) {
pressKey(key_addr, key);
glue_addrs_.set(key_addr);
break;
}
}
}
bool OneShot::isModifierActive(Key key) {
// This actually works for any `Key` value, not just modifiers. Because we're
// just searching the keymap cache, it's also possible to return a false
// positive (a plugin might have altered the cache for an idle `KeyAddr`), or
// a false negative (a plugin might be inserting a modifier without a valid
// `KeyAddr`), but as this is a deprecated function, I think this is good
// enough.
for (KeyAddr key_addr : KeyAddr::all()) {
if (live_keys[key_addr] == key) {
return true;
}
}
return false;
}
bool OneShot::isActive(Key oneshot_key) {
if (! isOneShotKey(oneshot_key)) {
return false;
}
Key key = decodeOneShotKey(oneshot_key);
for (KeyAddr key_addr : glue_addrs_) {
if (live_keys[key_addr] == key) {
return true;
}
}
return false;
}
bool OneShot::isSticky(Key oneshot_key) {
if (! isOneShotKey(oneshot_key)) {
return false;
}
Key key = decodeOneShotKey(oneshot_key);
for (KeyAddr key_addr : glue_addrs_) {
if (live_keys[key_addr] == key &&
!temp_addrs_.read(key_addr)) {
return true;
}
}
return false;
}
Rewrite OneShot plugin This is a complete rewrite of OneShot, based on the keymap cache redesign. This allows OneShot to abort the release of a key, causing its cache entry to stay valid if it's in an active state after the key is released, allowing us to fix #896 (double-tapping a layer shift key doesn't make it sticky). Instead of tracking `Key` values, OneShot now uses two bitfields of the keyboard in order to track the OneShot state of every valid `KeyAddr` independently. This could enable the creation of a OneShot "meta" key, which could be used as a way to make any key on the keyboard exhibit OneShot behaviour. The new OneShot plugin immediately replaces the OneShot `Key` value with its corresponding "normal" key, and activates its OneShot status by setting one bit in one of the bitfields. Also included: * A rewrite of LED-ActiveModColor that makes it compatible with the new OneShot, and add support for Qukeys * Updates to Escape-OneShot for compatibility and efficiency * Minor updates to Qukeys * The new KeyAddrBitfield class KeyAddrBitfield: This class can be used to represent a binary state of the physical key addresses on the keyboard. For example, ActiveModColor can use to to mark all the keys which should be highlighted at any given time. It includes a very efficient iterator, which returns only `KeyAddr` values corresponding to bits that are set in the bitfield. It checks a whole byte at a time before examining individual bits, so if most bits are unset most of the time, it's very fast, and suitable for use in hooks that get called every cycle. ActiveModColor: This makes LED-ActiveModColor compatible with Qukeys, and removes its 16-modifier limit, while simultaneously reducing it's footprint in RAM and eliminating a potential buffer overrun bug where it could have written past the end of its state array. Fixes #882 Fixes #894 Fixes #896 Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
4 years ago
} // namespace plugin
} // namespace kaleidoscope
kaleidoscope::plugin::OneShot OneShot;