Skip to content

feat(input): support per-app gamepad emulation - #932

Merged
qiin2333 merged 2 commits into
masterfrom
codex/per-app-gamepad
Aug 11, 2026
Merged

feat(input): support per-app gamepad emulation#932
qiin2333 merged 2 commits into
masterfrom
codex/per-app-gamepad

Conversation

@qiin2333

Copy link
Copy Markdown
Collaborator

改了啥呢

  • 在 Windows 应用高级设置中增加“模拟手柄类型”:继承全局、自动检测、Xbox 360、DualShock 4。
  • 启动应用时应用 override,结束时自动恢复全局配置;不改写 sunshine.conf,也不需要重启服务。
  • 保留现有 ViGEm 路径,只改变目标类型选择,避免杂鱼一样再叠一层 reWASD 虚拟手柄。
  • 保存 API 校验合法值,旧 apps.json 没有该字段时保持原行为。
  • 补齐 Web 数据格式化测试和全部 locale 的字段。

为啥要改

Issue #898 的用户需要部分游戏使用 DS4、另一些旧游戏或 Microsoft Store 游戏使用 X360。全局切换要求退出串流、改配置并重启服务,准备命令 workaround 也容易中断游戏。

这个 MVP 把选择放到应用配置里,让每个应用在创建虚拟手柄前决定类型,同时继续复用成熟的 ViGEm 驱动范围。

UX

  • 默认值为“继承全局设置”,现有用户无行为变化。
  • “自动检测”显式忽略全局固定类型,按照客户端上报类型、触摸板和运动能力选择。
  • 应用结束后自动恢复,不污染下一次串流。
  • 非 Windows 平台安全 no-op。

