CommonUI Focus Loss Due to Spurious WM_MOUSEMOVE Messages

Hello!

Since switching to UE 5.1 and CommonUI we’ve been seeing an issue where some players would frequently get stuck on random screens while playing on Windows with a gamepad while others players have no issues at all. When the problem occurs gamepad input would still be active and the correct button widget would appear hovered/focused, but pressing the accept button on gamepad would just do nothing. Some combination of alt+tabbing, spamming directional input on gamepad, or just using mouse would then be needed to get unstuck.

I’ve been poking at this for years and think I finally have an idea of what’s going on - if Windows sends a bunch of WM_MOUSEMOVE events without the platform cursor having actually moved, Slate will switch back to using the platform cursor (see FSlateApplication::OnMouseMove) while CommonUI will continue using the faux internal cursor (see FCommonInputPreprocessor::HandleMouseMoveEvent). Pressing accept on gamepad will then cause a fake mouse click to be generated at the platform cursor’s position instead of the faux internal cursor’s position (see FAnalogCursor::HandleKeyDownEvent via FCommonAnalogCursor), which means we’re basically clicking on a random location on the screen until you actually do something to cause CommonUI to cycle the active input type from & back into Gamepad.

The reason this is happening for some players and not others is because external programs can cause spurious WM_MOUSEMOVE events to be generated even when the mouse hasn’t actually moved! Here’s some relevant linkage on that:

This was briefly touched upon in [another [Content removed] but the suggested workaround of always forcing the faux cursor back on when gamepad input is received doesn’t fix our issue as it won’t move the faux cursor where it needs to be before the fake click event is sent. Instead I think we want to update FSlateApplication::OnMouseMove so it doesn’t ever use the faux cursor and specifically checks if the platform cursor moved before attempting to switch Slate back to using it (see attached diff).

Does this all make sense and seem like a reasonable fix? It seems to be working locally for me, but this is pretty low level so I wanted to confirm and see if you guys agree before moving forward with it.

Thanks!

Steps to Reproduce

On Windows do the following…

  1. Acquire UE 5.5 and the LyraStarterGame.uproject (we’re using locally built from Perforce, but this happens with the Epic Launcher version too)
  2. Open LyraStarterGame.uproject
  3. Open the L_LyraFrontEnd map
  4. Connect an XInput gamepad
  5. Outside of the editor, open the Windows Resource Monitor program (this generates fake WM_MOUSEMOVE events)
  6. Launch PIE
  7. Move your mouse cursor into the left/right areas on the main menu where there’s no buttons
  8. Use d-pad on gamepad to hover the Credits button
  9. Wait ~30s without touching mouse, keyboard, or gamepad
  10. Press the accept button on gamepad (facebutton bottom)

Observe that within step 9 the Credits button became unfocused (it switched back to kb+m input), and when you press accept on gamepad it focuses a random button in the list, and maybe when you press up/down on gamepad focus doesn’t change. Things be in a weird broken state.

Wow that was an info dump. Sorry!

Just to be clear, we’re currently on UE 5.5 and still seeing this issue. It just first showed up in UE 5.1 for us.

Hi there, thank you for the detailed post!

I was able to reproduce the issue and submitted a similar change to yours in CL 42102619, this will release with UE 5.6