From 846522037f3fac94e8c8cbc80481211135e16f98 Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 6 May 2024 14:01:59 +0800 Subject: [PATCH] fix: mstsc switch, plug in virtual displays (#7913) * fix: mstsc switch, plug in virtual displays Signed-off-by: fufesou * Update display_service.rs --------- Signed-off-by: fufesou Co-authored-by: fufesou Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com> --- src/server/connection.rs | 6 +++++- src/server/display_service.rs | 40 +++++++++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/server/connection.rs b/src/server/connection.rs index f5330b323..6bf9602e0 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1231,8 +1231,12 @@ impl Connection { } else { #[cfg(not(any(target_os = "android", target_os = "ios")))] { + #[cfg(not(all(windows, feature = "virtual_display_driver")))] + let displays = display_service::try_get_displays(); + #[cfg(all(windows, feature = "virtual_display_driver"))] + let displays = display_service::try_get_displays_add_amyuni_headless(); pi.resolutions = Some(SupportedResolutions { - resolutions: display_service::try_get_displays() + resolutions: displays .map(|displays| { displays .get(self.display_idx) diff --git a/src/server/display_service.rs b/src/server/display_service.rs index d3caa1362..386371c12 100644 --- a/src/server/display_service.rs +++ b/src/server/display_service.rs @@ -372,15 +372,47 @@ pub fn try_get_displays() -> ResultType> { Ok(Display::all()?) } +#[inline] #[cfg(all(windows, feature = "virtual_display_driver"))] pub fn try_get_displays() -> ResultType> { + try_get_displays_(false) +} + +// We can't get full control of the virtual display if we use amyuni idd. +// If we add a virtual display, we cannot remove it automatically. +// So when using amyuni idd, we only add a virtual display for headless if it is required. +// eg. when the client is connecting. +#[inline] +#[cfg(all(windows, feature = "virtual_display_driver"))] +pub fn try_get_displays_add_amyuni_headless() -> ResultType> { + try_get_displays_(true) +} + +#[inline] +#[cfg(all(windows, feature = "virtual_display_driver"))] +pub fn try_get_displays_(add_amyuni_headless: bool) -> ResultType> { let mut displays = Display::all()?; + + // Do not add virtual display if the platform is not installed or the virtual display is not supported. + if !crate::platform::is_installed() || !virtual_display_manager::is_virtual_display_supported() { + return Ok(displays); + } + + // Enable headless virtual display when + // 1. `amyuni` idd is not used. + // 2. `amyuni` idd is used and `add_amyuni_headless` is true. + if virtual_display_manager::is_amyuni_idd() && !add_amyuni_headless { + return Ok(displays); + } + + // If is switching session, no displays may be detected. But it is not a real case. + if displays.is_empty() && crate::platform::desktop_changed() { + return Ok(displays); + } + let no_displays_v = no_displays(&displays); virtual_display_manager::set_can_plug_out_all(!no_displays_v); - if crate::platform::is_installed() - && no_displays_v - && virtual_display_manager::is_virtual_display_supported() - { + if no_displays_v { log::debug!("no displays, create virtual display"); if let Err(e) = virtual_display_manager::plug_in_headless() { log::error!("plug in headless failed {}", e);