5.6 KiB
id, title, status, assignee, created_date, updated_date, labels, dependencies, references
| id | title | status | assignee | created_date | updated_date | labels | dependencies | references | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| TASK-165 | Make controller configuration easier with inline remapping modal | To Do |
|
2026-03-13 00:10 | 2026-03-13 00:10 |
|
|
|
Description
Replace the current controller-selection-only modal with a denser controller configuration surface that keeps device selection and adds inline controller remapping. The new flow should feel like emulator configuration: pick an overlay action, arm capture, then press the matching controller button, trigger, d-pad direction, or stick direction to bind it. Keep the current overlay-local renderer architecture, preserve controller gating to keyboard-only mode, and retain the separate raw debug modal for troubleshooting.
Acceptance Criteria
- #1
Alt+Copens a controller modal that includes both preferred-controller selection and controller-config editing in one surface. - #2 Controller device selection uses a compact dropdown or equivalent compact picker instead of the current full-height device list.
- #3 Each remappable controller action shows its current binding and supports learn/capture, clear, and reset-to-default flows.
- #4 Learn mode captures the next fresh controller input edge or stick/d-pad direction, not a held/stale input.
- #5 Captured bindings can represent non-standard controllers without depending only on the browser's standard semantic button names.
- #6 Updated bindings persist through the existing config pipeline and take effect in the renderer without restart unless a field explicitly requires reopen/reload.
- #7 Existing controller behavior remains gated to keyboard-only mode except for the controller action that toggles keyboard-only mode itself.
- #8 Renderer/config/IPC regression tests cover the new modal layout, capture flow, persistence, and runtime mapping behavior.
- #9 Docs/config example explain the new controller-config flow and when to use the debug modal.
Implementation Plan
- Add the design doc and implementation plan for inline controller remapping, tied to a new backlog task instead of reopening the already-completed base controller-support task.
- Expand controller config types/defaults/template output so action bindings can store captured input descriptors, not only semantic button-name enums.
- Extend preload/main/IPC write paths from preferred-controller-only saves to full controller-config patching needed by the modal.
- Redesign the controller modal UI into a compact device picker plus action-binding editor with learn, clear, and reset affordances.
- Add renderer capture state and a learn-mode runtime that waits for neutral-to-active transitions before saving a binding.
- Update the gamepad runtime to resolve the new stored descriptors into actions while preserving current gating and repeat/deadzone behavior.
- Keep the raw debug modal as a separate advanced surface; optionally expose copyable input-descriptor text for troubleshooting.
- Add focused regression tests first, then run the maintained gate needed for docs/config/renderer/main changes.
Implementation Notes
Planning only in this pass.
Current-state findings:
src/renderer/modals/controller-select.tsonly persistspreferredGamepadId/preferredGamepadLabel.src/preload.ts,src/core/services/ipc.ts, andsrc/main.tsonly expose a narrow save path for preferred controller, not general controller config writes.src/renderer/handlers/gamepad-controller.tscurrently resolves actions from semantic button bindings plus a few axis slots; this is fine for defaults but too narrow for emulator-style learn mode on non-standard controllers.src/renderer/modals/controller-debug.tsalready provides the raw input surface needed for troubleshooting and for validating capture behavior.
Recommended direction:
- keep
Alt+Cas the single controller-config entrypoint - keep
Alt+Shift+Cas raw debug - introduce stored input descriptors for discrete bindings so learn mode can capture buttons, triggers, d-pad directions, and stick directions directly
- defer per-controller profiles; keep one global binding set plus preferred-controller selection for this pass
Final Summary
Planned follow-up work to make controller configuration materially easier than the current “pick preferred device” modal. The proposed change keeps existing controller runtime/debug foundations, but upgrades the selection modal into a compact controller-config surface with inline learn-mode remapping and persistent binding storage.
Main architectural change in scope: move from semantic-button-only binding storage toward captured input descriptors so the UI can reliably learn from buttons, triggers, d-pad directions, and stick directions on non-standard controllers.