From 9fad2a1b599ec374e60f4dd1e2a675e325c16427 Mon Sep 17 00:00:00 2001 From: Ben Hillis Date: Thu, 13 Nov 2025 13:52:29 -0800 Subject: [PATCH] wslsettings: fix OOBE text truncation at 200% text scaling (#13693) * wslsettings: fix OOBE text truncation at 200% text scaling Add text scaling factor to window resize calculation and make hero image height responsive to text scaling. Increase minimum window size for better accessibility. Fix MAS 1.4.4 compliance for OOBE dialog. * pr feedback --------- Co-authored-by: Ben Hillis --- .../wslsettings/Controls/OOBEContent.xaml | 2 +- .../wslsettings/Controls/OOBEContent.xaml.cs | 35 +++++++++++++++++-- src/windows/wslsettings/LibWsl.cs | 4 +-- .../wslsettings/Windows/OOBEWindow.xaml | 4 +-- .../wslsettings/Windows/OOBEWindow.xaml.cs | 26 +++++++++++--- 5 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/windows/wslsettings/Controls/OOBEContent.xaml b/src/windows/wslsettings/Controls/OOBEContent.xaml index 670a4aa..e4c6721 100644 --- a/src/windows/wslsettings/Controls/OOBEContent.xaml +++ b/src/windows/wslsettings/Controls/OOBEContent.xaml @@ -19,7 +19,7 @@ diff --git a/src/windows/wslsettings/Controls/OOBEContent.xaml.cs b/src/windows/wslsettings/Controls/OOBEContent.xaml.cs index a017b0a..90f37dc 100644 --- a/src/windows/wslsettings/Controls/OOBEContent.xaml.cs +++ b/src/windows/wslsettings/Controls/OOBEContent.xaml.cs @@ -1,15 +1,46 @@ -// Copyright (c) Microsoft Corporation +// Copyright (C) Microsoft Corporation. All rights reserved. using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; +using Windows.UI.ViewManagement; namespace WslSettings.Controls { public sealed partial class OOBEContent : UserControl { + // Constants for hero image height calculations + private const double BaseImageHeight = 280.0; + private const double MinimumImageHeight = 200.0; + + private static readonly UISettings Settings = new UISettings(); + public OOBEContent() { this.InitializeComponent(); + + // Set initial hero image height based on current text scaling + UpdateHeroImageHeight(); + + // Subscribe to text scale factor changes for dynamic updates + Settings.TextScaleFactorChanged += OnTextScaleFactorChanged; + + // Ensure event cleanup when control is unloaded + this.Unloaded += (s, e) => Settings.TextScaleFactorChanged -= OnTextScaleFactorChanged; + } + + private void UpdateHeroImageHeight() + { + double textScaleFactor = Settings.TextScaleFactor; + + // Reduce image height when text scaling increases to preserve content space + // Use inverse relationship: as text gets larger, image gets proportionally smaller + HeroImageHeight = Math.Max(BaseImageHeight / textScaleFactor, MinimumImageHeight); + } + + private void OnTextScaleFactorChanged(UISettings sender, object args) + { + // Update hero image height when text scaling changes at runtime + this.DispatcherQueue.TryEnqueue(() => UpdateHeroImageHeight()); } public string Title @@ -46,6 +77,6 @@ namespace WslSettings.Controls public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register("Description", typeof(string), typeof(OOBEContent), new PropertyMetadata(default(string))); public static readonly DependencyProperty HeroImageProperty = DependencyProperty.Register("HeroImage", typeof(string), typeof(OOBEContent), new PropertyMetadata(default(string))); public static readonly DependencyProperty PageContentProperty = DependencyProperty.Register("PageContent", typeof(object), typeof(OOBEContent), new PropertyMetadata(new Grid())); - public static readonly DependencyProperty HeroImageHeightProperty = DependencyProperty.Register("HeroImageHeight", typeof(double), typeof(OOBEContent), new PropertyMetadata(280.0)); + public static readonly DependencyProperty HeroImageHeightProperty = DependencyProperty.Register("HeroImageHeight", typeof(double), typeof(OOBEContent), new PropertyMetadata(BaseImageHeight)); } } \ No newline at end of file diff --git a/src/windows/wslsettings/LibWsl.cs b/src/windows/wslsettings/LibWsl.cs index 4037772..cd151fd 100644 --- a/src/windows/wslsettings/LibWsl.cs +++ b/src/windows/wslsettings/LibWsl.cs @@ -80,7 +80,7 @@ namespace LibWsl internal static bool __TryGetNativeToManagedMapping(IntPtr native, out global::LibWsl.WslConfig managed) { - + return NativeToManagedMap.TryGetValue(native, out managed); } @@ -171,7 +171,7 @@ namespace LibWsl internal static bool __TryGetNativeToManagedMapping(IntPtr native, out global::LibWsl.WslConfigSetting managed) { - + return NativeToManagedMap.TryGetValue(native, out managed); } diff --git a/src/windows/wslsettings/Windows/OOBEWindow.xaml b/src/windows/wslsettings/Windows/OOBEWindow.xaml index 1c3d3cd..6181872 100644 --- a/src/windows/wslsettings/Windows/OOBEWindow.xaml +++ b/src/windows/wslsettings/Windows/OOBEWindow.xaml @@ -5,8 +5,8 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:windowex="using:WinUIEx" - MinWidth="480" - MinHeight="480" + MinWidth="600" + MinHeight="600" Closed="Window_Closed" mc:Ignorable="d"> diff --git a/src/windows/wslsettings/Windows/OOBEWindow.xaml.cs b/src/windows/wslsettings/Windows/OOBEWindow.xaml.cs index 383f4df..f344006 100644 --- a/src/windows/wslsettings/Windows/OOBEWindow.xaml.cs +++ b/src/windows/wslsettings/Windows/OOBEWindow.xaml.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation +// Copyright (C) Microsoft Corporation. All rights reserved. using Microsoft.UI.Windowing; using Microsoft.UI.Xaml; @@ -41,6 +41,7 @@ public sealed partial class OOBEWindow : WindowEx, IDisposable // Theme change code picked from https://github.com/microsoft/WinUI-Gallery/pull/1239 settings.ColorValuesChanged += Settings_ColorValuesChanged; // cannot use FrameworkElement.ActualThemeChanged event + settings.TextScaleFactorChanged += Settings_TextScaleFactorChanged; WindowManager.Get(this).IsMinimizable = false; WindowManager.Get(this).IsMaximizable = false; @@ -77,6 +78,16 @@ public sealed partial class OOBEWindow : WindowEx, IDisposable }); } + // This handles text scaling changes for accessibility + private void Settings_TextScaleFactorChanged(UISettings sender, object args) + { + // This calls comes off-thread, hence we will need to dispatch it to current app's thread + dispatcherQueue.TryEnqueue(() => + { + ResizeWindow(); + }); + } + private void Window_SizeChanged(object sender, WindowSizeChangedEventArgs args) { var dpi = GetDpiForWindow(hWnd); @@ -97,9 +108,15 @@ public sealed partial class OOBEWindow : WindowEx, IDisposable private void ResizeWindow() { - float scalingFactor = (float)currentDPI / DefaultDPI; - int width = (int)(ExpectedWidth * scalingFactor); - int height = (int)(ExpectedHeight * scalingFactor); + float dpiScalingFactor = (float)currentDPI / DefaultDPI; + float textScalingFactor = (float)settings.TextScaleFactor; + + // Combine DPI scaling and text scaling for accessibility + float combinedScalingFactor = dpiScalingFactor * textScalingFactor; + + int width = (int)(ExpectedWidth * combinedScalingFactor); + int height = (int)(ExpectedHeight * combinedScalingFactor); + SizeInt32 size; size.Width = width; size.Height = height; @@ -112,6 +129,7 @@ public sealed partial class OOBEWindow : WindowEx, IDisposable { msgMonitor?.Dispose(); settings.ColorValuesChanged -= Settings_ColorValuesChanged; + settings.TextScaleFactorChanged -= Settings_TextScaleFactorChanged; this.Activated -= OnWindowActivated; if (this.Content is Microsoft.UI.Xaml.Controls.Page page) {