Browse Source

Merge branch 'master' into master

pull/7368/head
JamDoggie 5 years ago
committed by GitHub
parent
commit
96199364e1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/Avalonia.Controls/Primitives/PopupRoot.cs
  2. 9
      src/Avalonia.Controls/TopLevel.cs
  3. 326
      src/Avalonia.Controls/ValidatingToplevel.cs
  4. 11
      src/Avalonia.Controls/Window.cs
  5. 9
      src/Avalonia.Controls/WindowBase.cs
  6. 13
      src/Avalonia.X11/X11Window.cs

2
src/Avalonia.Controls/Primitives/PopupRoot.cs

@ -44,7 +44,7 @@ namespace Avalonia.Controls.Primitives
/// The dependency resolver to use. If null the default dependency resolver will be used. /// The dependency resolver to use. If null the default dependency resolver will be used.
/// </param> /// </param>
public PopupRoot(TopLevel parent, IPopupImpl impl, IAvaloniaDependencyResolver dependencyResolver) public PopupRoot(TopLevel parent, IPopupImpl impl, IAvaloniaDependencyResolver dependencyResolver)
: base(impl, dependencyResolver) : base(ValidatingPopupImpl.Wrap(impl), dependencyResolver)
{ {
_parent = parent; _parent = parent;
} }

9
src/Avalonia.Controls/TopLevel.cs

@ -134,6 +134,8 @@ namespace Avalonia.Controls
"Could not create window implementation: maybe no windowing subsystem was initialized?"); "Could not create window implementation: maybe no windowing subsystem was initialized?");
} }
impl = ValidatingToplevelImpl.Wrap(impl);
PlatformImpl = impl; PlatformImpl = impl;
_actualTransparencyLevel = PlatformImpl.TransparencyLevel; _actualTransparencyLevel = PlatformImpl.TransparencyLevel;
@ -367,14 +369,15 @@ namespace Avalonia.Controls
Renderer?.Dispose(); Renderer?.Dispose();
Renderer = null; Renderer = null;
(this as IInputRoot).MouseDevice?.TopLevelClosed(this);
PlatformImpl = null;
var logicalArgs = new LogicalTreeAttachmentEventArgs(this, this, null); var logicalArgs = new LogicalTreeAttachmentEventArgs(this, this, null);
((ILogical)this).NotifyDetachedFromLogicalTree(logicalArgs); ((ILogical)this).NotifyDetachedFromLogicalTree(logicalArgs);
var visualArgs = new VisualTreeAttachmentEventArgs(this, this); var visualArgs = new VisualTreeAttachmentEventArgs(this, this);
OnDetachedFromVisualTreeCore(visualArgs); OnDetachedFromVisualTreeCore(visualArgs);
(this as IInputRoot).MouseDevice?.TopLevelClosed(this);
PlatformImpl = null;
OnClosed(EventArgs.Empty); OnClosed(EventArgs.Empty);
LayoutManager?.Dispose(); LayoutManager?.Dispose();

326
src/Avalonia.Controls/ValidatingToplevel.cs

