mirror of
https://github.com/Keychron/qmk_firmware.git
synced 2024-12-12 13:17:38 +06:00
[Feature] Add keycode PDF(layer) to set the default layer in EEPROM (#24630)
* [Feature] Add keycode PDF(layer) to set the default layer in EEPROM (#21881) * Apply suggestions from code review Co-authored-by: Nick Brassel <nick@tzarc.org> --------- Co-authored-by: Nebuleon <2391500+Nebuleon@users.noreply.github.com> Co-authored-by: Nick Brassel <nick@tzarc.org>
This commit is contained in:
parent
9e9b4acbde
commit
4a5bae51cd
|
@ -28,6 +28,7 @@ QUANTUM_SRC += \
|
||||||
$(QUANTUM_DIR)/sync_timer.c \
|
$(QUANTUM_DIR)/sync_timer.c \
|
||||||
$(QUANTUM_DIR)/logging/debug.c \
|
$(QUANTUM_DIR)/logging/debug.c \
|
||||||
$(QUANTUM_DIR)/logging/sendchar.c \
|
$(QUANTUM_DIR)/logging/sendchar.c \
|
||||||
|
$(QUANTUM_DIR)/process_keycode/process_default_layer.c \
|
||||||
|
|
||||||
VPATH += $(QUANTUM_DIR)/logging
|
VPATH += $(QUANTUM_DIR)/logging
|
||||||
# Fall back to lib/printf if there is no platform provided print
|
# Fall back to lib/printf if there is no platform provided print
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"ranges": {
|
||||||
|
"0x52E0/0x001F": {
|
||||||
|
"define": "QK_PERSISTENT_DEF_LAYER"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,8 @@ For a detailed explanation of how the layer stack works, checkout [Keymap Overvi
|
||||||
|
|
||||||
These functions allow you to activate layers in various ways. Note that layers are not generally independent layouts -- multiple layers can be activated at once, and it's typical for layers to use `KC_TRNS` to allow keypresses to pass through to lower layers. When using momentary layer switching with MO(), LM(), TT(), or LT(), make sure to leave the key on the above layers transparent or it may not work as intended.
|
These functions allow you to activate layers in various ways. Note that layers are not generally independent layouts -- multiple layers can be activated at once, and it's typical for layers to use `KC_TRNS` to allow keypresses to pass through to lower layers. When using momentary layer switching with MO(), LM(), TT(), or LT(), make sure to leave the key on the above layers transparent or it may not work as intended.
|
||||||
|
|
||||||
* `DF(layer)` - switches the default layer. The default layer is the always-active base layer that other layers stack on top of. See below for more about the default layer. This might be used to switch from QWERTY to Dvorak layout. (Note that this is a temporary switch that only persists until the keyboard loses power. To modify the default layer in a persistent way requires deeper customization, such as calling the `set_single_persistent_default_layer` function inside of [process_record_user](custom_quantum_functions#programming-the-behavior-of-any-keycode).)
|
* `DF(layer)` - switches the default layer. The default layer is the always-active base layer that other layers stack on top of. See below for more about the default layer. This might be used to switch from QWERTY to Dvorak layout. Note that this is a temporary switch that only persists until the keyboard loses power.
|
||||||
|
* `PDF(layer)` - sets a persistent default layer. This switch, which will last through a power loss, might be used to switch from QWERTY to Dvorak layout and only switch again when you want to.
|
||||||
* `MO(layer)` - momentarily activates *layer*. As soon as you let go of the key, the layer is deactivated.
|
* `MO(layer)` - momentarily activates *layer*. As soon as you let go of the key, the layer is deactivated.
|
||||||
* `LM(layer, mod)` - Momentarily activates *layer* (like `MO`), but with modifier(s) *mod* active. Only supports layers 0-15. The modifiers this keycode accept are prefixed with `MOD_`, not `KC_`. These modifiers can be combined using bitwise OR, e.g. `LM(_RAISE, MOD_LCTL | MOD_LALT)`.
|
* `LM(layer, mod)` - Momentarily activates *layer* (like `MO`), but with modifier(s) *mod* active. Only supports layers 0-15. The modifiers this keycode accept are prefixed with `MOD_`, not `KC_`. These modifiers can be combined using bitwise OR, e.g. `LM(_RAISE, MOD_LCTL | MOD_LALT)`.
|
||||||
* `LT(layer, kc)` - momentarily activates *layer* when held, and sends *kc* when tapped. Only supports layers 0-15.
|
* `LT(layer, kc)` - momentarily activates *layer* when held, and sends *kc* when tapped. Only supports layers 0-15.
|
||||||
|
|
|
@ -401,7 +401,8 @@ See also: [Layer Switching](feature_layers#switching-and-toggling-layers)
|
||||||
|
|
||||||
|Key |Description |
|
|Key |Description |
|
||||||
|----------------|----------------------------------------------------------------------------------|
|
|----------------|----------------------------------------------------------------------------------|
|
||||||
|`DF(layer)` |Set the base (default) layer |
|
|`DF(layer)` |Set the base (default) layer until the keyboard loses power |
|
||||||
|
|`PDF(layer)` |Set the base (default) layer in EEPROM |
|
||||||
|`MO(layer)` |Momentarily turn on `layer` when pressed (requires `KC_TRNS` on destination layer)|
|
|`MO(layer)` |Momentarily turn on `layer` when pressed (requires `KC_TRNS` on destination layer)|
|
||||||
|`OSL(layer)` |Momentarily activates `layer` until a key is pressed. See [One Shot Keys](one_shot_keys) for details. |
|
|`OSL(layer)` |Momentarily activates `layer` until a key is pressed. See [One Shot Keys](one_shot_keys) for details. |
|
||||||
|`LM(layer, mod)`|Momentarily turn on `layer` (like MO) with `mod` active as well. Where `mod` is a mods_bit. Mods can be viewed [here](mod_tap). Example Implementation: `LM(LAYER_1, MOD_LALT)`|
|
|`LM(layer, mod)`|Momentarily turn on `layer` (like MO) with `mod` active as well. Where `mod` is a mods_bit. Mods can be viewed [here](mod_tap). Example Implementation: `LM(LAYER_1, MOD_LALT)`|
|
||||||
|
|
|
@ -275,6 +275,7 @@ bool music_mask_kb(uint16_t keycode) {
|
||||||
case QK_TO ... QK_TO_MAX:
|
case QK_TO ... QK_TO_MAX:
|
||||||
case QK_MOMENTARY ... QK_MOMENTARY_MAX:
|
case QK_MOMENTARY ... QK_MOMENTARY_MAX:
|
||||||
case QK_DEF_LAYER ... QK_DEF_LAYER_MAX:
|
case QK_DEF_LAYER ... QK_DEF_LAYER_MAX:
|
||||||
|
case QK_PERSISTENT_DEF_LAYER ... QK_PERSISTENT_DEF_LAYER_MAX:
|
||||||
case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX:
|
case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX:
|
||||||
case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
|
case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
|
||||||
case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX:
|
case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX:
|
||||||
|
|
|
@ -237,6 +237,7 @@ bool music_mask_kb(uint16_t keycode) {
|
||||||
case QK_TO ... QK_TO_MAX:
|
case QK_TO ... QK_TO_MAX:
|
||||||
case QK_MOMENTARY ... QK_MOMENTARY_MAX:
|
case QK_MOMENTARY ... QK_MOMENTARY_MAX:
|
||||||
case QK_DEF_LAYER ... QK_DEF_LAYER_MAX:
|
case QK_DEF_LAYER ... QK_DEF_LAYER_MAX:
|
||||||
|
case QK_PERSISTENT_DEF_LAYER ... QK_PERSISTENT_DEF_LAYER_MAX:
|
||||||
case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX:
|
case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX:
|
||||||
case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
|
case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
|
||||||
case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX:
|
case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX:
|
||||||
|
|
|
@ -52,6 +52,8 @@ enum qk_keycode_ranges {
|
||||||
QK_ONE_SHOT_MOD_MAX = 0x52BF,
|
QK_ONE_SHOT_MOD_MAX = 0x52BF,
|
||||||
QK_LAYER_TAP_TOGGLE = 0x52C0,
|
QK_LAYER_TAP_TOGGLE = 0x52C0,
|
||||||
QK_LAYER_TAP_TOGGLE_MAX = 0x52DF,
|
QK_LAYER_TAP_TOGGLE_MAX = 0x52DF,
|
||||||
|
QK_PERSISTENT_DEF_LAYER = 0x52E0,
|
||||||
|
QK_PERSISTENT_DEF_LAYER_MAX = 0x52FF,
|
||||||
QK_SWAP_HANDS = 0x5600,
|
QK_SWAP_HANDS = 0x5600,
|
||||||
QK_SWAP_HANDS_MAX = 0x56FF,
|
QK_SWAP_HANDS_MAX = 0x56FF,
|
||||||
QK_TAP_DANCE = 0x5700,
|
QK_TAP_DANCE = 0x5700,
|
||||||
|
@ -1462,6 +1464,7 @@ enum qk_keycode_defines {
|
||||||
#define IS_QK_ONE_SHOT_LAYER(code) ((code) >= QK_ONE_SHOT_LAYER && (code) <= QK_ONE_SHOT_LAYER_MAX)
|
#define IS_QK_ONE_SHOT_LAYER(code) ((code) >= QK_ONE_SHOT_LAYER && (code) <= QK_ONE_SHOT_LAYER_MAX)
|
||||||
#define IS_QK_ONE_SHOT_MOD(code) ((code) >= QK_ONE_SHOT_MOD && (code) <= QK_ONE_SHOT_MOD_MAX)
|
#define IS_QK_ONE_SHOT_MOD(code) ((code) >= QK_ONE_SHOT_MOD && (code) <= QK_ONE_SHOT_MOD_MAX)
|
||||||
#define IS_QK_LAYER_TAP_TOGGLE(code) ((code) >= QK_LAYER_TAP_TOGGLE && (code) <= QK_LAYER_TAP_TOGGLE_MAX)
|
#define IS_QK_LAYER_TAP_TOGGLE(code) ((code) >= QK_LAYER_TAP_TOGGLE && (code) <= QK_LAYER_TAP_TOGGLE_MAX)
|
||||||
|
#define IS_QK_PERSISTENT_DEF_LAYER(code) ((code) >= QK_PERSISTENT_DEF_LAYER && (code) <= QK_PERSISTENT_DEF_LAYER_MAX)
|
||||||
#define IS_QK_SWAP_HANDS(code) ((code) >= QK_SWAP_HANDS && (code) <= QK_SWAP_HANDS_MAX)
|
#define IS_QK_SWAP_HANDS(code) ((code) >= QK_SWAP_HANDS && (code) <= QK_SWAP_HANDS_MAX)
|
||||||
#define IS_QK_TAP_DANCE(code) ((code) >= QK_TAP_DANCE && (code) <= QK_TAP_DANCE_MAX)
|
#define IS_QK_TAP_DANCE(code) ((code) >= QK_TAP_DANCE && (code) <= QK_TAP_DANCE_MAX)
|
||||||
#define IS_QK_MAGIC(code) ((code) >= QK_MAGIC && (code) <= QK_MAGIC_MAX)
|
#define IS_QK_MAGIC(code) ((code) >= QK_MAGIC && (code) <= QK_MAGIC_MAX)
|
||||||
|
|
|
@ -357,6 +357,8 @@ bool process_auto_mouse(uint16_t keycode, keyrecord_t* record) {
|
||||||
}
|
}
|
||||||
// DF ---------------------------------------------------------------------------------------------------------
|
// DF ---------------------------------------------------------------------------------------------------------
|
||||||
case QK_DEF_LAYER ... QK_DEF_LAYER_MAX:
|
case QK_DEF_LAYER ... QK_DEF_LAYER_MAX:
|
||||||
|
// PDF --------------------------------------------------------------------------------------------------------
|
||||||
|
case QK_PERSISTENT_DEF_LAYER ... QK_PERSISTENT_DEF_LAYER_MAX:
|
||||||
# ifndef NO_ACTION_ONESHOT
|
# ifndef NO_ACTION_ONESHOT
|
||||||
// OSL((AUTO_MOUSE_TARGET_LAYER))------------------------------------------------------------------------------
|
// OSL((AUTO_MOUSE_TARGET_LAYER))------------------------------------------------------------------------------
|
||||||
case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
|
case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
|
||||||
|
|
|
@ -98,6 +98,7 @@ bool process_autocorrect_default_handler(uint16_t *keycode, keyrecord_t *record,
|
||||||
case QK_TO ... QK_TO_MAX:
|
case QK_TO ... QK_TO_MAX:
|
||||||
case QK_MOMENTARY ... QK_MOMENTARY_MAX:
|
case QK_MOMENTARY ... QK_MOMENTARY_MAX:
|
||||||
case QK_DEF_LAYER ... QK_DEF_LAYER_MAX:
|
case QK_DEF_LAYER ... QK_DEF_LAYER_MAX:
|
||||||
|
case QK_PERSISTENT_DEF_LAYER ... QK_PERSISTENT_DEF_LAYER_MAX:
|
||||||
case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX:
|
case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX:
|
||||||
case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
|
case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
|
||||||
case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX:
|
case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX:
|
||||||
|
|
32
quantum/process_keycode/process_default_layer.c
Normal file
32
quantum/process_keycode/process_default_layer.c
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/* Copyright 2023 Nebuleon
|
||||||
|
*
|
||||||
|
* 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, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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 "process_default_layer.h"
|
||||||
|
#include "quantum.h"
|
||||||
|
#include "quantum_keycodes.h"
|
||||||
|
|
||||||
|
#if !defined(NO_ACTION_LAYER)
|
||||||
|
|
||||||
|
bool process_default_layer(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
if (IS_QK_PERSISTENT_DEF_LAYER(keycode) && !record->event.pressed) {
|
||||||
|
uint8_t layer = QK_PERSISTENT_DEF_LAYER_GET_LAYER(keycode);
|
||||||
|
set_single_persistent_default_layer(layer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !defined(NO_ACTION_LAYER)
|
27
quantum/process_keycode/process_default_layer.h
Normal file
27
quantum/process_keycode/process_default_layer.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/* Copyright 2023 Nebuleon
|
||||||
|
*
|
||||||
|
* 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, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "action.h"
|
||||||
|
|
||||||
|
#if !defined(NO_ACTION_LAYER)
|
||||||
|
|
||||||
|
bool process_default_layer(uint16_t keycode, keyrecord_t *record);
|
||||||
|
|
||||||
|
#endif // !defined(NO_ACTION_LAYER)
|
|
@ -52,6 +52,10 @@
|
||||||
# include "process_midi.h"
|
# include "process_midi.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(NO_ACTION_LAYER)
|
||||||
|
# include "process_default_layer.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PROGRAMMABLE_BUTTON_ENABLE
|
#ifdef PROGRAMMABLE_BUTTON_ENABLE
|
||||||
# include "process_programmable_button.h"
|
# include "process_programmable_button.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -404,6 +408,9 @@ bool process_record_quantum(keyrecord_t *record) {
|
||||||
#ifdef TRI_LAYER_ENABLE
|
#ifdef TRI_LAYER_ENABLE
|
||||||
process_tri_layer(keycode, record) &&
|
process_tri_layer(keycode, record) &&
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(NO_ACTION_LAYER)
|
||||||
|
process_default_layer(keycode, record) &&
|
||||||
|
#endif
|
||||||
#ifdef LAYER_LOCK_ENABLE
|
#ifdef LAYER_LOCK_ENABLE
|
||||||
process_layer_lock(keycode, record) &&
|
process_layer_lock(keycode, record) &&
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -92,6 +92,10 @@
|
||||||
#define DF(layer) (QK_DEF_LAYER | ((layer)&0x1F))
|
#define DF(layer) (QK_DEF_LAYER | ((layer)&0x1F))
|
||||||
#define QK_DEF_LAYER_GET_LAYER(kc) ((kc)&0x1F)
|
#define QK_DEF_LAYER_GET_LAYER(kc) ((kc)&0x1F)
|
||||||
|
|
||||||
|
// Set persistent default layer - 32 layer max
|
||||||
|
#define PDF(layer) (QK_PERSISTENT_DEF_LAYER | ((layer)&0x1F))
|
||||||
|
#define QK_PERSISTENT_DEF_LAYER_GET_LAYER(kc) ((kc)&0x1F)
|
||||||
|
|
||||||
// Toggle to layer - 32 layer max
|
// Toggle to layer - 32 layer max
|
||||||
#define TG(layer) (QK_TOGGLE_LAYER | ((layer)&0x1F))
|
#define TG(layer) (QK_TOGGLE_LAYER | ((layer)&0x1F))
|
||||||
#define QK_TOGGLE_LAYER_GET_LAYER(kc) ((kc)&0x1F)
|
#define QK_TOGGLE_LAYER_GET_LAYER(kc) ((kc)&0x1F)
|
||||||
|
|
|
@ -94,6 +94,8 @@ std::string generate_identifier(uint16_t kc) {
|
||||||
s << "MO(" << +QK_MOMENTARY_GET_LAYER(kc) << ")";
|
s << "MO(" << +QK_MOMENTARY_GET_LAYER(kc) << ")";
|
||||||
} else if (IS_QK_DEF_LAYER(kc)) {
|
} else if (IS_QK_DEF_LAYER(kc)) {
|
||||||
s << "DF(" << +QK_DEF_LAYER_GET_LAYER(kc) << ")";
|
s << "DF(" << +QK_DEF_LAYER_GET_LAYER(kc) << ")";
|
||||||
|
} else if (IS_QK_PERSISTENT_DEF_LAYER(kc)) {
|
||||||
|
s << "PDF(" << +QK_PERSISTENT_DEF_LAYER_GET_LAYER(kc) << ")";
|
||||||
} else if (IS_QK_TOGGLE_LAYER(kc)) {
|
} else if (IS_QK_TOGGLE_LAYER(kc)) {
|
||||||
s << "TG(" << +QK_TOGGLE_LAYER_GET_LAYER(kc) << ")";
|
s << "TG(" << +QK_TOGGLE_LAYER_GET_LAYER(kc) << ")";
|
||||||
} else if (IS_QK_LAYER_TAP_TOGGLE(kc)) {
|
} else if (IS_QK_LAYER_TAP_TOGGLE(kc)) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user