Add virtual display config to apps
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -64,6 +64,7 @@ namespace proc {
|
||||
bool elevated;
|
||||
bool auto_detach;
|
||||
bool wait_all;
|
||||
bool virtual_display;
|
||||
std::chrono::seconds exit_timeout;
|
||||
};
|
||||
|
||||
|
||||
BIN
src_assets/common/assets/virtual_desktop.png
Normal file
BIN
src_assets/common/assets/virtual_desktop.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 96 KiB |
@@ -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>
|
||||
|
||||
@@ -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",
|
||||
|
||||
12
third-party/sudovda/sudovda.h
vendored
12
third-party/sudovda/sudovda.h
vendored
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user