diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm index 33ab1529fc1..205f1efbdf5 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm @@ -465,11 +465,21 @@ static void ActivateApplication() { } void WindowBaseImpl::CreateNSWindow(bool usePanel) { + // Anchor the content rect to the primary screen's origin. It's usually at (0,0), but can be offset while the + // display server is mid-reconfiguration. This ensures the window is always on a proper screen. + // See https://github.com/AvaloniaUI/Avalonia/issues/18895 + NSPoint origin = NSZeroPoint; + NSArray* screens = [NSScreen screens]; + if (screens.count > 0) + origin = screens.firstObject.frame.origin; + + NSRect contentRect = NSRect { origin.x, origin.y, lastSize }; + if (usePanel) { - Window = [[AvnPanel alloc] initWithParent:this contentRect:NSRect{0, 0, lastSize} styleMask:NSWindowStyleMaskBorderless]; + Window = [[AvnPanel alloc] initWithParent:this contentRect:contentRect styleMask:NSWindowStyleMaskBorderless]; [Window setHidesOnDeactivate:false]; } else { - Window = [[AvnWindow alloc] initWithParent:this contentRect:NSRect{0, 0, lastSize} styleMask:NSWindowStyleMaskBorderless]; + Window = [[AvnWindow alloc] initWithParent:this contentRect:contentRect styleMask:NSWindowStyleMaskBorderless]; } } diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs index 8d7270dedea..1f7f4787880 100644 --- a/src/Avalonia.Native/WindowImplBase.cs +++ b/src/Avalonia.Native/WindowImplBase.cs @@ -51,11 +51,23 @@ internal override void Init(MacOSTopLevelHandle handle) base.Init(handle); + int defaultWidth = 0, defaultHeight = 0; + var monitor = this.TryGetFeature()!.AllScreens .OrderBy(x => x.Scaling) - .First(m => m.Bounds.Contains(Position)); + .FirstOrDefault(m => m.Bounds.Contains(Position)); + + if (monitor != null) + { + // Emulate Windows 7+ default window size behavior. + defaultWidth = (int)(monitor.WorkingArea.Width * 0.75d); + defaultHeight = (int)(monitor.WorkingArea.Height * 0.7d); + } + + defaultWidth = Math.Max(defaultWidth, 300); + defaultHeight = Math.Max(defaultHeight, 200); - Resize(new Size(monitor.WorkingArea.Width * 0.75d, monitor.WorkingArea.Height * 0.7d), WindowResizeReason.Layout); + Resize(new Size(defaultWidth, defaultHeight), WindowResizeReason.Layout); } public void Activate()