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?