Game Controller Input Limitations in visionOS Volumetric Windows
Hello Apple Developer Community,
I'm developing a game for visionOS and have encountered significant limitations with game controller input when using volumetric windows (WindowGroup with .volumetric style). I'd appreciate clarification on whether this is expected behavior and any guidance on best practices.
🧩 Issue Summary
When using a DualSense controller with a volumetric window in visionOS, only a subset of controller inputs are available to the app. The remaining inputs appear to be reserved by the system for UI navigation.
✅ Working Inputs (Volumetric Window)
- D-Pad (all directions)
- L3 (left thumbstick button click)
- R3 (right thumbstick button click)
- Menu button
- Options button
❌ Not Working Inputs (Volumetric Window)
- Left thumbstick analog movement (used for UI scrolling instead)
- Right thumbstick analog movement (used for UI scrolling instead)
- Face buttons (Cross, Circle, Square, Triangle / A, B, X, Y)
- Shoulder buttons (L1, R1)
- Triggers (L2, R2)
Key observation: When moving the left thumbstick in a volumetric window, the window's UI scrolls vertically instead of sending input to my app's GameController handlers. Similarly, face buttons seem to be reserved for system UI interactions.
⚙️ Implementation Details
I'm using the standard GameController framework:
- Connect to controller via
GCController.controllers() - Access
extendedGamepadprofile - Set up
valueChangedHandlerandpressedChangedHandlerfor all inputs - Handlers confirmed registered via logging
- Working inputs (D-Pad, L3, R3) trigger immediately and consistently
- Non-working inputs (thumbsticks, face buttons) never trigger
🧠 Critical Finding: ImmersiveSpace Works Perfectly
When testing the exact same code in an ImmersiveSpace (.mixed immersion style), all controller inputs work perfectly:
- ✅ Both thumbsticks provide full analog input
- ✅ All face buttons trigger their handlers
- ✅ All shoulder buttons and triggers work correctly
- ✅ 100% success rate with no intermittent issues
This suggests the issue isn't with my code, but rather how visionOS handles controller input differently between Volumetric Windows and ImmersiveSpace.
🧪 Test Environment
I created a minimal test project (Controller-Playground) to isolate the issue:
- A simple
ControllerTesterclass that registers all GameController handlers - A visual UI showing real-time input state
- No game logic, RealityKit physics, or other complexity
Results
- In volumetric window: Only D-Pad, L3, R3, Menu, Options work
- In ImmersiveSpace: All inputs work perfectly
This confirms the limitation exists at the visionOS platform level, not in app code.
🧰 Attempted Workarounds
I tried the following without success:
- Setting
GCSupportsControllerUserInteraction = falseinInfo.plist - Setting
UIRequiresFullScreen = true - Changing window styles (
.plain,.volumetric) - Polling vs. handler-based input approaches
- Various threading models (
MainActor, separate thread)
Result: The only way to enable full controller support is to switch to ImmersiveSpace.
❓ Questions for Apple
- Is this input reservation behavior in volumetric windows intended and documented?
- Are game controllers expected to have limited functionality in volumetric windows while full functionality is reserved for ImmersiveSpace?
- Is there a way to request full controller input access in a volumetric window, or is ImmersiveSpace the only option for complete controller support?
- Where can I find official documentation about controller input differences between window types?
- Are there any APIs or configuration options to disable system controller shortcuts in volumetric windows?
🎯 Impact
This limitation has a significant effect on game design and architecture:
- Volumetric windows offer a multitasking-friendly, less immersive experience
- ImmersiveSpace provides full controller support but may be more immersive than some games require
- Games that only need basic D-Pad and button input can work fine in volumetric windows
- Games requiring analog sticks or face buttons must currently use ImmersiveSpace
It would be very helpful if Apple could clarify or reference existing documentation regarding controller input handling in different visionOS window types. If such documentation doesn't exist yet, it might be valuable to include this information in future developer guides or best-practice documents.
🕹 Current Workaround
For now, I'm using:
- D-Pad for character movement (digital 8-direction)
- R3 (right stick click) as a substitute for the "X" button
This setup allows the game to function within a volumetric window, though full controller support still requires ImmersiveSpace.
📄 Request
If this is expected behavior, I may have simply missed the relevant documentation — could you please point me to any existing resources that explain this design?
If there isn't one yet, it would be great if future visionOS documentation could:
- Clearly outline controller input behavior across window types
- Provide guidance on when to use Volumetric Windows vs. ImmersiveSpace for games
- Consider adding an API option to request full controller access when appropriate
If this is not expected behavior, I'm happy to file a detailed bug report with sample code.
💻 System Information
- visionOS: Latest Simulator
- Xcode: Latest version
- Controller: Sony DualSense
- Framework: GameController (standard
extendedGamepadprofile) - Test project: Minimal reproducible example available
Thank you for any clarification or guidance you can provide. This information would be valuable for many developers working on visionOS games.
Hello
Would you clarify whether you are adding the handlesGameControllerEvents(matching:) modifier to the root view in your app window?
If not, please try adding the modifier like so:
.handlesGameControllerEvents(matching: .gamepad)
-- Justin