@ -44,6 +44,8 @@ uint16_t OneShot::stickable_keys_ = -1;
bool OneShot : : auto_modifiers_ = false ;
bool OneShot : : auto_layers_ = false ;
KeyAddr OneShot : : meta_sticky_key_addr_ = KeyAddr { KeyAddr : : invalid_state } ;
KeyAddrBitfield OneShot : : temp_addrs_ ;
KeyAddrBitfield OneShot : : glue_addrs_ ;
@ -140,6 +142,8 @@ bool OneShot::isStickable(Key key) {
if ( n < oneshot_key_count ) {
return bitRead ( stickable_keys_ , n ) ;
}
} else if ( key = = OneShot_MetaStickyKey ) {
return true ;
}
return false ;
}
@ -202,13 +206,40 @@ EventHandlerResult OneShot::onKeyswitchEvent(
if ( ! temp & & ! glue ) {
// This key_addr is not in a OneShot state.
if ( isOneShotKey ( key ) | |
if ( meta_sticky_key_addr_ . isValid ( ) ) {
// If the meta key isn't sticky, release it
bool ms_temp = temp_addrs_ . read ( meta_sticky_key_addr_ ) ;
bool ms_glue = glue_addrs_ . read ( meta_sticky_key_addr_ ) ;
if ( ms_temp ) {
if ( ms_glue ) {
// ms key is temp one-shot
releaseKey ( meta_sticky_key_addr_ ) ;
meta_sticky_key_addr_ = KeyAddr { KeyAddr : : invalid_state } ;
} else {
// ms key is held
temp_addrs_ . clear ( meta_sticky_key_addr_ ) ;
}
} else {
// ms key is sticky
}
glue_addrs_ . set ( key_addr ) ;
//prev_key_addr_ = key_addr;
start_time_ = Runtime . millisAtCycleStart ( ) ;
//return EventHandlerResult::OK;
} else if ( key = = OneShot_MetaStickyKey ) {
meta_sticky_key_addr_ = key_addr ;
temp_addrs_ . set ( key_addr ) ;
start_time_ = Runtime . millisAtCycleStart ( ) ;
} else if ( isOneShotKey ( key ) | |
( auto_modifiers_ & & isModifier ( key ) ) | |
( auto_layers_ & & isLayerShift ( key ) ) ) {
// Replace the OneShot key with its corresponding normal key.
pressKey ( key_addr , key ) ;
return EventHandlerResult : : ABORT ;
} else if ( ! isModifier ( key ) & & ! isLayerShift ( key ) ) {
// Only trigger release of temporary OneShot keys if the
// pressed key is neither a modifier nor a layer shift.
release_countdown_ = ( 1 < < 1 ) ;
@ -246,6 +277,9 @@ EventHandlerResult OneShot::onKeyswitchEvent(
// This is a sticky OneShot key that has been pressed. Clear
// state now, so it will become a normal key.
glue_addrs_ . clear ( key_addr ) ;
// Then replace the key toggled on event with a key held event.
holdKey ( key_addr ) ;
return EventHandlerResult : : EVENT_CONSUMED ;
} else { // (temp && !glue)
// A key has been pressed that is in the "pending" OneShot
@ -273,6 +307,9 @@ EventHandlerResult OneShot::onKeyswitchEvent(
// `beforeReportingState()` hook below.
//Layer.updateLiveCompositeKeymap(key_addr, key);
return EventHandlerResult : : ABORT ;
} else if ( key = = OneShot_MetaStickyKey ) {
meta_sticky_key_addr_ = KeyAddr { KeyAddr : : invalid_state } ;
//cancel(true);
}
} else {
@ -404,6 +441,10 @@ void OneShot::holdKey(KeyAddr key_addr) {
void OneShot : : releaseKey ( KeyAddr key_addr ) {
glue_addrs_ . clear ( key_addr ) ;
temp_addrs_ . clear ( key_addr ) ;
if ( live_keys [ key_addr ] = = OneShot_MetaStickyKey )
meta_sticky_key_addr_ = KeyAddr { KeyAddr : : invalid_state } ;
handleKeyswitchEvent ( Key_NoKey , key_addr , WAS_PRESSED | INJECTED ) ;
}