Implement "hold and double tap" layer switch mode and temporarily treat every hold mode keys this way.
This commit is contained in:
@@ -48,11 +48,11 @@ static parser_error_t parseKeyStrokeAction(key_action_t *keyAction, uint8_t keyS
|
||||
static parser_error_t parseSwitchLayerAction(key_action_t *KeyAction, config_buffer_t *buffer)
|
||||
{
|
||||
uint8_t layer = ReadUInt8(buffer) + 1;
|
||||
bool isToggle = ReadBool(buffer);
|
||||
uint8_t mode = ReadBool(buffer) ? SwitchLayerMode_Toggle : SwitchLayerMode_HoldAndDoubleTapToggle;
|
||||
|
||||
KeyAction->type = KeyActionType_SwitchLayer;
|
||||
KeyAction->switchLayer.layer = layer;
|
||||
KeyAction->switchLayer.isToggle = isToggle;
|
||||
KeyAction->switchLayer.mode = mode;
|
||||
return ParserError_Success;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,12 @@
|
||||
KeystrokeType_System,
|
||||
} keystroke_type_t;
|
||||
|
||||
typedef enum {
|
||||
SwitchLayerMode_Hold,
|
||||
SwitchLayerMode_HoldAndDoubleTapToggle,
|
||||
SwitchLayerMode_Toggle,
|
||||
} switch_layer_mode_t;
|
||||
|
||||
typedef enum {
|
||||
MouseButton_Left = 1 << 0,
|
||||
MouseButton_Right = 1 << 1,
|
||||
@@ -48,7 +54,7 @@
|
||||
} ATTR_PACKED keystroke;
|
||||
serialized_mouse_action_t mouseAction;
|
||||
struct {
|
||||
bool isToggle;
|
||||
switch_layer_mode_t mode;
|
||||
uint8_t layer;
|
||||
} ATTR_PACKED switchLayer;
|
||||
struct {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "keymap.h"
|
||||
|
||||
static bool heldLayers[LAYER_COUNT];
|
||||
static bool pressedLayers[LAYER_COUNT];
|
||||
static switch_layer_mode_t pressedLayers[LAYER_COUNT];
|
||||
|
||||
void updateLayerStates(void)
|
||||
{
|
||||
@@ -18,10 +18,11 @@ void updateLayerStates(void)
|
||||
if (keyState->current) {
|
||||
key_action_t action = CurrentKeymap[LayerId_Base][slotId][keyId];
|
||||
if (action.type == KeyActionType_SwitchLayer) {
|
||||
if (!action.switchLayer.isToggle) {
|
||||
if (action.switchLayer.mode != SwitchLayerMode_Toggle) {
|
||||
heldLayers[action.switchLayer.layer] = true;
|
||||
} else if (!keyState->previous && keyState->current) {
|
||||
pressedLayers[action.switchLayer.layer] = true;
|
||||
}
|
||||
if (action.switchLayer.mode != SwitchLayerMode_Hold && !keyState->previous && keyState->current) {
|
||||
pressedLayers[action.switchLayer.layer] = action.switchLayer.mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,6 +31,7 @@ void updateLayerStates(void)
|
||||
}
|
||||
|
||||
layer_id_t PreviousHeldLayer = LayerId_Base;
|
||||
layer_id_t ToggledLayer = LayerId_Base;
|
||||
|
||||
layer_id_t GetActiveLayer()
|
||||
{
|
||||
@@ -37,22 +39,20 @@ layer_id_t GetActiveLayer()
|
||||
|
||||
// Handle toggled layers
|
||||
|
||||
static layer_id_t toggledLayer = LayerId_Base;
|
||||
|
||||
for (layer_id_t layerId=LayerId_Mod; layerId<=LayerId_Mouse; layerId++) {
|
||||
if (pressedLayers[layerId]) {
|
||||
if (toggledLayer == layerId) {
|
||||
toggledLayer = LayerId_Base;
|
||||
if (ToggledLayer == layerId) {
|
||||
ToggledLayer = LayerId_Base;
|
||||
break;
|
||||
} else if (toggledLayer == LayerId_Base) {
|
||||
toggledLayer = layerId;
|
||||
} else if (ToggledLayer == LayerId_Base && pressedLayers[layerId] == SwitchLayerMode_Toggle) {
|
||||
ToggledLayer = layerId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (toggledLayer != LayerId_Base) {
|
||||
return toggledLayer;
|
||||
if (ToggledLayer != LayerId_Base) {
|
||||
return ToggledLayer;
|
||||
}
|
||||
|
||||
// Handle held layers
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
// Variables:
|
||||
|
||||
extern layer_id_t PreviousHeldLayer;
|
||||
extern layer_id_t ToggledLayer;
|
||||
|
||||
// Functions:
|
||||
|
||||
layer_id_t GetActiveLayer();
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -132,9 +132,11 @@ void processMouseActions()
|
||||
wasMoveAction = isMoveAction;
|
||||
}
|
||||
|
||||
static layer_id_t previousLayer = LayerId_Base;
|
||||
static uint8_t basicScancodeIndex = 0;
|
||||
static uint8_t mediaScancodeIndex = 0;
|
||||
static uint8_t systemScancodeIndex = 0;
|
||||
key_state_t *doubleTapSwitchLayerKey;
|
||||
|
||||
void applyKeyAction(key_state_t *keyState, key_action_t *action)
|
||||
{
|
||||
@@ -142,6 +144,10 @@ void applyKeyAction(key_state_t *keyState, key_action_t *action)
|
||||
return;
|
||||
}
|
||||
|
||||
if (doubleTapSwitchLayerKey && doubleTapSwitchLayerKey != keyState && !keyState->previous) {
|
||||
doubleTapSwitchLayerKey = NULL;
|
||||
}
|
||||
|
||||
switch (action->type) {
|
||||
case KeyActionType_Keystroke:
|
||||
ActiveUsbBasicKeyboardReport->modifiers |= action->keystroke.modifiers;
|
||||
@@ -170,15 +176,24 @@ void applyKeyAction(key_state_t *keyState, key_action_t *action)
|
||||
case KeyActionType_Mouse:
|
||||
activeMouseStates[action->mouseAction] = true;
|
||||
break;
|
||||
case KeyActionType_SwitchLayer:
|
||||
if (!keyState->previous && previousLayer == LayerId_Base && action->switchLayer.mode == SwitchLayerMode_HoldAndDoubleTapToggle) {
|
||||
if (doubleTapSwitchLayerKey) {
|
||||
ToggledLayer = action->switchLayer.layer;
|
||||
doubleTapSwitchLayerKey = NULL;
|
||||
} else {
|
||||
doubleTapSwitchLayerKey = keyState;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KeyActionType_SwitchKeymap:
|
||||
if (!keyState->previous && keyState->current) {
|
||||
if (!keyState->previous) {
|
||||
SwitchKeymap(action->switchKeymap.keymapId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static layer_id_t previousLayer = LayerId_Base;
|
||||
static uint8_t secondaryRoleState = SecondaryRoleState_Released;
|
||||
static uint8_t secondaryRoleSlotId;
|
||||
static uint8_t secondaryRoleKeyId;
|
||||
|
||||
Reference in New Issue
Block a user