From 0789093ffab5819445a560763d064d5c13fc4d82 Mon Sep 17 00:00:00 2001 From: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com> Date: Sun, 29 Dec 2024 03:19:26 +0100 Subject: [PATCH 1/6] Feature: Scale rdp session and use UpdateSessionDisplaySettings instead of reconnect --- .../Controls/RemoteDesktopControl.xaml | 5 +- .../Controls/RemoteDesktopControl.xaml.cs | 227 +++++++++++++++--- 2 files changed, 191 insertions(+), 41 deletions(-) diff --git a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml index 8b457bad50..19e54d58f8 100644 --- a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml +++ b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml @@ -20,7 +20,8 @@ + Background="{DynamicResource ResourceKey=MahApps.Brushes.Window.Background}" + DpiChanged="WindowsFormsHost_DpiChanged"> - + diff --git a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs index 7c7e1fda2c..faef5991b3 100644 --- a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs +++ b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs @@ -1,21 +1,24 @@ // Documenation: https://docs.microsoft.com/en-us/windows/desktop/termserv/remote-desktop-web-connection-reference -using System; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Input; using AxMSTSCLib; +using log4net; using MSTSCLib; using NETworkManager.Localization.Resources; using NETworkManager.Models.RemoteDesktop; using NETworkManager.Settings; using NETworkManager.Utilities; +using System; +using System.Diagnostics; +using System.Windows; +using System.Windows.Input; +using System.Windows.Threading; namespace NETworkManager.Controls; public partial class RemoteDesktopControl : UserControlBase, IDragablzTabItem { #region Variables + private static readonly ILog Log = LogManager.GetLogger(typeof(RemoteDesktopControl)); private bool _initialized; private bool _closed; @@ -23,6 +26,8 @@ public partial class RemoteDesktopControl : UserControlBase, IDragablzTabItem private readonly Guid _tabId; private readonly RemoteDesktopSessionInfo _sessionInfo; + private DispatcherTimer _adjustScreenTimer; + // Fix WindowsFormsHost width private double _rdpClientWidth; @@ -132,6 +137,7 @@ public RemoteDesktopControl(Guid tabId, RemoteDesktopSessionInfo sessionInfo) Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted; } + private void UserControl_Loaded(object sender, RoutedEventArgs e) { // Connect after the control is drawn and only on the first init @@ -201,17 +207,31 @@ private void Connect() // Display RdpClient.ColorDepth = _sessionInfo.ColorDepth; // 8, 15, 16, 24 + double desktopWidth, desktopHeight; + if (_sessionInfo.AdjustScreenAutomatically || _sessionInfo.UseCurrentViewSize) { - RdpClient.DesktopWidth = (int)RdpGrid.ActualWidth; - RdpClient.DesktopHeight = (int)RdpGrid.ActualHeight; + desktopWidth = RdpGrid.ActualWidth; + desktopHeight = RdpGrid.ActualHeight; } else { - RdpClient.DesktopWidth = _sessionInfo.DesktopWidth; - RdpClient.DesktopHeight = _sessionInfo.DesktopHeight; + desktopWidth = _sessionInfo.DesktopWidth; + desktopHeight = _sessionInfo.DesktopHeight; } + var scaleFactor = GetDpiScaleFactor(); + + desktopWidth = desktopWidth * scaleFactor / 100; + desktopHeight = desktopHeight * scaleFactor / 100; + + RdpClient.DesktopWidth = (int)desktopWidth; + RdpClient.DesktopHeight = (int)desktopHeight; + + // Initial scaling before connecting + ((IMsRdpExtendedSettings)RdpClient.GetOcx()).set_Property("DesktopScaleFactor", GetDesktopScaleFactor()); + ((IMsRdpExtendedSettings)RdpClient.GetOcx()).set_Property("DeviceScaleFactor", GetDeviceScaleFactor()); + // Authentication RdpClient.AdvancedSettings9.AuthenticationLevel = _sessionInfo.AuthenticationLevel; RdpClient.AdvancedSettings9.EnableCredSspSupport = _sessionInfo.EnableCredSspSupport; @@ -307,7 +327,7 @@ private void Connect() // Connect RdpClient.Connect(); - FixWindowsFormsHostSize(); + FixWindowsFormsHostSize(desktopWidth, desktopHeight); } private void Reconnect() @@ -317,16 +337,30 @@ private void Reconnect() IsConnecting = true; - // Update screen size + double desktopWidth, desktopHeight; + if (_sessionInfo.AdjustScreenAutomatically || _sessionInfo.UseCurrentViewSize) { - RdpClient.DesktopWidth = (int)RdpGrid.ActualWidth; - RdpClient.DesktopHeight = (int)RdpGrid.ActualHeight; + desktopWidth = RdpGrid.ActualWidth; + desktopHeight = RdpGrid.ActualHeight; + } + else + { + desktopWidth = _sessionInfo.DesktopWidth; + desktopHeight = _sessionInfo.DesktopHeight; } + var scaleFactor = GetDpiScaleFactor(); + + desktopWidth = desktopWidth * scaleFactor / 100; + desktopHeight = desktopHeight * scaleFactor / 100; + + RdpClient.DesktopWidth = (int)desktopWidth; + RdpClient.DesktopHeight = (int)desktopHeight; + RdpClient.Connect(); - FixWindowsFormsHostSize(); + FixWindowsFormsHostSize(desktopWidth, desktopHeight); } public void FullScreen() @@ -337,22 +371,83 @@ public void FullScreen() RdpClient.FullScreen = true; } - public void AdjustScreen() + public async void AdjustScreen() { + if (IsConnecting) + return; + if (!IsConnected) return; - // Adjust screen size + if (IsReconnecting) + return; + + IsReconnecting = true; + + double desktopWidth, desktopHeight; + if (_sessionInfo.AdjustScreenAutomatically || _sessionInfo.UseCurrentViewSize) - RdpClient.Reconnect((uint)RdpGrid.ActualWidth, (uint)RdpGrid.ActualHeight); + { + desktopWidth = RdpGrid.ActualWidth; + desktopHeight = RdpGrid.ActualHeight; + } + else + { + desktopWidth = _sessionInfo.DesktopWidth; + desktopHeight = _sessionInfo.DesktopHeight; + } + + var scaleFactor = GetDpiScaleFactor(); + + desktopWidth = desktopWidth * scaleFactor / 100; + desktopHeight = desktopHeight * scaleFactor / 100; - FixWindowsFormsHostSize(); + try + { + // This may fail if the RDP session was connected recently + RdpClient.UpdateSessionDisplaySettings((uint)desktopWidth, (uint)desktopHeight, (uint)desktopWidth, (uint)desktopHeight, 0, GetDesktopScaleFactor(), GetDeviceScaleFactor()); + } + catch (Exception ex) + { + Log.Error("Error while adjusting screen", ex); + } + + FixWindowsFormsHostSize(desktopWidth, desktopHeight); + + IsReconnecting = false; } - private void FixWindowsFormsHostSize() + /// + /// Adjust the screen when the size of the control changes. + /// Prevent multiple calls while resizing by using a timer. + /// + private void AdjustScreenOnSizeChanged() { - RdpClientWidth = RdpClient.DesktopWidth; - RdpClientHeight = RdpClient.DesktopHeight; + if (_adjustScreenTimer == null) + { + _adjustScreenTimer = new DispatcherTimer + { + Interval = TimeSpan.FromMilliseconds(250) + }; + + _adjustScreenTimer.Tick += (sender, args) => + { + _adjustScreenTimer.Stop(); + + AdjustScreen(); + }; + } + + _adjustScreenTimer.Start(); + } + + private void FixWindowsFormsHostSize(double width, double height) + { + RdpClientWidth = width; + RdpClientHeight = height; + + Debug.WriteLine($"Values: {width} x {height}"); + Debug.WriteLine($"RDPClient: {RdpClient.DesktopWidth} x {RdpClient.DesktopHeight}"); } public void SendKey(Keystroke keystroke) @@ -487,6 +582,73 @@ private static string GetDisconnectReason(int reason) }; } + /// + /// Get the desktop scale factor based on the DPI scale factor. + /// Supported values are 100, 125, 150, 175, 200. + /// See docs: + /// https://learn.microsoft.com/en-us/windows/win32/termserv/imsrdpextendedsettings-property --> DesktopScaleFactor + /// https://cdnweb.devolutions.net/blog/pdf/smart-resizing-and-high-dpi-issues-in-remote-desktop-manager.pdf + /// + /// + protected uint GetDesktopScaleFactor() + { + var scaleFactor = GetDpiScaleFactor(); + + switch (scaleFactor) + { + case 125: + return 125; + case 150: + case 175: + return 150; + case 200: + return 200; + } + + if (scaleFactor > 200) + return 200; + + return 100; + } + + /// + /// Get the device scale factor based on the DPI scale factor. + /// Supported values are 100, 140, 180. + /// See docs: + /// https://learn.microsoft.com/en-us/windows/win32/termserv/imsrdpextendedsettings-property --> DeviceScaleFactor + /// https://cdnweb.devolutions.net/blog/pdf/smart-resizing-and-high-dpi-issues-in-remote-desktop-manager.pdf + /// + /// Device scale factor. + protected uint GetDeviceScaleFactor() + { + var scaleFactor = GetDpiScaleFactor(); + + switch (scaleFactor) + { + case 125: + case 150: + case 175: + return 140; + case 200: + return 180; + } + + if (scaleFactor > 200) + return 180; + + return 100; + } + + /// + /// Get the current DPI scale factor like 100, 125, 150, 175, 200, 225, etc. + /// + /// Returns the DPI scale factor. + public uint GetDpiScaleFactor() + { + var x = System.Windows.Media.VisualTreeHelper.GetDpi(this); + + return (uint)(x.PixelsPerDip * 100); + } #endregion #region Events @@ -508,26 +670,13 @@ private void RdpClient_OnDisconnected(object sender, IMsTscAxEvents_OnDisconnect private void RdpGrid_SizeChanged(object sender, SizeChangedEventArgs e) { // Resize the RDP screen size when the window size changes - if (IsConnected && _sessionInfo.AdjustScreenAutomatically && !IsReconnecting) - ReconnectOnSizeChanged().ConfigureAwait(false); + if (_sessionInfo.AdjustScreenAutomatically) + AdjustScreenOnSizeChanged(); } + #endregion - private async Task ReconnectOnSizeChanged() + private void WindowsFormsHost_DpiChanged(object sender, DpiChangedEventArgs e) { - IsReconnecting = true; - - do // Prevent to many requests - { - await Task.Delay(250); - } while (Mouse.LeftButton == MouseButtonState.Pressed); - - // Reconnect with the new screen size - RdpClient.Reconnect((uint)RdpGrid.ActualWidth, (uint)RdpGrid.ActualHeight); - - FixWindowsFormsHostSize(); - - IsReconnecting = false; + AdjustScreen(); } - - #endregion -} \ No newline at end of file +} From 0b714ba2d1a4621d43ad039d0d18dedbfc80d35d Mon Sep 17 00:00:00 2001 From: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com> Date: Sun, 29 Dec 2024 03:25:27 +0100 Subject: [PATCH 2/6] Chore: Cleanup --- Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs index faef5991b3..3755ebff69 100644 --- a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs +++ b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs @@ -371,7 +371,7 @@ public void FullScreen() RdpClient.FullScreen = true; } - public async void AdjustScreen() + public void AdjustScreen() { if (IsConnecting) return; From 656362075456992a03cc11b9b07e1396a7327ad2 Mon Sep 17 00:00:00 2001 From: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com> Date: Tue, 31 Dec 2024 04:51:44 +0100 Subject: [PATCH 3/6] Fix: Set correct size for dpi --- .../Controls/RemoteDesktopControl.xaml | 30 +-- .../Controls/RemoteDesktopControl.xaml.cs | 219 ++++++++---------- Source/NETworkManager/MainWindow.xaml.cs | 33 ++- .../ViewModels/RemoteDesktopHostViewModel.cs | 30 ++- .../Views/RemoteDesktopHostView.xaml.cs | 11 +- 5 files changed, 157 insertions(+), 166 deletions(-) diff --git a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml index 19e54d58f8..95a613787a 100644 --- a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml +++ b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml @@ -9,7 +9,8 @@ xmlns:localization="clr-namespace:NETworkManager.Localization.Resources;assembly=NETworkManager.Localization" xmlns:local="clr-namespace:NETworkManager.Controls" xmlns:settings="clr-namespace:NETworkManager.Settings;assembly=NETworkManager.Settings" - mc:Ignorable="d" Loaded="UserControl_Loaded" + xmlns:windowsForms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" + mc:Ignorable="d" Loaded="UserControl_Loaded" d:DataContext="{d:DesignInstance local:RemoteDesktopControl}"> @@ -17,10 +18,10 @@ - - + @@ -66,18 +64,6 @@ - - - - - - - - - - - + \ No newline at end of file diff --git a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs index 3755ebff69..759ddd2531 100644 --- a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs +++ b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs @@ -8,7 +8,7 @@ using NETworkManager.Settings; using NETworkManager.Utilities; using System; -using System.Diagnostics; +using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using System.Windows.Threading; @@ -26,36 +26,32 @@ public partial class RemoteDesktopControl : UserControlBase, IDragablzTabItem private readonly Guid _tabId; private readonly RemoteDesktopSessionInfo _sessionInfo; - private DispatcherTimer _adjustScreenTimer; + private double _windowsFormsHostMaxWidth; - // Fix WindowsFormsHost width - private double _rdpClientWidth; - - public double RdpClientWidth + public double WindowsFormsHostMaxWidth { - get => _rdpClientWidth; + get => _windowsFormsHostMaxWidth; private set { - if (Math.Abs(value - _rdpClientWidth) < double.Epsilon) + if (Math.Abs(value - _windowsFormsHostMaxWidth) < double.Epsilon) return; - _rdpClientWidth = value; + _windowsFormsHostMaxWidth = value; OnPropertyChanged(); } } - // Fix WindowsFormsHost height - private double _rdpClientHeight; + private double _windowsFormsHostMaxHeight; - public double RdpClientHeight + public double WindowsFormsHostMaxHeight { - get => _rdpClientHeight; + get => _windowsFormsHostMaxHeight; private set { - if (Math.Abs(value - _rdpClientHeight) < double.Epsilon) + if (Math.Abs(value - _windowsFormsHostMaxHeight) < double.Epsilon) return; - _rdpClientHeight = value; + _windowsFormsHostMaxHeight = value; OnPropertyChanged(); } } @@ -105,25 +101,9 @@ private set } } - private bool _isReconnecting; - - public bool IsReconnecting - { - get => _isReconnecting; - set - { - if (value == _isReconnecting) - return; - - _isReconnecting = value; - OnPropertyChanged(); - } - } - #endregion #region Constructor, load - public RemoteDesktopControl(Guid tabId, RemoteDesktopSessionInfo sessionInfo) { InitializeComponent(); @@ -145,6 +125,7 @@ private void UserControl_Loaded(object sender, RoutedEventArgs e) return; Connect(); + _initialized = true; } @@ -181,6 +162,38 @@ private void DisconnectAction() #region Methods + private Tuple GetDesktopSize() + { + // Get the screen size + int desktopWidth, desktopHeight; + + if (_sessionInfo.AdjustScreenAutomatically || _sessionInfo.UseCurrentViewSize) + { + desktopWidth = (int)Math.Floor(RdpGrid.ActualWidth); + desktopHeight = (int)Math.Floor(RdpGrid.ActualHeight); + } + else + { + desktopWidth = _sessionInfo.DesktopWidth; + desktopHeight = _sessionInfo.DesktopHeight; + } + + // Scale the screen size based on the DPI + var scaleFactor = GetDpiScaleFactor(); + + desktopWidth = desktopWidth * scaleFactor / 100; + desktopHeight = desktopHeight * scaleFactor / 100; + + // Round the screen size to an even number + desktopWidth = desktopWidth % 2 == 0 ? desktopWidth : desktopWidth - 1; + desktopHeight = desktopHeight % 2 == 0 ? desktopHeight : desktopHeight - 1; + + return new Tuple(desktopWidth, desktopHeight); + } + + /// + /// Connect to the remote session with the given session info. + /// private void Connect() { IsConnecting = true; @@ -207,26 +220,12 @@ private void Connect() // Display RdpClient.ColorDepth = _sessionInfo.ColorDepth; // 8, 15, 16, 24 - double desktopWidth, desktopHeight; + var desktopSize = GetDesktopSize(); - if (_sessionInfo.AdjustScreenAutomatically || _sessionInfo.UseCurrentViewSize) - { - desktopWidth = RdpGrid.ActualWidth; - desktopHeight = RdpGrid.ActualHeight; - } - else - { - desktopWidth = _sessionInfo.DesktopWidth; - desktopHeight = _sessionInfo.DesktopHeight; - } - - var scaleFactor = GetDpiScaleFactor(); + RdpClient.DesktopWidth = desktopSize.Item1; + RdpClient.DesktopHeight = desktopSize.Item2; - desktopWidth = desktopWidth * scaleFactor / 100; - desktopHeight = desktopHeight * scaleFactor / 100; - - RdpClient.DesktopWidth = (int)desktopWidth; - RdpClient.DesktopHeight = (int)desktopHeight; + FixWindowsFormsHostSize(desktopSize.Item1, desktopSize.Item2); // Initial scaling before connecting ((IMsRdpExtendedSettings)RdpClient.GetOcx()).set_Property("DesktopScaleFactor", GetDesktopScaleFactor()); @@ -326,8 +325,6 @@ private void Connect() // Connect RdpClient.Connect(); - - FixWindowsFormsHostSize(desktopWidth, desktopHeight); } private void Reconnect() @@ -337,30 +334,14 @@ private void Reconnect() IsConnecting = true; - double desktopWidth, desktopHeight; + var desktopSize = GetDesktopSize(); - if (_sessionInfo.AdjustScreenAutomatically || _sessionInfo.UseCurrentViewSize) - { - desktopWidth = RdpGrid.ActualWidth; - desktopHeight = RdpGrid.ActualHeight; - } - else - { - desktopWidth = _sessionInfo.DesktopWidth; - desktopHeight = _sessionInfo.DesktopHeight; - } + RdpClient.DesktopWidth = desktopSize.Item1; + RdpClient.DesktopHeight = desktopSize.Item2; - var scaleFactor = GetDpiScaleFactor(); - - desktopWidth = desktopWidth * scaleFactor / 100; - desktopHeight = desktopHeight * scaleFactor / 100; - - RdpClient.DesktopWidth = (int)desktopWidth; - RdpClient.DesktopHeight = (int)desktopHeight; + FixWindowsFormsHostSize(desktopSize.Item1, desktopSize.Item2); RdpClient.Connect(); - - FixWindowsFormsHostSize(desktopWidth, desktopHeight); } public void FullScreen() @@ -371,85 +352,62 @@ public void FullScreen() RdpClient.FullScreen = true; } - public void AdjustScreen() + public async void AdjustScreen() { + // Check preconditions if (IsConnecting) return; if (!IsConnected) return; - if (IsReconnecting) - return; + // Wait for the control to be drawn (if window is resized or the DPI changes) + await Task.Delay(250); - IsReconnecting = true; + var desktopSize = GetDesktopSize(); - double desktopWidth, desktopHeight; - - if (_sessionInfo.AdjustScreenAutomatically || _sessionInfo.UseCurrentViewSize) - { - desktopWidth = RdpGrid.ActualWidth; - desktopHeight = RdpGrid.ActualHeight; - } - else - { - desktopWidth = _sessionInfo.DesktopWidth; - desktopHeight = _sessionInfo.DesktopHeight; - } - - var scaleFactor = GetDpiScaleFactor(); + // Check if we need to adjust the screen + if (RdpClient.DesktopWidth == desktopSize.Item1 && RdpClient.DesktopHeight == desktopSize.Item2) + return; - desktopWidth = desktopWidth * scaleFactor / 100; - desktopHeight = desktopHeight * scaleFactor / 100; + if (RdpClient.Width == desktopSize.Item1 && RdpClient.Height == desktopSize.Item2) + return; try { // This may fail if the RDP session was connected recently - RdpClient.UpdateSessionDisplaySettings((uint)desktopWidth, (uint)desktopHeight, (uint)desktopWidth, (uint)desktopHeight, 0, GetDesktopScaleFactor(), GetDeviceScaleFactor()); + RdpClient.UpdateSessionDisplaySettings((uint)desktopSize.Item1, (uint)desktopSize.Item2, (uint)desktopSize.Item1, (uint)desktopSize.Item2, 0, GetDesktopScaleFactor(), GetDeviceScaleFactor()); + + // Fix the size of the WindowsFormsHost and the RDP control + FixWindowsFormsHostSize(desktopSize.Item1, desktopSize.Item2); } catch (Exception ex) { Log.Error("Error while adjusting screen", ex); } - - FixWindowsFormsHostSize(desktopWidth, desktopHeight); - - IsReconnecting = false; } /// - /// Adjust the screen when the size of the control changes. - /// Prevent multiple calls while resizing by using a timer. + /// Fix the size of the WindowsFormsHost and the RDP control after the size + /// or DPI of the control has changed. /// - private void AdjustScreenOnSizeChanged() - { - if (_adjustScreenTimer == null) - { - _adjustScreenTimer = new DispatcherTimer - { - Interval = TimeSpan.FromMilliseconds(250) - }; - - _adjustScreenTimer.Tick += (sender, args) => - { - _adjustScreenTimer.Stop(); - - AdjustScreen(); - }; - } - - _adjustScreenTimer.Start(); - } - + /// Width of the RDP session. + /// Height of the RDP session. private void FixWindowsFormsHostSize(double width, double height) { - RdpClientWidth = width; - RdpClientHeight = height; + // Set the max width and height for the WindowsFormsHost + WindowsFormsHostMaxWidth = (int)(width / GetDpiScaleFactor() * 100); + WindowsFormsHostMaxHeight = (int)(height / GetDpiScaleFactor() * 100); - Debug.WriteLine($"Values: {width} x {height}"); - Debug.WriteLine($"RDPClient: {RdpClient.DesktopWidth} x {RdpClient.DesktopHeight}"); + // Update the size of the RDP control + RdpClient.Width = (int)width; + RdpClient.Height = (int)height; } + /// + /// Send a keystroke to the remote session. + /// + /// Keystroke to send. public void SendKey(Keystroke keystroke) { if (!IsConnected) @@ -464,6 +422,9 @@ public void SendKey(Keystroke keystroke) ocx.SendKeys(info.KeyData.Length, info.ArrayKeyUp, info.KeyData); } + /// + /// Disconnect the RDP session. + /// private void Disconnect() { if (!IsConnected) @@ -472,6 +433,9 @@ private void Disconnect() RdpClient.Disconnect(); } + /// + /// Close the tab. + /// public void CloseTab() { // Prevent multiple calls @@ -643,11 +607,11 @@ protected uint GetDeviceScaleFactor() /// Get the current DPI scale factor like 100, 125, 150, 175, 200, 225, etc. /// /// Returns the DPI scale factor. - public uint GetDpiScaleFactor() + public int GetDpiScaleFactor() { var x = System.Windows.Media.VisualTreeHelper.GetDpi(this); - return (uint)(x.PixelsPerDip * 100); + return (int)(x.PixelsPerDip * 100); } #endregion @@ -666,14 +630,13 @@ private void RdpClient_OnDisconnected(object sender, IMsTscAxEvents_OnDisconnect DisconnectReason = GetDisconnectReason(e.discReason); } + #endregion - private void RdpGrid_SizeChanged(object sender, SizeChangedEventArgs e) + public void UpdateOnWindowResize() { - // Resize the RDP screen size when the window size changes if (_sessionInfo.AdjustScreenAutomatically) - AdjustScreenOnSizeChanged(); + AdjustScreen(); } - #endregion private void WindowsFormsHost_DpiChanged(object sender, DpiChangedEventArgs e) { diff --git a/Source/NETworkManager/MainWindow.xaml.cs b/Source/NETworkManager/MainWindow.xaml.cs index fb2f2dcb6a..846e21c74c 100644 --- a/Source/NETworkManager/MainWindow.xaml.cs +++ b/Source/NETworkManager/MainWindow.xaml.cs @@ -1555,10 +1555,15 @@ private void Updater_UpdateAvailable(object sender, UpdateAvailableArgs e) #endregion - #region Handle WndProc messages (Single instance, handle HotKeys) + #region Handle WndProc messages (Single instance, handle HotKeys, handle window size events) private HwndSource _hwndSource; + private const int WmExitSizeMove = 0x232; + private const int WmSysCommand = 0x0112; + private const int ScMaximize = 0xF030; + private const int ScRestore = 0xF120; + // This is called after MainWindow() and before OnContentRendered() --> to register hotkeys... protected override void OnSourceInitialized(EventArgs e) { @@ -1578,8 +1583,32 @@ private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref { ShowWindow(); handled = true; + + return IntPtr.Zero; } + // Window size events + switch (msg) + { + case WmExitSizeMove: + _remoteDesktopHostView?.UpdateOnWindowResize(); + break; + + case WmSysCommand: + // Handle system commands (like maximize and restore) + if (wParam.ToInt32() == ScMaximize) + // Window is maximized + _remoteDesktopHostView?.UpdateOnWindowResize(); + + if (wParam.ToInt32() == ScRestore) + // Window is restored (back to normal size from maximized state) + _remoteDesktopHostView?.UpdateOnWindowResize(); + + break; + } + + handled = false; + return IntPtr.Zero; } @@ -1601,7 +1630,7 @@ private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref * 1 | ShowWindow() */ - private readonly List _registeredHotKeys = new(); + private readonly List _registeredHotKeys = []; private void RegisterHotKeys() { diff --git a/Source/NETworkManager/ViewModels/RemoteDesktopHostViewModel.cs b/Source/NETworkManager/ViewModels/RemoteDesktopHostViewModel.cs index 50e8c9d81b..7f22893600 100644 --- a/Source/NETworkManager/ViewModels/RemoteDesktopHostViewModel.cs +++ b/Source/NETworkManager/ViewModels/RemoteDesktopHostViewModel.cs @@ -1,4 +1,14 @@ -using System; +using Dragablz; +using MahApps.Metro.Controls.Dialogs; +using NETworkManager.Controls; +using NETworkManager.Localization.Resources; +using NETworkManager.Models; +using NETworkManager.Models.RemoteDesktop; +using NETworkManager.Profiles; +using NETworkManager.Settings; +using NETworkManager.Utilities; +using NETworkManager.Views; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; @@ -9,16 +19,6 @@ using System.Windows.Data; using System.Windows.Input; using System.Windows.Threading; -using Dragablz; -using MahApps.Metro.Controls.Dialogs; -using NETworkManager.Controls; -using NETworkManager.Localization.Resources; -using NETworkManager.Models; -using NETworkManager.Models.RemoteDesktop; -using NETworkManager.Profiles; -using NETworkManager.Settings; -using NETworkManager.Utilities; -using NETworkManager.Views; using RemoteDesktop = NETworkManager.Profiles.Application.RemoteDesktop; namespace NETworkManager.ViewModels; @@ -574,6 +574,12 @@ public void OnViewHide() _isViewActive = false; } + public void UpdateOnWindowResize() + { + foreach (var tab in TabItems) + (tab.View as RemoteDesktopControl)?.UpdateOnWindowResize(); + } + private void SetProfilesView(ProfileInfo profile = null) { Profiles = new CollectionViewSource @@ -652,4 +658,6 @@ private void SearchDispatcherTimer_Tick(object sender, EventArgs e) } #endregion + + } \ No newline at end of file diff --git a/Source/NETworkManager/Views/RemoteDesktopHostView.xaml.cs b/Source/NETworkManager/Views/RemoteDesktopHostView.xaml.cs index 1aa2cd384e..45140ed077 100644 --- a/Source/NETworkManager/Views/RemoteDesktopHostView.xaml.cs +++ b/Source/NETworkManager/Views/RemoteDesktopHostView.xaml.cs @@ -1,9 +1,9 @@ -using System.Threading.Tasks; +using MahApps.Metro.Controls.Dialogs; +using NETworkManager.ViewModels; +using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; -using MahApps.Metro.Controls.Dialogs; -using NETworkManager.ViewModels; namespace NETworkManager.Views; @@ -54,4 +54,9 @@ public void OnViewVisible() { _viewModel.OnViewVisible(); } + + public void UpdateOnWindowResize() + { + _viewModel.UpdateOnWindowResize(); + } } \ No newline at end of file From 2b37134b16097553f9fbbd31f8d17fce5a463f85 Mon Sep 17 00:00:00 2001 From: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com> Date: Tue, 31 Dec 2024 05:28:53 +0100 Subject: [PATCH 4/6] Fix: Rounding issue --- .../Controls/RemoteDesktopControl.xaml.cs | 70 +++++++++++++------ 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs index 759ddd2531..b8916c1279 100644 --- a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs +++ b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs @@ -8,6 +8,7 @@ using NETworkManager.Settings; using NETworkManager.Utilities; using System; +using System.Diagnostics; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; @@ -162,15 +163,15 @@ private void DisconnectAction() #region Methods - private Tuple GetDesktopSize() + private Tuple GetDesktopSize() { // Get the screen size - int desktopWidth, desktopHeight; + double desktopWidth, desktopHeight; if (_sessionInfo.AdjustScreenAutomatically || _sessionInfo.UseCurrentViewSize) { - desktopWidth = (int)Math.Floor(RdpGrid.ActualWidth); - desktopHeight = (int)Math.Floor(RdpGrid.ActualHeight); + desktopWidth = RdpGrid.ActualWidth; + desktopHeight = RdpGrid.ActualHeight; } else { @@ -185,10 +186,10 @@ private Tuple GetDesktopSize() desktopHeight = desktopHeight * scaleFactor / 100; // Round the screen size to an even number - desktopWidth = desktopWidth % 2 == 0 ? desktopWidth : desktopWidth - 1; - desktopHeight = desktopHeight % 2 == 0 ? desktopHeight : desktopHeight - 1; + desktopWidth = Math.Floor(desktopWidth / 2) * 2; + desktopHeight = Math.Floor(desktopHeight / 2) * 2; - return new Tuple(desktopWidth, desktopHeight); + return new Tuple(desktopWidth, desktopHeight); } /// @@ -222,8 +223,8 @@ private void Connect() var desktopSize = GetDesktopSize(); - RdpClient.DesktopWidth = desktopSize.Item1; - RdpClient.DesktopHeight = desktopSize.Item2; + RdpClient.DesktopWidth = (int)desktopSize.Item1; + RdpClient.DesktopHeight = (int)desktopSize.Item2; FixWindowsFormsHostSize(desktopSize.Item1, desktopSize.Item2); @@ -336,8 +337,8 @@ private void Reconnect() var desktopSize = GetDesktopSize(); - RdpClient.DesktopWidth = desktopSize.Item1; - RdpClient.DesktopHeight = desktopSize.Item2; + RdpClient.DesktopWidth = (int)desktopSize.Item1; + RdpClient.DesktopHeight = (int)desktopSize.Item2; FixWindowsFormsHostSize(desktopSize.Item1, desktopSize.Item2); @@ -352,7 +353,7 @@ public void FullScreen() RdpClient.FullScreen = true; } - public async void AdjustScreen() + public async void AdjustScreen(bool dpiChange = false) { // Check preconditions if (IsConnecting) @@ -366,20 +367,30 @@ public async void AdjustScreen() var desktopSize = GetDesktopSize(); - // Check if we need to adjust the screen - if (RdpClient.DesktopWidth == desktopSize.Item1 && RdpClient.DesktopHeight == desktopSize.Item2) - return; + // Check if we need to adjust the screen (always on DPI changes) + if (dpiChange == false) + { + if (RdpClient.DesktopWidth == desktopSize.Item1 && RdpClient.DesktopHeight == desktopSize.Item2) + { + Debug.WriteLine("==>>> Screen size is already correct."); + return; + } - if (RdpClient.Width == desktopSize.Item1 && RdpClient.Height == desktopSize.Item2) - return; + + if (RdpClient.Width == desktopSize.Item1 && RdpClient.Height == desktopSize.Item2) + { + Debug.WriteLine("==>>> Screen size is already correct."); + return; + } + } try { - // This may fail if the RDP session was connected recently - RdpClient.UpdateSessionDisplaySettings((uint)desktopSize.Item1, (uint)desktopSize.Item2, (uint)desktopSize.Item1, (uint)desktopSize.Item2, 0, GetDesktopScaleFactor(), GetDeviceScaleFactor()); - + Debug.WriteLine("UpdateSessionDisplaySettings..."); // Fix the size of the WindowsFormsHost and the RDP control FixWindowsFormsHostSize(desktopSize.Item1, desktopSize.Item2); + // This may fail if the RDP session was connected recently + RdpClient.UpdateSessionDisplaySettings((uint)desktopSize.Item1, (uint)desktopSize.Item2, (uint)desktopSize.Item1, (uint)desktopSize.Item2, 0, GetDesktopScaleFactor(), GetDeviceScaleFactor()); } catch (Exception ex) { @@ -395,13 +406,23 @@ public async void AdjustScreen() /// Height of the RDP session. private void FixWindowsFormsHostSize(double width, double height) { + var widthScaled = width / GetDpiScaleFactor() * 100; + var heightScaled = height / GetDpiScaleFactor() * 100; + + widthScaled = Math.Ceiling(widthScaled / 2) * 2; + heightScaled = Math.Ceiling(heightScaled / 2) * 2; + // Set the max width and height for the WindowsFormsHost - WindowsFormsHostMaxWidth = (int)(width / GetDpiScaleFactor() * 100); - WindowsFormsHostMaxHeight = (int)(height / GetDpiScaleFactor() * 100); + WindowsFormsHostMaxWidth = widthScaled; + WindowsFormsHostMaxHeight = heightScaled; // Update the size of the RDP control RdpClient.Width = (int)width; RdpClient.Height = (int)height; + + Debug.WriteLine($"RDP control size: {RdpClient.Width}x{RdpClient.Height}"); + Debug.WriteLine($"WindowsFormsHost size: {WindowsFormsHostMaxWidth}x{WindowsFormsHostMaxHeight}"); + Debug.WriteLine($"Values: {width}x{height} - DPI: {GetDpiScaleFactor()}%"); } /// @@ -634,12 +655,15 @@ private void RdpClient_OnDisconnected(object sender, IMsTscAxEvents_OnDisconnect public void UpdateOnWindowResize() { + + Debug.WriteLine("UpdateOnWindowResize..."); + if (_sessionInfo.AdjustScreenAutomatically) AdjustScreen(); } private void WindowsFormsHost_DpiChanged(object sender, DpiChangedEventArgs e) { - AdjustScreen(); + AdjustScreen(dpiChange: true); } } From 097840bef0da8f92447979f3f0d8b655bc81ed83 Mon Sep 17 00:00:00 2001 From: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com> Date: Tue, 31 Dec 2024 17:46:57 +0100 Subject: [PATCH 5/6] Feature: RDP scaling --- .../Controls/DragablzTabHostWindow.xaml.cs | 2 +- .../Controls/IDragablzTabItem.cs | 1 + .../Controls/RemoteDesktopControl.xaml | 1 - .../Controls/RemoteDesktopControl.xaml.cs | 162 +++++++++++------- .../ViewModels/RemoteDesktopHostViewModel.cs | 2 +- Website/docs/changelog/next-release.md | 15 +- 6 files changed, 118 insertions(+), 65 deletions(-) diff --git a/Source/NETworkManager/Controls/DragablzTabHostWindow.xaml.cs b/Source/NETworkManager/Controls/DragablzTabHostWindow.xaml.cs index 28f715d080..c17732bc69 100644 --- a/Source/NETworkManager/Controls/DragablzTabHostWindow.xaml.cs +++ b/Source/NETworkManager/Controls/DragablzTabHostWindow.xaml.cs @@ -212,7 +212,7 @@ private void RemoteDesktop_FullscreenAction(object view) private void RemoteDesktop_AdjustScreenAction(object view) { if (view is RemoteDesktopControl control) - control.AdjustScreen(); + control.AdjustScreen(force:true); } public ICommand RemoteDesktop_SendCtrlAltDelCommand => diff --git a/Source/NETworkManager/Controls/IDragablzTabItem.cs b/Source/NETworkManager/Controls/IDragablzTabItem.cs index 51756a8592..bfc824c170 100644 --- a/Source/NETworkManager/Controls/IDragablzTabItem.cs +++ b/Source/NETworkManager/Controls/IDragablzTabItem.cs @@ -13,5 +13,6 @@ public interface IDragablzTabItem /// public void CloseTab() { + } } \ No newline at end of file diff --git a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml index 95a613787a..3418e5932e 100644 --- a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml +++ b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml @@ -9,7 +9,6 @@ xmlns:localization="clr-namespace:NETworkManager.Localization.Resources;assembly=NETworkManager.Localization" xmlns:local="clr-namespace:NETworkManager.Controls" xmlns:settings="clr-namespace:NETworkManager.Settings;assembly=NETworkManager.Settings" - xmlns:windowsForms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" mc:Ignorable="d" Loaded="UserControl_Loaded" d:DataContext="{d:DesignInstance local:RemoteDesktopControl}"> diff --git a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs index b8916c1279..c2ff6f4ed4 100644 --- a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs +++ b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs @@ -12,7 +12,6 @@ using System.Threading.Tasks; using System.Windows; using System.Windows.Input; -using System.Windows.Threading; namespace NETworkManager.Controls; @@ -353,48 +352,95 @@ public void FullScreen() RdpClient.FullScreen = true; } - public async void AdjustScreen(bool dpiChange = false) + public async void AdjustScreen(bool force = false) { - // Check preconditions - if (IsConnecting) - return; - - if (!IsConnected) - return; - - // Wait for the control to be drawn (if window is resized or the DPI changes) - await Task.Delay(250); - - var desktopSize = GetDesktopSize(); - - // Check if we need to adjust the screen (always on DPI changes) - if (dpiChange == false) + try { - if (RdpClient.DesktopWidth == desktopSize.Item1 && RdpClient.DesktopHeight == desktopSize.Item2) + // Check preconditions + if (IsConnecting) { - Debug.WriteLine("==>>> Screen size is already correct."); + Log.Debug("AdjustScreen - RDP session is connecting... We can't adjust the screen, yet."); return; } - - if (RdpClient.Width == desktopSize.Item1 && RdpClient.Height == desktopSize.Item2) + if (!IsConnected) { - Debug.WriteLine("==>>> Screen size is already correct."); + Log.Debug("AdjustScreen - RDP session is not connected! We can't adjust the screen."); return; } - } - try - { - Debug.WriteLine("UpdateSessionDisplaySettings..."); + // Wait for the control to be drawn (if window is resized or the DPI changes) + await Task.Delay(250); + + var desktopSize = GetDesktopSize(); + + Log.Debug($"AdjustScreen - Desktop size: {desktopSize.Item1}x{desktopSize.Item2}"); + + // Check if we need to adjust the screen (always on DPI changes or manual) + if (force == false) + { + var needUpdate = false; + + var windowsFormsHostSize = GetWindowsFormsHostSize(desktopSize.Item1, desktopSize.Item2); + + Log.Debug($"AdjustScreen - WindowsFormsHost size: {windowsFormsHostSize.Item1}x{windowsFormsHostSize.Item2}"); + + if (!(Math.Abs(WindowsFormsHostMaxWidth - windowsFormsHostSize.Item1) < double.Epsilon) || + !(Math.Abs(WindowsFormsHostMaxHeight - windowsFormsHostSize.Item2) < double.Epsilon)) + { + Log.Debug("AdjustScreen - WindowsFormsHost size is not adjusted!" + + $" Old size: {WindowsFormsHostMaxWidth}x{WindowsFormsHostMaxHeight}, new size: {windowsFormsHostSize.Item1}x{windowsFormsHostSize.Item2}"); + needUpdate = true; + } + + + if (!(Math.Abs(RdpClient.Width - desktopSize.Item1) < double.Epsilon) || + !(Math.Abs(RdpClient.Height - desktopSize.Item2) < double.Epsilon)) + { + Log.Debug("AdjustScreen - RDP control size is not adjusted!" + + $" Old size: {RdpClient.Width}x{RdpClient.Height}, new size: {desktopSize.Item1}x{desktopSize.Item2}"); + needUpdate = true; + } + + if (!(Math.Abs(RdpClient.DesktopWidth - desktopSize.Item1) < double.Epsilon) || + !(Math.Abs(RdpClient.DesktopHeight - desktopSize.Item2) < double.Epsilon)) + { + Log.Debug("AdjustScreen - RDP session size is not adjusted!" + + $" Old size: {RdpClient.DesktopWidth}x{RdpClient.DesktopHeight}, new size: {desktopSize.Item1}x{desktopSize.Item2}"); + needUpdate = true; + } + + if (needUpdate) + { + Log.Debug("AdjustScreen - Adjusting screen size..."); + } + else + { + Log.Debug("AdjustScreen - Screen size is already adjusted!"); + return; + } + } + else + { + Log.Debug("AdjustScreen - Screen size adjustment is forced..."); + } + // Fix the size of the WindowsFormsHost and the RDP control FixWindowsFormsHostSize(desktopSize.Item1, desktopSize.Item2); - // This may fail if the RDP session was connected recently - RdpClient.UpdateSessionDisplaySettings((uint)desktopSize.Item1, (uint)desktopSize.Item2, (uint)desktopSize.Item1, (uint)desktopSize.Item2, 0, GetDesktopScaleFactor(), GetDeviceScaleFactor()); + + try + { + // This may fail if the RDP session was connected recently + RdpClient.UpdateSessionDisplaySettings((uint)desktopSize.Item1, (uint)desktopSize.Item2, (uint)desktopSize.Item1, (uint)desktopSize.Item2, 0, GetDesktopScaleFactor(), GetDeviceScaleFactor()); + } + catch (Exception ex) + { + Log.Error("Error while updating the session display settings of the RDP control!", ex); + } } - catch (Exception ex) + catch (Exception e) { - Log.Error("Error while adjusting screen", ex); + Log.Error("Could not adjust screen!", e); } } @@ -406,25 +452,30 @@ public async void AdjustScreen(bool dpiChange = false) /// Height of the RDP session. private void FixWindowsFormsHostSize(double width, double height) { - var widthScaled = width / GetDpiScaleFactor() * 100; - var heightScaled = height / GetDpiScaleFactor() * 100; - - widthScaled = Math.Ceiling(widthScaled / 2) * 2; - heightScaled = Math.Ceiling(heightScaled / 2) * 2; + var windowsFormsHostSize = GetWindowsFormsHostSize(width, height); // Set the max width and height for the WindowsFormsHost - WindowsFormsHostMaxWidth = widthScaled; - WindowsFormsHostMaxHeight = heightScaled; + WindowsFormsHostMaxWidth = windowsFormsHostSize.Item1; + WindowsFormsHostMaxHeight = windowsFormsHostSize.Item2; // Update the size of the RDP control RdpClient.Width = (int)width; RdpClient.Height = (int)height; - - Debug.WriteLine($"RDP control size: {RdpClient.Width}x{RdpClient.Height}"); - Debug.WriteLine($"WindowsFormsHost size: {WindowsFormsHostMaxWidth}x{WindowsFormsHostMaxHeight}"); - Debug.WriteLine($"Values: {width}x{height} - DPI: {GetDpiScaleFactor()}%"); } + private Tuple GetWindowsFormsHostSize(double width, double height) + { + var scaleFactor = GetDpiScaleFactor(); + + var widthScaled = width / scaleFactor * 100; + var heightScaled = height / scaleFactor * 100; + + widthScaled = Math.Ceiling(widthScaled / 2) * 2; + heightScaled = Math.Ceiling(heightScaled / 2) * 2; + + return new Tuple(widthScaled, heightScaled); + } + /// /// Send a keystroke to the remote session. /// @@ -575,25 +626,17 @@ private static string GetDisconnectReason(int reason) /// https://cdnweb.devolutions.net/blog/pdf/smart-resizing-and-high-dpi-issues-in-remote-desktop-manager.pdf /// /// - protected uint GetDesktopScaleFactor() + private uint GetDesktopScaleFactor() { var scaleFactor = GetDpiScaleFactor(); - switch (scaleFactor) + return scaleFactor switch { - case 125: - return 125; - case 150: - case 175: - return 150; - case 200: - return 200; - } - - if (scaleFactor > 200) - return 200; - - return 100; + 125 => 125, + 150 or 175 => 150, + 200 => 200, + _ => (uint)(scaleFactor > 200 ? 200 : 100) + }; } /// @@ -604,7 +647,7 @@ protected uint GetDesktopScaleFactor() /// https://cdnweb.devolutions.net/blog/pdf/smart-resizing-and-high-dpi-issues-in-remote-desktop-manager.pdf /// /// Device scale factor. - protected uint GetDeviceScaleFactor() + private uint GetDeviceScaleFactor() { var scaleFactor = GetDpiScaleFactor(); @@ -628,7 +671,7 @@ protected uint GetDeviceScaleFactor() /// Get the current DPI scale factor like 100, 125, 150, 175, 200, 225, etc. /// /// Returns the DPI scale factor. - public int GetDpiScaleFactor() + private int GetDpiScaleFactor() { var x = System.Windows.Media.VisualTreeHelper.GetDpi(this); @@ -655,15 +698,12 @@ private void RdpClient_OnDisconnected(object sender, IMsTscAxEvents_OnDisconnect public void UpdateOnWindowResize() { - - Debug.WriteLine("UpdateOnWindowResize..."); - if (_sessionInfo.AdjustScreenAutomatically) AdjustScreen(); } private void WindowsFormsHost_DpiChanged(object sender, DpiChangedEventArgs e) { - AdjustScreen(dpiChange: true); + AdjustScreen(force: true); } } diff --git a/Source/NETworkManager/ViewModels/RemoteDesktopHostViewModel.cs b/Source/NETworkManager/ViewModels/RemoteDesktopHostViewModel.cs index 7f22893600..0d097bdc2c 100644 --- a/Source/NETworkManager/ViewModels/RemoteDesktopHostViewModel.cs +++ b/Source/NETworkManager/ViewModels/RemoteDesktopHostViewModel.cs @@ -281,7 +281,7 @@ private void FullscreenAction(object view) private void AdjustScreenAction(object view) { if (view is RemoteDesktopControl control) - control.AdjustScreen(); + control.AdjustScreen(force:true); } public ICommand SendCtrlAltDelCommand => new RelayCommand(SendCtrlAltDelAction, IsConnected_CanExecute); diff --git a/Website/docs/changelog/next-release.md b/Website/docs/changelog/next-release.md index 771ba31bd8..cff1c6ace3 100644 --- a/Website/docs/changelog/next-release.md +++ b/Website/docs/changelog/next-release.md @@ -17,7 +17,9 @@ Release date: **xx.xx.2024** ## Breaking Changes -- Minimum supported Windows version increased to `22H2`. [#2912](https://github.com/BornToBeRoot/NETworkManager/pull/2912) +- Minimum supported Windows version increased to `22H2` to support: + - WiFi 6 GHz, WPA3, 802.11be [#2912](https://github.com/BornToBeRoot/NETworkManager/pull/2912) + - Remote Desktop high DPI, scaling and resizing [#2968](https://github.com/BornToBeRoot/NETworkManager/pull/2968) ## What's new? @@ -27,6 +29,17 @@ Release date: **xx.xx.2024** - `WPA3 Personal (SAE)`, `WPA3 Enterprise` and `WPA3 Enterprise (192-bit)` are now supported. [#2912](https://github.com/BornToBeRoot/NETworkManager/pull/2912) - `802.11be` (`EHT`) is now supported. [#2912](https://github.com/BornToBeRoot/NETworkManager/pull/2912) +- **Remote Desktop** + + - Scale rdp session and control to support high DPI (e.g. per Monitor DPI like 125%, 150%, etc.). [#2968](https://github.com/BornToBeRoot/NETworkManager/pull/2968) + - Resizing now uses [`IMsRdpClient9::UpdateSessionDisplaySettings`]() instead of [`IMsRdpClient::Reconnect`](https://learn.microsoft.com/en-us/windows/win32/termserv/imsrdpclient8-reconnect) to support scaling and faster resizing (without the need of reconnecting). [#2968](https://github.com/BornToBeRoot/NETworkManager/pull/2968). + + :::warning + + The new features for high DPI, scaling and resizing may cause issues or doesn't work with legacy servers/clients. Please report any issues you find here: [#2911](https://github.com/BornToBeRoot/NETworkManager/issues/2911) + + ::: + ## Improvements - Improve ToolTips (e.g. migrate from Twitter to X, etc.), Buttons, etc. [#2955](https://github.com/BornToBeRoot/NETworkManager/pull/2955) From 97e2094fde260b5a3e3a6d512bb97d2bf8aeda46 Mon Sep 17 00:00:00 2001 From: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com> Date: Tue, 31 Dec 2024 17:51:41 +0100 Subject: [PATCH 6/6] Docs: ... --- Website/docs/changelog/next-release.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Website/docs/changelog/next-release.md b/Website/docs/changelog/next-release.md index cff1c6ace3..4e7d1c8b94 100644 --- a/Website/docs/changelog/next-release.md +++ b/Website/docs/changelog/next-release.md @@ -19,7 +19,7 @@ Release date: **xx.xx.2024** - Minimum supported Windows version increased to `22H2` to support: - WiFi 6 GHz, WPA3, 802.11be [#2912](https://github.com/BornToBeRoot/NETworkManager/pull/2912) - - Remote Desktop high DPI, scaling and resizing [#2968](https://github.com/BornToBeRoot/NETworkManager/pull/2968) + - Remote Desktop high DPI, scaling and fast resizing [#2968](https://github.com/BornToBeRoot/NETworkManager/pull/2968) ## What's new?