diff --git a/docs/changelog.markdown b/docs/changelog.markdown index 7022475f4..4100a14a7 100644 --- a/docs/changelog.markdown +++ b/docs/changelog.markdown @@ -61,6 +61,9 @@ brief notes about them may accumulate here. * The multiplexer server has been moved into its own `wezterm-mux-server` executable. You will need to revise your `serve_command` configuration. +* Windows: when started in an RDP session, force the use + of the Mesa software renderer to work around problems with + RDP GPU emulation. ### 20200909-002054-4c9af461 diff --git a/wezterm/src/gui/mod.rs b/wezterm/src/gui/mod.rs index ff401fb66..ec276dd15 100644 --- a/wezterm/src/gui/mod.rs +++ b/wezterm/src/gui/mod.rs @@ -53,6 +53,15 @@ impl GuiFrontEnd { Connection::disable_wayland(); } } + #[cfg(windows)] + { + if is_running_in_rdp_session() { + // Using OpenGL in RDP has problematic behavior upon + // disconnect, so we force the use of software rendering. + log::trace!("Running in an RDP session, use SWRAST"); + prefer_swrast(); + } + } let connection = Connection::init()?; let front_end = Rc::new(GuiFrontEnd { connection }); diff --git a/window/src/os/windows/mod.rs b/window/src/os/windows/mod.rs index 0926cf483..9b72fe642 100644 --- a/window/src/os/windows/mod.rs +++ b/window/src/os/windows/mod.rs @@ -17,3 +17,38 @@ fn wide_string(s: &str) -> Vec { .chain(std::iter::once(0)) .collect() } + +/// Returns true if we are running in an RDP session. +/// See +pub fn is_running_in_rdp_session() -> bool { + use winapi::shared::minwindef::DWORD; + use winapi::um::processthreadsapi::{GetCurrentProcessId, ProcessIdToSessionId}; + use winapi::um::winuser::{GetSystemMetrics, SM_REMOTESESSION}; + use winreg::{enums::HKEY_LOCAL_MACHINE, RegKey}; + + if unsafe { GetSystemMetrics(SM_REMOTESESSION) } != 0 { + return true; + } + + let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); + let terminal_server = + match hklm.open_subkey("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\") { + Ok(k) => k, + Err(_) => return false, + }; + + let glass_session_id: DWORD = match terminal_server.get_value("GlassSessionId") { + Ok(sess) => sess, + Err(_) => return false, + }; + + unsafe { + let mut current_session = 0; + if ProcessIdToSessionId(GetCurrentProcessId(), &mut current_session) != 0 { + // If we're not the glass session then we're a remote session + current_session != glass_session_id + } else { + false + } + } +}