@ -0,0 +1,326 @@
using System;
using System.Collections.Generic;
using Avalonia.Controls.Platform;
using Avalonia.Controls.Primitives.PopupPositioning;
using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Input.TextInput;
using Avalonia.Platform;
using Avalonia.Rendering;
namespace Avalonia.Controls;
internal class ValidatingToplevelImpl : ITopLevelImpl, ITopLevelImplWithNativeControlHost,
ITopLevelImplWithNativeMenuExporter, ITopLevelImplWithTextInputMethod
{
private readonly ITopLevelImpl _impl;
private bool _disposed;
public ValidatingToplevelImpl(ITopLevelImpl impl)
{
_impl = impl ?? throw new InvalidOperationException(
"Could not create TopLevel implementation: maybe no windowing subsystem was initialized?");
}
public void Dispose()
{
_disposed = true;
_impl.Dispose();
}
protected void CheckDisposed()
{
if (_disposed)
throw new ObjectDisposedException(_impl.GetType().FullName);
}
protected ITopLevelImpl Inner
{
get
{
CheckDisposed();
return _impl;
}
}
public static ITopLevelImpl Wrap(ITopLevelImpl impl)
{
#if DEBUG
if (impl is ValidatingToplevelImpl)
return impl;
return new ValidatingToplevelImpl(impl);
#else
return impl;
#endif
}
public Size ClientSize => Inner.ClientSize;
public Size? FrameSize => Inner.FrameSize;
public double RenderScaling => Inner.RenderScaling;
public IEnumerable<object> Surfaces => Inner.Surfaces;
public Action<RawInputEventArgs> Input
{
get => Inner.Input;
set => Inner.Input = value;
}
public Action<Rect> Paint
{
get => Inner.Paint;
set => Inner.Paint = value;
}
public Action<Size, PlatformResizeReason> Resized
{
get => Inner.Resized;
set => Inner.Resized = value;
}
public Action<double> ScalingChanged
{
get => Inner.ScalingChanged;
set => Inner.ScalingChanged = value;
}
public Action<WindowTransparencyLevel> TransparencyLevelChanged
{
get => Inner.TransparencyLevelChanged;
set => Inner.TransparencyLevelChanged = value;
}
public IRenderer CreateRenderer(IRenderRoot root) => Inner.CreateRenderer(root);
public void Invalidate(Rect rect) => Inner.Invalidate(rect);
public void SetInputRoot(IInputRoot inputRoot) => Inner.SetInputRoot(inputRoot);
public Point PointToClient(PixelPoint point) => Inner.PointToClient(point);
public PixelPoint PointToScreen(Point point) => Inner.PointToScreen(point);
public void SetCursor(ICursorImpl cursor) => Inner.SetCursor(cursor);
public Action Closed
{
get => Inner.Closed;
set => Inner.Closed = value;
}
public Action LostFocus
{
get => Inner.LostFocus;
set => Inner.LostFocus = value;
}
// Exception: for some reason we are notifying platform mouse device from TopLevel.cs
public IMouseDevice MouseDevice => _impl.MouseDevice;
public IPopupImpl CreatePopup() => Inner.CreatePopup();
public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) =>
Inner.SetTransparencyLevelHint(transparencyLevel);
public WindowTransparencyLevel TransparencyLevel => Inner.TransparencyLevel;
public AcrylicPlatformCompensationLevels AcrylicCompensationLevels => Inner.AcrylicCompensationLevels;
public INativeControlHostImpl NativeControlHost => (Inner as ITopLevelImplWithNativeControlHost)?.NativeControlHost;
public ITopLevelNativeMenuExporter NativeMenuExporter =>
(Inner as ITopLevelImplWithNativeMenuExporter)?.NativeMenuExporter;
public ITextInputMethodImpl TextInputMethod => (Inner as ITopLevelImplWithTextInputMethod)?.TextInputMethod;
}
internal class ValidatingWindowBaseImpl : ValidatingToplevelImpl, IWindowBaseImpl
{
private readonly IWindowBaseImpl _impl;
public ValidatingWindowBaseImpl(IWindowBaseImpl impl) : base(impl)
{
_impl = impl;
}
protected new IWindowBaseImpl Inner
{
get
{
CheckDisposed();
return _impl;
}
}
public static IWindowBaseImpl Wrap(IWindowBaseImpl impl)
{
#if DEBUG
if (impl is ValidatingToplevelImpl)
return impl;
return new ValidatingWindowBaseImpl(impl);
#else
return impl;
#endif
}
public void Show(bool activate, bool isDialog) => Inner.Show(activate, isDialog);
public void Hide() => Inner.Hide();
public double DesktopScaling => Inner.DesktopScaling;
public PixelPoint Position => Inner.Position;
public Action<PixelPoint> PositionChanged
{
get => Inner.PositionChanged;
set => Inner.PositionChanged = value;
}
public void Activate() => Inner.Activate();
public Action Deactivated
{
get => Inner.Deactivated;
set => Inner.Deactivated = value;
}
public Action Activated
{
get => Inner.Activated;
set => Inner.Deactivated = value;
}
public IPlatformHandle Handle => Inner.Handle;
public Size MaxAutoSizeHint => Inner.MaxAutoSizeHint;
public void SetTopmost(bool value) => Inner.SetTopmost(value);
public IScreenImpl Screen => Inner.Screen;
}
internal class ValidatingWindowImpl : ValidatingWindowBaseImpl, IWindowImpl
{
private readonly IWindowImpl _impl;
public ValidatingWindowImpl(IWindowImpl impl) : base(impl)
{
_impl = impl;
}
protected new IWindowImpl Inner
{
get
{
CheckDisposed();
return _impl;
}
}
public static IWindowImpl Wrap(IWindowImpl impl)
{
#if DEBUG
if (impl is ValidatingToplevelImpl)
return impl;
return new ValidatingWindowImpl(impl);
#else
return impl;
#endif
}
public WindowState WindowState
{
get => Inner.WindowState;
set => Inner.WindowState = value;
}
public Action<WindowState> WindowStateChanged
{
get => Inner.WindowStateChanged;
set => Inner.WindowStateChanged = value;
}
public void SetTitle(string title) => Inner.SetTitle(title);
public void SetParent(IWindowImpl parent) => Inner.SetParent(parent);
public void SetEnabled(bool enable) => Inner.SetEnabled(enable);
public Action GotInputWhenDisabled
{
get => Inner.GotInputWhenDisabled;
set => Inner.GotInputWhenDisabled = value;
}
public void SetSystemDecorations(SystemDecorations enabled) => Inner.SetSystemDecorations(enabled);
public void SetIcon(IWindowIconImpl icon) => Inner.SetIcon(icon);
public void ShowTaskbarIcon(bool value) => Inner.ShowTaskbarIcon(value);
public void CanResize(bool value) => Inner.CanResize(value);
public Func<bool> Closing
{
get => Inner.Closing;
set => Inner.Closing = value;
}
public bool IsClientAreaExtendedToDecorations => Inner.IsClientAreaExtendedToDecorations;
public Action<bool> ExtendClientAreaToDecorationsChanged
{
get => Inner.ExtendClientAreaToDecorationsChanged;
set => Inner.ExtendClientAreaToDecorationsChanged = value;
}
public bool NeedsManagedDecorations => Inner.NeedsManagedDecorations;
public Thickness ExtendedMargins => Inner.ExtendedMargins;
public Thickness OffScreenMargin => Inner.OffScreenMargin;
public void BeginMoveDrag(PointerPressedEventArgs e) => Inner.BeginMoveDrag(e);
public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e) => Inner.BeginResizeDrag(edge, e);
public void Resize(Size clientSize, PlatformResizeReason reason) =>
Inner.Resize(clientSize, reason);
public void Move(PixelPoint point) => Inner.Move(point);
public void SetMinMaxSize(Size minSize, Size maxSize) => Inner.SetMinMaxSize(minSize, maxSize);
public void SetExtendClientAreaToDecorationsHint(bool extendIntoClientAreaHint) =>
Inner.SetExtendClientAreaToDecorationsHint(extendIntoClientAreaHint);
public void SetExtendClientAreaChromeHints(ExtendClientAreaChromeHints hints) =>
Inner.SetExtendClientAreaChromeHints(hints);
public void SetExtendClientAreaTitleBarHeightHint(double titleBarHeight) =>
Inner.SetExtendClientAreaTitleBarHeightHint(titleBarHeight);
}
internal class ValidatingPopupImpl : ValidatingWindowBaseImpl, IPopupImpl
{
private readonly IPopupImpl _impl;
public ValidatingPopupImpl(IPopupImpl impl) : base(impl)
{
_impl = impl;
}
protected new IPopupImpl Inner
{
get
{
CheckDisposed();
return _impl;
}
}
public static IPopupImpl Wrap(IPopupImpl impl)
{
#if DEBUG
if (impl is ValidatingToplevelImpl)
return impl;
return new ValidatingPopupImpl(impl);
#else
return impl;
#endif
}
public IPopupPositioner PopupPositioner => Inner.PopupPositioner;
public void SetWindowManagerAddShadowHint(bool enabled) => Inner.SetWindowManagerAddShadowHint(enabled);
}

