Focus is a property, not a widget
Directional navigation is attached to ordinary WPF controls rather than built into a private set of six lookalikes, so a screen added later gets it by declaring it. The rule that decides where focus goes is kept apart from the handler that moves it, which is why the same rule holds on a settings row, a console row and a mapping cell.
The pad in the room, not the pad in a config file
- ✓The device list, the button events and the axis positions are read on the thread that owns SDL, so a controller plugged in mid-session is a controller that works.
- ✓Bindings come from the device's own strings, so a pad that already works elsewhere on the machine arrives mapped.
- ✓The capture takes a press rather than waiting for movement, and a stick resting off centre reads as resting rather than as input.
- ✓Triggers are captured without turning on the axes, because the sticks flood the log and the trigger is what you were trying to bind.
Any pad SDL can map, an Xbox one included
SDL is the one native dependency this port did not move. Nothing about the device layer was tied to Qt, so it is called directly rather than through the shim the rest of the C goes through, which means the pads that work here are the pads SDL already knows. An Xbox controller enumerates, arrives carrying its own binding string, and reaches the mapping screen with every row already filled in.
- ✓The rows are named for the PlayStation pad: Cross, Moon, Box, Pyramid, the shoulders, the triggers. What sits on each row is whatever your controller calls that control, so rebinding an Xbox pad is the same screen and the same capture as rebinding a DualSense.
- ✓A device SDL has no mapping for is left out of the list rather than shown with empty rows, because a pad with no bindings gives the screen nothing to draw.
- ✓Haptics fold to rumble on a pad with no haptic motors. The console sends a stereo haptic stream a DualSense plays as sound, and a controller that cannot play one gets a single strength scaled by your intensity setting instead, which is what a PS4 pad already feels during a PS5 session.
- ✓What is hardware stays hardware: adaptive triggers and the touchpad are not emulated on a pad that has neither, though the D-pad can be turned into a finger on the touchpad for the ones without.
When the machine disagrees with you
Running the application with --controllers prints what SDL sees right now, and --capture-controller logs presses for twenty seconds so a pad that reports nothing can be told apart from a pad that reports the wrong thing.