Add app config to set virtual display as primary
This commit is contained in:
@@ -36,6 +36,24 @@ LONG changeDisplaySettings(const wchar_t* deviceName, int width, int height, int
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::wstring getPrimaryDisplay() {
|
||||
DISPLAY_DEVICEW displayDevice;
|
||||
displayDevice.cb = sizeof(DISPLAY_DEVICE);
|
||||
|
||||
std::wstring primaryDeviceName;
|
||||
|
||||
int deviceIndex = 0;
|
||||
while (EnumDisplayDevicesW(NULL, deviceIndex, &displayDevice, 0)) {
|
||||
if (displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
|
||||
primaryDeviceName = displayDevice.DeviceName;
|
||||
break;
|
||||
}
|
||||
deviceIndex++;
|
||||
}
|
||||
|
||||
return primaryDeviceName;
|
||||
}
|
||||
|
||||
bool setPrimaryDisplay(const wchar_t* primaryDeviceName) {
|
||||
DEVMODEW primaryDevMode{};
|
||||
if (!getDeviceSettings(primaryDeviceName, primaryDevMode)) {
|
||||
@@ -178,7 +196,7 @@ std::wstring createVirtualDisplay(
|
||||
retryInterval *= 2;
|
||||
}
|
||||
|
||||
wprintf(L"[SUDOVDA] Virtual display added successfully: %ws\n", deviceName);
|
||||
wprintf(L"[SUDOVDA] Virtual display added successfully: %ls\n", deviceName);
|
||||
printf("[SUDOVDA] Configuration: W: %d, H: %d, FPS: %d\n", width, height, fps);
|
||||
|
||||
return std::wstring(deviceName);
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace VDISPLAY {
|
||||
|
||||
LONG getDeviceSettings(const wchar_t* deviceName, DEVMODEW& devMode);
|
||||
LONG changeDisplaySettings(const wchar_t* deviceName, int width, int height, int refresh_rate);
|
||||
std::wstring getPrimaryDisplay();
|
||||
bool setPrimaryDisplay(const wchar_t* primaryDeviceName);
|
||||
|
||||
bool startPingThread();
|
||||
|
||||
@@ -208,15 +208,15 @@ namespace proc {
|
||||
|
||||
#ifdef _WIN32
|
||||
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();
|
||||
}
|
||||
|
||||
if (vdisplayDriverInitialized) {
|
||||
std::wstring vdisplay_name = VDISPLAY::createVirtualDisplay(
|
||||
std::wstring prevPrimaryDisplayName = VDISPLAY::getPrimaryDisplay();
|
||||
|
||||
std::wstring vdisplayName = VDISPLAY::createVirtualDisplay(
|
||||
launch_session->unique_id.c_str(),
|
||||
launch_session->device_name.c_str(),
|
||||
_app.name.c_str(),
|
||||
@@ -225,11 +225,33 @@ 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());
|
||||
std::wstring currentPrimaryDisplayName = VDISPLAY::getPrimaryDisplay();
|
||||
|
||||
// Apply display settings
|
||||
VDISPLAY::changeDisplaySettings(vdisplayName.c_str(), launch_session->width, launch_session->height, launch_session->fps);
|
||||
|
||||
// Determine if we need to set the virtual display as primary
|
||||
bool shouldSetPrimary = false;
|
||||
|
||||
if (launch_session->virtual_display || _app.virtual_display_primary) {
|
||||
shouldSetPrimary = (currentPrimaryDisplayName != vdisplayName);
|
||||
} else {
|
||||
shouldSetPrimary = (currentPrimaryDisplayName != prevPrimaryDisplayName);
|
||||
}
|
||||
|
||||
// Set primary display if needed
|
||||
if (shouldSetPrimary) {
|
||||
VDISPLAY::setPrimaryDisplay(
|
||||
(launch_session->virtual_display || _app.virtual_display_primary)
|
||||
? vdisplayName.c_str()
|
||||
: prevPrimaryDisplayName.c_str()
|
||||
);
|
||||
}
|
||||
|
||||
// Set virtual_display to true when everything went fine
|
||||
this->virtual_display = true;
|
||||
this->display_name = platf::to_utf8(vdisplayName);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -369,7 +391,7 @@ namespace proc {
|
||||
_pipe.reset();
|
||||
|
||||
#ifdef _WIN32
|
||||
if (vdisplayDriverInitialized && _launch_session && _launch_session->virtual_display) {
|
||||
if (vdisplayDriverInitialized && _launch_session && this->virtual_display) {
|
||||
VDISPLAY::removeVirtualDisplay(_launch_session->display_guid);
|
||||
}
|
||||
#endif
|
||||
@@ -387,6 +409,7 @@ namespace proc {
|
||||
_app_id = -1;
|
||||
display_name.clear();
|
||||
_launch_session.reset();
|
||||
virtual_display = false;
|
||||
}
|
||||
|
||||
const std::vector<ctx_t> &
|
||||
@@ -640,6 +663,7 @@ namespace proc {
|
||||
ctx.name = "Virtual Display";
|
||||
ctx.image_path = parse_env_val(this_env, "virtual_desktop.png");
|
||||
ctx.virtual_display = true;
|
||||
ctx.virtual_display_primary = true;
|
||||
|
||||
ctx.elevated = false;
|
||||
ctx.auto_detach = true;
|
||||
@@ -676,6 +700,7 @@ namespace proc {
|
||||
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");
|
||||
auto virtual_display_primary = app_node.get_optional<bool>("virtual-display-primary");
|
||||
|
||||
std::vector<proc::cmd_t> prep_cmds;
|
||||
if (!exclude_global_prep.value_or(false)) {
|
||||
@@ -744,6 +769,7 @@ namespace proc {
|
||||
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);
|
||||
ctx.virtual_display_primary = virtual_display_primary.value_or(true);
|
||||
|
||||
auto possible_ids = calculate_app_id(name, ctx.image_path, i++);
|
||||
if (ids.count(std::get<0>(possible_ids)) == 0) {
|
||||
|
||||
@@ -65,6 +65,7 @@ namespace proc {
|
||||
bool auto_detach;
|
||||
bool wait_all;
|
||||
bool virtual_display;
|
||||
bool virtual_display_primary;
|
||||
std::chrono::seconds exit_timeout;
|
||||
};
|
||||
|
||||
@@ -73,6 +74,7 @@ namespace proc {
|
||||
KITTY_DEFAULT_CONSTR_MOVE_THROW(proc_t)
|
||||
|
||||
std::string display_name;
|
||||
bool virtual_display;
|
||||
|
||||
proc_t(
|
||||
boost::process::environment &&env,
|
||||
|
||||
@@ -249,8 +249,6 @@ namespace system_tray {
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Tray playing: %s\n", app_name.c_str());
|
||||
|
||||
tray.notification_title = NULL;
|
||||
tray.notification_text = NULL;
|
||||
tray.notification_cb = NULL;
|
||||
|
||||
@@ -229,12 +229,19 @@
|
||||
<div class="form-text">{{ $t('apps.wait_all_desc') }}</div>
|
||||
</div>
|
||||
<!-- use virtual display -->
|
||||
<div class="mb-3 form-check">
|
||||
<div class="mb-3 form-check" v-if="platform === 'windows'">
|
||||
<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>
|
||||
<!-- set virtual display to primary -->
|
||||
<div class="mb-3 form-check" v-if="platform === 'windows' && editForm['virtual-display'] == 'true'">
|
||||
<label for="virtualDisplayPrimary" class="form-check-label">{{ $t('apps.virtual_display_primary') }}</label>
|
||||
<input type="checkbox" class="form-check-input" id="virtualDisplayPrimary" v-model="editForm['virtual-display-primary']"
|
||||
true-value="true" false-value="false" />
|
||||
<div class="form-text">{{ $t('apps.virtual_display_primary_desc') }}</div>
|
||||
</div>
|
||||
<!-- exit timeout -->
|
||||
<div class="mb-3">
|
||||
<label for="exitTimeout" class="form-label">{{ $t('apps.exit_timeout') }}</label>
|
||||
@@ -373,11 +380,13 @@
|
||||
import { createApp } from 'vue'
|
||||
import { initApp } from './init'
|
||||
import Navbar from './Navbar.vue'
|
||||
import PlatformLayout from './PlatformLayout.vue'
|
||||
import { Dropdown } from 'bootstrap/dist/js/bootstrap'
|
||||
|
||||
const app = createApp({
|
||||
components: {
|
||||
Navbar
|
||||
Navbar,
|
||||
PlatformLayout
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -417,7 +426,8 @@
|
||||
"exit-timeout": 5,
|
||||
"prep-cmd": [],
|
||||
detached: [],
|
||||
"image-path": ""
|
||||
"image-path": "",
|
||||
"virtual-display-primary": true
|
||||
};
|
||||
this.editForm.index = -1;
|
||||
this.showEditForm = true;
|
||||
@@ -443,6 +453,9 @@
|
||||
if (this.editForm["exit-timeout"] === undefined) {
|
||||
this.editForm["exit-timeout"] = 5;
|
||||
}
|
||||
if (typeof this.editForm["virtual-display-primary"] === "undefined") {
|
||||
this.editForm["virtual-display-primary"] = true;
|
||||
}
|
||||
this.showEditForm = true;
|
||||
},
|
||||
showDeleteForm(id) {
|
||||
|
||||
@@ -81,7 +81,9 @@
|
||||
"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",
|
||||
"virtual_display": "Use Virtual Display",
|
||||
"virtual_display_desc": "Always use Virtual Display on this app, overriding client request."
|
||||
"virtual_display_desc": "Always use Virtual Display on this app, overriding client request. Please make sure the SudoVDA driver is installed and enabled.",
|
||||
"virtual_display_primary": "Set Virtual Display as Primary Display",
|
||||
"virtual_display_primary_desc": "Automatically set the Virtual Display as Primary Display when the app starts. (Recommended to keep on)"
|
||||
},
|
||||
"config": {
|
||||
"adapter_name": "Adapter Name",
|
||||
|
||||
Reference in New Issue
Block a user