11
src/Avalonia.Controls/Window.cs

@ -237,13 +237,14 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
/// <param name="impl">The window implementation.</param> /// <param name="impl">The window implementation.</param>
public Window(IWindowImpl impl) public Window(IWindowImpl impl)
: base(impl) : base(ValidatingWindowImpl.Wrap(impl))
{ {
impl.Closing = HandleClosing; var wrapped = (IWindowImpl)base.PlatformImpl!;
impl.GotInputWhenDisabled = OnGotInputWhenDisabled; wrapped.Closing = HandleClosing;
impl.WindowStateChanged = HandleWindowStateChanged; wrapped.GotInputWhenDisabled = OnGotInputWhenDisabled;
wrapped.WindowStateChanged = HandleWindowStateChanged;
_maxPlatformClientSize = PlatformImpl?.MaxAutoSizeHint ?? default(Size); _maxPlatformClientSize = PlatformImpl?.MaxAutoSizeHint ?? default(Size);
impl.ExtendClientAreaToDecorationsChanged = ExtendClientAreaToDecorationsChanged; wrapped.ExtendClientAreaToDecorationsChanged = ExtendClientAreaToDecorationsChanged;
this.GetObservable(ClientSizeProperty).Skip(1).Subscribe(x => PlatformImpl?.Resize(x, PlatformResizeReason.Application)); this.GetObservable(ClientSizeProperty).Skip(1).Subscribe(x => PlatformImpl?.Resize(x, PlatformResizeReason.Application));
PlatformImpl?.ShowTaskbarIcon(ShowInTaskbar); PlatformImpl?.ShowTaskbarIcon(ShowInTaskbar);

9
src/Avalonia.Controls/WindowBase.cs

@ -57,12 +57,13 @@ namespace Avalonia.Controls
{ {
} }
public WindowBase(IWindowBaseImpl impl, IAvaloniaDependencyResolver dependencyResolver) : base(impl, dependencyResolver) public WindowBase(IWindowBaseImpl impl, IAvaloniaDependencyResolver dependencyResolver) : base(ValidatingWindowBaseImpl.Wrap(impl), dependencyResolver)
{ {
Screens = new Screens(PlatformImpl?.Screen); Screens = new Screens(PlatformImpl?.Screen);
impl.Activated = HandleActivated; var wrapped = PlatformImpl!;
impl.Deactivated = HandleDeactivated; wrapped.Activated = HandleActivated;
impl.PositionChanged = HandlePositionChanged; wrapped.Deactivated = HandleDeactivated;
wrapped.PositionChanged = HandlePositionChanged;
} }
/// <summary> /// <summary>

13
src/Avalonia.X11/X11Window.cs

@ -341,9 +341,13 @@ namespace Avalonia.X11
public Action<WindowTransparencyLevel> TransparencyLevelChanged public Action<WindowTransparencyLevel> TransparencyLevelChanged
{ {
get => _transparencyHelper.TransparencyLevelChanged; get => _transparencyHelper?.TransparencyLevelChanged;
set => _transparencyHelper.TransparencyLevelChanged = value; set
} {
if (_transparencyHelper != null)
_transparencyHelper.TransparencyLevelChanged = value;
}
}
public Action<bool> ExtendClientAreaToDecorationsChanged { get; set; } public Action<bool> ExtendClientAreaToDecorationsChanged { get; set; }
@ -1163,7 +1167,8 @@ namespace Avalonia.X11
{ {
} }
public WindowTransparencyLevel TransparencyLevel => _transparencyHelper.CurrentLevel; public WindowTransparencyLevel TransparencyLevel =>
_transparencyHelper?.CurrentLevel ?? WindowTransparencyLevel.None;
public AcrylicPlatformCompensationLevels AcrylicCompensationLevels { get; } = new AcrylicPlatformCompensationLevels(1, 0.8, 0.8); public AcrylicPlatformCompensationLevels AcrylicCompensationLevels { get; } = new AcrylicPlatformCompensationLevels(1, 0.8, 0.8);

Loading…
Cancel
Save