5 Commits

Author SHA1 Message Date
László Monda
6ab0c2eb72 Bump version to 8.5.4, update changelog, package.json and versions.h 2019-01-05 16:16:37 +01:00
László Monda
2e73bb9ea1 Merge pull request #203 from UltimateHackingKeyboard/sticky-modifiers
Adjust the behavior of sticky modifiers
2018-12-26 03:42:47 +01:00
Eric Tang
e5ac605b4c Adjust the behavior of sticky modiifers 2018-12-25 16:08:10 -08:00
László Monda
fb220038b7 Merge pull request #200 from kareltucek/origin_master
Feature firmware forks in readme
2018-11-18 14:44:46 +01:00
Karel Tuček
464c56f599 Feature firmware forks in Readme 2018-11-18 12:36:34 +01:00
9 changed files with 102 additions and 66 deletions

View File

@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is loosely based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) The format is loosely based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to the [UHK Versioning](VERSIONING.md) conventions. and this project adheres to the [UHK Versioning](VERSIONING.md) conventions.
## [8.5.4] - 2018-01-05
Device Protocol: 4.5.0 | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0
- Make the modifiers of shortcut keys stick only as long as the layer switcher key of a shortcut key is being held.
## [8.5.3] - 2018-10-20 ## [8.5.3] - 2018-10-20
Device Protocol: 4.5.0 | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0 Device Protocol: 4.5.0 | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0

View File

@@ -25,3 +25,10 @@ Going forward, it's easier to flash the firmware of your choice by using the dow
## Contributing ## Contributing
Want to contribute? Let us show you [how](/CONTRIBUTING.md). Want to contribute? Let us show you [how](/CONTRIBUTING.md).
## Custom Firmwares
The following list contains unofficial forks of the firmware. These forks provide functionality unavailable in the official firmware, but come without guarantees of any kind:
- [https://github.com/kareltucek/firmware](https://github.com/kareltucek/firmware) - firmware featuring macro engine extended by a set of custom commands, allowing more advanced configurations including custom layer switching logic, doubletap bindings, alternative secondary roles etc.

View File

@@ -13,7 +13,6 @@
uint8_t timestamp; uint8_t timestamp;
bool previous : 1; bool previous : 1;
bool current : 1; bool current : 1;
bool suppressed : 1;
bool debouncing : 1; bool debouncing : 1;
} key_state_t; } key_state_t;

View File

