-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Problem
Xbox Wireless Controller connected via Bluetooth Low Energy (BLE) is not detected by Conductor on macOS, even though the controller is connected and functional with macOS system.
Environment
- Platform: macOS (Apple Silicon)
- Controller: Xbox Wireless Controller (Product ID: 0x0B22, Vendor ID: 0x045E)
- Connection: Bluetooth Low Energy (BLE)
- Current Library: gilrs 0.10
Root Cause Analysis
Investigation Results
✅ Controller is connected to macOS:
Xbox Wireless Controller:
Address: 3C:FA:06:18:BD:A5
Vendor ID: 0x045E (Microsoft)
Product ID: 0x0B22
Minor Type: Gamepad
Services: BLE
✅ Conductor code is correct:
ListDevicesIPC command properly enumerates both MIDI and HID devicesHidDeviceManager::list_gamepads()calls gilrs correctly- Test confirms:
Found 0 game controllers
❌ gilrs doesn't detect BLE controllers on macOS:
- gilrs uses
IOKitframework which primarily supports USB HID devices - BLE controllers are exposed via different macOS APIs
- macOS requires native
GameControllerframework for BLE gamepad support
Test Evidence
cargo test --package conductor-daemon test_list_gamepads -- --nocapture
// Output: Found 0 game controllersProposed Solutions
Option 1: Dynamic Library Plugin Architecture ⭐ (Recommended)
Architecture:
conductor-daemon: 3MB (no gamepad libs)
├── plugins/
├── libconductor-backend-gilrs.dylib (~500KB)
├── libconductor-backend-sdl2.dylib (~2MB)
└── libconductor-backend-macos.dylib (~100KB)
Config:
[device]
gamepad_backend = "sdl2" # Runtime selection
Implementation:
- Define
GamepadBackendtrait with C ABI - Use
libloadingcrate for dynamic library loading - Load backend based on
config.tomlsetting - Users download only needed plugins
Pros:
- ✅ Smallest core binary (3MB vs 5-8MB)
- ✅ Runtime config selection (no recompile)
- ✅ Download on-demand (install just needed backend)
- ✅ Hot-swap backends (change config, reload)
Cons:
- Distribution complexity (multiple files)
- Version compatibility management
- Security considerations (loading external code)
Effort: ~6-8 hours
Option 2: Separate Backend Binaries (Simpler)
Architecture:
conductor-daemon: 3MB (coordinator only)
conductor-backend-gilrs: 1MB (standalone binary)
conductor-backend-sdl2: 3MB (standalone binary)
conductor-backend-macos: 500KB (standalone binary)
Config:
[device]
gamepad_backend = "sdl2"
Implementation:
- Each backend is a separate executable
- Daemon spawns backend as subprocess
- Communicate via stdin/stdout (JSON protocol)
- Reuse existing IPC infrastructure
Pros:
- ✅ Simple to implement (no FFI/ABI concerns)
- ✅ Process isolation (backend crash safe)
- ✅ Easy distribution (separate binaries)
- ✅ Runtime selection via config
- ✅ Can distribute via
cargo install conductor-backend-sdl2 - ✅ Fits existing architecture (already have IPC)
Cons:
- Extra process overhead (~1-2ms latency)
- Multiple binaries to distribute
Effort: ~4-6 hours
Option 3: Cargo Features (Current Approach)
Architecture:
[features]
default = ["gilrs-backend"]
gilrs-backend = ["gilrs"]
sdl2-backend = ["sdl2"]
macos-native = [] # macOS only
# User builds with:
cargo build --features sdl2-backendPros:
- ✅ Smallest binary (only one backend compiled)
- ✅ No runtime overhead
- ✅ Simple implementation
Cons:
- ❌ Requires recompile to switch backends
- ❌ User must know to use correct feature
- ❌ Larger binary if multiple features enabled
Effort: ~2-3 hours
Option 4: Immediate SDL2 Integration
Quick Fix: Replace gilrs with sdl2 globally
- Works on macOS BLE controllers
- Proven, battle-tested
- ~2MB binary size increase
Pros:
- ✅ Fastest path to working Xbox support (1 hour)
- ✅ Works on all platforms
Cons:
- ❌ Larger binary for everyone
- ❌ No user choice
Effort: ~1 hour
Backend Comparison
| Backend | macOS BLE | macOS USB | Linux | Windows | Binary Size |
|---|---|---|---|---|---|
| gilrs | ❌ | ✅ | ✅ | ✅ | +500KB |
| SDL2 | ✅ | ✅ | ✅ | ✅ | +2MB |
| macOS GameController | ✅ | ✅ | ❌ | ❌ | +100KB |
Recommendation
Phase 1: Implement Option 2 (Separate Backend Binaries)
- Best balance of flexibility, simplicity, and binary size
- Fits existing IPC architecture
- Process isolation provides safety
- Easy to distribute and update
Phase 2: Add backend implementations
conductor-backend-sdl2(immediate - fixes macOS BLE)conductor-backend-macos(later - optimal macOS performance)- Keep
conductor-backend-gilrs(default for Linux/Windows)
Phase 3 (Optional): Convert to dynamic library plugins (Option 1) if needed
Implementation Checklist
- Define
GamepadBackendtrait inconductor-core - Create
conductor-backend-gilrsbinary (extract existing code) - Create
conductor-backend-sdl2binary (new) - Add subprocess spawning to
input_manager.rs - Implement JSON protocol for backend communication
- Add
gamepad_backendconfig option - Update documentation
- Add macOS-specific testing guide
- Create releases for all backends
References
Labels
enhancement, architecture, macos, gamepad, v3.1
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request