[Core] Tri Layer Keys (#19795)
Co-authored-by: wilba <wilba@wilba.tech> Co-authored-by: Pablo Martínez <58857054+elpekenin@users.noreply.github.com> Co-authored-by: Joel Challis <git@zvecr.com> Co-authored-by: Nick Brassel <nick@tzarc.org>
This commit is contained in:
parent
4002843797
commit
fe02abc479
@ -620,6 +620,7 @@ ifeq ($(strip $(VIA_ENABLE)), yes)
|
|||||||
DYNAMIC_KEYMAP_ENABLE := yes
|
DYNAMIC_KEYMAP_ENABLE := yes
|
||||||
RAW_ENABLE := yes
|
RAW_ENABLE := yes
|
||||||
BOOTMAGIC_ENABLE := yes
|
BOOTMAGIC_ENABLE := yes
|
||||||
|
TRI_LAYER_ENABLE := yes
|
||||||
SRC += $(QUANTUM_DIR)/via.c
|
SRC += $(QUANTUM_DIR)/via.c
|
||||||
OPT_DEFS += -DVIA_ENABLE
|
OPT_DEFS += -DVIA_ENABLE
|
||||||
endif
|
endif
|
||||||
|
@ -39,6 +39,7 @@ GENERIC_FEATURES = \
|
|||||||
VELOCIKEY \
|
VELOCIKEY \
|
||||||
WPM \
|
WPM \
|
||||||
DYNAMIC_TAPPING_TERM \
|
DYNAMIC_TAPPING_TERM \
|
||||||
|
TRI_LAYER
|
||||||
|
|
||||||
define HANDLE_GENERIC_FEATURE
|
define HANDLE_GENERIC_FEATURE
|
||||||
# $$(info "Processing: $1_ENABLE $2.c")
|
# $$(info "Processing: $1_ENABLE $2.c")
|
||||||
|
@ -84,7 +84,8 @@ OTHER_OPTION_NAMES = \
|
|||||||
PROGRAMMABLE_BUTTON_ENABLE \
|
PROGRAMMABLE_BUTTON_ENABLE \
|
||||||
SECURE_ENABLE \
|
SECURE_ENABLE \
|
||||||
CAPS_WORD_ENABLE \
|
CAPS_WORD_ENABLE \
|
||||||
AUTOCORRECT_ENABLE
|
AUTOCORRECT_ENABLE \
|
||||||
|
TRI_LAYER_ENABLE
|
||||||
|
|
||||||
define NAME_ECHO
|
define NAME_ECHO
|
||||||
@printf " %-30s = %-16s # %s\\n" "$1" "$($1)" "$(origin $1)"
|
@printf " %-30s = %-16s # %s\\n" "$1" "$($1)" "$(origin $1)"
|
||||||
|
18
data/constants/keycodes/keycodes_0.0.2_quantum.hjson
Normal file
18
data/constants/keycodes/keycodes_0.0.2_quantum.hjson
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"keycodes": {
|
||||||
|
"0x7C77": {
|
||||||
|
"group": "quantum",
|
||||||
|
"key": "QK_TRI_LAYER_LOWER",
|
||||||
|
"aliases": [
|
||||||
|
"TL_LOWR"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"0x7C78": {
|
||||||
|
"group": "quantum",
|
||||||
|
"key": "QK_TRI_LAYER_UPPER",
|
||||||
|
"aliases": [
|
||||||
|
"TL_UPPR"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -93,6 +93,7 @@
|
|||||||
* [Swap Hands](feature_swap_hands.md)
|
* [Swap Hands](feature_swap_hands.md)
|
||||||
* [Tap Dance](feature_tap_dance.md)
|
* [Tap Dance](feature_tap_dance.md)
|
||||||
* [Tap-Hold Configuration](tap_hold.md)
|
* [Tap-Hold Configuration](tap_hold.md)
|
||||||
|
* [Tri Layer](feature_tri_layer.md)
|
||||||
* [Unicode](feature_unicode.md)
|
* [Unicode](feature_unicode.md)
|
||||||
* [Userspace](feature_userspace.md)
|
* [Userspace](feature_userspace.md)
|
||||||
* [WPM Calculation](feature_wpm.md)
|
* [WPM Calculation](feature_wpm.md)
|
||||||
|
48
docs/feature_tri_layer.md
Normal file
48
docs/feature_tri_layer.md
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
# Tri Layers :id=tri-layers
|
||||||
|
|
||||||
|
This enables support for the OLKB style "Tri Layer" keycodes. These function similar to the `MO` (momentary) function key, but if both the "Lower" and "Upper" keys are pressed, it activates a third "Adjust" layer. To enable this functionality, add this line to your `rules.mk`:
|
||||||
|
|
||||||
|
```make
|
||||||
|
TRI_LAYER_ENABLE = yes
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the "upper", "lower" and "adjust" names don't have a particular significance, they are just used to identify and clarify the behavior. Layers are processed from highest numeric value to lowest, however the values are not required to be consecutive.
|
||||||
|
|
||||||
|
For a detailed explanation of how the layer stack works, check out [Keymap Overview](keymap.md#keymap-and-layers).
|
||||||
|
|
||||||
|
## Keycodes :id=keycodes
|
||||||
|
|
||||||
|
| Keycode | Alias | Description |
|
||||||
|
|----------------------|-----------|---------------------------------------------------------------------------------------------------------|
|
||||||
|
| `QK_TRI_LAYER_LOWER` | `TL_LOWR` | Momentarily enables the "lower" layer. Enables the "adjust" layer if the "upper" layer is also enabled" |
|
||||||
|
| `QK_TRI_LAYER_UPPER` | `TL_UPPR` | Momentarily enables the "upper" layer. Enables the "adjust" layer if the "lower" layer is also enabled" |
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
To change the default values for the layers, you can change these defines, in your `config.h`
|
||||||
|
|
||||||
|
| Config name | Default | Description |
|
||||||
|
|--------------------------|---------|------------------------------------------|
|
||||||
|
| `TRI_LAYER_LOWER_LAYER` | `1` | Sets the default for the "lower" layer. |
|
||||||
|
| `TRI_LAYER_UPPER_LAYER` | `2` | Sets the default for the "upper" layer. |
|
||||||
|
| `TRI_LAYER_ADJUST_LAYER` | `3` | Sets the default for the "adjust" layer. |
|
||||||
|
|
||||||
|
Eg, if you wanted to set the "Adjust" layer to be layer 5, you'd add this to your `config.h`:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define TRI_LAYER_ADJUST_LAYER 5
|
||||||
|
```
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
| Function name | Description |
|
||||||
|
|----------------------------------------------|-------------------------------------------------|
|
||||||
|
| `set_tri_layer_lower_layer(layer)` | Changes the "lower" layer*. |
|
||||||
|
| `set_tri_layer_upper_layer(layer)` | Changes the "upper" layer*. |
|
||||||
|
| `set_tri_layer_adjust_layer(layer)` | Changes the "adjust" layer*. |
|
||||||
|
| `set_tri_layer_layers(lower, upper, adjust)` | Stes the "lower", "upper" and "adjust" layers*. |
|
||||||
|
| `get_tri_layer_lower_layer()` | Gets the current "lower" layer. |
|
||||||
|
| `get_tri_layer_upper_layer()` | Gets the current "upper" layer. |
|
||||||
|
| `get_tri_layer_adjust_layer()` | Gets the current "adjust" layer. |
|
||||||
|
|
||||||
|
!> Note: these settings are not persisent, and will be reset to the default on power loss or power cycling of the controller.
|
@ -349,3 +349,13 @@ uint8_t layer_switch_get_layer(keypos_t key) {
|
|||||||
action_t layer_switch_get_action(keypos_t key) {
|
action_t layer_switch_get_action(keypos_t key) {
|
||||||
return action_for_key(layer_switch_get_layer(key), key);
|
return action_for_key(layer_switch_get_layer(key), key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
|
||||||
|
layer_state_t mask12 = ((layer_state_t)1 << layer1) | ((layer_state_t)1 << layer2);
|
||||||
|
layer_state_t mask3 = (layer_state_t)1 << layer3;
|
||||||
|
return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
|
||||||
|
layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3));
|
||||||
|
}
|
||||||
|
@ -113,6 +113,25 @@ void layer_and(layer_state_t state);
|
|||||||
void layer_xor(layer_state_t state);
|
void layer_xor(layer_state_t state);
|
||||||
layer_state_t layer_state_set_user(layer_state_t state);
|
layer_state_t layer_state_set_user(layer_state_t state);
|
||||||
layer_state_t layer_state_set_kb(layer_state_t state);
|
layer_state_t layer_state_set_kb(layer_state_t state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Applies the tri layer to global layer state. Not be used in layer_state_set_(kb|user) functions.
|
||||||
|
*
|
||||||
|
* @param layer1 First layer to check for tri layer
|
||||||
|
* @param layer2 Second layer to check for tri layer
|
||||||
|
* @param layer3 Layer to activate if both other layers are enabled
|
||||||
|
*/
|
||||||
|
void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3);
|
||||||
|
/**
|
||||||
|
* @brief Applies the tri layer behavior to supplied layer bitmask, without using layer functions.
|
||||||
|
*
|
||||||
|
* @param state Original layer bitmask to check and modify
|
||||||
|
* @param layer1 First layer to check for tri layer
|
||||||
|
* @param layer2 Second layer to check for tri layer
|
||||||
|
* @param layer3 Layer to activate if both other layers are enabled
|
||||||
|
* @return layer_state_t returns a modified layer bitmask with tri layer modifications applied
|
||||||
|
*/
|
||||||
|
layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3);
|
||||||
#else
|
#else
|
||||||
# define layer_state 0
|
# define layer_state 0
|
||||||
|
|
||||||
@ -131,6 +150,8 @@ layer_state_t layer_state_set_kb(layer_state_t state);
|
|||||||
# define layer_xor(state) (void)state
|
# define layer_xor(state) (void)state
|
||||||
# define layer_state_set_kb(state) (void)state
|
# define layer_state_set_kb(state) (void)state
|
||||||
# define layer_state_set_user(state) (void)state
|
# define layer_state_set_user(state) (void)state
|
||||||
|
# define update_tri_layer(layer1, layer2, layer3)
|
||||||
|
# define update_tri_layer_state(state, layer1, layer2, layer3) (void)state
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* pressed actions cache */
|
/* pressed actions cache */
|
||||||
|
@ -717,6 +717,8 @@ enum qk_keycode_defines {
|
|||||||
QK_AUTOCORRECT_ON = 0x7C74,
|
QK_AUTOCORRECT_ON = 0x7C74,
|
||||||
QK_AUTOCORRECT_OFF = 0x7C75,
|
QK_AUTOCORRECT_OFF = 0x7C75,
|
||||||
QK_AUTOCORRECT_TOGGLE = 0x7C76,
|
QK_AUTOCORRECT_TOGGLE = 0x7C76,
|
||||||
|
QK_TRI_LAYER_LOWER = 0x7C77,
|
||||||
|
QK_TRI_LAYER_UPPER = 0x7C78,
|
||||||
SAFE_RANGE = 0x7E00,
|
SAFE_RANGE = 0x7E00,
|
||||||
|
|
||||||
// Alias
|
// Alias
|
||||||
@ -1282,6 +1284,8 @@ enum qk_keycode_defines {
|
|||||||
AC_ON = QK_AUTOCORRECT_ON,
|
AC_ON = QK_AUTOCORRECT_ON,
|
||||||
AC_OFF = QK_AUTOCORRECT_OFF,
|
AC_OFF = QK_AUTOCORRECT_OFF,
|
||||||
AC_TOGG = QK_AUTOCORRECT_TOGGLE,
|
AC_TOGG = QK_AUTOCORRECT_TOGGLE,
|
||||||
|
TL_LOWR = QK_TRI_LAYER_LOWER,
|
||||||
|
TL_UPPR = QK_TRI_LAYER_UPPER,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Range Helpers
|
// Range Helpers
|
||||||
@ -1333,4 +1337,4 @@ enum qk_keycode_defines {
|
|||||||
#define IS_MACRO_KEYCODE(code) ((code) >= QK_MACRO_0 && (code) <= QK_MACRO_31)
|
#define IS_MACRO_KEYCODE(code) ((code) >= QK_MACRO_0 && (code) <= QK_MACRO_31)
|
||||||
#define IS_BACKLIGHT_KEYCODE(code) ((code) >= QK_BACKLIGHT_ON && (code) <= QK_BACKLIGHT_TOGGLE_BREATHING)
|
#define IS_BACKLIGHT_KEYCODE(code) ((code) >= QK_BACKLIGHT_ON && (code) <= QK_BACKLIGHT_TOGGLE_BREATHING)
|
||||||
#define IS_RGB_KEYCODE(code) ((code) >= RGB_TOG && (code) <= RGB_MODE_TWINKLE)
|
#define IS_RGB_KEYCODE(code) ((code) >= RGB_TOG && (code) <= RGB_MODE_TWINKLE)
|
||||||
#define IS_QUANTUM_KEYCODE(code) ((code) >= QK_BOOTLOADER && (code) <= QK_AUTOCORRECT_TOGGLE)
|
#define IS_QUANTUM_KEYCODE(code) ((code) >= QK_BOOTLOADER && (code) <= QK_TRI_LAYER_UPPER)
|
||||||
|
30
quantum/process_keycode/process_tri_layer.c
Normal file
30
quantum/process_keycode/process_tri_layer.c
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2023 QMK
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "process_tri_layer.h"
|
||||||
|
#include "tri_layer.h"
|
||||||
|
#include "action_layer.h"
|
||||||
|
|
||||||
|
bool process_tri_layer(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
switch (keycode) {
|
||||||
|
case QK_TRI_LAYER_LOWER:
|
||||||
|
if (record->event.pressed) {
|
||||||
|
layer_on(get_tri_layer_lower_layer());
|
||||||
|
update_tri_layer(get_tri_layer_lower_layer(), get_tri_layer_upper_layer(), get_tri_layer_adjust_layer());
|
||||||
|
} else {
|
||||||
|
layer_off(get_tri_layer_lower_layer());
|
||||||
|
update_tri_layer(get_tri_layer_lower_layer(), get_tri_layer_upper_layer(), get_tri_layer_adjust_layer());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case QK_TRI_LAYER_UPPER:
|
||||||
|
if (record->event.pressed) {
|
||||||
|
layer_on(get_tri_layer_upper_layer());
|
||||||
|
update_tri_layer(get_tri_layer_lower_layer(), get_tri_layer_upper_layer(), get_tri_layer_adjust_layer());
|
||||||
|
} else {
|
||||||
|
layer_off(get_tri_layer_upper_layer());
|
||||||
|
update_tri_layer(get_tri_layer_lower_layer(), get_tri_layer_upper_layer(), get_tri_layer_adjust_layer());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
16
quantum/process_keycode/process_tri_layer.h
Normal file
16
quantum/process_keycode/process_tri_layer.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2023 QMK
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "action.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handles tri layer behavior
|
||||||
|
*
|
||||||
|
* @param keycode the keycode
|
||||||
|
* @param record the key record structure
|
||||||
|
* @return true continue handling keycodes
|
||||||
|
* @return false stop handling keycodes
|
||||||
|
*/
|
||||||
|
bool process_tri_layer(uint16_t keycode, keyrecord_t *record);
|
@ -342,6 +342,9 @@ bool process_record_quantum(keyrecord_t *record) {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef AUTOCORRECT_ENABLE
|
#ifdef AUTOCORRECT_ENABLE
|
||||||
process_autocorrect(keycode, record) &&
|
process_autocorrect(keycode, record) &&
|
||||||
|
#endif
|
||||||
|
#ifdef TRI_LAYER_ENABLE
|
||||||
|
process_tri_layer(keycode, record) &&
|
||||||
#endif
|
#endif
|
||||||
true)) {
|
true)) {
|
||||||
return false;
|
return false;
|
||||||
@ -443,16 +446,6 @@ void set_single_persistent_default_layer(uint8_t default_layer) {
|
|||||||
default_layer_set((layer_state_t)1 << default_layer);
|
default_layer_set((layer_state_t)1 << default_layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
|
|
||||||
layer_state_t mask12 = ((layer_state_t)1 << layer1) | ((layer_state_t)1 << layer2);
|
|
||||||
layer_state_t mask3 = (layer_state_t)1 << layer3;
|
|
||||||
return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
|
|
||||||
layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3));
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Override these functions in your keymap file to play different tunes on
|
// Override these functions in your keymap file to play different tunes on
|
||||||
// different events such as startup and bootloader jump
|
// different events such as startup and bootloader jump
|
||||||
|
@ -240,9 +240,10 @@ extern layer_state_t layer_state;
|
|||||||
# include "process_autocorrect.h"
|
# include "process_autocorrect.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// For tri-layer
|
#ifdef TRI_LAYER_ENABLE
|
||||||
void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3);
|
# include "tri_layer.h"
|
||||||
layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3);
|
# include "process_tri_layer.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
void set_single_persistent_default_layer(uint8_t default_layer);
|
void set_single_persistent_default_layer(uint8_t default_layer);
|
||||||
|
|
||||||
|
39
quantum/tri_layer.c
Normal file
39
quantum/tri_layer.c
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2023 QMK
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "tri_layer.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
static uint8_t tri_layer_lower_layer = TRI_LAYER_LOWER_LAYER;
|
||||||
|
static uint8_t tri_layer_upper_layer = TRI_LAYER_UPPER_LAYER;
|
||||||
|
static uint8_t tri_layer_adjust_layer = TRI_LAYER_ADJUST_LAYER;
|
||||||
|
|
||||||
|
void set_tri_layer_lower_layer(uint8_t layer) {
|
||||||
|
tri_layer_lower_layer = layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_tri_layer_upper_layer(uint8_t layer) {
|
||||||
|
tri_layer_upper_layer = layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_tri_layer_adjust_layer(uint8_t layer) {
|
||||||
|
tri_layer_adjust_layer = layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_tri_layer_layers(uint8_t lower, uint8_t raise, uint8_t adjust) {
|
||||||
|
tri_layer_lower_layer = lower;
|
||||||
|
tri_layer_upper_layer = raise;
|
||||||
|
tri_layer_adjust_layer = adjust;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t get_tri_layer_lower_layer(void) {
|
||||||
|
return tri_layer_lower_layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t get_tri_layer_upper_layer(void) {
|
||||||
|
return tri_layer_upper_layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t get_tri_layer_adjust_layer(void) {
|
||||||
|
return tri_layer_adjust_layer;
|
||||||
|
}
|
59
quantum/tri_layer.h
Normal file
59
quantum/tri_layer.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// Copyright 2023 QMK
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifndef TRI_LAYER_LOWER_LAYER
|
||||||
|
# define TRI_LAYER_LOWER_LAYER 1
|
||||||
|
#endif
|
||||||
|
#ifndef TRI_LAYER_UPPER_LAYER
|
||||||
|
# define TRI_LAYER_UPPER_LAYER 2
|
||||||
|
#endif
|
||||||
|
#ifndef TRI_LAYER_ADJUST_LAYER
|
||||||
|
# define TRI_LAYER_ADJUST_LAYER 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the tri layer lower layer index
|
||||||
|
*
|
||||||
|
* @param layer
|
||||||
|
*/
|
||||||
|
void set_tri_layer_lower_layer(uint8_t layer);
|
||||||
|
/**
|
||||||
|
* @brief Set the tri layer upper layer index
|
||||||
|
*
|
||||||
|
* @param layer
|
||||||
|
*/
|
||||||
|
void set_tri_layer_upper_layer(uint8_t layer);
|
||||||
|
/**
|
||||||
|
* @brief Set the tri layer adjust layer index
|
||||||
|
*
|
||||||
|
* @param layer
|
||||||
|
*/
|
||||||
|
void set_tri_layer_adjust_layer(uint8_t layer);
|
||||||
|
/**
|
||||||
|
* @brief Set the tri layer indices
|
||||||
|
*
|
||||||
|
* @param lower
|
||||||
|
* @param upper
|
||||||
|
* @param adjust
|
||||||
|
*/
|
||||||
|
void set_tri_layer_layers(uint8_t lower, uint8_t upper, uint8_t adjust);
|
||||||
|
/**
|
||||||
|
* @brief Get the tri layer lower layer index
|
||||||
|
*
|
||||||
|
* @return uint8_t
|
||||||
|
*/
|
||||||
|
uint8_t get_tri_layer_lower_layer(void);
|
||||||
|
/**
|
||||||
|
* @brief Get the tri layer upper layer index
|
||||||
|
*
|
||||||
|
* @return uint8_t
|
||||||
|
*/
|
||||||
|
uint8_t get_tri_layer_upper_layer(void);
|
||||||
|
/**
|
||||||
|
* @brief Get the tri layer adjust layer index
|
||||||
|
*
|
||||||
|
* @return uint8_t
|
||||||
|
*/
|
||||||
|
uint8_t get_tri_layer_adjust_layer(void);
|
@ -659,5 +659,7 @@ std::map<uint16_t, std::string> KEYCODE_ID_TABLE = {
|
|||||||
{QK_AUTOCORRECT_ON, "QK_AUTOCORRECT_ON"},
|
{QK_AUTOCORRECT_ON, "QK_AUTOCORRECT_ON"},
|
||||||
{QK_AUTOCORRECT_OFF, "QK_AUTOCORRECT_OFF"},
|
{QK_AUTOCORRECT_OFF, "QK_AUTOCORRECT_OFF"},
|
||||||
{QK_AUTOCORRECT_TOGGLE, "QK_AUTOCORRECT_TOGGLE"},
|
{QK_AUTOCORRECT_TOGGLE, "QK_AUTOCORRECT_TOGGLE"},
|
||||||
|
{QK_TRI_LAYER_LOWER, "QK_TRI_LAYER_LOWER"},
|
||||||
|
{QK_TRI_LAYER_UPPER, "QK_TRI_LAYER_UPPER"},
|
||||||
{SAFE_RANGE, "SAFE_RANGE"},
|
{SAFE_RANGE, "SAFE_RANGE"},
|
||||||
};
|
};
|
||||||
|
6
tests/tri_layer/config.h
Normal file
6
tests/tri_layer/config.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// Copyright 2021 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "test_common.h"
|
8
tests/tri_layer/test.mk
Normal file
8
tests/tri_layer/test.mk
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Copyright 2021 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
# Keep this file, even if it is empty, as a marker that this folder contains tests
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
TRI_LAYER_ENABLE = yes
|
103
tests/tri_layer/test_tri_layer.cpp
Normal file
103
tests/tri_layer/test_tri_layer.cpp
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// Copyright 2021 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "test_common.hpp"
|
||||||
|
|
||||||
|
using testing::_;
|
||||||
|
using testing::InSequence;
|
||||||
|
|
||||||
|
class TriLayer : public TestFixture {};
|
||||||
|
|
||||||
|
TEST_F(TriLayer, TriLayerLowerTest) {
|
||||||
|
TestDriver driver;
|
||||||
|
KeymapKey lower_layer_key = KeymapKey{0, 0, 0, QK_TRI_LAYER_LOWER};
|
||||||
|
|
||||||
|
set_keymap({lower_layer_key, KeymapKey{1, 0, 0, KC_TRNS}});
|
||||||
|
|
||||||
|
/* Press Lower. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
lower_layer_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
EXPECT_TRUE(layer_state_is(get_tri_layer_lower_layer()));
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_upper_layer()));
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_adjust_layer()));
|
||||||
|
VERIFY_AND_CLEAR(driver);
|
||||||
|
|
||||||
|
/* Release Lower. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
lower_layer_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_lower_layer()));
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_upper_layer()));
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_adjust_layer()));
|
||||||
|
VERIFY_AND_CLEAR(driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TriLayer, TriLayerUpperTest) {
|
||||||
|
TestDriver driver;
|
||||||
|
KeymapKey upper_layer_key = KeymapKey{0, 0, 0, QK_TRI_LAYER_UPPER};
|
||||||
|
|
||||||
|
set_keymap({upper_layer_key, KeymapKey{2, 0, 0, KC_TRNS}});
|
||||||
|
|
||||||
|
/* Press Raise. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
upper_layer_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_lower_layer()));
|
||||||
|
EXPECT_TRUE(layer_state_is(get_tri_layer_upper_layer()));
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_adjust_layer()));
|
||||||
|
VERIFY_AND_CLEAR(driver);
|
||||||
|
|
||||||
|
/* Release Raise. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
upper_layer_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_lower_layer()));
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_upper_layer()));
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_adjust_layer()));
|
||||||
|
VERIFY_AND_CLEAR(driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TriLayer, TriLayerAdjustTest) {
|
||||||
|
TestDriver driver;
|
||||||
|
KeymapKey lower_layer_key = KeymapKey{0, 0, 0, QK_TRI_LAYER_LOWER};
|
||||||
|
KeymapKey upper_layer_key = KeymapKey{0, 1, 0, QK_TRI_LAYER_UPPER};
|
||||||
|
|
||||||
|
set_keymap({
|
||||||
|
upper_layer_key,
|
||||||
|
lower_layer_key,
|
||||||
|
KeymapKey{1, 0, 0, KC_TRNS},
|
||||||
|
KeymapKey{1, 1, 0, KC_TRNS},
|
||||||
|
KeymapKey{2, 0, 0, KC_TRNS},
|
||||||
|
KeymapKey{2, 1, 0, KC_TRNS},
|
||||||
|
KeymapKey{3, 0, 0, KC_TRNS},
|
||||||
|
KeymapKey{3, 1, 0, KC_TRNS},
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Press Lower, then upper, and release upper and then lower. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
lower_layer_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
EXPECT_TRUE(layer_state_is(get_tri_layer_lower_layer()));
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_upper_layer()));
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_adjust_layer()));
|
||||||
|
|
||||||
|
upper_layer_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
EXPECT_TRUE(layer_state_is(get_tri_layer_lower_layer()));
|
||||||
|
EXPECT_TRUE(layer_state_is(get_tri_layer_upper_layer()));
|
||||||
|
EXPECT_TRUE(layer_state_is(get_tri_layer_adjust_layer()));
|
||||||
|
|
||||||
|
lower_layer_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_lower_layer()));
|
||||||
|
EXPECT_TRUE(layer_state_is(get_tri_layer_upper_layer()));
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_adjust_layer()));
|
||||||
|
|
||||||
|
upper_layer_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_lower_layer()));
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_upper_layer()));
|
||||||
|
EXPECT_FALSE(layer_state_is(get_tri_layer_adjust_layer()));
|
||||||
|
VERIFY_AND_CLEAR(driver);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user