Add gamepad override for each app

This commit is contained in:
Yukino Song
2025-05-19 14:22:17 +08:00
parent 98a35b81f6
commit b0871a9a5b
6 changed files with 77 additions and 19 deletions
+16
View File
@@ -218,6 +218,16 @@ namespace proc {
display_device::revert_configuration(); display_device::revert_configuration();
}); });
if (!app.gamepad.empty()) {
_saved_input_config = std::make_shared<config::input_t>(config::input);
if (app.gamepad == "disabled") {
config::input.controller = false;
} else {
config::input.controller = true;
config::input.gamepad = app.gamepad;
}
}
#ifdef _WIN32 #ifdef _WIN32
if ( if (
config::video.headless_mode // Headless mode config::video.headless_mode // Headless mode
@@ -671,6 +681,11 @@ namespace proc {
virtual_display = false; virtual_display = false;
allow_client_commands = false; allow_client_commands = false;
if (_saved_input_config) {
config::input = *_saved_input_config;
_saved_input_config.reset();
}
if (needs_refresh) { if (needs_refresh) {
refresh(config::stream.file_apps, false); refresh(config::stream.file_apps, false);
} }
@@ -1193,6 +1208,7 @@ namespace proc {
ctx.use_app_identity = app_node.value("use-app-identity", false); ctx.use_app_identity = app_node.value("use-app-identity", false);
ctx.per_client_app_identity = app_node.value("per-client-app-identity", false); ctx.per_client_app_identity = app_node.value("per-client-app-identity", false);
ctx.allow_client_commands = app_node.value("allow-client-commands", true); ctx.allow_client_commands = app_node.value("allow-client-commands", true);
ctx.gamepad = app_node.value("gamepad", "");
// Calculate a unique application id. // Calculate a unique application id.
auto possible_ids = calculate_app_id(name, ctx.image_path, i++); auto possible_ids = calculate_app_id(name, ctx.image_path, i++);
+2
View File
@@ -78,6 +78,7 @@ namespace proc {
std::string output; std::string output;
std::string image_path; std::string image_path;
std::string id; std::string id;
std::string gamepad;
bool elevated; bool elevated;
bool auto_detach; bool auto_detach;
bool wait_all; bool wait_all;
@@ -136,6 +137,7 @@ namespace proc {
boost::process::v1::environment _env; boost::process::v1::environment _env;
std::shared_ptr<rtsp_stream::launch_session_t> _launch_session; std::shared_ptr<rtsp_stream::launch_session_t> _launch_session;
std::shared_ptr<config::input_t> _saved_input_config;
std::vector<ctx_t> _apps; std::vector<ctx_t> _apps;
ctx_t _app; ctx_t _app;
-1
View File
@@ -44,7 +44,6 @@ namespace rtsp_stream {
int height; int height;
int fps; int fps;
int gcmap; int gcmap;
int appid;
int surround_info; int surround_info;
std::string surround_params; std::string surround_params;
bool enable_hdr; bool enable_hdr;
+55 -18
View File
@@ -164,12 +164,36 @@
</div> </div>
<div id="appNameHelp" class="form-text">{{ $t('apps.app_name_desc') }}</div> <div id="appNameHelp" class="form-text">{{ $t('apps.app_name_desc') }}</div>
</div> </div>
<!-- Application Image -->
<div class="mb-3"> <div class="mb-3">
<label for="appImagePath" class="form-label">{{ $t('apps.image') }}</label> <label for="appImagePath" class="form-label">{{ $t('apps.image') }}</label>
<input type="text" class="form-control monospace" id="appImagePath" aria-describedby="appImagePathHelp" <input type="text" class="form-control monospace" id="appImagePath" aria-describedby="appImagePathHelp"
v-model="editForm['image-path']" /> v-model="editForm['image-path']" />
<div id="appImagePathHelp" class="form-text">{{ $t('apps.image_desc') }}</div> <div id="appImagePathHelp" class="form-text">{{ $t('apps.image_desc') }}</div>
</div> </div>
<!-- gamepad override -->
<div class="mb-3" v-if="platform !== 'macos'">
<label for="gamepad" class="form-label">{{ $t('config.gamepad') }}</label>
<select id="gamepad" class="form-select" v-model="editForm.gamepad">
<option value="">{{ $t('_common.default_global') }}</option>
<option value="disabled">{{ $t('_common.disabled') }}</option>
<option value="auto">{{ $t('_common.auto') }}</option>
<Platformlayout :platform="platform">
<template #linux>
<option value="ds5">{{ $t("config.gamepad_ds5") }}</option>
<option value="switch">{{ $t("config.gamepad_switch") }}</option>
<option value="xone">{{ $t("config.gamepad_xone") }}</option>
</template>
<template #windows>
<option value="ds4">{{ $t('config.gamepad_ds4') }}</option>
<option value="x360">{{ $t('config.gamepad_x360') }}</option>
</template>
</Platformlayout>
</select>
<div class="form-text">{{ $t('config.gamepad_desc') }}</div>
</div>
<!-- allow client commands --> <!-- allow client commands -->
<Checkbox class="mb-3" <Checkbox class="mb-3"
id="clientCommands" id="clientCommands"
@@ -301,6 +325,13 @@
v-model="editForm['wait-all']" v-model="editForm['wait-all']"
default="true" default="true"
></Checkbox> ></Checkbox>
<!-- exit timeout -->
<div class="mb-3">
<label for="exitTimeout" class="form-label">{{ $t('apps.exit_timeout') }}</label>
<input type="number" class="form-control monospace" id="exitTimeout" aria-describedby="exitTimeoutHelp"
v-model="editForm['exit-timeout']" min="0" placeholder="5" />
<div id="exitTimeoutHelp" class="form-text">{{ $t('apps.exit_timeout_desc') }}</div>
</div>
<!-- use virtual display --> <!-- use virtual display -->
<Checkbox class="mb-3" <Checkbox class="mb-3"
id="virtualDisplay" id="virtualDisplay"
@@ -317,7 +348,7 @@
v-model="editForm['use-app-identity']" v-model="editForm['use-app-identity']"
default="false" default="false"
></Checkbox> ></Checkbox>
<!-- use app identity --> <!-- per-client app identity -->
<Checkbox class="mb-3" <Checkbox class="mb-3"
v-if="editForm['use-app-identity']" v-if="editForm['use-app-identity']"
id="perClientAppIdentity" id="perClientAppIdentity"
@@ -332,13 +363,6 @@
<input type="range" step="1" min="20" max="200" class="form-range" id="resolutionScaleFactor" v-model="editForm['scale-factor']"/> <input type="range" step="1" min="20" max="200" class="form-range" id="resolutionScaleFactor" v-model="editForm['scale-factor']"/>
<div class="form-text">{{ $t('apps.resolution_scale_factor_desc') }}</div> <div class="form-text">{{ $t('apps.resolution_scale_factor_desc') }}</div>
</div> </div>
<!-- exit timeout -->
<div class="mb-3">
<label for="exitTimeout" class="form-label">{{ $t('apps.exit_timeout') }}</label>
<input type="number" class="form-control monospace" id="exitTimeout" aria-describedby="exitTimeoutHelp"
v-model="editForm['exit-timeout']" min="0" placeholder="5" />
<div id="exitTimeoutHelp" class="form-text">{{ $t('apps.exit_timeout_desc') }}</div>
</div>
<div class="env-hint alert alert-info overflow-auto"> <div class="env-hint alert alert-info overflow-auto">
<div class="form-text"> <div class="form-text">
<h4>{{ $t('apps.env_vars_about') }}</h4> <h4>{{ $t('apps.env_vars_about') }}</h4>
@@ -407,15 +431,23 @@
<i class="fa-solid fa-xl fa-circle-info"></i> {{ $t('apps.env_sunshine_compatibility') }} <i class="fa-solid fa-xl fa-circle-info"></i> {{ $t('apps.env_sunshine_compatibility') }}
</div> </div>
<div class="form-text" v-if="platform === 'windows'"><b>{{ $t('apps.env_rtss_cli_example') }}</b> <Platformlayout v-bind:platform="platform">
<pre>cmd /C \path\to\rtss-cli.exe limit:set %APOLLO_CLIENT_FPS%</pre> <template #windows>
</div> <div class="form-text"><b>{{ $t('apps.env_rtss_cli_example') }}</b>
<div class="form-text" v-else-if="platform === 'linux'"><b>{{ $t('apps.env_xrandr_example') }}</b> <pre>cmd /C \path\to\rtss-cli.exe limit:set %APOLLO_CLIENT_FPS%</pre>
<pre>sh -c "xrandr --output HDMI-1 --mode \"${APOLLO_CLIENT_WIDTH}x${APOLLO_CLIENT_HEIGHT}\" --rate ${APOLLO_CLIENT_FPS}"</pre> </div>
</div> </template>
<div class="form-text" v-else-if="platform === 'macos'"><b>{{ $t('apps.env_displayplacer_example') }}</b> <template #linux>
<pre>sh -c "displayplacer "id:&lt;screenId&gt; res:${APOLLO_CLIENT_WIDTH}x${APOLLO_CLIENT_HEIGHT} hz:${APOLLO_CLIENT_FPS} scaling:on origin:(0,0) degree:0""</pre> <div class="form-text"><b>{{ $t('apps.env_xrandr_example') }}</b>
</div> <pre>sh -c "xrandr --output HDMI-1 --mode \"${APOLLO_CLIENT_WIDTH}x${APOLLO_CLIENT_HEIGHT}\" --rate ${APOLLO_CLIENT_FPS}"</pre>
</div>
</template>
<template #macos>
<div class="form-text"><b>{{ $t('apps.env_displayplacer_example') }}</b>
<pre>sh -c "displayplacer "id:&lt;screenId&gt; res:${APOLLO_CLIENT_WIDTH}x${APOLLO_CLIENT_HEIGHT} hz:${APOLLO_CLIENT_FPS} scaling:on origin:(0,0) degree:0""</pre>
</div>
</template>
</Platformlayout>
<div class="form-text"><a <div class="form-text"><a
href="https://docs.lizardbyte.dev/projects/sunshine/latest/md_docs_2app__examples.html" href="https://docs.lizardbyte.dev/projects/sunshine/latest/md_docs_2app__examples.html"
target="_blank">{{ $t('_common.see_more') }}</a></div> target="_blank">{{ $t('_common.see_more') }}</a></div>
@@ -441,6 +473,7 @@
import { initApp } from './init' import { initApp } from './init'
import Navbar from './Navbar.vue' import Navbar from './Navbar.vue'
import Checkbox from './Checkbox.vue' import Checkbox from './Checkbox.vue'
import Platformlayout from './PlatformLayout.vue'
import { Dropdown } from 'bootstrap/dist/js/bootstrap' import { Dropdown } from 'bootstrap/dist/js/bootstrap'
const newApp = { const newApp = {
@@ -460,12 +493,16 @@
"per-client-app-identity": false, "per-client-app-identity": false,
"allow-client-commands": true, "allow-client-commands": true,
"virtual-display": false, "virtual-display": false,
"gamepad": ""
} }
console.log(Platformlayout)
const app = createApp({ const app = createApp({
components: { components: {
Navbar, Navbar,
Checkbox Checkbox,
Platformlayout
}, },
data() { data() {
return { return {
@@ -7,6 +7,8 @@
"cancel": "Cancel", "cancel": "Cancel",
"cmd_name": "Command Name", "cmd_name": "Command Name",
"cmd_val": "Command Value", "cmd_val": "Command Value",
"default": "Default",
"default_global": "Default (Global)",
"disabled": "Disabled", "disabled": "Disabled",
"disabled_def": "Disabled (default)", "disabled_def": "Disabled (default)",
"disabled_def_cbox": "Default: unchecked", "disabled_def_cbox": "Default: unchecked",
@@ -7,6 +7,8 @@
"cancel": "取消", "cancel": "取消",
"cmd_name": "命令名称", "cmd_name": "命令名称",
"cmd_val": "命令值", "cmd_val": "命令值",
"default": "默认",
"default_global": "默认(全局)",
"disabled": "禁用", "disabled": "禁用",
"disabled_def": "禁用(默认)", "disabled_def": "禁用(默认)",
"disabled_def_cbox": "默认值:未选", "disabled_def_cbox": "默认值:未选",