diff --git a/right/src/key_states.h b/right/src/key_states.h index 66eb9b9..3e7e906 100644 --- a/right/src/key_states.h +++ b/right/src/key_states.h @@ -13,7 +13,6 @@ uint8_t timestamp; bool previous : 1; bool current : 1; - bool suppressed : 1; bool debouncing : 1; } key_state_t; diff --git a/right/src/layer.c b/right/src/layer.c index 0d99520..6de1591 100644 --- a/right/src/layer.c +++ b/right/src/layer.c @@ -15,7 +15,7 @@ void updateLayerStates(void) for (uint8_t slotId=0; slotIdcurrent && !keyState->suppressed) { + if (keyState->current) { key_action_t action = CurrentKeymap[LayerId_Base][slotId][keyId]; if (action.type == KeyActionType_SwitchLayer) { if (action.switchLayer.mode != SwitchLayerMode_Toggle) { @@ -70,3 +70,14 @@ layer_id_t GetActiveLayer() return heldLayer; } + +bool IsLayerHeld(void) +{ + for (layer_id_t layerId = LayerId_Mod; layerId <= LayerId_Mouse; layerId++) { + if (heldLayers[layerId]) { + return true; + } + } + + return false; +} diff --git a/right/src/layer.h b/right/src/layer.h index 9828ccd..d981c7f 100644 --- a/right/src/layer.h +++ b/right/src/layer.h @@ -25,6 +25,7 @@ // Functions: - layer_id_t GetActiveLayer(); + layer_id_t GetActiveLayer(void); + bool IsLayerHeld(void); #endif diff --git a/right/src/usb_report_updater.c b/right/src/usb_report_updater.c index c5f8022..d2e3199 100644 --- a/right/src/usb_report_updater.c +++ b/right/src/usb_report_updater.c @@ -237,72 +237,84 @@ static void handleSwitchLayerAction(key_state_t *keyState, key_action_t *action) static uint8_t basicScancodeIndex = 0; static uint8_t mediaScancodeIndex = 0; static uint8_t systemScancodeIndex = 0; -static uint8_t stickyModifiers; +static uint8_t stickyModifiers, stickySlotId, stickyKeyId; static uint8_t secondaryRoleState = SecondaryRoleState_Released; static uint8_t secondaryRoleSlotId; static uint8_t secondaryRoleKeyId; static secondary_role_t secondaryRole; -static void applyKeyAction(key_state_t *keyState, key_action_t *action) +static void applyKeyAction(key_state_t *keyState, key_action_t *action, uint8_t slotId, uint8_t keyId) { - if (keyState->suppressed) { - return; - } + if (keyState->current) { + handleSwitchLayerAction(keyState, action); - handleSwitchLayerAction(keyState, action); - - switch (action->type) { - case KeyActionType_Keystroke: - if (action->keystroke.scancode) { - if (!keyState->previous) { - stickyModifiers = action->keystroke.modifiers; + switch (action->type) { + case KeyActionType_Keystroke: + if (action->keystroke.scancode) { + if (!keyState->previous) { + stickyModifiers = action->keystroke.modifiers; + stickySlotId = slotId; + stickyKeyId = keyId; + } + } else { + ActiveUsbBasicKeyboardReport->modifiers |= action->keystroke.modifiers; } - } else { - ActiveUsbBasicKeyboardReport->modifiers |= action->keystroke.modifiers; - } - switch (action->keystroke.keystrokeType) { - case KeystrokeType_Basic: - if (basicScancodeIndex >= USB_BASIC_KEYBOARD_MAX_KEYS || action->keystroke.scancode == 0) { + switch (action->keystroke.keystrokeType) { + case KeystrokeType_Basic: + if (basicScancodeIndex >= USB_BASIC_KEYBOARD_MAX_KEYS || action->keystroke.scancode == 0) { + break; + } + ActiveUsbBasicKeyboardReport->scancodes[basicScancodeIndex++] = action->keystroke.scancode; break; - } - ActiveUsbBasicKeyboardReport->scancodes[basicScancodeIndex++] = action->keystroke.scancode; - break; - case KeystrokeType_Media: - if (mediaScancodeIndex >= USB_MEDIA_KEYBOARD_MAX_KEYS) { + case KeystrokeType_Media: + if (mediaScancodeIndex >= USB_MEDIA_KEYBOARD_MAX_KEYS) { + break; + } + ActiveUsbMediaKeyboardReport->scancodes[mediaScancodeIndex++] = action->keystroke.scancode; break; - } - ActiveUsbMediaKeyboardReport->scancodes[mediaScancodeIndex++] = action->keystroke.scancode; - break; - case KeystrokeType_System: - if (systemScancodeIndex >= USB_SYSTEM_KEYBOARD_MAX_KEYS) { + case KeystrokeType_System: + if (systemScancodeIndex >= USB_SYSTEM_KEYBOARD_MAX_KEYS) { + break; + } + ActiveUsbSystemKeyboardReport->scancodes[systemScancodeIndex++] = action->keystroke.scancode; break; + } + break; + case KeyActionType_Mouse: + if (!keyState->previous) { + stickyModifiers = 0; + } + activeMouseStates[action->mouseAction] = true; + break; + case KeyActionType_SwitchLayer: + // Handled by handleSwitchLayerAction() + break; + case KeyActionType_SwitchKeymap: + if (!keyState->previous) { + stickyModifiers = 0; + secondaryRoleState = SecondaryRoleState_Released; + SwitchKeymapById(action->switchKeymap.keymapId); + } + break; + case KeyActionType_PlayMacro: + if (!keyState->previous) { + stickyModifiers = 0; + Macros_StartMacro(action->playMacro.macroId); + } + break; + } + } else { + switch (action->type) { + case KeyActionType_Keystroke: + if (keyState->previous) { + if (slotId == stickySlotId && keyId == stickyKeyId) { + if (!IsLayerHeld() && !(secondaryRoleState == SecondaryRoleState_Triggered && IS_SECONDARY_ROLE_LAYER_SWITCHER(secondaryRole))) { + stickyModifiers = 0; + } } - ActiveUsbSystemKeyboardReport->scancodes[systemScancodeIndex++] = action->keystroke.scancode; - break; - } - break; - case KeyActionType_Mouse: - if (!keyState->previous) { - stickyModifiers = 0; - } - activeMouseStates[action->mouseAction] = true; - break; - case KeyActionType_SwitchLayer: - // Handled by handleSwitchLayerAction() - break; - case KeyActionType_SwitchKeymap: - if (!keyState->previous) { - stickyModifiers = 0; - secondaryRoleState = SecondaryRoleState_Released; - SwitchKeymapById(action->switchKeymap.keymapId); - } - break; - case KeyActionType_PlayMacro: - if (!keyState->previous) { - stickyModifiers = 0; - Macros_StartMacro(action->playMacro.macroId); - } - break; + } + break; + } } } @@ -394,22 +406,22 @@ static void updateActiveUsbReports(void) secondaryRoleSlotId = slotId; secondaryRoleKeyId = keyId; secondaryRole = action->keystroke.secondaryRole; - keyState->suppressed = true; } } else { - applyKeyAction(keyState, action); + applyKeyAction(keyState, action, slotId, keyId); } } else { - keyState->suppressed = false; - // Release secondary role key. - if (keyState->previous && secondaryRoleSlotId == slotId && secondaryRoleKeyId == keyId) { + if (keyState->previous && secondaryRoleSlotId == slotId && secondaryRoleKeyId == keyId && secondaryRoleState != SecondaryRoleState_Released) { // Trigger primary role. if (secondaryRoleState == SecondaryRoleState_Pressed) { keyState->previous = false; - applyKeyAction(keyState, action); + keyState->current = true; + applyKeyAction(keyState, action, slotId, keyId); } secondaryRoleState = SecondaryRoleState_Released; + } else { + applyKeyAction(keyState, action, slotId, keyId); } }