diff --git a/native/Avalonia.Native/src/OSX/AvnView.mm b/native/Avalonia.Native/src/OSX/AvnView.mm index 01725ace03..4ae6ad5a00 100644 --- a/native/Avalonia.Native/src/OSX/AvnView.mm +++ b/native/Avalonia.Native/src/OSX/AvnView.mm @@ -127,7 +127,11 @@ [self updateRenderTarget]; auto reason = [self inLiveResize] ? ResizeUser : _resizeReason; - _parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height}, reason); + + if(_parent->IsShown()) + { + _parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height}, reason); + } } } diff --git a/native/Avalonia.Native/src/OSX/rendertarget.mm b/native/Avalonia.Native/src/OSX/rendertarget.mm index 266d0345d1..2075cc85ab 100644 --- a/native/Avalonia.Native/src/OSX/rendertarget.mm +++ b/native/Avalonia.Native/src/OSX/rendertarget.mm @@ -13,6 +13,7 @@ { @public IOSurfaceRef surface; @public AvnPixelSize size; + @public bool hasContent; @public float scale; ComPtr _context; GLuint _framebuffer, _texture, _renderbuffer; @@ -41,6 +42,7 @@ self->scale = scale; self->size = size; self->_context = context; + self->hasContent = false; return self; } @@ -92,6 +94,7 @@ _context->MakeCurrent(release.getPPV()); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glFlush(); + self->hasContent = true; } -(void) dealloc @@ -170,6 +173,8 @@ static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* ta @synchronized (lock) { if(_layer == nil) return; + if(!surface->hasContent) + return; [CATransaction begin]; [_layer setContents: nil]; if(surface != nil) @@ -213,6 +218,7 @@ static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* ta memcpy(pSurface + y*sstride, pFb + y*fstride, wbytes); } IOSurfaceUnlock(surf, 0, nil); + surface->hasContent = true; [self updateLayer]; return S_OK; } diff --git a/src/Avalonia.Base/Controls/IPseudoClasses.cs b/src/Avalonia.Base/Controls/IPseudoClasses.cs index eda521727f..438b05a8cf 100644 --- a/src/Avalonia.Base/Controls/IPseudoClasses.cs +++ b/src/Avalonia.Base/Controls/IPseudoClasses.cs @@ -19,5 +19,12 @@ namespace Avalonia.Controls /// /// The pseudoclass name. bool Remove(string name); + + /// + /// Returns whether a pseudoclass is present in the collection. + /// + /// The pseudoclass name. + /// Whether the pseudoclass is present. + bool Contains(string name); } } diff --git a/src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml b/src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml index 2baa8c88c9..fb032fec3e 100644 --- a/src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml +++ b/src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml @@ -7,7 +7,7 @@ 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 - M1939 1581l90 -90l-1005 -1005l-1005 1005l90 90l915 -915z + M109 486 19 576 1024 1581 2029 576 1939 486 1024 1401z @@ -499,12 +499,12 @@ diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs index 2dd391945b..9b4bb51aca 100644 --- a/src/Avalonia.Controls/Window.cs +++ b/src/Avalonia.Controls/Window.cs @@ -681,8 +681,8 @@ namespace Avalonia.Controls IsVisible = true; var initialSize = new Size( - double.IsNaN(Width) ? ClientSize.Width : Width, - double.IsNaN(Height) ? ClientSize.Height : Height); + double.IsNaN(Width) ? Math.Max(MinWidth, ClientSize.Width) : Width, + double.IsNaN(Height) ? Math.Max(MinHeight, ClientSize.Height) : Height); if (initialSize != ClientSize) { diff --git a/tests/Avalonia.Benchmarks/Program.cs b/tests/Avalonia.Benchmarks/Program.cs index 903778ff00..8f7aa3eb79 100644 --- a/tests/Avalonia.Benchmarks/Program.cs +++ b/tests/Avalonia.Benchmarks/Program.cs @@ -1,6 +1,8 @@ +using System.Collections.Generic; using System.Linq; using System.Reflection; using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; using BenchmarkDotNet.Running; namespace Avalonia.Benchmarks @@ -19,7 +21,17 @@ namespace Avalonia.Benchmarks .ThenBy(t => t.Name) .ToArray(); var benchmarkSwitcher = new BenchmarkSwitcher(benchmarks); - benchmarkSwitcher.Run(args); + IConfig config = null; + + if (args.Contains("--debug")) + { + config = new DebugInProcessConfig(); + var a = new List(args); + a.Remove("--debug"); + args = a.ToArray(); + } + + benchmarkSwitcher.Run(args, config); } } } diff --git a/tests/Avalonia.Controls.UnitTests/WindowTests.cs b/tests/Avalonia.Controls.UnitTests/WindowTests.cs index a8c9b68d12..0cdde445d5 100644 --- a/tests/Avalonia.Controls.UnitTests/WindowTests.cs +++ b/tests/Avalonia.Controls.UnitTests/WindowTests.cs @@ -540,6 +540,33 @@ namespace Avalonia.Controls.UnitTests Assert.Equal(window.Position, expectedPosition); } } + + [Fact] + public void Window_Should_Be_Sized_To_MinSize_If_InitialSize_Less_Than_MinSize() + { + var screen1 = new Mock(1.75, new PixelRect(new PixelSize(1920, 1080)), new PixelRect(new PixelSize(1920, 966)), true); + var screens = new Mock(); + screens.Setup(x => x.AllScreens).Returns(new Screen[] { screen1.Object }); + screens.Setup(x => x.ScreenFromPoint(It.IsAny())).Returns(screen1.Object); + + var windowImpl = MockWindowingPlatform.CreateWindowMock(400, 300); + windowImpl.Setup(x => x.DesktopScaling).Returns(1.75); + windowImpl.Setup(x => x.RenderScaling).Returns(1.75); + windowImpl.Setup(x => x.Screen).Returns(screens.Object); + + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var window = new Window(windowImpl.Object); + window.WindowStartupLocation = WindowStartupLocation.CenterScreen; + window.MinWidth = 720; + window.MinHeight = 480; + + window.Show(); + + Assert.Equal(new PixelPoint(330, 63), window.Position); + Assert.Equal(new Size(720, 480), window.Bounds.Size); + } + } [Fact] public void Window_Should_Be_Centered_Relative_To_Owner_When_WindowStartupLocation_Is_CenterOwner() diff --git a/tests/Avalonia.IntegrationTests.Appium/macos-clean-build-test.sh b/tests/Avalonia.IntegrationTests.Appium/macos-clean-build-test.sh index 635c593f37..b03a8a7a69 100755 --- a/tests/Avalonia.IntegrationTests.Appium/macos-clean-build-test.sh +++ b/tests/Avalonia.IntegrationTests.Appium/macos-clean-build-test.sh @@ -3,7 +3,13 @@ SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) cd "$SCRIPT_DIR"/../.. || exit git clean -xdf +pkill node +appium & +pkill IntegrationTestApp ./build.sh CompileNative ./samples/IntegrationTestApp/bundle.sh open -n ./samples/IntegrationTestApp/bin/Debug/net6.0/osx-arm64/publish/IntegrationTestApp.app +pkill IntegrationTestApp dotnet test tests/Avalonia.IntegrationTests.Appium/ -l "console;verbosity=detailed" +pkill IntegrationTestApp +pkill node diff --git a/tests/Avalonia.UnitTests/MockWindowingPlatform.cs b/tests/Avalonia.UnitTests/MockWindowingPlatform.cs index 461e0f4392..339b87cf88 100644 --- a/tests/Avalonia.UnitTests/MockWindowingPlatform.cs +++ b/tests/Avalonia.UnitTests/MockWindowingPlatform.cs @@ -21,11 +21,11 @@ namespace Avalonia.UnitTests _popupImpl = popupImpl; } - public static Mock CreateWindowMock() + public static Mock CreateWindowMock(double initialWidth = 800, double initialHeight = 600) { var windowImpl = new Mock(); var position = new PixelPoint(); - var clientSize = new Size(800, 600); + var clientSize = new Size(initialWidth, initialHeight); windowImpl.SetupAllProperties(); windowImpl.Setup(x => x.ClientSize).Returns(() => clientSize); @@ -55,12 +55,18 @@ namespace Avalonia.UnitTests windowImpl.Setup(x => x.Resize(It.IsAny(), It.IsAny())) .Callback((x, y) => { - clientSize = x.Constrain(s_screenSize); - windowImpl.Object.Resized?.Invoke(clientSize, y); + var constrainedSize = x.Constrain(s_screenSize); + + if (constrainedSize != clientSize) + { + clientSize = constrainedSize; + windowImpl.Object.Resized?.Invoke(clientSize, y); + } }); windowImpl.Setup(x => x.Show(true, It.IsAny())).Callback(() => { + windowImpl.Object.Resized?.Invoke(windowImpl.Object.ClientSize, PlatformResizeReason.Unspecified); windowImpl.Object.Activated?.Invoke(); });