@@ -15,7 +15,7 @@ void updateLayerStates(void)
for (uint8_t slotId=0; slotId<SLOT_COUNT; slotId++) { for (uint8_t slotId=0; slotId<SLOT_COUNT; slotId++) {
for (uint8_t keyId=0; keyId<MAX_KEY_COUNT_PER_MODULE; keyId++) { for (uint8_t keyId=0; keyId<MAX_KEY_COUNT_PER_MODULE; keyId++) {
key_state_t *keyState = &KeyStates[slotId][keyId]; key_state_t *keyState = &KeyStates[slotId][keyId];
if (keyState->current && !keyState->suppressed) { if (keyState->current) {
key_action_t action = CurrentKeymap[LayerId_Base][slotId][keyId]; key_action_t action = CurrentKeymap[LayerId_Base][slotId][keyId];
if (action.type == KeyActionType_SwitchLayer) { if (action.type == KeyActionType_SwitchLayer) {
if (action.switchLayer.mode != SwitchLayerMode_Toggle) { if (action.switchLayer.mode != SwitchLayerMode_Toggle) {
@@ -70,3 +70,14 @@ layer_id_t GetActiveLayer()
return heldLayer; return heldLayer;
} }
bool IsLayerHeld(void)
{
for (layer_id_t layerId = LayerId_Mod; layerId <= LayerId_Mouse; layerId++) {
if (heldLayers[layerId]) {
return true;
}
}
return false;
}

View File

@@ -25,6 +25,7 @@
// Functions: // Functions:
layer_id_t GetActiveLayer(); layer_id_t GetActiveLayer(void);
bool IsLayerHeld(void);
#endif #endif

View File

@@ -237,72 +237,84 @@ static void handleSwitchLayerAction(key_state_t *keyState, key_action_t *action)
static uint8_t basicScancodeIndex = 0; static uint8_t basicScancodeIndex = 0;
static uint8_t mediaScancodeIndex = 0; static uint8_t mediaScancodeIndex = 0;
static uint8_t systemScancodeIndex = 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 secondaryRoleState = SecondaryRoleState_Released;
static uint8_t secondaryRoleSlotId; static uint8_t secondaryRoleSlotId;
static uint8_t secondaryRoleKeyId; static uint8_t secondaryRoleKeyId;
static secondary_role_t secondaryRole; 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) { if (keyState->current) {
return; handleSwitchLayerAction(keyState, action);
}
handleSwitchLayerAction(keyState, action); switch (action->type) {
case KeyActionType_Keystroke:
switch (action->type) { if (action->keystroke.scancode) {
case KeyActionType_Keystroke: if (!keyState->previous) {
if (action->keystroke.scancode) { stickyModifiers = action->keystroke.modifiers;
if (!keyState->previous) { stickySlotId = slotId;
stickyModifiers = action->keystroke.modifiers; stickyKeyId = keyId;
}
} else {
ActiveUsbBasicKeyboardReport->modifiers |= action->keystroke.modifiers;
} }
} else { switch (action->keystroke.keystrokeType) {
ActiveUsbBasicKeyboardReport->modifiers |= action->keystroke.modifiers; case KeystrokeType_Basic:
} if (basicScancodeIndex >= USB_BASIC_KEYBOARD_MAX_KEYS || action->keystroke.scancode == 0) {
switch (action->keystroke.keystrokeType) { break;
case KeystrokeType_Basic: }
if (basicScancodeIndex >= USB_BASIC_KEYBOARD_MAX_KEYS || action->keystroke.scancode == 0) { ActiveUsbBasicKeyboardReport->scancodes[basicScancodeIndex++] = action->keystroke.scancode;
break; break;
} case KeystrokeType_Media:
ActiveUsbBasicKeyboardReport->scancodes[basicScancodeIndex++] = action->keystroke.scancode; if (mediaScancodeIndex >= USB_MEDIA_KEYBOARD_MAX_KEYS) {
break; break;
case KeystrokeType_Media: }
if (mediaScancodeIndex >= USB_MEDIA_KEYBOARD_MAX_KEYS) { ActiveUsbMediaKeyboardReport->scancodes[mediaScancodeIndex++] = action->keystroke.scancode;
break; break;
} case KeystrokeType_System:
ActiveUsbMediaKeyboardReport->scancodes[mediaScancodeIndex++] = action->keystroke.scancode; if (systemScancodeIndex >= USB_SYSTEM_KEYBOARD_MAX_KEYS) {
break; break;
case KeystrokeType_System: }
if (systemScancodeIndex >= USB_SYSTEM_KEYBOARD_MAX_KEYS) { ActiveUsbSystemKeyboardReport->scancodes[systemScancodeIndex++] = action->keystroke.scancode;
break; 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;
} }
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;
} }
} }
@@ -394,22 +406,22 @@ static void updateActiveUsbReports(void)
secondaryRoleSlotId = slotId; secondaryRoleSlotId = slotId;
secondaryRoleKeyId = keyId; secondaryRoleKeyId = keyId;
secondaryRole = action->keystroke.secondaryRole; secondaryRole = action->keystroke.secondaryRole;
keyState->suppressed = true;
} }
} else { } else {
applyKeyAction(keyState, action); applyKeyAction(keyState, action, slotId, keyId);
} }
} else { } else {
keyState->suppressed = false;
// Release secondary role key. // Release secondary role key.
if (keyState->previous && secondaryRoleSlotId == slotId && secondaryRoleKeyId == keyId) { if (keyState->previous && secondaryRoleSlotId == slotId && secondaryRoleKeyId == keyId && secondaryRoleState != SecondaryRoleState_Released) {
// Trigger primary role. // Trigger primary role.
if (secondaryRoleState == SecondaryRoleState_Pressed) { if (secondaryRoleState == SecondaryRoleState_Pressed) {
keyState->previous = false; keyState->previous = false;
applyKeyAction(keyState, action); keyState->current = true;
applyKeyAction(keyState, action, slotId, keyId);
} }
secondaryRoleState = SecondaryRoleState_Released; secondaryRoleState = SecondaryRoleState_Released;
} else {
applyKeyAction(keyState, action, slotId, keyId);
} }
} }

View File

@@ -15,7 +15,7 @@
"commander": "^2.11.0", "commander": "^2.11.0",
"shelljs": "^0.7.8" "shelljs": "^0.7.8"
}, },
"firmwareVersion": "8.5.3", "firmwareVersion": "8.5.4",
"deviceProtocolVersion": "4.5.0", "deviceProtocolVersion": "4.5.0",
"moduleProtocolVersion": "4.0.0", "moduleProtocolVersion": "4.0.0",
"userConfigVersion": "4.1.0", "userConfigVersion": "4.1.0",

View File

@@ -20,7 +20,7 @@
#define FIRMWARE_MAJOR_VERSION 8 #define FIRMWARE_MAJOR_VERSION 8
#define FIRMWARE_MINOR_VERSION 5 #define FIRMWARE_MINOR_VERSION 5
#define FIRMWARE_PATCH_VERSION 3 #define FIRMWARE_PATCH_VERSION 4
#define DEVICE_PROTOCOL_MAJOR_VERSION 4 #define DEVICE_PROTOCOL_MAJOR_VERSION 4
#define DEVICE_PROTOCOL_MINOR_VERSION 5 #define DEVICE_PROTOCOL_MINOR_VERSION 5