Add builtin modifier/layer-shift combo keys

Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
pull/1070/head
Michael Richters 3 years ago
parent 65621738d2
commit e6deb09e88
No known key found for this signature in database
GPG Key ID: 1288FD13E4EEF0C0

@ -157,9 +157,13 @@ void Runtime_::handleKeyEvent(KeyEvent event) {
event.key == Key_Transparent) event.key == Key_Transparent)
return; return;
// If it's a built-in Layer key, we handle it here, and skip sending report(s) // Built-in layer change keys are handled by the Layer object.
if (event.key.isLayerKey()) { if (event.key.isLayerKey() || event.key.isModLayerKey()) {
Layer.handleLayerKeyEvent(event); Layer.handleLayerKeyEvent(event);
}
// If the event is for a layer change key, there's no need to send a HID
// report, so we return early.
if (event.key.isLayerKey()) {
return; return;
} }
@ -226,6 +230,11 @@ void Runtime_::addToReport(Key key) {
if (result == EventHandlerResult::ABORT) if (result == EventHandlerResult::ABORT)
return; return;
if (key.isModLayerKey()) {
uint8_t mod = key.getKeyCode() % 8;
key = Key(Key_LeftControl.getRaw() + mod);
}
if (key.isKeyboardKey()) { if (key.isKeyboardKey()) {
// The only incidental Keyboard modifiers that are allowed are the ones on // The only incidental Keyboard modifiers that are allowed are the ones on
// the key that generated the event, so we strip any others before adding // the key that generated the event, so we strip any others before adding

@ -53,6 +53,12 @@
#define SWITCH_TO_KEYMAP 0b00000100 #define SWITCH_TO_KEYMAP 0b00000100
#define IS_CONSUMER 0b00001000 #define IS_CONSUMER 0b00001000
// consumer: 01..1...
// sysctl: 01..0001
// layer: 01000100
// modlayer: 01000110
// macros: 01100000
// HID Usage Types: Because these constants, like the ones above, are // HID Usage Types: Because these constants, like the ones above, are
// used in the flags byte of the Key class, they can't overlap any of // used in the flags byte of the Key class, they can't overlap any of
// the above bits. Nor can we use `SYNTHETIC` and `RESERVED` to encode // the above bits. Nor can we use `SYNTHETIC` and `RESERVED` to encode
@ -180,6 +186,9 @@ class Key {
constexpr bool isLayerKey() const { constexpr bool isLayerKey() const {
return (flags_ == (SYNTHETIC | SWITCH_TO_KEYMAP)); return (flags_ == (SYNTHETIC | SWITCH_TO_KEYMAP));
} }
constexpr bool isModLayerKey() const {
return (flags_ == (SYNTHETIC | SWITCH_TO_KEYMAP | IS_INTERNAL));
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Additional utility functions for builtin `Key` variants // Additional utility functions for builtin `Key` variants
@ -206,19 +215,26 @@ class Key {
// used in a conceptually different way: to get a different symbol in the // used in a conceptually different way: to get a different symbol in the
// output. We don't normally think "type `shift`+`1`"; we think "type `!`". // output. We don't normally think "type `shift`+`1`"; we think "type `!`".
constexpr bool isKeyboardShift() const { constexpr bool isKeyboardShift() const {
return (isKeyboardModifier() && return ((isKeyboardModifier() &&
((keyCode_ == HID_KEYBOARD_LEFT_SHIFT || ((keyCode_ == HID_KEYBOARD_LEFT_SHIFT ||
keyCode_ == HID_KEYBOARD_RIGHT_SHIFT) || keyCode_ == HID_KEYBOARD_RIGHT_SHIFT) ||
((flags_ & SHIFT_HELD) != 0))); ((flags_ & SHIFT_HELD) != 0))) ||
(isModLayerKey() &&
(keyCode_ % 8) % 4 == 1));
} }
// Layer shift keys are conceptually similar to Keyboard modifier keys in that // Layer shift keys are conceptually similar to Keyboard modifier keys in that
// they are used chorded to change the result of typing those other // they are used chorded to change the result of typing those other
// keys. They're even more similar to `shift` keys. For both reasons, it's // keys. They're even more similar to `shift` keys. For both reasons, it's
// worth singling them out. // worth singling them out.
constexpr bool __attribute__((always_inline)) isLayerShift() const { constexpr bool __attribute__((always_inline)) isLayerShift() const {
return (isLayerKey() && return ((isLayerKey() &&
keyCode_ >= LAYER_SHIFT_OFFSET && keyCode_ >= LAYER_SHIFT_OFFSET &&
keyCode_ < LAYER_MOVE_OFFSET); keyCode_ < LAYER_MOVE_OFFSET) ||
isModLayerKey());
}
constexpr bool isMomentary() const {
return (isKeyboardModifier() || isLayerShift() || isModLayerKey());
} }
private: private:
@ -254,6 +270,14 @@ constexpr Key addFlags(Key k, uint8_t add_flags) {
return Key(k.getKeyCode(), k.getFlags() | add_flags); return Key(k.getKeyCode(), k.getFlags() | add_flags);
} }
// =============================================================================
/// Generate a ModLayer key (unchecked)
constexpr Key modLayerKey(Key modifier, uint8_t layer) {
uint8_t mod = modifier.getRaw() - Key_LeftControl.getRaw();
uint8_t code = mod + (layer * 8);
return Key(code, SYNTHETIC | SWITCH_TO_KEYMAP | IS_INTERNAL);
}
} // namespace kaleidoscope } // namespace kaleidoscope
// Redefine this macro to enable using alternative char-string to Key // Redefine this macro to enable using alternative char-string to Key

@ -80,3 +80,6 @@ static const uint8_t LAYER_MOVE_OFFSET = LAYER_SHIFT_OFFSET + LAYER_OP_OFFSET;
* this is a one-way operation. * this is a one-way operation.
*/ */
#define MoveToLayer(n) Key(n + LAYER_MOVE_OFFSET, KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP) #define MoveToLayer(n) Key(n + LAYER_MOVE_OFFSET, KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP)
// Shorthand for keymap entry (e.g. `ML(LeftAlt, 3)`)
#define ML(mod, layer) kaleidoscope::modLayerKey(Key_##mod, layer)

@ -62,6 +62,11 @@ void Layer_::handleLayerKeyEvent(const KeyEvent &event) {
// The caller is responsible for checking that this is a Layer `Key`, so we // The caller is responsible for checking that this is a Layer `Key`, so we
// skip checking for it here. // skip checking for it here.
uint8_t key_code = event.key.getKeyCode(); uint8_t key_code = event.key.getKeyCode();
// If this is a ModLayer key, we need to convert it into a layer shift first.
if (event.key.isModLayerKey())
key_code = (key_code / 8) + LAYER_SHIFT_OFFSET;
uint8_t target_layer; uint8_t target_layer;
if (key_code >= LAYER_MOVE_OFFSET) { if (key_code >= LAYER_MOVE_OFFSET) {

Loading…
Cancel
Save