Distinguishing SteamDeck Trackpad/Gyro Mouse Events from Real Mouse Input

The Problem

We’re shipping a Win64 title that runs on SteamDeck via Proton. On SteamDeck, Steam Input translates the built-in trackpad and gyroscope into regular Win32 mouse events (WM_MOUSEMOVE, WM_INPUT, etc.). This causes FCommonInputPreprocessor to switch from Gamepad to MouseAndKeyboard mode whenever the player touches the trackpad, which flips all UI glyphs to MKB, even though the player is holding a gamepad technically.

We need to distinguish these synthetic mouse events from real external mouse input so CommonInput stays in Gamepad mode for trackpad/gyro but correctly switches to MKB when a real USB/Bluetooth mouse is used.

Our Current Workaround

In our custom SteamDeck plugin, we are doing the following in a subsystem, using existing extension points:

- IInputProcessor registered at EInputPreProcessorType::Engine priority. It watches HandleKeyDownEvent for non-gamepad keys and sets a bExternalKeyboardDetected flag.

- OnPlatformInputSupportOverride delegate suppresses MouseAndKeyboard unless that flag is set.

- OnInputMethodChangedNative clears the flag when input returns to Gamepad.

This works well for the core problem that using the trackpad no longer flips the input mode to MKB.

The Limitation

Our workaround effectively blocks all mouse movement input from triggering MKB mode. The only way to switch to MKB mode is to press a keyboard key now. This means if a player docks their SteamDeck and plugs in only a mouse (no keyboard), they’re stuck in Gamepad mode with no cursor.

We can’t find a way to tell, on a per-event basis, whether a mouse event came from the SteamDeck’s trackpad/gyro or from a real external mouse.

What We’ve Investigated

- FPointerEvent::GetInputDeviceId() returns the default platform device for all mice. No differentiation.

- WM_INPUT / RAWINPUT path in WindowsApplication.cpp the raw input data includes hDevice which identifies the physical source device, but this is discarded. The FInputDeviceScope is hardcoded to the default input device regardless of which mouse generated the event.

- ISteamInput API GetConnectedControllers() only knows about gamepads, not mice. GetMotionData() gives raw gyro data, nothing for the trackpads

- IInputProcessor mouse handlers FPointerEvent carries no source device information. All mice look identical.

Questions

1. Is there a recommended way to distinguish synthetic mouse events (from Steam Input’s trackpad/gyro) from real external mouse events? We feel like we must be missing something.

2. Is there a better extension point than `OnPlatformInputSupportOverride for conditionally blocking input type switching based on the source device rather than just the input type?

3. Is there an existing or planned mechanism for tagging certain mouse devices as virtual/synthetic so CommonInput can ignore them for input type switching?

Any guidance would be appreciated. Happy to share our full implementation if helpful.

[Attachment Removed]

Hi,

Ultimately it seems like things are working as intended/expected here; using the trackpad is equivalent to using a trackpad on a laptop, which is a real mouse input versus something like a touchscreen (which on Windows sends both a touch event and a fallback mouse event, though in 5.7 we updated things on our end to handle this as a WM_POINTER event so we can properly suppress the mouse event if the touch is handled). Does your game support using the trackpad to play the full experience using mouse controls?

Any time in the engine we refer to a synthetic mouse event we mean something created in code instead of instigating from hardware, so from the engine perspective this will be a real mouse event and probably should be handled as one. I’m not sure if there’s any way through the Steam API to disable or change behavior of the trackpads, but if you wanted to change this at the engine level you’d probably need to update WindowsApplication to expose that device identifier and check against that to filter out the inputs. I’m not sure how evergreen that approach would be, as other types of pointer devices may be included with future hardware and you’ll end up maintaining a list of hardware identifiers to ignore.

The alternative would be to change or extend CommonUI’s preprocessor to specify your own rules on when to change input modes. You could probably implement something similar to palm detection on laptop trackpads by adding a delay before switching modes so that it won’t switch to mouse input if a gamepad key was detected recently enough.

Best,

Cody

[Attachment Removed]