From 01305c67a760f9c208709a2631b4972007363a90 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Mon, 15 Jun 2026 07:31:39 +0000 Subject: [PATCH] fix(apple/gamepad): resolve DualSense type reliably at connect (no Auto race) The DualSense intermittently showed up as an Xbox 360 pad on the host: the client's `.auto` gamepad-type resolution read `GamepadManager.active`, which is populated only by the async `.GCControllerDidConnect` notification (or the init-time snapshot). At connect time `active` could still be nil with a DualSense attached, so the client sent `.auto` and the host's pick_gamepad mapped that to Xbox 360. Confirmed live: same box, two connects minutes apart logged `gamepad="xbox360"` (auto) vs `honoring client gamepad request gamepad="dualsense"`. resolveType() now calls rebuild() first to re-read GCController.controllers() synchronously before reading `active`, closing the race for the common case (controller attached before connecting). Co-Authored-By: Claude Opus 4.8 (1M context) --- clients/apple/Sources/PunktfunkKit/GamepadManager.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clients/apple/Sources/PunktfunkKit/GamepadManager.swift b/clients/apple/Sources/PunktfunkKit/GamepadManager.swift index a7957a4..4ca488c 100644 --- a/clients/apple/Sources/PunktfunkKit/GamepadManager.swift +++ b/clients/apple/Sources/PunktfunkKit/GamepadManager.swift @@ -107,6 +107,11 @@ public final class GamepadManager: ObservableObject { setting: PunktfunkConnection.GamepadType ) -> PunktfunkConnection.GamepadType { guard setting == .auto else { return setting } + // Refresh from the LIVE controller list first. `active` is otherwise only populated by the + // async `.GCControllerDidConnect` notification, so at connect time it can still be nil even + // with a DualSense attached — which would send `.auto` and the host would create an Xbox 360 + // pad. `rebuild()` re-reads `GCController.controllers()` synchronously, closing that race. + rebuild() guard let active else { return .auto } return active.isDualSense ? .dualSense : .xbox360 }