From 2101d9718c4de80c1ba5a04b7fe7e39b7f67a8af Mon Sep 17 00:00:00 2001 From: Colton Date: Tue, 2 Sep 2025 18:01:09 -0400 Subject: [PATCH] Dispose of Win32 GDI handles when TrayIcon closed (#19583) --- src/Windows/Avalonia.Win32/TrayIconImpl.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Windows/Avalonia.Win32/TrayIconImpl.cs b/src/Windows/Avalonia.Win32/TrayIconImpl.cs index fdb6327a85..67130d1e4f 100644 --- a/src/Windows/Avalonia.Win32/TrayIconImpl.cs +++ b/src/Windows/Avalonia.Win32/TrayIconImpl.cs @@ -274,10 +274,11 @@ namespace Avalonia.Win32 private class TrayPopupRoot : Window { private readonly ManagedPopupPositioner _positioner; - + private readonly TrayIconManagedPopupPositionerPopupImplHelper _positionerHelper; public TrayPopupRoot() { - _positioner = new ManagedPopupPositioner(new TrayIconManagedPopupPositionerPopupImplHelper(MoveResize)); + _positionerHelper = new TrayIconManagedPopupPositionerPopupImplHelper(MoveResize); + _positioner = new ManagedPopupPositioner(_positionerHelper); Topmost = true; Deactivated += TrayPopupRoot_Deactivated; @@ -292,6 +293,12 @@ namespace Avalonia.Win32 Close(); } + protected override void OnClosed(EventArgs e) + { + base.OnClosed(e); + _positionerHelper.Dispose(); + } + private void MoveResize(PixelPoint position, Size size, double scaling) { if (PlatformImpl is { } platformImpl) @@ -315,7 +322,7 @@ namespace Avalonia.Win32 }); } - private class TrayIconManagedPopupPositionerPopupImplHelper : IManagedPopupPositionerPopup + private class TrayIconManagedPopupPositionerPopupImplHelper : IManagedPopupPositionerPopup, IDisposable { private readonly Action _moveResize; private readonly Window _hiddenWindow; @@ -350,6 +357,11 @@ namespace Avalonia.Win32 _moveResize(new PixelPoint((int)devicePoint.X, (int)devicePoint.Y), virtualSize, Scaling); } + public void Dispose() + { + _hiddenWindow.Close(); + } + public double Scaling => _hiddenWindow.Screens.Primary?.Scaling ?? 1.0; } }