Browse Source

Merge pull request #8236 from AvaloniaUI/fix-popup-leak

Fix FlyoutBase/ContextMenu memory leak
pull/8239/head
Dan Walmsley 4 years ago
parent
commit
81698eb502
  1. 5
      src/Avalonia.Controls/ContextMenu.cs
  2. 3
      src/Avalonia.Controls/Flyouts/FlyoutBase.cs
  3. 21
      tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs
  4. 25
      tests/Avalonia.Controls.UnitTests/FlyoutTests.cs

5
src/Avalonia.Controls/ContextMenu.cs

@ -448,6 +448,11 @@ namespace Avalonia.Controls
if (sender is Control control
&& control.ContextMenu is ContextMenu contextMenu)
{
if (contextMenu._popup?.Parent == control)
{
((ISetLogicalParent)contextMenu._popup).SetParent(null);
}
contextMenu.Close();
}
}

3
src/Avalonia.Controls/Flyouts/FlyoutBase.cs

@ -177,7 +177,8 @@ namespace Avalonia.Controls.Primitives
IsOpen = false;
Popup.IsOpen = false;
((ISetLogicalParent)Popup).SetParent(null);
// Ensure this isn't active
_transientDisposable?.Dispose();
_transientDisposable = null;

21
tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs

@ -445,6 +445,27 @@ namespace Avalonia.Controls.UnitTests
}
}
[Fact]
public void Should_Reset_Popup_Parent_On_Target_Detached()
{
using (Application())
{
var userControl = new UserControl();
var window = PreparedWindow(userControl);
window.Show();
var menu = new ContextMenu();
userControl.ContextMenu = menu;
menu.Open();
var popup = Assert.IsType<Popup>(menu.Parent);
Assert.NotNull(popup.Parent);
window.Content = null;
Assert.Null(popup.Parent);
}
}
[Fact]
public void Context_Menu_In_Resources_Can_Be_Shared()
{

25
tests/Avalonia.Controls.UnitTests/FlyoutTests.cs

@ -432,6 +432,26 @@ namespace Avalonia.Controls.UnitTests
}
}
[Fact]
public void Should_Reset_Popup_Parent_On_Target_Detached()
{
using (CreateServicesWithFocus())
{
var userControl = new UserControl();
var window = PreparedWindow(userControl);
window.Show();
var flyout = new TestFlyout();
flyout.ShowAt(userControl);
var popup = Assert.IsType<Popup>(flyout.Popup);
Assert.NotNull(popup.Parent);
window.Content = null;
Assert.Null(popup.Parent);
}
}
[Fact]
public void ContextFlyout_Can_Be_Set_In_Styles()
{
@ -549,5 +569,10 @@ namespace Avalonia.Controls.UnitTests
new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.LeftButtonPressed),
KeyModifiers.None);
}
public class TestFlyout : Flyout
{
public new Popup Popup => base.Popup;
}
}
}

Loading…
Cancel
Save