验证

  • node --test src_assets/common/assets/web/tests/*.test.js:97 passed
  • npm run lint:webui
  • npm run build
  • git diff --check
  • 单独编译本次修改的 C++ 单元:
    • src/process.cpp
    • src/confighttp.cpp
    • src/platform/windows/input.cpp

本机全量 CMake 增量构建被旧缓存中 Strawberry GCC 与 MSYS2 headers 混用阻断,失败点位于未修改的 src/config.cpp;交给 CI 的干净工具链继续验收啦。

Implements #898

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: c635f5f4-61c7-488d-bdd5-b237f9465163

📥 Commits

Reviewing files that changed from the base of the PR and between 9a13f3f and fac1742.

📒 Files selected for processing (16)
  • src/confighttp.cpp
  • src_assets/common/assets/web/public/assets/locale/bg.json
  • src_assets/common/assets/web/public/assets/locale/cs.json
  • src_assets/common/assets/web/public/assets/locale/de.json
  • src_assets/common/assets/web/public/assets/locale/es.json
  • src_assets/common/assets/web/public/assets/locale/fr.json
  • src_assets/common/assets/web/public/assets/locale/it.json
  • src_assets/common/assets/web/public/assets/locale/ja.json
  • src_assets/common/assets/web/public/assets/locale/ko.json
  • src_assets/common/assets/web/public/assets/locale/pl.json
  • src_assets/common/assets/web/public/assets/locale/pt.json
  • src_assets/common/assets/web/public/assets/locale/pt_BR.json
  • src_assets/common/assets/web/public/assets/locale/ru.json
  • src_assets/common/assets/web/public/assets/locale/sv.json
  • src_assets/common/assets/web/public/assets/locale/tr.json
  • src_assets/common/assets/web/public/assets/locale/uk.json
🚧 Files skipped from review as they are similar to previous changes (16)
  • src_assets/common/assets/web/public/assets/locale/pt_BR.json
  • src_assets/common/assets/web/public/assets/locale/cs.json
  • src_assets/common/assets/web/public/assets/locale/sv.json
  • src_assets/common/assets/web/public/assets/locale/fr.json
  • src_assets/common/assets/web/public/assets/locale/ja.json
  • src/confighttp.cpp
  • src_assets/common/assets/web/public/assets/locale/bg.json
  • src_assets/common/assets/web/public/assets/locale/it.json
  • src_assets/common/assets/web/public/assets/locale/tr.json
  • src_assets/common/assets/web/public/assets/locale/uk.json
  • src_assets/common/assets/web/public/assets/locale/es.json
  • src_assets/common/assets/web/public/assets/locale/pl.json
  • src_assets/common/assets/web/public/assets/locale/ko.json
  • src_assets/common/assets/web/public/assets/locale/de.json
  • src_assets/common/assets/web/public/assets/locale/pt.json
  • src_assets/common/assets/web/public/assets/locale/ru.json
📜 Recent review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Windows

Summary by CodeRabbit

  • 新功能

    • 新增应用级游戏手柄模式设置,可选择继承全局配置、自动、Xbox 360 或 DualShock 4。
    • Windows 平台支持按应用选择虚拟手柄类型,应用退出后恢复全局设置。
  • 改进

    • 无效的手柄模式会被拒绝或自动回退为默认设置。
    • 应用编辑界面及多语言内容已同步更新。
  • 测试

    • 新增手柄模式配置校验测试。

Walkthrough

新增应用级游戏手柄模式配置。配置支持继承、自动、Xbox 360 和 DualShock 4。应用启动时切换模式,应用终止时恢复全局模式。Windows 输入逻辑使用有效模式。

Changes

应用级游戏手柄模式

Layer / File(s) Summary
配置契约与解析
src/platform/common.h, src/process.h, src/process.cpp, src/confighttp.cpp
新增 gamepad_mode 字段和四种模式。保存应用配置时校验 autox360ds4,并清理空值。
运行时模式应用
src/platform/windows/input.cpp, src/process.cpp, src/platform/linux/input/*, src/platform/macos/input.cpp
应用启动时设置应用级模式,终止时恢复全局模式。Windows 输入分配和触控板能力判断使用有效模式。Linux 与 macOS 提供空操作接口。
Web 配置界面与数据格式
src_assets/common/assets/web/components/AppEditor.vue, src_assets/common/assets/web/services/appService.js, src_assets/common/assets/web/utils/constants.js, src_assets/common/assets/web/tests/appService.test.js, src_assets/common/assets/web/public/assets/locale/*
应用编辑器新增手柄模式选择器。前端保留有效值,并将无效值归一化为空字符串。各语言资源新增相关文本。

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AppEditor
  participant appService
  participant confighttp
  participant process
  participant WindowsInput
  AppEditor->>appService: 提交 gamepad 配置
  appService->>confighttp: 传递规范化值
  confighttp->>process: 保存应用配置
  process->>WindowsInput: 应用有效手柄模式
  WindowsInput-->>process: 分配对应控制器类型
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 标题准确概括了按应用支持游戏手柄仿真的主要变更,内容简洁且与变更范围一致。
Description check ✅ Passed 描述说明了应用级手柄配置、平台行为、验证结果和实现目的,与变更内容相关。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/per-app-gamepad

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qiin2333
qiin2333 requested a balanced review from Copilot August 11, 2026 07:26
@qiin2333
qiin2333 marked this pull request as ready for review August 11, 2026 07:26

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src_assets/common/assets/web/public/assets/locale/bg.json`:
- Around line 133-138: Translate every newly added gamepad_mode,
gamepad_mode_desc, gamepad_mode_inherit, gamepad_mode_auto, gamepad_mode_x360,
and gamepad_mode_ds4 value into its target language in
src_assets/common/assets/web/public/assets/locale/bg.json lines 133-138, cs.json
lines 133-138, ru.json lines 133-138, sv.json lines 133-138, tr.json lines
133-138, and uk.json lines 133-138, preserving the existing keys and JSON
structure.

In `@src_assets/common/assets/web/public/assets/locale/de.json`:
- Around line 133-138: Translate the newly added gamepad_mode,
gamepad_mode_desc, gamepad_mode_inherit, and gamepad_mode_auto values into the
corresponding languages while preserving the product names Xbox 360 and
DualShock 4. Apply the translations in
src_assets/common/assets/web/public/assets/locale/de.json#L133-L138,
es.json#L133-L138, fr.json#L133-L138, it.json#L133-L138, ja.json#L133-L138,
ko.json#L133-L138, pl.json#L133-L138, pt.json#L133-L138, and
pt_BR.json#L133-L138.

In `@src/confighttp.cpp`:
- Around line 850-858: 在 editApp 为空、替换 input_apps_node 之前,遍历完整应用列表并对每个应用的
gamepad 执行与 input_edit_node 相同的处理:删除空值,并仅允许 auto、x360 或
ds4。遇到无效值时设置相同错误响应并终止保存,避免无效配置被成功写入。
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 37ef5285-1985-4acf-b97d-84c08e2cd46b

📥 Commits

Reviewing files that changed from the base of the PR and between d80144e and 9a13f3f.

📒 Files selected for processing (32)
  • src/confighttp.cpp
  • src/platform/common.h
  • src/platform/linux/input/inputtino.cpp
  • src/platform/linux/input/legacy_input.cpp
  • src/platform/macos/input.cpp
  • src/platform/windows/input.cpp
  • src/process.cpp
  • src/process.h
  • src_assets/common/assets/web/components/AppEditor.vue
  • src_assets/common/assets/web/public/assets/locale/bg.json
  • src_assets/common/assets/web/public/assets/locale/cs.json
  • src_assets/common/assets/web/public/assets/locale/de.json
  • src_assets/common/assets/web/public/assets/locale/en.json
  • src_assets/common/assets/web/public/assets/locale/en_GB.json
  • src_assets/common/assets/web/public/assets/locale/en_US.json
  • src_assets/common/assets/web/public/assets/locale/es.json
  • src_assets/common/assets/web/public/assets/locale/fr.json
  • src_assets/common/assets/web/public/assets/locale/it.json
  • src_assets/common/assets/web/public/assets/locale/ja.json
  • src_assets/common/assets/web/public/assets/locale/ko.json
  • src_assets/common/assets/web/public/assets/locale/pl.json
  • src_assets/common/assets/web/public/assets/locale/pt.json
  • src_assets/common/assets/web/public/assets/locale/pt_BR.json
  • src_assets/common/assets/web/public/assets/locale/ru.json
  • src_assets/common/assets/web/public/assets/locale/sv.json
  • src_assets/common/assets/web/public/assets/locale/tr.json
  • src_assets/common/assets/web/public/assets/locale/uk.json
  • src_assets/common/assets/web/public/assets/locale/zh.json
  • src_assets/common/assets/web/public/assets/locale/zh_TW.json
  • src_assets/common/assets/web/services/appService.js
  • src_assets/common/assets/web/tests/appService.test.js
  • src_assets/common/assets/web/utils/constants.js
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: copilot-pull-request-reviewer
  • GitHub Check: Windows
🧰 Additional context used
📓 Path-based instructions (3)
src_assets/**/*.{vue,js,html}

