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)
return;
// If it's a built-in Layer key, we handle it here, and skip sending report(s)
if (event.key.isLayerKey()) {
// Built-in layer change keys are handled by the Layer object.
if (event.key.isLayerKey() || event.key.isModLayerKey()) {
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;
}
@ -226,6 +230,11 @@ void Runtime_::addToReport(Key key) {
if (result == EventHandlerResult::ABORT)
return;
if (key.isModLayerKey()) {
uint8_t mod = key.getKeyCode() % 8;
key = Key(Key_LeftControl.getRaw() + mod);
}
if (key.isKeyboardKey()) {
// 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

@ -53,6 +53,12 @@
#define SWITCH_TO_KEYMAP 0b00000100
#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
// 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
@ -180,6 +186,9 @@ class Key {
constexpr bool isLayerKey() const {
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
@ -206,19 +215,26 @@ class Key {
// 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 `!`".
constexpr bool isKeyboardShift() const {
return (isKeyboardModifier() &&
((keyCode_ == HID_KEYBOARD_LEFT_SHIFT ||
keyCode_ == HID_KEYBOARD_RIGHT_SHIFT) ||
((flags_ & SHIFT_HELD) != 0)));
return ((isKeyboardModifier() &&
((keyCode_ == HID_KEYBOARD_LEFT_SHIFT ||
keyCode_ == HID_KEYBOARD_RIGHT_SHIFT) ||
((flags_ & SHIFT_HELD) != 0))) ||
(isModLayerKey() &&
(keyCode_ % 8) % 4 == 1));
}
// Layer shift keys are conceptually similar to Keyboard modifier keys in that
// 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
// worth singling them out.
constexpr bool __attribute__((always_inline)) isLayerShift() const {
return (isLayerKey() &&
keyCode_ >= LAYER_SHIFT_OFFSET &&
keyCode_ < LAYER_MOVE_OFFSET);
return ((isLayerKey() &&
keyCode_ >= LAYER_SHIFT_OFFSET &&
keyCode_ < LAYER_MOVE_OFFSET) ||
isModLayerKey());
}
constexpr bool isMomentary() const {
return (isKeyboardModifier() || isLayerShift() || isModLayerKey());
}
private:
@ -254,6 +270,14 @@ constexpr Key addFlags(Key k, uint8_t 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
// 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.
*/
#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
// skip checking for it here.
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;
if (key_code >= LAYER_MOVE_OFFSET) {

Loading…
Cancel
Save