From f4804551316b4141367f3ef3fa38c50d9a702fc0 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 29 Nov 2022 12:39:24 +0100 Subject: [PATCH 01/14] Added failing test for #9565. And another (passing) test for checking that window order is correct when a child window is shown in fullscreen. --- samples/IntegrationTestApp/MainWindow.axaml | 7 +- .../IntegrationTestApp/MainWindow.axaml.cs | 3 + .../WindowTests_MacOS.cs | 74 +++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/samples/IntegrationTestApp/MainWindow.axaml b/samples/IntegrationTestApp/MainWindow.axaml index 038ced4e5c..801ff765c8 100644 --- a/samples/IntegrationTestApp/MainWindow.axaml +++ b/samples/IntegrationTestApp/MainWindow.axaml @@ -17,11 +17,15 @@ - + + + WindowState: + + @@ -136,6 +140,7 @@ + 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/tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs b/tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs index 05ed0616a8..8f4417a451 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("WindowState"); + 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("WindowState"); + 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("WindowState"); + 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("WindowState"); + Assert.Equal("Normal", windowState.Text); + } [PlatformFact(TestPlatforms.MacOS)] public void WindowOrder_NonOwned_Window_Does_Not_Stay_InFront_Of_Parent() From d00f19d55671373ea0329e35e4a52afb3815364b Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 29 Nov 2022 12:40:02 +0100 Subject: [PATCH 02/14] Fix #9565 - Only bring window to front if it's on the currently active space - Ensure correct order of child windows after fullscreen transition --- native/Avalonia.Native/src/OSX/WindowImpl.mm | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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() { From 915aff2eeace37ad57b16493c348159e64a2f715 Mon Sep 17 00:00:00 2001 From: zhouzj Date: Mon, 5 Dec 2022 14:34:33 +0800 Subject: [PATCH 03/14] Prevent showing trayMenu if the menu is empty. --- src/Windows/Avalonia.Win32/TrayIconImpl.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Windows/Avalonia.Win32/TrayIconImpl.cs b/src/Windows/Avalonia.Win32/TrayIconImpl.cs index 8d565d7fef..ddc42b3248 100644 --- a/src/Windows/Avalonia.Win32/TrayIconImpl.cs +++ b/src/Windows/Avalonia.Win32/TrayIconImpl.cs @@ -19,7 +19,7 @@ namespace Avalonia.Win32 public class TrayIconImpl : ITrayIconImpl { private static readonly IntPtr s_emptyIcon = new System.Drawing.Bitmap(32, 32).GetHicon(); - + private readonly int _uniqueId; private static int s_nextUniqueId; private bool _iconAdded; @@ -137,6 +137,12 @@ namespace Avalonia.Win32 private void OnRightClicked() { + var menuItems = _exporter.GetMenu(); + if (null == menuItems || menuItems.Count == 0) + { + return; + } + var _trayMenu = new TrayPopupRoot() { SystemDecorations = SystemDecorations.None, @@ -145,7 +151,7 @@ namespace Avalonia.Win32 TransparencyLevelHint = WindowTransparencyLevel.Transparent, Content = new TrayIconMenuFlyoutPresenter() { - Items = _exporter.GetMenu() + Items = menuItems } }; From 19043beda148892ee5d60d5786c9c811c0170309 Mon Sep 17 00:00:00 2001 From: zhouzj Date: Mon, 5 Dec 2022 14:40:10 +0800 Subject: [PATCH 04/14] fix typo --- src/Windows/Avalonia.Win32/TrayIconImpl.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/TrayIconImpl.cs b/src/Windows/Avalonia.Win32/TrayIconImpl.cs index ddc42b3248..ab70d77a09 100644 --- a/src/Windows/Avalonia.Win32/TrayIconImpl.cs +++ b/src/Windows/Avalonia.Win32/TrayIconImpl.cs @@ -19,7 +19,6 @@ namespace Avalonia.Win32 public class TrayIconImpl : ITrayIconImpl { private static readonly IntPtr s_emptyIcon = new System.Drawing.Bitmap(32, 32).GetHicon(); - private readonly int _uniqueId; private static int s_nextUniqueId; private bool _iconAdded; From 58b5eeb9d21a074cd588bc3b58026a9ca87b0575 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Mon, 5 Dec 2022 14:38:12 +0100 Subject: [PATCH 05/14] Added failing tests for #9561. --- .../Styling/StyledElementTests_Theming.cs | 51 +++++++++++++++---- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests_Theming.cs b/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests_Theming.cs index 672945cb24..b5a9b35134 100644 --- a/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests_Theming.cs +++ b/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests_Theming.cs @@ -359,16 +359,49 @@ public class StyledElementTests_Theming } [Fact] - public void Implicit_Theme_Is_Cleared_When_Removed_From_Logical_Tree() + public void Implicit_Theme_Is_Not_Detached_When_Removed_From_Logical_Tree() { var target = CreateTarget(); var root = CreateRoot(target); - - Assert.NotNull(target.GetEffectiveTheme()); + + Assert.Equal("theme", target.Tag); root.Child = null; - Assert.Null(target.GetEffectiveTheme()); + var border = Assert.IsType(target.VisualChild); + Assert.Equal("theme", target.Tag); + Assert.Equal("theme", border.Tag); + } + + [Fact] + public void Can_Attach_Then_Reattach_To_Same_Logical_Tree() + { + var target = CreateTarget(); + var root = CreateRoot(target); + + Assert.Equal("theme", target.Tag); + + root.Child = null; + root.Child = target; + + Assert.Equal("theme", target.Tag); + } + + [Fact] + public void Implicit_Theme_Is_Reevaluated_When_Removed_And_Added_To_Different_Logical_Tree() + { + var target = CreateTarget(); + var root1 = CreateRoot(target, "theme1"); + var root2 = CreateRoot(null, "theme2"); + + Assert.Equal("theme1", target.Tag); + + root1.Child = null; + root2.Child = target; + + var border = Assert.IsType(target.VisualChild); + Assert.Equal("theme2", target.Tag); + Assert.Equal("theme2", border.Tag); } [Fact] @@ -402,10 +435,10 @@ public class StyledElementTests_Theming private static ThemedControl CreateTarget() => new ThemedControl(); - private static TestRoot CreateRoot(Control child) + private static TestRoot CreateRoot(Control? child, string themeTag = "theme") { var result = new TestRoot(); - result.Resources.Add(typeof(ThemedControl), CreateTheme()); + result.Resources.Add(typeof(ThemedControl), CreateTheme(themeTag)); result.Child = child; result.LayoutManager.ExecuteInitialLayoutPass(); return result; @@ -530,7 +563,7 @@ public class StyledElementTests_Theming } } - private static ControlTheme CreateTheme() + private static ControlTheme CreateTheme(string tag = "theme") { var template = new FuncControlTemplate((o, n) => new Border()); @@ -539,7 +572,7 @@ public class StyledElementTests_Theming TargetType = typeof(ThemedControl), Setters = { - new Setter(Control.TagProperty, "theme"), + new Setter(Control.TagProperty, tag), new Setter(TemplatedControl.TemplateProperty, template), new Setter(TemplatedControl.CornerRadiusProperty, new CornerRadius(5)), }, @@ -550,7 +583,7 @@ public class StyledElementTests_Theming Setters = { new Setter(Border.BackgroundProperty, Brushes.Red), - new Setter(Control.TagProperty, "theme"), + new Setter(Control.TagProperty, tag), } }, new Style(x => x.Nesting().Class("foo").Template().OfType()) From b382a9d6ac1a4c237d891585f4f94e1d47d5abc9 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Mon, 5 Dec 2022 14:43:39 +0100 Subject: [PATCH 06/14] Re-evaluate theme on tree detach + reattach. Fixes #9561 --- src/Avalonia.Base/StyledElement.cs | 67 ++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/src/Avalonia.Base/StyledElement.cs b/src/Avalonia.Base/StyledElement.cs index 6fa2027e1e..6043175eee 100644 --- a/src/Avalonia.Base/StyledElement.cs +++ b/src/Avalonia.Base/StyledElement.cs @@ -81,6 +81,7 @@ namespace Avalonia private Styles? _styles; private bool _stylesApplied; private bool _themeApplied; + private bool _templatedParentThemeApplied; private AvaloniaObject? _templatedParent; private bool _dataContextUpdating; private ControlTheme? _implicitTheme; @@ -375,6 +376,12 @@ namespace Avalonia _themeApplied = true; } + if (!_templatedParentThemeApplied) + { + ApplyTemplatedParentControlTheme(); + _templatedParentThemeApplied = true; + } + if (!_stylesApplied) { ApplyStyles(this); @@ -613,26 +620,38 @@ namespace Avalonia base.OnPropertyChanged(change); if (change.Property == ThemeProperty) - { OnControlThemeChanged(); - _themeApplied = false; - } } private protected virtual void OnControlThemeChanged() { var values = GetValueStore(); values.BeginStyling(); - try { values.RemoveFrames(FrameType.Theme); } - finally { values.EndStyling(); } + + try + { + values.RemoveFrames(FrameType.Theme); + } + finally + { + values.EndStyling(); + _themeApplied = false; + } } internal virtual void OnTemplatedParentControlThemeChanged() { var values = GetValueStore(); values.BeginStyling(); - try { values.RemoveFrames(FrameType.TemplatedParentTheme); } - finally { values.EndStyling(); } + try + { + values.RemoveFrames(FrameType.TemplatedParentTheme); + } + finally + { + values.EndStyling(); + _templatedParentThemeApplied = false; + } } internal ControlTheme? GetEffectiveTheme() @@ -743,13 +762,13 @@ namespace Avalonia private void ApplyControlTheme() { - var theme = GetEffectiveTheme(); - - if (theme is not null) + if (GetEffectiveTheme() is { } theme) ApplyControlTheme(theme, FrameType.Theme); + } - if (TemplatedParent is StyledElement styleableParent && - styleableParent.GetEffectiveTheme() is { } parentTheme) + private void ApplyTemplatedParentControlTheme() + { + if ((TemplatedParent as StyledElement)?.GetEffectiveTheme() is { } parentTheme) { ApplyControlTheme(parentTheme, FrameType.TemplatedParentTheme); } @@ -793,6 +812,28 @@ namespace Avalonia ApplyStyle(child, host, type); } + private void ReevaluateImplicitTheme() + { + // We only need to check if the theme has changed when Theme isn't set (i.e. when we + // have an implicit theme). + if (Theme is not null) + return; + + // Refetch the implicit theme. + var oldImplicitTheme = _implicitTheme == s_invalidTheme ? null : _implicitTheme; + _implicitTheme = null; + GetEffectiveTheme(); + + var newImplicitTheme = _implicitTheme == s_invalidTheme ? null : _implicitTheme; + + // If the implicit theme has changed, detach the existing theme. + if (newImplicitTheme != oldImplicitTheme) + { + OnControlThemeChanged(); + _themeApplied = false; + } + } + private void OnAttachedToLogicalTreeCore(LogicalTreeAttachmentEventArgs e) { if (this.GetLogicalParent() == null && !(this is ILogicalRoot)) @@ -811,6 +852,7 @@ namespace Avalonia { _logicalRoot = e.Root; + ReevaluateImplicitTheme(); ApplyStyling(); NotifyResourcesChanged(propagate: false); @@ -835,7 +877,6 @@ namespace Avalonia if (_logicalRoot != null) { _logicalRoot = null; - _implicitTheme = null; InvalidateStyles(recurse: false); OnDetachedFromLogicalTree(e); DetachedFromLogicalTree?.Invoke(this, e); From 387728fb2d0ab7019e22cd506851e3624c7ae469 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Mon, 5 Dec 2022 16:17:08 +0100 Subject: [PATCH 07/14] Added failing test for animations without activator. Mentioned in #9561. --- .../Styling/StyleTests.cs | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/tests/Avalonia.Base.UnitTests/Styling/StyleTests.cs b/tests/Avalonia.Base.UnitTests/Styling/StyleTests.cs index 805b3e7aa6..4f5d1b8ec8 100644 --- a/tests/Avalonia.Base.UnitTests/Styling/StyleTests.cs +++ b/tests/Avalonia.Base.UnitTests/Styling/StyleTests.cs @@ -868,7 +868,53 @@ namespace Avalonia.Base.UnitTests.Styling } [Fact] - public void Animations_Should_Be_Activated_And_Deactivated() + public void Animations_Should_Be_Activated() + { + Style style = new Style(x => x.OfType()) + { + Animations = + { + new Avalonia.Animation.Animation + { + Duration = TimeSpan.FromSeconds(1), + Children = + { + new KeyFrame + { + Setters = + { + new Setter { Property = Class1.DoubleProperty, Value = 5.0 } + }, + }, + new KeyFrame + { + Setters = + { + new Setter { Property = Class1.DoubleProperty, Value = 10.0 } + }, + Cue = new Cue(1d) + } + }, + } + } + }; + + var clock = new TestClock(); + var target = new Class1 { Clock = clock }; + + StyleHelpers.TryAttach(style, target); + + Assert.Equal(0.0, target.Double); + + clock.Step(TimeSpan.Zero); + Assert.Equal(5.0, target.Double); + + clock.Step(TimeSpan.FromSeconds(0.5)); + Assert.Equal(7.5, target.Double); + } + + [Fact] + public void Animations_With_Trigger_Should_Be_Activated_And_Deactivated() { Style style = new Style(x => x.OfType().Class("foo")) { From a3e79d3127672748064a53b08963d98dd0665c4a Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Mon, 5 Dec 2022 16:18:10 +0100 Subject: [PATCH 08/14] Start animations in styles without activators. Fixes issue mentioned in #9561. --- src/Avalonia.Base/Styling/StyleInstance.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Avalonia.Base/Styling/StyleInstance.cs b/src/Avalonia.Base/Styling/StyleInstance.cs index 4985aa16c7..ca602167c0 100644 --- a/src/Avalonia.Base/Styling/StyleInstance.cs +++ b/src/Avalonia.Base/Styling/StyleInstance.cs @@ -70,6 +70,9 @@ namespace Avalonia.Styling _animationTrigger ??= new Subject(); foreach (var animation in _animations) animation.Apply(animatable, null, _animationTrigger); + + if (_activator is null) + _animationTrigger.OnNext(true); } } From a691e7c8fae35c34f9fdfed272f857a6f228e8af Mon Sep 17 00:00:00 2001 From: Emmanuel Hansen Date: Mon, 5 Dec 2022 17:26:27 +0000 Subject: [PATCH 09/14] don't set key event to handled when selection changes with space or enter --- src/Avalonia.Controls/Primitives/SelectingItemsControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs index f8951b3fa3..44fa78ac21 100644 --- a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs +++ b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs @@ -588,7 +588,7 @@ namespace Avalonia.Controls.Primitives } else if (e.Key == Key.Space || e.Key == Key.Enter) { - e.Handled = UpdateSelectionFromEventSource( + UpdateSelectionFromEventSource( e.Source, true, e.KeyModifiers.HasFlag(KeyModifiers.Shift), From 845fea9d1103eb0487335d55ff0488fe66d22c5f Mon Sep 17 00:00:00 2001 From: Kevin Ivarsen Date: Mon, 5 Dec 2022 14:36:33 -0800 Subject: [PATCH 10/14] Swap the figures used for expanded/collapsed groups in DataGrid to match the standard convention. --- src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml b/src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml index a3c0ed1d0c..fb4335f4de 100644 --- a/src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml +++ b/src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml @@ -6,8 +6,8 @@ M1875 1011l-787 787v-1798h-128v1798l-787 -787l-90 90l941 941l941 -941z M1965 947l-941 -941l-941 941l90 90l787 -787v1798h128v-1798l787 787z - M515 93l930 931l-930 931l90 90l1022 -1021l-1022 -1021z - M109 486 19 576 1024 1581 2029 576 1939 486 1024 1401z + M515 93l930 931l-930 931l90 90l1022 -1021l-1022 -1021z + M109 486 19 576 1024 1581 2029 576 1939 486 1024 1401z From bdceb1c3dff626173fbfdd4d24d5723b1977c37d Mon Sep 17 00:00:00 2001 From: Max Katz Date: Mon, 5 Dec 2022 23:02:18 -0500 Subject: [PATCH 11/14] Do not require matching ctor, if top level element --- .../AvaloniaXamlIlRuntimeCompiler.cs | 2 +- .../Avalonia.Markup.Xaml.Loader/xamlil.github | 2 +- .../Xaml/BasicTests.cs | 23 +++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs index 28d5a55f86..2bb91e8a32 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs @@ -234,7 +234,7 @@ namespace Avalonia.Markup.Xaml.XamlIl parsedDocuments.Add(new XamlDocumentResource(parsed, document.BaseUri?.ToString(), null, null, builder, compiler.DefinePopulateMethod(builder, parsed, AvaloniaXamlIlCompiler.PopulateName, true), - compiler.DefineBuildMethod(builder, parsed, AvaloniaXamlIlCompiler.BuildName, true))); + document.RootInstance is null ? compiler.DefineBuildMethod(builder, parsed, AvaloniaXamlIlCompiler.BuildName, true) : null)); originalDocuments.Add(document); } diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github b/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github index 491de981dd..b800d3e1fa 160000 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github @@ -1 +1 @@ -Subproject commit 491de981dd4433ee58bc9540e2cd4a5d168f8168 +Subproject commit b800d3e1fac0940c571bfa540e3af4dbd59f7dbb diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs index c7afaee697..18a6dd9803 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs @@ -899,6 +899,17 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml Assert.Equal("Foo", target.Text); } + [Fact] + public void Should_Parse_And_Populate_Type_Without_Public_Ctor() + { + var xaml = @""; + var target = (ObjectWithoutPublicCtor)AvaloniaRuntimeXamlLoader.Load(xaml, rootInstance: new ObjectWithoutPublicCtor("Hello")); + + Assert.NotNull(target); + Assert.Equal("World", target.Test2); + Assert.Equal("Hello", target.Test1); + } + private class SelectedItemsViewModel : INotifyPropertyChanged { public string[] Items { get; set; } @@ -928,6 +939,18 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml Child = child; } } + + public class ObjectWithoutPublicCtor + { + public ObjectWithoutPublicCtor(string param) + { + Test1 = param; + } + + public string Test1 { get; set; } + + public string Test2 { get; set; } + } public class ObjectWithAddChildOfT : IAddChild, IAddChild { From 003923b50d635eadd18b979c98d9ec753630e5c6 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 6 Dec 2022 11:42:37 +0100 Subject: [PATCH 12/14] Fix integration tests on Windows. We need to be explicit about which element we're talking about when there are two elements with the same content, and so use accessibility IDs rather than Name. --- samples/IntegrationTestApp/MainWindow.axaml | 10 +++++----- samples/IntegrationTestApp/ShowWindowTest.axaml | 8 ++++---- .../WindowTests.cs | 16 ++++++++-------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/samples/IntegrationTestApp/MainWindow.axaml b/samples/IntegrationTestApp/MainWindow.axaml index 801ff765c8..54c0cb0655 100644 --- a/samples/IntegrationTestApp/MainWindow.axaml +++ b/samples/IntegrationTestApp/MainWindow.axaml @@ -24,7 +24,7 @@ WindowState: - + @@ -133,10 +133,10 @@ CenterOwner - Normal - Minimized - Maximized - FullScreen + Normal + Minimized + Maximized + FullScreen 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(); } From 23e45beb906fff790715a530ee1d2663601dbff3 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 6 Dec 2022 12:00:25 +0100 Subject: [PATCH 13/14] Fix integration tests on macOS. --- .../Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs b/tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs index 8f4417a451..6c61a85561 100644 --- a/tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs +++ b/tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs @@ -128,7 +128,7 @@ namespace Avalonia.IntegrationTests.Appium Thread.Sleep(1000); // Make sure we entered fullscreen. - var windowState = mainWindow.FindElementByAccessibilityId("WindowState"); + var windowState = mainWindow.FindElementByAccessibilityId("MainWindowState"); Assert.Equal("FullScreen", windowState.Text); // Open child window. @@ -147,7 +147,7 @@ namespace Avalonia.IntegrationTests.Appium // Make sure we exited fullscreen. mainWindow = _session.FindElementByAccessibilityId("MainWindow"); - windowState = mainWindow.FindElementByAccessibilityId("WindowState"); + windowState = mainWindow.FindElementByAccessibilityId("MainWindowState"); Assert.Equal("Normal", windowState.Text); } @@ -169,7 +169,7 @@ namespace Avalonia.IntegrationTests.Appium // Make sure we entered fullscreen. mainWindow = _session.FindElementByAccessibilityId("MainWindow"); - windowState = mainWindow.FindElementByAccessibilityId("WindowState"); + windowState = mainWindow.FindElementByAccessibilityId("MainWindowState"); Assert.Equal("FullScreen", windowState.Text); // Click on main window @@ -185,7 +185,7 @@ namespace Avalonia.IntegrationTests.Appium // Make sure we exited fullscreen. mainWindow = _session.FindElementByAccessibilityId("MainWindow"); - windowState = mainWindow.FindElementByAccessibilityId("WindowState"); + windowState = mainWindow.FindElementByAccessibilityId("MainWindowState"); Assert.Equal("Normal", windowState.Text); } From ba1c4dcc1b4b468c32859233a9898cbcfa525b55 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Tue, 6 Dec 2022 07:19:55 -0500 Subject: [PATCH 14/14] Switch to upstream xamlx --- src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github b/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github index b800d3e1fa..5e498f8bcc 160000 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github @@ -1 +1 @@ -Subproject commit b800d3e1fac0940c571bfa540e3af4dbd59f7dbb +Subproject commit 5e498f8bcca403a34aff5efc825cbb4e12b7fa8e