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 8b457bad50..3418e5932e 100644
--- a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml
+++ b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml
@@ -9,7 +9,7 @@
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"
+ mc:Ignorable="d" Loaded="UserControl_Loaded"
d:DataContext="{d:DesignInstance local:RemoteDesktopControl}">
@@ -17,10 +17,11 @@
-
-
+
+
-
+
@@ -65,18 +63,6 @@
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs b/Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs
index 7c7e1fda2c..c2ff6f4ed4 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.Threading.Tasks;
+using System.Windows;
+using System.Windows.Input;
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,34 +26,32 @@ public partial class RemoteDesktopControl : UserControlBase, IDragablzTabItem
private readonly Guid _tabId;
private readonly RemoteDesktopSessionInfo _sessionInfo;
- // Fix WindowsFormsHost width
- private double _rdpClientWidth;
+ private double _windowsFormsHostMaxWidth;
- 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();
}
}
@@ -100,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();
@@ -132,6 +117,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
@@ -139,6 +125,7 @@ private void UserControl_Loaded(object sender, RoutedEventArgs e)
return;
Connect();
+
_initialized = true;
}
@@ -175,6 +162,38 @@ private void DisconnectAction()
#region Methods
+ private Tuple GetDesktopSize()
+ {
+ // Get the screen size
+ double desktopWidth, desktopHeight;
+
+ if (_sessionInfo.AdjustScreenAutomatically || _sessionInfo.UseCurrentViewSize)
+ {
+ desktopWidth = RdpGrid.ActualWidth;
+ desktopHeight = 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 = Math.Floor(desktopWidth / 2) * 2;
+ desktopHeight = Math.Floor(desktopHeight / 2) * 2;
+
+ return new Tuple(desktopWidth, desktopHeight);
+ }
+
+ ///
+ /// Connect to the remote session with the given session info.
+ ///
private void Connect()
{
IsConnecting = true;
@@ -201,16 +220,16 @@ private void Connect()
// Display
RdpClient.ColorDepth = _sessionInfo.ColorDepth; // 8, 15, 16, 24
- if (_sessionInfo.AdjustScreenAutomatically || _sessionInfo.UseCurrentViewSize)
- {
- RdpClient.DesktopWidth = (int)RdpGrid.ActualWidth;
- RdpClient.DesktopHeight = (int)RdpGrid.ActualHeight;
- }
- else
- {
- RdpClient.DesktopWidth = _sessionInfo.DesktopWidth;
- RdpClient.DesktopHeight = _sessionInfo.DesktopHeight;
- }
+ var desktopSize = GetDesktopSize();
+
+ RdpClient.DesktopWidth = (int)desktopSize.Item1;
+ RdpClient.DesktopHeight = (int)desktopSize.Item2;
+
+ FixWindowsFormsHostSize(desktopSize.Item1, desktopSize.Item2);
+
+ // Initial scaling before connecting
+ ((IMsRdpExtendedSettings)RdpClient.GetOcx()).set_Property("DesktopScaleFactor", GetDesktopScaleFactor());
+ ((IMsRdpExtendedSettings)RdpClient.GetOcx()).set_Property("DeviceScaleFactor", GetDeviceScaleFactor());
// Authentication
RdpClient.AdvancedSettings9.AuthenticationLevel = _sessionInfo.AuthenticationLevel;
@@ -306,8 +325,6 @@ private void Connect()
// Connect
RdpClient.Connect();
-
- FixWindowsFormsHostSize();
}
private void Reconnect()
@@ -317,16 +334,14 @@ private void Reconnect()
IsConnecting = true;
- // Update screen size
- if (_sessionInfo.AdjustScreenAutomatically || _sessionInfo.UseCurrentViewSize)
- {
- RdpClient.DesktopWidth = (int)RdpGrid.ActualWidth;
- RdpClient.DesktopHeight = (int)RdpGrid.ActualHeight;
- }
+ var desktopSize = GetDesktopSize();
- RdpClient.Connect();
+ RdpClient.DesktopWidth = (int)desktopSize.Item1;
+ RdpClient.DesktopHeight = (int)desktopSize.Item2;
+
+ FixWindowsFormsHostSize(desktopSize.Item1, desktopSize.Item2);
- FixWindowsFormsHostSize();
+ RdpClient.Connect();
}
public void FullScreen()
@@ -337,24 +352,134 @@ public void FullScreen()
RdpClient.FullScreen = true;
}
- public void AdjustScreen()
+ public async void AdjustScreen(bool force = false)
{
- if (!IsConnected)
- return;
+ try
+ {
+ // Check preconditions
+ if (IsConnecting)
+ {
+ Log.Debug("AdjustScreen - RDP session is connecting... We can't adjust the screen, yet.");
+ return;
+ }
- // Adjust screen size
- if (_sessionInfo.AdjustScreenAutomatically || _sessionInfo.UseCurrentViewSize)
- RdpClient.Reconnect((uint)RdpGrid.ActualWidth, (uint)RdpGrid.ActualHeight);
+ if (!IsConnected)
+ {
+ Log.Debug("AdjustScreen - RDP session is not connected! We can't adjust the screen.");
+ return;
+ }
+
+ // 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...");
+ }
- FixWindowsFormsHostSize();
+ // Fix the size of the WindowsFormsHost and the RDP control
+ FixWindowsFormsHostSize(desktopSize.Item1, desktopSize.Item2);
+
+ 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 e)
+ {
+ Log.Error("Could not adjust screen!", e);
+ }
}
- private void FixWindowsFormsHostSize()
+ ///
+ /// Fix the size of the WindowsFormsHost and the RDP control after the size
+ /// or DPI of the control has changed.
+ ///
+ /// Width of the RDP session.
+ /// Height of the RDP session.
+ private void FixWindowsFormsHostSize(double width, double height)
{
- RdpClientWidth = RdpClient.DesktopWidth;
- RdpClientHeight = RdpClient.DesktopHeight;
+ var windowsFormsHostSize = GetWindowsFormsHostSize(width, height);
+
+ // Set the max width and height for the WindowsFormsHost
+ WindowsFormsHostMaxWidth = windowsFormsHostSize.Item1;
+ WindowsFormsHostMaxHeight = windowsFormsHostSize.Item2;
+
+ // Update the size of the RDP control
+ RdpClient.Width = (int)width;
+ RdpClient.Height = (int)height;
}
+ 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.
+ ///
+ /// Keystroke to send.
public void SendKey(Keystroke keystroke)
{
if (!IsConnected)
@@ -369,6 +494,9 @@ public void SendKey(Keystroke keystroke)
ocx.SendKeys(info.KeyData.Length, info.ArrayKeyUp, info.KeyData);
}
+ ///
+ /// Disconnect the RDP session.
+ ///
private void Disconnect()
{
if (!IsConnected)
@@ -377,6 +505,9 @@ private void Disconnect()
RdpClient.Disconnect();
}
+ ///
+ /// Close the tab.
+ ///
public void CloseTab()
{
// Prevent multiple calls
@@ -487,6 +618,65 @@ 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
+ ///
+ ///
+ private uint GetDesktopScaleFactor()
+ {
+ var scaleFactor = GetDpiScaleFactor();
+
+ return scaleFactor switch
+ {
+ 125 => 125,
+ 150 or 175 => 150,
+ 200 => 200,
+ _ => (uint)(scaleFactor > 200 ? 200 : 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.
+ private 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.
+ private int GetDpiScaleFactor()
+ {
+ var x = System.Windows.Media.VisualTreeHelper.GetDpi(this);
+
+ return (int)(x.PixelsPerDip * 100);
+ }
#endregion
#region Events
@@ -504,30 +694,16 @@ 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 (IsConnected && _sessionInfo.AdjustScreenAutomatically && !IsReconnecting)
- ReconnectOnSizeChanged().ConfigureAwait(false);
+ if (_sessionInfo.AdjustScreenAutomatically)
+ AdjustScreen();
}
- 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(force: true);
}
-
- #endregion
-}
\ No newline at end of file
+}
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..0d097bdc2c 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;
@@ -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);
@@ -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
diff --git a/Website/docs/changelog/next-release.md b/Website/docs/changelog/next-release.md
index 771ba31bd8..4e7d1c8b94 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 fast 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)