From d48286a3ebedff8b6c64bbe8e57302a34a36c257 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 3 Apr 2025 06:44:10 -0500 Subject: [PATCH] Scale the toast window for DPI (#38198) Ah of course, AppWindow.Resize doesn't use DIPs. Why would it? It's not like literally everything else in XAML does. Related to half of https://github.com/zadjii-msft/PowerToys/issues/508 --- .../Microsoft.CmdPal.UI/NativeMethods.txt | 1 + .../Microsoft.CmdPal.UI/ToastWindow.xaml.cs | 27 ++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/NativeMethods.txt b/src/modules/cmdpal/Microsoft.CmdPal.UI/NativeMethods.txt index 6186b45ef8..566f459c65 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/NativeMethods.txt +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/NativeMethods.txt @@ -19,6 +19,7 @@ SetFocus SetActiveWindow MonitorFromWindow GetMonitorInfo +GetDpiForMonitor SHCreateStreamOnFileEx CoAllowSetForegroundWindow SHCreateStreamOnFileEx diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/ToastWindow.xaml.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/ToastWindow.xaml.cs index e21c8dd55d..47ecf96975 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/ToastWindow.xaml.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/ToastWindow.xaml.cs @@ -4,6 +4,7 @@ using CommunityToolkit.Mvvm.Messaging; using CommunityToolkit.WinUI; +using ManagedCommon; using Microsoft.CmdPal.UI.Helpers; using Microsoft.CmdPal.UI.ViewModels; using Microsoft.CmdPal.UI.ViewModels.Messages; @@ -13,6 +14,8 @@ using Microsoft.UI.Xaml; using Windows.Graphics; using Windows.Win32; using Windows.Win32.Foundation; +using Windows.Win32.Graphics.Gdi; +using Windows.Win32.UI.HiDpi; using Windows.Win32.UI.WindowsAndMessaging; using RS_ = Microsoft.CmdPal.UI.Helpers.ResourceLoaderInstance; @@ -44,6 +47,21 @@ public sealed partial class ToastWindow : Window, WeakReferenceMessenger.Default.Register(this); } + private static double GetScaleFactor(HWND hwnd) + { + try + { + var monitor = PInvoke.MonitorFromWindow(hwnd, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST); + _ = PInvoke.GetDpiForMonitor(monitor, MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, out var dpiX, out _); + return dpiX / 96.0; + } + catch (Exception ex) + { + Logger.LogError($"Failed to get scale factor, error: {ex.Message}"); + return 1.0; + } + } + private void PositionCentered() { var intSize = new SizeInt32 @@ -51,7 +69,14 @@ public sealed partial class ToastWindow : Window, Width = Convert.ToInt32(ToastText.ActualWidth), Height = Convert.ToInt32(ToastText.ActualHeight), }; - AppWindow.Resize(intSize); + + var scaleAdjustment = GetScaleFactor(_hwnd); + var scaled = new SizeInt32 + { + Width = (int)Math.Round(intSize.Width * scaleAdjustment), + Height = (int)Math.Round(intSize.Height * scaleAdjustment), + }; + AppWindow.Resize(scaled); var displayArea = DisplayArea.GetFromWindowId(AppWindow.Id, DisplayAreaFallback.Nearest); if (displayArea is not null)