From 39baee97de220b803081283c288a3262d5730b04 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Fri, 11 Sep 2026 23:01:07 -0700 Subject: [PATCH] Add WindowOrder_Owned_Window_Stays_InFront_Of_Topmost_Owner integration test Co-Authored-By: Claude Opus 5 (1M context) --- .../TopmostWindowTest.axaml | 6 ++-- .../TopmostWindowTest.axaml.cs | 23 ++++++++++++++ .../WindowTests_MacOS.cs | 30 +++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/samples/IntegrationTestApp/TopmostWindowTest.axaml b/samples/IntegrationTestApp/TopmostWindowTest.axaml index fbd2d9cf40..1b69805dac 100644 --- a/samples/IntegrationTestApp/TopmostWindowTest.axaml +++ b/samples/IntegrationTestApp/TopmostWindowTest.axaml @@ -9,8 +9,10 @@ Height="480"> + diff --git a/samples/IntegrationTestApp/TopmostWindowTest.axaml.cs b/samples/IntegrationTestApp/TopmostWindowTest.axaml.cs index c3ee80e3d6..613d97b113 100644 --- a/samples/IntegrationTestApp/TopmostWindowTest.axaml.cs +++ b/samples/IntegrationTestApp/TopmostWindowTest.axaml.cs @@ -1,16 +1,39 @@ +using System; +using System.Runtime.InteropServices; using Avalonia; using Avalonia.Controls; using Avalonia.Interactivity; +using Avalonia.Threading; namespace IntegrationTestApp; public partial class TopmostWindowTest : Window { + private readonly DispatcherTimer? _timer; + public TopmostWindowTest(string name) { Name = name; InitializeComponent(); PositionChanged += (s, e) => CurrentPosition.Text = $"{Position}"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + _timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(250) }; + _timer.Tick += TimerOnTick; + _timer.Start(); + } + } + + protected override void OnClosed(EventArgs e) + { + base.OnClosed(e); + _timer?.Stop(); + } + + private void TimerOnTick(object? sender, EventArgs e) + { + CurrentOrder.Text = MacOSIntegration.GetOrderedIndex(this).ToString(); } private void Button_OnClick(object? sender, RoutedEventArgs e) diff --git a/tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs b/tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs index e2554a346b..42a8a02a35 100644 --- a/tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs +++ b/tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs @@ -202,6 +202,30 @@ namespace Avalonia.IntegrationTests.Appium } } + [PlatformFact(TestPlatforms.MacOS)] + public void WindowOrder_Owned_Window_Stays_InFront_Of_Topmost_Owner() + { + Session.FindElementByAccessibilityId("ShowTopmostWindow").Click(); + + try + { + Thread.Sleep(1000); + + var ownerWindowIndex = GetWindowOrder("OwnerWindow"); + var ownedWindowIndex = GetWindowOrder("OwnedWindow"); + + // orderedIndex counts from the front, so the owned window needs the lower index. + Assert.True(ownedWindowIndex < ownerWindowIndex, + $"Expected the owned window in front of its topmost owner, but the owner was at " + + $"{ownerWindowIndex} and the owned window at {ownedWindowIndex}."); + } + finally + { + CloseWindow("OwnedWindow"); + CloseWindow("OwnerWindow"); + } + } + [PlatformFact(TestPlatforms.MacOS)] public void WindowOrder_Owned_Is_Correct_After_Closing_Window() { @@ -441,6 +465,12 @@ namespace Avalonia.IntegrationTests.Appium return int.Parse(order.Text); } + private void CloseWindow(string identifier) + { + GetWindow(identifier).FindElementByAccessibilityId("_XCUI:CloseWindow").Click(); + Thread.Sleep(1000); + } + public enum ShowWindowMode { NonOwned,