diff --git a/native/Avalonia.Native/src/OSX/WindowImpl.mm b/native/Avalonia.Native/src/OSX/WindowImpl.mm
index 2443965957..b6dacb6ce4 100644
--- a/native/Avalonia.Native/src/OSX/WindowImpl.mm
+++ b/native/Avalonia.Native/src/OSX/WindowImpl.mm
@@ -137,7 +137,11 @@ void WindowImpl::BringToFront()
for(auto iterator = _children.begin(); iterator != _children.end(); iterator++)
{
- (*iterator)->BringToFront();
+ auto window = (*iterator)->Window;
+
+ // #9565: Only bring window to front if it's on the currently active space
+ if ([window isOnActiveSpace])
+ (*iterator)->BringToFront();
}
}
}
@@ -161,6 +165,9 @@ void WindowImpl::StartStateTransition() {
void WindowImpl::EndStateTransition() {
_transitioningWindowState = false;
+
+ // Ensure correct order of child windows after fullscreen transition.
+ BringToFront();
}
SystemDecorations WindowImpl::Decorations() {
diff --git a/samples/IntegrationTestApp/MainWindow.axaml b/samples/IntegrationTestApp/MainWindow.axaml
index 038ced4e5c..54c0cb0655 100644
--- a/samples/IntegrationTestApp/MainWindow.axaml
+++ b/samples/IntegrationTestApp/MainWindow.axaml
@@ -17,11 +17,15 @@
-
+
+
+ WindowState:
+
+
@@ -129,13 +133,14 @@
CenterOwner
- Normal
- Minimized
- Maximized
- FullScreen
+ Normal
+ Minimized
+ Maximized
+ FullScreen
+
diff --git a/samples/IntegrationTestApp/MainWindow.axaml.cs b/samples/IntegrationTestApp/MainWindow.axaml.cs
index c1acc7ca88..841947673a 100644
--- a/samples/IntegrationTestApp/MainWindow.axaml.cs
+++ b/samples/IntegrationTestApp/MainWindow.axaml.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia;
@@ -178,6 +179,8 @@ namespace IntegrationTestApp
ShowWindow();
if (source?.Name == "SendToBack")
SendToBack();
+ if (source?.Name == "EnterFullscreen")
+ WindowState = WindowState.FullScreen;
if (source?.Name == "ExitFullscreen")
WindowState = WindowState.Normal;
if (source?.Name == "RestoreAll")
diff --git a/samples/IntegrationTestApp/ShowWindowTest.axaml b/samples/IntegrationTestApp/ShowWindowTest.axaml
index c3a0d8d2e2..00987429d0 100644
--- a/samples/IntegrationTestApp/ShowWindowTest.axaml
+++ b/samples/IntegrationTestApp/ShowWindowTest.axaml
@@ -27,10 +27,10 @@
- Normal
- Minimized
- Maximized
- FullScreen
+ Normal
+ Minimized
+ Maximized
+ FullScreen
diff --git a/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs b/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs
index b6ac75b78e..4d833cdb1f 100644
--- a/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs
+++ b/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs
@@ -90,7 +90,7 @@ namespace Avalonia.IntegrationTests.Appium
try
{
_session.FindElementByAccessibilityId("WindowState").SendClick();
- _session.FindElementByName("Normal").SendClick();
+ _session.FindElementByAccessibilityId("WindowStateNormal").SendClick();
// Wait for animations to run.
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
@@ -155,11 +155,11 @@ namespace Avalonia.IntegrationTests.Appium
Assert.Equal("Normal", windowState.GetComboBoxValue());
windowState.Click();
- _session.FindElementByName("Maximized").SendClick();
+ _session.FindElementByAccessibilityId("WindowStateMaximized").SendClick();
Assert.Equal("Maximized", windowState.GetComboBoxValue());
windowState.Click();
- _session.FindElementByName("Normal").SendClick();
+ _session.FindElementByAccessibilityId("WindowStateNormal").SendClick();
var current = GetWindowInfo();
Assert.Equal(original.Position, current.Position);
@@ -169,7 +169,7 @@ namespace Avalonia.IntegrationTests.Appium
if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || mode == ShowWindowMode.NonOwned)
{
windowState.Click();
- _session.FindElementByName("FullScreen").SendClick();
+ _session.FindElementByAccessibilityId("WindowStateFullScreen").SendClick();
Assert.Equal("FullScreen", windowState.GetComboBoxValue());
current = GetWindowInfo();
@@ -179,7 +179,7 @@ namespace Avalonia.IntegrationTests.Appium
windowState.SendClick();
- _session.FindElementByName("Normal").SendClick();
+ _session.FindElementByAccessibilityId("WindowStateNormal").SendClick();
current = GetWindowInfo();
Assert.Equal(original.Position, current.Position);
@@ -223,13 +223,13 @@ namespace Avalonia.IntegrationTests.Appium
// Not sure how to handle testing minimized windows currently.
if (state == Controls.WindowState.Minimized)
continue;
-
+
// Child/Modal windows cannot be fullscreen on macOS.
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) &&
state == Controls.WindowState.FullScreen &&
mode != ShowWindowMode.NonOwned)
continue;
-
+
data.Add(size, mode, state);
}
}
@@ -286,7 +286,7 @@ namespace Avalonia.IntegrationTests.Appium
_session.FindElementByName(location.ToString()).SendClick();
stateComboBox.Click();
- _session.FindElementByName(state.ToString()).SendClick();
+ _session.FindElementByAccessibilityId($"ShowWindowState{state}").SendClick();
return showButton.OpenWindowWithClick();
}
diff --git a/tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs b/tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs
index 05ed0616a8..6c61a85561 100644
--- a/tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs
+++ b/tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Avalonia.Controls;
+using Avalonia.Utilities;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Interactions;
@@ -114,6 +115,79 @@ namespace Avalonia.IntegrationTests.Appium
Assert.Equal(1, secondaryWindowIndex);
}
}
+
+ [PlatformFact(TestPlatforms.MacOS)]
+ public void WindowOrder_Owned_Dialog_Stays_InFront_Of_FullScreen_Parent()
+ {
+ var mainWindow = _session.FindElementByAccessibilityId("MainWindow");
+
+ // Enter fullscreen
+ mainWindow.FindElementByAccessibilityId("EnterFullscreen").Click();
+
+ // Wait for fullscreen transition.
+ Thread.Sleep(1000);
+
+ // Make sure we entered fullscreen.
+ var windowState = mainWindow.FindElementByAccessibilityId("MainWindowState");
+ Assert.Equal("FullScreen", windowState.Text);
+
+ // Open child window.
+ using (OpenWindow(new PixelSize(200, 100), ShowWindowMode.Owned, WindowStartupLocation.Manual))
+ {
+ mainWindow.SendClick();
+ var secondaryWindowIndex = GetWindowOrder("SecondaryWindow");
+ Assert.Equal(1, secondaryWindowIndex);
+ }
+
+ // Exit fullscreen by menu shortcut Command+R
+ mainWindow.FindElementByAccessibilityId("ExitFullscreen").Click();
+
+ // Wait for restore transition.
+ Thread.Sleep(1000);
+
+ // Make sure we exited fullscreen.
+ mainWindow = _session.FindElementByAccessibilityId("MainWindow");
+ windowState = mainWindow.FindElementByAccessibilityId("MainWindowState");
+ Assert.Equal("Normal", windowState.Text);
+ }
+
+ [PlatformFact(TestPlatforms.MacOS)]
+ public void Does_Not_Switch_Space_From_FullScreen_To_Main_Desktop_When_FullScreen_Window_Clicked()
+ {
+ // Issue #9565
+ var mainWindow = _session.FindElementByAccessibilityId("MainWindow");
+ AppiumWebElement windowState;
+
+ // Open child window.
+ using (OpenWindow(new PixelSize(200, 100), ShowWindowMode.Owned, WindowStartupLocation.Manual))
+ {
+ // Enter fullscreen
+ mainWindow.FindElementByAccessibilityId("EnterFullscreen").Click();
+
+ // Wait for fullscreen transition.
+ Thread.Sleep(1000);
+
+ // Make sure we entered fullscreen.
+ mainWindow = _session.FindElementByAccessibilityId("MainWindow");
+ windowState = mainWindow.FindElementByAccessibilityId("MainWindowState");
+ Assert.Equal("FullScreen", windowState.Text);
+
+ // Click on main window
+ mainWindow.Click();
+
+ // Failed here due to #9565: main window is no longer visible as the main space is now shown instead
+ // of the fullscreen space.
+ mainWindow.FindElementByAccessibilityId("ExitFullscreen").Click();
+
+ // Wait for restore transition.
+ Thread.Sleep(1000);
+ }
+
+ // Make sure we exited fullscreen.
+ mainWindow = _session.FindElementByAccessibilityId("MainWindow");
+ windowState = mainWindow.FindElementByAccessibilityId("MainWindowState");
+ Assert.Equal("Normal", windowState.Text);
+ }
[PlatformFact(TestPlatforms.MacOS)]
public void WindowOrder_NonOwned_Window_Does_Not_Stay_InFront_Of_Parent()