bShouldBeIgnored prematurely cleared after FlushPressedKeys in Enhanced Input

Hello,

We are experiencing an issue where a phantom Started event is intermittently fired when adding an IMC in a gamepad environment. This occurs when FlushPressedKeys() is called after adding an IMC while the key is still physically held (e.g., via a Hold trigger’s Triggered event).

We believe the cause is that the bShouldBeIgnored check in UEnhancedPlayerInput::EvaluateInputDelegates (EnhancedPlayerInput.cpp) only checks bDown:

if(Mapping.bShouldBeIgnored && KeyState)
{
   if(KeyState->bDown)
   {
     continue;
   }
   else
   {
     Mapping.bShouldBeIgnored = false;
   }
 }

FlushPressedKeys sets bDown=false without generating an IE_Released event. This code treats the logical release the same as a physical user release, prematurely clearing bShouldBeIgnored. When bAutoReconcilePressedEventsOnFirstRepeat subsequently restores bDown=true via IE_Repeat, the mapping is no longer protected.

The reason this issue is intermittent depends on whether OS IE_Repeat arrives before the next EvaluateInputDelegates tick. Gamepads have a longer polling interval than keyboards, making this issue more likely to occur.

Normal case:

  1. Frame N : AddMappingContext → bShouldBeIgnored=true → FlushPressedKeys → bDown=false
  2. Frame N+1: OS IE_Repeat arrives → AutoReconcile → bDown=true
  3. Frame N+1: EvaluateInputDelegates → bDown=true → continue (protected)

Phantom case:

  1. Frame N : AddMappingContext → bShouldBeIgnored=true → FlushPressedKeys → bDown=false
  2. Frame N+1: OS IE_Repeat not yet arrived → bDown=false
  3. Frame N+1: EvaluateInputDelegates → bDown=false → bShouldBeIgnored cleared
  4. Frame N+K: OS IE_Repeat arrives → AutoReconcile → bDown=true
  5. Frame N+K: EvaluateInputDelegates → bShouldBeIgnored=false → phantom Started

We are planning to apply the following fix in our project:

if(KeyState->bDown || KeyState->bWasJustFlushed)
{
   continue;
 }

bWasJustFlushed is set to true after FlushPressedKeys, and is only reset to false when InputKey(PlayerInput.cpp) processes the first OS event for that key. This defers the clearing of bShouldBeIgnored until an actual OS event arrives, preventing premature clearing.

Is this the right approach, or is there a better way to distinguish a FlushPressedKeys reset from a natural release in this context?

Thank you.

ReproProject.zip(59.6 KB)

재현 방법
1. Hold gamepad B button to trigger “IA_OpenWidget” (Hold trigger)

2. On IA_OpenWidget Triggered, add WBP_Dummy widget and call AddMappingContext with bForceImmediately=true, bIgnoreAllPressedKeysUntilRelease=true

(bShouldBeIgnored=true)

3. Game logic causes FlushPressedKeys to be called (e.g. viewport focus loss due to widget focus) (bDown=false)

4. On the next frame, EvaluateInputDelegates sees bDown=false and clears bShouldBeIgnored

5. When OS IE_Repeat arrives a few frames later, bAutoReconcilePressedEventsOnFirstRepeat injects IE_Pressed → bDown=true

6. Since bShouldBeIgnored is already cleared, the action instance fires a phantom Started

Hi there! Thank you for this details repro case and project. I have filed https://issues.unrealengine.com/issue/UE\-372464, which you will be able to see once it goes live.

Your proposed fix looks reasonable to me and I don’t think would cause any issues.

Thanks again!

Thanks for the help. We can close this ticket now.