Add virtual display config to apps

This commit is contained in:
Yukino Song
2024-08-19 07:08:39 +08:00
parent 833c902a56
commit 25eb5c8714
6 changed files with 56 additions and 11 deletions

View File

@@ -58,9 +58,6 @@ namespace proc {
std::unique_ptr<platf::deinit_t>
init() {
#ifdef _WIN32
vdisplayDriverInitialized = VDISPLAY::openVDisplayDevice();
#endif
return std::make_unique<deinit_t>();
}
@@ -210,7 +207,9 @@ namespace proc {
_launch_session = launch_session;
#ifdef _WIN32
if (launch_session->virtual_display) {
if (launch_session->virtual_display || _app.virtual_display) {
// Mark as no vdisplay by default
launch_session->virtual_display = false;
if (!vdisplayDriverInitialized) {
// Try init driver again
vdisplayDriverInitialized = VDISPLAY::openVDisplayDevice();
@@ -226,6 +225,8 @@ namespace proc {
launch_session->fps,
launch_session->display_guid
);
// Set virtual_display to true when everything went fine
launch_session->virtual_display = true;
VDISPLAY::changeDisplaySettings(vdisplay_name.c_str(), launch_session->width, launch_session->height, launch_session->fps);
VDISPLAY::setPrimaryDisplay(vdisplay_name.c_str());
@@ -633,6 +634,32 @@ namespace proc {
std::set<std::string> ids;
std::vector<proc::ctx_t> apps;
int i = 0;
if (vdisplayDriverInitialized) {
proc::ctx_t ctx;
ctx.name = "Virtual Display";
ctx.image_path = parse_env_val(this_env, "virtual_desktop.png");
ctx.virtual_display = true;
ctx.elevated = false;
ctx.auto_detach = true;
ctx.wait_all = true;
ctx.exit_timeout = 5s;
auto possible_ids = calculate_app_id(ctx.name, ctx.image_path, i++);
if (ids.count(std::get<0>(possible_ids)) == 0) {
// Avoid using index to generate id if possible
ctx.id = std::get<0>(possible_ids);
}
else {
// Fallback to include index on collision
ctx.id = std::get<1>(possible_ids);
}
ids.insert(ctx.id);
apps.emplace_back(std::move(ctx));
}
for (auto &[_, app_node] : apps_node) {
proc::ctx_t ctx;
@@ -648,6 +675,7 @@ namespace proc {
auto auto_detach = app_node.get_optional<bool>("auto-detach"s);
auto wait_all = app_node.get_optional<bool>("wait-all"s);
auto exit_timeout = app_node.get_optional<int>("exit-timeout"s);
auto virtual_display = app_node.get_optional<bool>("virtual-display");
std::vector<proc::cmd_t> prep_cmds;
if (!exclude_global_prep.value_or(false)) {
@@ -715,6 +743,7 @@ namespace proc {
ctx.auto_detach = auto_detach.value_or(true);
ctx.wait_all = wait_all.value_or(true);
ctx.exit_timeout = std::chrono::seconds { exit_timeout.value_or(5) };
ctx.virtual_display = virtual_display.value_or(false);
auto possible_ids = calculate_app_id(name, ctx.image_path, i++);
if (ids.count(std::get<0>(possible_ids)) == 0) {
@@ -747,6 +776,12 @@ namespace proc {
void
refresh(const std::string &file_name) {
#ifdef _WIN32
if (!vdisplayDriverInitialized) {
vdisplayDriverInitialized = VDISPLAY::openVDisplayDevice();
}
#endif
auto proc_opt = proc::parse(file_name);
if (proc_opt) {

View File

@@ -64,6 +64,7 @@ namespace proc {
bool elevated;
bool auto_detach;
bool wait_all;
bool virtual_display;
std::chrono::seconds exit_timeout;
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

View File

@@ -228,6 +228,13 @@
true-value="true" false-value="false" />
<div class="form-text">{{ $t('apps.wait_all_desc') }}</div>
</div>
<!-- use virtual display -->
<div class="mb-3 form-check">
<label for="virtualDisplay" class="form-check-label">{{ $t('apps.virtual_display') }}</label>
<input type="checkbox" class="form-check-input" id="virtualDisplay" v-model="editForm['virtual-display']"
true-value="true" false-value="false" />
<div class="form-text">{{ $t('apps.virtual_display_desc') }}</div>
</div>
<!-- exit timeout -->
<div class="mb-3">
<label for="exitTimeout" class="form-label">{{ $t('apps.exit_timeout') }}</label>

View File

@@ -79,7 +79,9 @@
"wait_all": "Continue streaming until all app processes exit",
"wait_all_desc": "This will continue streaming until all processes started by the app have terminated. When unchecked, streaming will stop when the initial app process exits, even if other app processes are still running.",
"working_dir": "Working Directory",
"working_dir_desc": "The working directory that should be passed to the process. For example, some applications use the working directory to search for configuration files. If not set, Apollo will default to the parent directory of the command"
"working_dir_desc": "The working directory that should be passed to the process. For example, some applications use the working directory to search for configuration files. If not set, Apollo will default to the parent directory of the command",
"virtual_display": "Use Virtual Display",
"virtual_display_desc": "Always use Virtual Display on this app, overriding client request."
},
"config": {
"adapter_name": "Adapter Name",

View File

@@ -79,7 +79,7 @@ static const bool AddVirtualDisplay(HANDLE hDevice, UINT Width, UINT Height, UIN
);
if (!success) {
std::cerr << "AddVirtualDisplay failed: " << GetLastError() << std::endl;
std::cerr << "[SUVDA] AddVirtualDisplay failed: " << GetLastError() << std::endl;
}
return success;
@@ -100,7 +100,7 @@ static const bool RemoveVirtualDisplay(HANDLE hDevice, const GUID& MonitorGuid)
);
if (!success) {
std::cerr << "RemoveVirtualDisplay failed: " << GetLastError() << std::endl;
std::cerr << "[SUVDA] RemoveVirtualDisplay failed: " << GetLastError() << std::endl;
}
return success;
@@ -121,7 +121,7 @@ static const bool SetRenderAdapter(HANDLE hDevice, const LUID& AdapterLuid) {
);
if (!success) {
std::cerr << "SetRenderAdapter failed: " << GetLastError() << std::endl;
std::cerr << "[SUVDA] SetRenderAdapter failed: " << GetLastError() << std::endl;
}
return success;
@@ -141,7 +141,7 @@ static const bool GetWatchdogTimeout(HANDLE hDevice, VIRTUAL_DISPLAY_GET_WATCHDO
);
if (!success) {
std::cerr << "DeviceIoControl failed: " << GetLastError() << std::endl;
std::cerr << "[SUVDA] GetWatchdogTimeout failed: " << GetLastError() << std::endl;
}
return success;
@@ -161,7 +161,7 @@ static const bool GetProtocolVersion(HANDLE hDevice, VIRTUAL_DISPLAY_GET_PROTOCO
);
if (!success) {
std::cerr << "DeviceIoControl failed: " << GetLastError() << std::endl;
std::cerr << "[SUVDA] GetProtocolVersion failed: " << GetLastError() << std::endl;
}
return success;
@@ -206,7 +206,7 @@ static const bool PingDriver(HANDLE hDevice) {
);
if (!success) {
std::cerr << "DeviceIoControl failed: " << GetLastError() << std::endl;
std::cerr << "[SUVDA] PingDriver failed: " << GetLastError() << std::endl;
}
return success;