diff --git a/right/src/config_parser/parse_keymap.c b/right/src/config_parser/parse_keymap.c index 691ef91..4517bf9 100644 --- a/right/src/config_parser/parse_keymap.c +++ b/right/src/config_parser/parse_keymap.c @@ -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; } diff --git a/right/src/key_action.h b/right/src/key_action.h index 5e09be6..dae70fe 100644 --- a/right/src/key_action.h +++ b/right/src/key_action.h @@ -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 { diff --git a/right/src/layer.c b/right/src/layer.c index fc8b138..b012079 100644 --- a/right/src/layer.c +++ b/right/src/layer.c @@ -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 diff --git a/right/src/layer.h b/right/src/layer.h index c084bff..9828ccd 100644 --- a/right/src/layer.h +++ b/right/src/layer.h @@ -21,10 +21,10 @@ // Variables: extern layer_id_t PreviousHeldLayer; + extern layer_id_t ToggledLayer; // Functions: layer_id_t GetActiveLayer(); - #endif diff --git a/right/src/usb_report_updater.c b/right/src/usb_report_updater.c index 31c3cbf..3b1f15c 100644 --- a/right/src/usb_report_updater.c +++ b/right/src/usb_report_updater.c @@ -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;