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
This commit is contained in:
Mike Griese
2025-04-03 06:44:10 -05:00
committed by GitHub
parent 7a5b25cd3e
commit d48286a3eb
2 changed files with 27 additions and 1 deletions

View File

@@ -19,6 +19,7 @@ SetFocus
SetActiveWindow
MonitorFromWindow
GetMonitorInfo
GetDpiForMonitor
SHCreateStreamOnFileEx
CoAllowSetForegroundWindow
SHCreateStreamOnFileEx

View File

@@ -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<QuitMessage>(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)