⚙️ CodeRabbit configuration file

src_assets/**/*.{vue,js,html}: 基于 Vue.js 的 Web 配置面板。审查 XSS/CSRF 安全性、 组件设计、状态管理和可访问性。

Files:

  • src_assets/common/assets/web/services/appService.js
  • src_assets/common/assets/web/tests/appService.test.js
  • src_assets/common/assets/web/utils/constants.js
  • src_assets/common/assets/web/components/AppEditor.vue
src/**/*.{cpp,c,h}

⚙️ CodeRabbit configuration file

src/**/*.{cpp,c,h}: Sunshine 核心 C++ 源码,自托管游戏串流服务器。审查要点:内存安全、 线程安全、RAII 资源管理、安全漏洞。注意预处理宏控制的平台相关代码。

Files:

  • src/process.h
  • src/platform/linux/input/inputtino.cpp
  • src/process.cpp
  • src/platform/macos/input.cpp
  • src/platform/linux/input/legacy_input.cpp
  • src/confighttp.cpp
  • src/platform/common.h
  • src/platform/windows/input.cpp
src/platform/**

⚙️ CodeRabbit configuration file

src/platform/**: 平台抽象层代码(Windows/Linux/macOS)。确保各平台实现一致, 注意 Windows API 调用的错误处理和资源释放。

Files:

  • src/platform/linux/input/inputtino.cpp
  • src/platform/macos/input.cpp
  • src/platform/linux/input/legacy_input.cpp
  • src/platform/common.h
  • src/platform/windows/input.cpp
🧠 Learnings (1)
📚 Learning: 2026-07-27T15:33:54.262Z
Learnt from: Yundi339
Repo: AlkaidLab/foundation-sunshine PR: 848
File: src_assets/common/assets/web/public/assets/locale/ru.json:661-673
Timestamp: 2026-07-27T15:33:54.262Z
Learning: Webhook payload language must follow the backend contract: only locales `zh` and `zh_TW` receive Chinese text in the Sunshine Webhook runtime payload; every other locale (e.g., `ru`) must use English. When updating locale JSON files (like `ru.json`), do not independently translate webhook payload strings for non-`zh` locales—coordinate any full non-Chinese localization with the required backend locale/language-selection changes and corresponding locale updates. Ensure any curl/test payload examples and related UI payload previews (e.g., in `WebhookCard.vue`) match this backend payload-language behavior.

Applied to files:

  • src_assets/common/assets/web/public/assets/locale/pt.json
  • src_assets/common/assets/web/public/assets/locale/zh_TW.json
  • src_assets/common/assets/web/public/assets/locale/en.json
  • src_assets/common/assets/web/public/assets/locale/pl.json
  • src_assets/common/assets/web/public/assets/locale/cs.json
  • src_assets/common/assets/web/public/assets/locale/it.json
  • src_assets/common/assets/web/public/assets/locale/en_US.json
  • src_assets/common/assets/web/public/assets/locale/tr.json
  • src_assets/common/assets/web/public/assets/locale/sv.json
  • src_assets/common/assets/web/public/assets/locale/pt_BR.json
  • src_assets/common/assets/web/public/assets/locale/uk.json
  • src_assets/common/assets/web/public/assets/locale/fr.json
  • src_assets/common/assets/web/public/assets/locale/ru.json
  • src_assets/common/assets/web/public/assets/locale/en_GB.json
  • src_assets/common/assets/web/public/assets/locale/bg.json
  • src_assets/common/assets/web/public/assets/locale/ko.json
  • src_assets/common/assets/web/public/assets/locale/zh.json
  • src_assets/common/assets/web/public/assets/locale/ja.json
  • src_assets/common/assets/web/public/assets/locale/es.json
  • src_assets/common/assets/web/public/assets/locale/de.json
🔇 Additional comments (16)
src/platform/common.h (1)

991-996: LGTM!

src/process.h (1)

73-73: LGTM!

src/process.cpp (1)

178-180: LGTM!

Also applies to: 422-423, 833-833, 915-930

src/platform/windows/input.cpp (1)

480-508: LGTM!

Also applies to: 1913-1921, 2105-2105, 2514-2514

src/platform/linux/input/inputtino.cpp (1)

44-48: LGTM!

src/platform/linux/input/legacy_input.cpp (1)

1189-1193: LGTM!

src/platform/macos/input.cpp (1)

388-392: LGTM!

src_assets/common/assets/web/utils/constants.js (1)

29-29: LGTM!

src_assets/common/assets/web/components/AppEditor.vue (1)

218-235: LGTM!

Also applies to: 343-343, 458-460

src_assets/common/assets/web/services/appService.js (1)

210-210: LGTM!

src_assets/common/assets/web/tests/appService.test.js (1)

62-62: LGTM!

Also applies to: 80-80, 90-98

src_assets/common/assets/web/public/assets/locale/zh.json (1)

133-138: LGTM!

src_assets/common/assets/web/public/assets/locale/zh_TW.json (1)

133-138: LGTM!

src_assets/common/assets/web/public/assets/locale/en.json (1)

133-138: LGTM!

src_assets/common/assets/web/public/assets/locale/en_GB.json (1)

133-138: LGTM!

src_assets/common/assets/web/public/assets/locale/en_US.json (1)

133-138: LGTM!

Comment thread src_assets/common/assets/web/public/assets/locale/bg.json Outdated
Comment thread src_assets/common/assets/web/public/assets/locale/de.json Outdated
Comment thread src/confighttp.cpp Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds per-application Windows gamepad emulation settings to address issue #898 while preserving global defaults.

Changes:

  • Adds inherit, auto, Xbox 360, and DualShock 4 modes.
  • Applies overrides during app execution and resets them afterward.
  • Adds UI controls, validation, tests, and locale keys.

Reviewed changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/process.h Adds the per-app gamepad mode field.
src/process.cpp Parses and manages override lifecycle.
src/platform/common.h Declares the platform API.
src/platform/windows/input.cpp Applies overrides to ViGEm selection and capabilities.
src/platform/macos/input.cpp Adds the macOS no-op implementation.
src/platform/linux/input/legacy_input.cpp Adds the legacy Linux no-op.
src/platform/linux/input/inputtino.cpp Adds the Inputtino no-op.
src/confighttp.cpp Validates edited app values; bulk-save validation remains incomplete.
src_assets/common/assets/web/utils/constants.js Adds the default app value.
src_assets/common/assets/web/services/appService.js Normalizes gamepad values.
src_assets/common/assets/web/tests/appService.test.js Tests gamepad formatting.
src_assets/common/assets/web/components/AppEditor.vue Adds the Windows gamepad selector.
src_assets/common/assets/web/public/assets/locale/bg.json Adds locale keys.
src_assets/common/assets/web/public/assets/locale/cs.json Adds locale keys.
src_assets/common/assets/web/public/assets/locale/de.json Adds locale keys.
src_assets/common/assets/web/public/assets/locale/en.json Adds English strings.
src_assets/common/assets/web/public/assets/locale/en_GB.json Adds English strings.
src_assets/common/assets/web/public/assets/locale/en_US.json Adds English strings.
src_assets/common/assets/web/public/assets/locale/es.json Adds locale keys.
src_assets/common/assets/web/public/assets/locale/fr.json Adds locale keys.
src_assets/common/assets/web/public/assets/locale/it.json Adds locale keys.
src_assets/common/assets/web/public/assets/locale/ja.json Adds locale keys.
src_assets/common/assets/web/public/assets/locale/ko.json Adds locale keys.
src_assets/common/assets/web/public/assets/locale/pl.json Adds locale keys.
src_assets/common/assets/web/public/assets/locale/pt.json Adds locale keys.
src_assets/common/assets/web/public/assets/locale/pt_BR.json Adds locale keys.
src_assets/common/assets/web/public/assets/locale/ru.json Adds locale keys.
src_assets/common/assets/web/public/assets/locale/sv.json Adds locale keys.
src_assets/common/assets/web/public/assets/locale/tr.json Adds locale keys.
src_assets/common/assets/web/public/assets/locale/uk.json Adds locale keys.
src_assets/common/assets/web/public/assets/locale/zh.json Adds Simplified Chinese strings.
src_assets/common/assets/web/public/assets/locale/zh_TW.json Adds Traditional Chinese strings.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/confighttp.cpp Outdated
Comment on lines +850 to +854
auto gamepad = input_edit_node.get_optional<std::string>("gamepad");
if (gamepad && gamepad->empty()) {
input_edit_node.erase("gamepad");
}
else if (gamepad && *gamepad != "auto"sv && *gamepad != "x360"sv && *gamepad != "ds4"sv) {
@qiin2333
qiin2333 merged commit 26874a8 into master Aug 11, 2026
4 checks passed
@qiin2333
qiin2333 deleted the codex/per-app-gamepad branch August 11, 2026 07:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants