From 947e3587331db1985acd052aa88132fbf3117fc2 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 8 Mar 2022 11:30:43 +0000 Subject: [PATCH] fix opening child window center screen when parent maximized. --- src/Avalonia.Controls/Platform/IScreenImpl.cs | 2 ++ src/Avalonia.Controls/Screens.cs | 17 +++++++++++++++++ src/Avalonia.Controls/Window.cs | 13 +++++++++++-- src/Avalonia.DesignerSupport/Remote/Stubs.cs | 5 +++++ src/Avalonia.Headless/HeadlessPlatformStubs.cs | 5 +++++ src/Avalonia.Native/ScreenImpl.cs | 5 +++++ src/Avalonia.X11/X11Screens.cs | 5 +++++ src/Windows/Avalonia.Win32/ScreenImpl.cs | 9 +++++++++ src/Windows/Avalonia.Win32/WinScreen.cs | 2 ++ 9 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Controls/Platform/IScreenImpl.cs b/src/Avalonia.Controls/Platform/IScreenImpl.cs index 5bd45057d9..f6f4df07db 100644 --- a/src/Avalonia.Controls/Platform/IScreenImpl.cs +++ b/src/Avalonia.Controls/Platform/IScreenImpl.cs @@ -7,5 +7,7 @@ namespace Avalonia.Platform int ScreenCount { get; } IReadOnlyList AllScreens { get; } + + Screen? ScreenFromWindow(IWindowImpl windowImpl); } } diff --git a/src/Avalonia.Controls/Screens.cs b/src/Avalonia.Controls/Screens.cs index ef438576a7..dde309aa83 100644 --- a/src/Avalonia.Controls/Screens.cs +++ b/src/Avalonia.Controls/Screens.cs @@ -52,5 +52,22 @@ namespace Avalonia.Controls var br = visual.PointToScreen(visual.Bounds.BottomRight); return ScreenFromBounds(new PixelRect(tl, br)); } + + public Screen? ScreenFromWindow(Window window) + { + Screen? screen = null; + + if (window.PlatformImpl != null) + { + screen = _iScreenImpl?.ScreenFromWindow(window.PlatformImpl) ?? null; + + if (screen is { }) + { + return screen; + } + } + + return ScreenFromPoint(window.Position); + } } } diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs index eda23389f7..fdbf988ead 100644 --- a/src/Avalonia.Controls/Window.cs +++ b/src/Avalonia.Controls/Window.cs @@ -879,8 +879,17 @@ namespace Avalonia.Controls if (startupLocation == WindowStartupLocation.CenterScreen) { - var screen = Screens.ScreenFromPoint(owner?.Position ?? Position); - + Screen? screen = null; + + if (Owner is Window ownerWin) + { + screen = Screens.ScreenFromWindow(ownerWin); + } + else + { + screen = Screens.ScreenFromPoint(Position); + } + if (screen != null) { Position = screen.WorkingArea.CenterRect(rect).Position; diff --git a/src/Avalonia.DesignerSupport/Remote/Stubs.cs b/src/Avalonia.DesignerSupport/Remote/Stubs.cs index 8fb2c456b2..29777fdc3e 100644 --- a/src/Avalonia.DesignerSupport/Remote/Stubs.cs +++ b/src/Avalonia.DesignerSupport/Remote/Stubs.cs @@ -237,5 +237,10 @@ namespace Avalonia.DesignerSupport.Remote public IReadOnlyList AllScreens { get; } = new Screen[] { new Screen(1, new PixelRect(0, 0, 4000, 4000), new PixelRect(0, 0, 4000, 4000), true) }; + + public Screen? ScreenFromWindow(IWindowImpl windowImpl) + { + return null; + } } } diff --git a/src/Avalonia.Headless/HeadlessPlatformStubs.cs b/src/Avalonia.Headless/HeadlessPlatformStubs.cs index 9ac74e5e78..6befefa488 100644 --- a/src/Avalonia.Headless/HeadlessPlatformStubs.cs +++ b/src/Avalonia.Headless/HeadlessPlatformStubs.cs @@ -200,5 +200,10 @@ namespace Avalonia.Headless new Screen(1, new PixelRect(0, 0, 1920, 1280), new PixelRect(0, 0, 1920, 1280), true), }; + + public Screen ScreenFromWindow(IWindowImpl windowImpl) + { + return null; + } } } diff --git a/src/Avalonia.Native/ScreenImpl.cs b/src/Avalonia.Native/ScreenImpl.cs index 7b4a001486..d6ac84404c 100644 --- a/src/Avalonia.Native/ScreenImpl.cs +++ b/src/Avalonia.Native/ScreenImpl.cs @@ -42,6 +42,11 @@ namespace Avalonia.Native return Array.Empty(); } } + + public Screen ScreenFromWindow(IWindowImpl windowImpl) + { + return null; + } public void Dispose () { diff --git a/src/Avalonia.X11/X11Screens.cs b/src/Avalonia.X11/X11Screens.cs index bf5c74e0e5..b63637d368 100644 --- a/src/Avalonia.X11/X11Screens.cs +++ b/src/Avalonia.X11/X11Screens.cs @@ -17,6 +17,11 @@ namespace Avalonia.X11 { _impl = impl; } + + public Screen ScreenFromWindow(IWindowImpl windowImpl) + { + return null; + } static unsafe X11Screen[] UpdateWorkArea(X11Info info, X11Screen[] screens) { diff --git a/src/Windows/Avalonia.Win32/ScreenImpl.cs b/src/Windows/Avalonia.Win32/ScreenImpl.cs index 442794f0f0..ca49a9d42a 100644 --- a/src/Windows/Avalonia.Win32/ScreenImpl.cs +++ b/src/Windows/Avalonia.Win32/ScreenImpl.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Avalonia.Platform; using Avalonia.Win32.Interop; using static Avalonia.Win32.Interop.UnmanagedMethods; @@ -70,5 +71,13 @@ namespace Avalonia.Win32 { _allScreens = null; } + + public Screen? ScreenFromWindow(IWindowImpl windowImpl) + { + var hmonitor = MonitorFromWindow(windowImpl.Handle.Handle, MONITOR.MONITOR_DEFAULTTONEAREST); + + return AllScreens.Select(x => x as WinScreen).Where(x => x is { }) + .FirstOrDefault(x => x.Handle == hmonitor); + } } } diff --git a/src/Windows/Avalonia.Win32/WinScreen.cs b/src/Windows/Avalonia.Win32/WinScreen.cs index 0cf9fe31db..417871f733 100644 --- a/src/Windows/Avalonia.Win32/WinScreen.cs +++ b/src/Windows/Avalonia.Win32/WinScreen.cs @@ -21,5 +21,7 @@ namespace Avalonia.Win32 { return (obj is WinScreen screen) ? this._hMonitor == screen._hMonitor : base.Equals(obj); } + + internal IntPtr Handle => _hMonitor; } }