diff --git a/samples/IntegrationTestApp/MainWindow.axaml b/samples/IntegrationTestApp/MainWindow.axaml
index 493a3c6567..038ced4e5c 100644
--- a/samples/IntegrationTestApp/MainWindow.axaml
+++ b/samples/IntegrationTestApp/MainWindow.axaml
@@ -128,6 +128,12 @@
CenterScreen
CenterOwner
+
+ Normal
+ Minimized
+ Maximized
+ FullScreen
+
diff --git a/samples/IntegrationTestApp/MainWindow.axaml.cs b/samples/IntegrationTestApp/MainWindow.axaml.cs
index e8fb455c35..c1acc7ca88 100644
--- a/samples/IntegrationTestApp/MainWindow.axaml.cs
+++ b/samples/IntegrationTestApp/MainWindow.axaml.cs
@@ -59,6 +59,7 @@ namespace IntegrationTestApp
var sizeTextBox = this.GetControl("ShowWindowSize");
var modeComboBox = this.GetControl("ShowWindowMode");
var locationComboBox = this.GetControl("ShowWindowLocation");
+ var stateComboBox = this.GetControl("ShowWindowState");
var size = !string.IsNullOrWhiteSpace(sizeTextBox.Text) ? Size.Parse(sizeTextBox.Text) : (Size?)null;
var owner = (Window)this.GetVisualRoot()!;
@@ -85,6 +86,7 @@ namespace IntegrationTestApp
}
sizeTextBox.Text = string.Empty;
+ window.WindowState = (WindowState)stateComboBox.SelectedIndex;
switch (modeComboBox.SelectedIndex)
{
diff --git a/samples/IntegrationTestApp/ShowWindowTest.axaml b/samples/IntegrationTestApp/ShowWindowTest.axaml
index 68d1f3cf2f..c3a0d8d2e2 100644
--- a/samples/IntegrationTestApp/ShowWindowTest.axaml
+++ b/samples/IntegrationTestApp/ShowWindowTest.axaml
@@ -30,7 +30,7 @@
Normal
Minimized
Maximized
- Fullscreen
+ FullScreen
diff --git a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs
index 8aa4746b5a..4ce13ae0e0 100644
--- a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs
+++ b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs
@@ -588,9 +588,13 @@ namespace Avalonia.Win32
Resized(clientSize / RenderScaling, _resizeReason);
}
- var windowState = size == SizeCommand.Maximized ?
- WindowState.Maximized :
- (size == SizeCommand.Minimized ? WindowState.Minimized : WindowState.Normal);
+ var windowState = size switch
+ {
+ SizeCommand.Maximized => WindowState.Maximized,
+ SizeCommand.Minimized => WindowState.Minimized,
+ _ when _isFullScreenActive => WindowState.FullScreen,
+ _ => WindowState.Normal,
+ };
if (windowState != _lastWindowState)
{
diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs
index 9ed1a50ff2..42c576d01c 100644
--- a/src/Windows/Avalonia.Win32/WindowImpl.cs
+++ b/src/Windows/Avalonia.Win32/WindowImpl.cs
@@ -269,6 +269,11 @@ namespace Avalonia.Win32
{
get
{
+ if (!IsWindowVisible(_hwnd))
+ {
+ return _showWindowState;
+ }
+
if (_isFullScreenActive)
{
return WindowState.FullScreen;
@@ -562,6 +567,9 @@ namespace Avalonia.Win32
public void Resize(Size value, PlatformResizeReason reason)
{
+ if (WindowState != WindowState.Normal)
+ return;
+
int requestedClientWidth = (int)(value.Width * RenderScaling);
int requestedClientHeight = (int)(value.Height * RenderScaling);
@@ -902,11 +910,10 @@ namespace Avalonia.Win32
var window_rect = monitor_info.rcMonitor.ToPixelRect();
+ _isFullScreenActive = true;
SetWindowPos(_hwnd, IntPtr.Zero, window_rect.X, window_rect.Y,
window_rect.Width, window_rect.Height,
SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOACTIVATE | SetWindowPosFlags.SWP_FRAMECHANGED);
-
- _isFullScreenActive = true;
}
else
{
diff --git a/tests/Avalonia.IntegrationTests.Appium/ElementExtensions.cs b/tests/Avalonia.IntegrationTests.Appium/ElementExtensions.cs
index 4b361c6716..e7837a6971 100644
--- a/tests/Avalonia.IntegrationTests.Appium/ElementExtensions.cs
+++ b/tests/Avalonia.IntegrationTests.Appium/ElementExtensions.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Reactive.Disposables;
using System.Runtime.InteropServices;
+using System.Threading;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Interactions;
@@ -110,24 +111,30 @@ namespace Avalonia.IntegrationTests.Appium
{
var oldWindows = session.FindElements(By.XPath("/XCUIElementTypeApplication/XCUIElementTypeWindow"));
var oldWindowTitles = oldWindows.ToDictionary(x => x.Text);
-
+
element.Click();
+
+ // Wait for animations to run.
+ Thread.Sleep(1000);
var newWindows = session.FindElements(By.XPath("/XCUIElementTypeApplication/XCUIElementTypeWindow"));
var newWindowTitles = newWindows.ToDictionary(x => x.Text);
var newWindowTitle = Assert.Single(newWindowTitles.Keys.Except(oldWindowTitles.Keys));
- var newWindow = (AppiumWebElement)newWindowTitles[newWindowTitle];
-
+
return Disposable.Create(() =>
{
// TODO: We should be able to use Cmd+W here but Avalonia apps don't seem to have this shortcut
// set up by default.
- var (close, _, _) = newWindow.GetChromeButtons();
+ var windows = session.FindElements(By.XPath("/XCUIElementTypeApplication/XCUIElementTypeWindow"));
+ var text = windows.Select(x => x.Text).ToList();
+ var newWindow = session.FindElements(By.XPath("/XCUIElementTypeApplication/XCUIElementTypeWindow"))
+ .First(x => x.Text == newWindowTitle);
+ var (close, _, _) = ((AppiumWebElement)newWindow).GetChromeButtons();
close!.Click();
});
}
}
-
+
public static void SendClick(this AppiumWebElement element)
{
// The Click() method seems to correspond to accessibilityPerformPress on macOS but certain controls
diff --git a/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs b/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs
index 9cce169744..b6ac75b78e 100644
--- a/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs
+++ b/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs
@@ -57,7 +57,53 @@ namespace Avalonia.IntegrationTests.Appium
}
}
}
-
+
+ [Theory]
+ [MemberData(nameof(WindowStateData))]
+ public void WindowState(Size? size, ShowWindowMode mode, WindowState state)
+ {
+ using var window = OpenWindow(size, mode, state: state);
+
+ try
+ {
+ var info = GetWindowInfo();
+
+ Assert.Equal(state, info.WindowState);
+
+ switch (state)
+ {
+ case Controls.WindowState.Normal:
+ Assert.True(info.FrameSize.Width * info.Scaling < info.ScreenRect.Size.Width);
+ Assert.True(info.FrameSize.Height * info.Scaling < info.ScreenRect.Size.Height);
+ break;
+ case Controls.WindowState.Maximized:
+ case Controls.WindowState.FullScreen:
+ Assert.True(info.FrameSize.Width * info.Scaling >= info.ScreenRect.Size.Width);
+ Assert.True(info.FrameSize.Height * info.Scaling >= info.ScreenRect.Size.Height);
+ break;
+ }
+ }
+ finally
+ {
+ if (state == Controls.WindowState.FullScreen)
+ {
+ try
+ {
+ _session.FindElementByAccessibilityId("WindowState").SendClick();
+ _session.FindElementByName("Normal").SendClick();
+
+ // Wait for animations to run.
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ Thread.Sleep(1000);
+ }
+ catch
+ {
+ /* Ignore errors in cleanup */
+ }
+ }
+ }
+ }
+
[PlatformFact(TestPlatforms.Windows)]
public void OnWindows_Docked_Windows_Retain_Size_Position_When_Restored()
{
@@ -100,7 +146,7 @@ namespace Avalonia.IntegrationTests.Appium
[InlineData(ShowWindowMode.NonOwned)]
[InlineData(ShowWindowMode.Owned)]
[InlineData(ShowWindowMode.Modal)]
- public void WindowState(ShowWindowMode mode)
+ public void ShowMode(ShowWindowMode mode)
{
using var window = OpenWindow(null, mode, WindowStartupLocation.Manual);
var windowState = _session.FindElementByAccessibilityId("WindowState");
@@ -123,8 +169,8 @@ namespace Avalonia.IntegrationTests.Appium
if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || mode == ShowWindowMode.NonOwned)
{
windowState.Click();
- _session.FindElementByName("Fullscreen").SendClick();
- Assert.Equal("Fullscreen", windowState.GetComboBoxValue());
+ _session.FindElementByName("FullScreen").SendClick();
+ Assert.Equal("FullScreen", windowState.GetComboBoxValue());
current = GetWindowInfo();
var clientSize = PixelSize.FromSize(current.ClientSize, current.Scaling);
@@ -163,6 +209,35 @@ namespace Avalonia.IntegrationTests.Appium
return data;
}
+ public static TheoryData WindowStateData()
+ {
+ var sizes = new Size?[] { null, new Size(400, 300) };
+ var data = new TheoryData();
+
+ foreach (var size in sizes)
+ {
+ foreach (var mode in Enum.GetValues())
+ {
+ foreach (var state in Enum.GetValues())
+ {
+ // 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);
+ }
+ }
+ }
+
+ return data;
+ }
+
private static void AssertCloseEnough(PixelPoint expected, PixelPoint actual)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
@@ -189,11 +264,16 @@ namespace Avalonia.IntegrationTests.Appium
}
}
- private IDisposable OpenWindow(Size? size, ShowWindowMode mode, WindowStartupLocation location)
+ private IDisposable OpenWindow(
+ Size? size,
+ ShowWindowMode mode,
+ WindowStartupLocation location = WindowStartupLocation.Manual,
+ WindowState state = Controls.WindowState.Normal)
{
var sizeTextBox = _session.FindElementByAccessibilityId("ShowWindowSize");
var modeComboBox = _session.FindElementByAccessibilityId("ShowWindowMode");
var locationComboBox = _session.FindElementByAccessibilityId("ShowWindowLocation");
+ var stateComboBox = _session.FindElementByAccessibilityId("ShowWindowState");
var showButton = _session.FindElementByAccessibilityId("ShowWindow");
if (size.HasValue)
@@ -205,6 +285,9 @@ namespace Avalonia.IntegrationTests.Appium
locationComboBox.Click();
_session.FindElementByName(location.ToString()).SendClick();
+ stateComboBox.Click();
+ _session.FindElementByName(state.ToString()).SendClick();
+
return showButton.OpenWindowWithClick();
}
@@ -228,7 +311,8 @@ namespace Avalonia.IntegrationTests.Appium
PixelPoint.Parse(_session.FindElementByAccessibilityId("Position").Text),
ReadOwnerRect(),
PixelRect.Parse(_session.FindElementByAccessibilityId("ScreenRect").Text),
- double.Parse(_session.FindElementByAccessibilityId("Scaling").Text));
+ double.Parse(_session.FindElementByAccessibilityId("Scaling").Text),
+ Enum.Parse(_session.FindElementByAccessibilityId("WindowState").Text));
}
catch (OpenQA.Selenium.NoSuchElementException) when (retry++ < 3)
{
@@ -252,6 +336,7 @@ namespace Avalonia.IntegrationTests.Appium
PixelPoint Position,
PixelRect? OwnerRect,
PixelRect ScreenRect,
- double Scaling);
+ double Scaling,
+ WindowState WindowState);
}
}