2bea02b0ea
The shared skeleton of the five stateful UHID/UMDF managers (Linux DualSense / DualShock 4 / Steam Deck, Windows DualSense / DualShock 4), written once over PadSlots: event routing with the unplug sweep and was-the-unplug early return, the merge-preserving frame fold, rich-input application, the silence heartbeat (with a backend force hook for the Steam mode-entry pulse), and the feedback pump with rumble dedup + HidoutDedup. A backend supplies only its per-controller half via PadProto: open / neutral / merge_frame / apply_rich / write_state / service — exactly where the real protocol differences live. Method surface (new/handle/apply_rich/pump/heartbeat) matches what the punktfunk1.rs Pads router already drives, so each backend will convert as a pub type alias with zero router edits. Additive only — no backend converted yet. 8 mock-backend tests make the manager lifecycle unit-testable for the first time; G2 (rich fields survive a button-only frame) and G10 (Arrival eager-creates) are now generic regression tests, plus removal-frame no-recreate, absent-pad rich drop, create-backoff state tracking, rumble/hidout dedup + re-arm on recreate, and heartbeat gap/force semantics. Verified on .21: clippy --all-targets -D warnings clean; suite 293 pass / 0 fail (285 prior + 8 new). Part of G12/3.3 (gamepad-review-cleanup.md §3a.3, commit 3 of the §3a.4 sequence). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>