Browse Source
* Add non-overlay popup support to the headless platform When AvaloniaHeadlessPlatformOptions.UsePlatformPopups is enabled, popups are hosted in dedicated headless top-levels positioned via ManagedPopupPositioner instead of the parent's overlay layer. HeadlessWindowExtensions.GetOpenPopups exposes the popups open above a given toplevel. PointToScreen/PointToClient now account for the window position, so popup placement can be asserted in desktop coordinates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Rename UsePlatformPopups to OverlayPopups for consistency with other platforms Inverted semantics to match Win32/X11/macOS options; defaults to true for now so existing headless test suites keep overlay popup behavior. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>pull/21918/head
committed by
GitHub
6 changed files with 258 additions and 13 deletions
@ -0,0 +1,185 @@ |
|||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Controls.Primitives; |
||||
|
using Avalonia.Input; |
||||
|
using Avalonia.Layout; |
||||
|
using Avalonia.Media; |
||||
|
using Avalonia.Threading; |
||||
|
|
||||
|
namespace Avalonia.Headless.UnitTests; |
||||
|
|
||||
|
public class PopupTests |
||||
|
{ |
||||
|
#if NUNIT
|
||||
|
[AvaloniaTest] |
||||
|
#elif XUNIT
|
||||
|
[AvaloniaFact] |
||||
|
#endif
|
||||
|
public void Point_To_Screen_Respects_Window_Position() |
||||
|
{ |
||||
|
var window = new Window { Width = 100, Height = 100 }; |
||||
|
window.Position = new PixelPoint(100, 200); |
||||
|
window.Show(); |
||||
|
Dispatcher.UIThread.RunJobs(); |
||||
|
|
||||
|
AssertHelper.Equal(new PixelPoint(110, 220), window.PointToScreen(new Point(10, 20))); |
||||
|
AssertHelper.Equal(new Point(10, 20), window.PointToClient(new PixelPoint(110, 220))); |
||||
|
|
||||
|
window.Close(); |
||||
|
} |
||||
|
|
||||
|
#if NUNIT
|
||||
|
[AvaloniaTest] |
||||
|
#elif XUNIT
|
||||
|
[AvaloniaFact] |
||||
|
#endif
|
||||
|
public void Popup_Uses_Dedicated_TopLevel_And_Is_Discoverable() |
||||
|
{ |
||||
|
var target = new Border { Background = Brushes.Red }; |
||||
|
var popup = new Popup |
||||
|
{ |
||||
|
PlacementTarget = target, |
||||
|
Child = new Border { Width = 20, Height = 20 } |
||||
|
}; |
||||
|
var window = new Window |
||||
|
{ |
||||
|
Width = 100, |
||||
|
Height = 100, |
||||
|
Content = new Panel { Children = { target, popup } } |
||||
|
}; |
||||
|
window.Show(); |
||||
|
Dispatcher.UIThread.RunJobs(); |
||||
|
|
||||
|
AssertHelper.Equal(0, window.GetOpenPopups().Count); |
||||
|
|
||||
|
popup.Open(); |
||||
|
Dispatcher.UIThread.RunJobs(); |
||||
|
|
||||
|
AssertHelper.True(popup.IsOpen); |
||||
|
AssertHelper.False(popup.IsUsingOverlayLayer); |
||||
|
AssertHelper.Equal(1, window.GetOpenPopups().Count); |
||||
|
AssertHelper.True(window.GetOpenPopups()[0] is PopupRoot); |
||||
|
|
||||
|
popup.Close(); |
||||
|
Dispatcher.UIThread.RunJobs(); |
||||
|
|
||||
|
AssertHelper.Equal(0, window.GetOpenPopups().Count); |
||||
|
|
||||
|
window.Close(); |
||||
|
} |
||||
|
|
||||
|
#if NUNIT
|
||||
|
[AvaloniaTest] |
||||
|
#elif XUNIT
|
||||
|
[AvaloniaFact] |
||||
|
#endif
|
||||
|
public void Can_Click_Button_Inside_Platform_Popup() |
||||
|
{ |
||||
|
var clickCount = 0; |
||||
|
var button = new Button { Width = 80, Height = 30 }; |
||||
|
button.Click += (_, _) => clickCount++; |
||||
|
|
||||
|
var target = new Border { Background = Brushes.Red }; |
||||
|
var popup = new Popup { PlacementTarget = target, Child = button }; |
||||
|
var window = new Window |
||||
|
{ |
||||
|
Width = 100, |
||||
|
Height = 100, |
||||
|
Content = new Panel { Children = { target, popup } } |
||||
|
}; |
||||
|
window.Show(); |
||||
|
Dispatcher.UIThread.RunJobs(); |
||||
|
|
||||
|
popup.Open(); |
||||
|
Dispatcher.UIThread.RunJobs(); |
||||
|
|
||||
|
var popupRoot = window.GetOpenPopups()[0]; |
||||
|
popupRoot.MouseDown(new Point(40, 15), MouseButton.Left); |
||||
|
popupRoot.MouseUp(new Point(40, 15), MouseButton.Left); |
||||
|
|
||||
|
AssertHelper.Equal(1, clickCount); |
||||
|
|
||||
|
window.Close(); |
||||
|
} |
||||
|
|
||||
|
#if NUNIT
|
||||
|
[AvaloniaTest] |
||||
|
#elif XUNIT
|
||||
|
[AvaloniaFact] |
||||
|
#endif
|
||||
|
public void Popup_Placement_Respects_Window_Position() |
||||
|
{ |
||||
|
var target = new Border |
||||
|
{ |
||||
|
Width = 20, |
||||
|
Height = 20, |
||||
|
HorizontalAlignment = HorizontalAlignment.Left, |
||||
|
VerticalAlignment = VerticalAlignment.Top, |
||||
|
Background = Brushes.Red |
||||
|
}; |
||||
|
var popup = new Popup |
||||
|
{ |
||||
|
PlacementTarget = target, |
||||
|
Placement = PlacementMode.Bottom, |
||||
|
Child = new Border { Width = 20, Height = 20 } |
||||
|
}; |
||||
|
var window = new Window |
||||
|
{ |
||||
|
Width = 100, |
||||
|
Height = 100, |
||||
|
Content = new Panel { Children = { target, popup } } |
||||
|
}; |
||||
|
window.Position = new PixelPoint(100, 200); |
||||
|
window.Show(); |
||||
|
Dispatcher.UIThread.RunJobs(); |
||||
|
|
||||
|
popup.Open(); |
||||
|
Dispatcher.UIThread.RunJobs(); |
||||
|
|
||||
|
var popupRoot = window.GetOpenPopups()[0]; |
||||
|
var expected = target.PointToScreen(new Point(0, target.Bounds.Height)); |
||||
|
AssertHelper.Equal(expected, popupRoot.PointToScreen(default)); |
||||
|
|
||||
|
window.Close(); |
||||
|
} |
||||
|
|
||||
|
#if NUNIT
|
||||
|
[AvaloniaTest] |
||||
|
#elif XUNIT
|
||||
|
[AvaloniaFact] |
||||
|
#endif
|
||||
|
public void Nested_Popup_Is_Child_Of_Popup_Root() |
||||
|
{ |
||||
|
var nestedTarget = new Border { Width = 20, Height = 20, Background = Brushes.Green }; |
||||
|
var nestedPopup = new Popup |
||||
|
{ |
||||
|
PlacementTarget = nestedTarget, |
||||
|
Child = new Border { Width = 10, Height = 10 } |
||||
|
}; |
||||
|
var target = new Border { Background = Brushes.Red }; |
||||
|
var popup = new Popup |
||||
|
{ |
||||
|
PlacementTarget = target, |
||||
|
Child = new Panel { Children = { nestedTarget, nestedPopup } } |
||||
|
}; |
||||
|
var window = new Window |
||||
|
{ |
||||
|
Width = 100, |
||||
|
Height = 100, |
||||
|
Content = new Panel { Children = { target, popup } } |
||||
|
}; |
||||
|
window.Show(); |
||||
|
Dispatcher.UIThread.RunJobs(); |
||||
|
|
||||
|
popup.Open(); |
||||
|
Dispatcher.UIThread.RunJobs(); |
||||
|
nestedPopup.Open(); |
||||
|
Dispatcher.UIThread.RunJobs(); |
||||
|
|
||||
|
var popupRoot = window.GetOpenPopups()[0]; |
||||
|
AssertHelper.Equal(1, window.GetOpenPopups().Count); |
||||
|
AssertHelper.Equal(1, popupRoot.GetOpenPopups().Count); |
||||
|
AssertHelper.True(popupRoot.GetOpenPopups()[0] is PopupRoot); |
||||
|
|
||||
|
window.Close(); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue