Browse Source

Make ShowDialog respect WindowStartupLocation.

`SetWindowStartupLocation` needs to be called _after_ the window is shown as is done in `Show`. In addition, the owner window needs to be passed so we can get the correct screen.

Renamed the `parent` parameter to `ShowDialog` to `owner` as its `WindowStartupLocation.CenterOwner` not `CenterParent`.
pull/2250/head
Steven Kirk 7 years ago
parent
commit
db44faf4ad
  1. 44
      src/Avalonia.Controls/Window.cs

44
src/Avalonia.Controls/Window.cs

@ -394,39 +394,42 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Shows the window as a dialog. /// Shows the window as a dialog.
/// </summary> /// </summary>
/// <param name="owner">The dialog's owner window.</param>
/// <returns> /// <returns>
/// A task that can be used to track the lifetime of the dialog. /// A task that can be used to track the lifetime of the dialog.
/// </returns> /// </returns>
public Task ShowDialog(Window parent) public Task ShowDialog(Window owner)
{ {
return ShowDialog<object>(parent); return ShowDialog<object>(owner);
} }
/// <summary> /// <summary>
/// Shows the window as a dialog. /// Shows the window as a dialog.
/// </summary> /// </summary>
/// <typeparam name="TResult"> /// <typeparam name="TResult">
/// The type of the result produced by the dialog. /// The type of the result produced by the dialog.
/// </typeparam> /// </typeparam>
/// <param name="owner">The dialog's owner window.</param>
/// <returns>. /// <returns>.
/// A task that can be used to retrieve the result of the dialog when it closes. /// A task that can be used to retrieve the result of the dialog when it closes.
/// </returns> /// </returns>
public Task<TResult> ShowDialog<TResult>(Window parent) => ShowDialog<TResult>(parent.PlatformImpl); public Task<TResult> ShowDialog<TResult>(Window owner) => ShowDialog<TResult>(owner.PlatformImpl);
/// <summary> /// <summary>
/// Shows the window as a dialog. /// Shows the window as a dialog.
/// </summary> /// </summary>
/// <typeparam name="TResult"> /// <typeparam name="TResult">
/// The type of the result produced by the dialog. /// The type of the result produced by the dialog.
/// </typeparam> /// </typeparam>
/// <param name="owner">The dialog's owner window.</param>
/// <returns>. /// <returns>.
/// A task that can be used to retrieve the result of the dialog when it closes. /// A task that can be used to retrieve the result of the dialog when it closes.
/// </returns> /// </returns>
public Task<TResult> ShowDialog<TResult>(IWindowImpl parent) public Task<TResult> ShowDialog<TResult>(IWindowImpl owner)
{ {
if(parent == null) if(owner == null)
throw new ArgumentNullException(nameof(parent)); throw new ArgumentNullException(nameof(owner));
if (IsVisible) if (IsVisible)
{ {
throw new InvalidOperationException("The window is already being shown."); throw new InvalidOperationException("The window is already being shown.");
@ -435,15 +438,15 @@ namespace Avalonia.Controls
AddWindow(this); AddWindow(this);
EnsureInitialized(); EnsureInitialized();
SetWindowStartupLocation();
IsVisible = true; IsVisible = true;
LayoutManager.ExecuteInitialLayoutPass(this); LayoutManager.ExecuteInitialLayoutPass(this);
var result = new TaskCompletionSource<TResult>();
using (BeginAutoSizing()) using (BeginAutoSizing())
{ {
PlatformImpl?.ShowDialog(parent); PlatformImpl?.ShowDialog(owner);
var result = new TaskCompletionSource<TResult>();
Renderer?.Start(); Renderer?.Start();
Observable.FromEventPattern<EventHandler, EventArgs>( Observable.FromEventPattern<EventHandler, EventArgs>(
@ -452,17 +455,18 @@ namespace Avalonia.Controls
.Take(1) .Take(1)
.Subscribe(_ => .Subscribe(_ =>
{ {
parent.Activate(); owner.Activate();
result.SetResult((TResult)(_dialogResult ?? default(TResult))); result.SetResult((TResult)(_dialogResult ?? default(TResult)));
}); });
return result.Task;
} }
SetWindowStartupLocation(owner);
return result.Task;
} }
void SetWindowStartupLocation() private void SetWindowStartupLocation(IWindowImpl owner = null)
{ {
var scaling = PlatformImpl?.Scaling ?? 1; var scaling = owner?.Scaling ?? PlatformImpl?.Scaling ?? 1;
// TODO: We really need non-client size here. // TODO: We really need non-client size here.
var rect = new PixelRect( var rect = new PixelRect(
@ -471,7 +475,7 @@ namespace Avalonia.Controls
if (WindowStartupLocation == WindowStartupLocation.CenterScreen) if (WindowStartupLocation == WindowStartupLocation.CenterScreen)
{ {
var screen = Screens.ScreenFromPoint(Position); var screen = Screens.ScreenFromPoint(owner?.Position ?? Position);
if (screen != null) if (screen != null)
{ {
@ -480,12 +484,12 @@ namespace Avalonia.Controls
} }
else if (WindowStartupLocation == WindowStartupLocation.CenterOwner) else if (WindowStartupLocation == WindowStartupLocation.CenterOwner)
{ {
if (Owner != null) if (owner != null)
{ {
// TODO: We really need non-client size here. // TODO: We really need non-client size here.
var ownerRect = new PixelRect( var ownerRect = new PixelRect(
Owner.Position, owner.Position,
PixelSize.FromSize(Owner.ClientSize, scaling)); PixelSize.FromSize(owner.ClientSize, scaling));
Position = ownerRect.CenterRect(rect).Position; Position = ownerRect.CenterRect(rect).Position;
} }
} }

Loading…
Cancel
Save