diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs index c11cadfbac..2e6f4a67c3 100644 --- a/src/Android/Avalonia.Android/AndroidPlatform.cs +++ b/src/Android/Avalonia.Android/AndroidPlatform.cs @@ -67,7 +67,7 @@ namespace Avalonia.Android throw new NotSupportedException(); } - public IEmbeddableWindowImpl CreateEmbeddableWindow() + public IWindowImpl CreateEmbeddableWindow() { throw new NotSupportedException(); } diff --git a/src/Android/Avalonia.Android/AvaloniaView.cs b/src/Android/Avalonia.Android/AvaloniaView.cs index fbe027db00..72732a1f95 100644 --- a/src/Android/Avalonia.Android/AvaloniaView.cs +++ b/src/Android/Avalonia.Android/AvaloniaView.cs @@ -33,10 +33,8 @@ namespace Avalonia.Android return _view.View.DispatchKeyEvent(e); } - class ViewImpl : TopLevelImpl, IEmbeddableWindowImpl + class ViewImpl : TopLevelImpl { - public event Action LostFocus; - public ViewImpl(Context context) : base(context) { View.Focusable = true; diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs index 71706676d6..69fd2a9f13 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs @@ -194,6 +194,8 @@ namespace Avalonia.Android.Platform.SkiaPlatform } public IPopupImpl CreatePopup() => null; + + public Action LostFocus { get; set; } ILockedFramebuffer IFramebufferPlatformSurface.Lock()=>new AndroidFramebuffer(_view.Holder.Surface); } diff --git a/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs b/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs index 2d48a7d33b..8a21d7aa4b 100644 --- a/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs +++ b/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs @@ -10,7 +10,7 @@ namespace Avalonia.Controls.Embedding { public class EmbeddableControlRoot : TopLevel, IStyleable, IFocusScope, IDisposable { - public EmbeddableControlRoot(IEmbeddableWindowImpl impl) : base(impl) + public EmbeddableControlRoot(ITopLevelImpl impl) : base(impl) { } @@ -19,9 +19,6 @@ namespace Avalonia.Controls.Embedding { } - [CanBeNull] - public new IEmbeddableWindowImpl PlatformImpl => (IEmbeddableWindowImpl) base.PlatformImpl; - protected bool EnforceClientSize { get; set; } = true; public void Prepare() diff --git a/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs b/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs index 29f0374301..57e96f18bf 100644 --- a/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs +++ b/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs @@ -60,6 +60,7 @@ namespace Avalonia.Controls.Embedding.Offscreen } public Action Closed { get; set; } + public Action LostFocus { get; set; } public abstract IMouseDevice MouseDevice { get; } public IPopupImpl CreatePopup() => null; } diff --git a/src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs b/src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs index ccee811b2e..bbe9d73304 100644 --- a/src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs +++ b/src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs @@ -67,8 +67,8 @@ namespace Avalonia.Controls.Platform window.Deactivated += WindowDeactivated; } - if (_root is TopLevel tl && tl.PlatformImpl is IEmbeddableWindowImpl eimpl) - eimpl.LostFocus += TopLevelLostPlatformFocus; + if (_root is TopLevel tl) + tl.PlatformImpl.LostFocus += TopLevelLostPlatformFocus; _inputManagerSubscription = InputManager?.Process.Subscribe(RawInput); } @@ -100,8 +100,8 @@ namespace Avalonia.Controls.Platform root.Deactivated -= WindowDeactivated; } - if (_root is TopLevel tl && tl.PlatformImpl is IEmbeddableWindowImpl eimpl) - eimpl.LostFocus -= TopLevelLostPlatformFocus; + if (_root is TopLevel tl) + tl.PlatformImpl.LostFocus -= TopLevelLostPlatformFocus; _inputManagerSubscription?.Dispose(); diff --git a/src/Avalonia.Controls/Platform/IEmbeddableWindowImpl.cs b/src/Avalonia.Controls/Platform/IEmbeddableWindowImpl.cs deleted file mode 100644 index e2d174d9b6..0000000000 --- a/src/Avalonia.Controls/Platform/IEmbeddableWindowImpl.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Avalonia.Platform -{ - /// - /// Defines a platform-specific embeddable window implementation. - /// - public interface IEmbeddableWindowImpl : ITopLevelImpl - { - event Action LostFocus; - } -} diff --git a/src/Avalonia.Controls/Platform/ITopLevelImpl.cs b/src/Avalonia.Controls/Platform/ITopLevelImpl.cs index 98ee17ee1f..eaba3ac895 100644 --- a/src/Avalonia.Controls/Platform/ITopLevelImpl.cs +++ b/src/Avalonia.Controls/Platform/ITopLevelImpl.cs @@ -98,6 +98,11 @@ namespace Avalonia.Platform /// Gets or sets a method called when the underlying implementation is destroyed. /// Action Closed { get; set; } + + /// + /// Gets or sets a method called when the input focus is lost. + /// + Action LostFocus { get; set; } /// /// Gets a mouse device associated with toplevel diff --git a/src/Avalonia.Controls/Platform/IWindowingPlatform.cs b/src/Avalonia.Controls/Platform/IWindowingPlatform.cs index a55bd63c6a..be8939e19a 100644 --- a/src/Avalonia.Controls/Platform/IWindowingPlatform.cs +++ b/src/Avalonia.Controls/Platform/IWindowingPlatform.cs @@ -3,6 +3,6 @@ namespace Avalonia.Platform public interface IWindowingPlatform { IWindowImpl CreateWindow(); - IEmbeddableWindowImpl CreateEmbeddableWindow(); + IWindowImpl CreateEmbeddableWindow(); } } diff --git a/src/Avalonia.Controls/Platform/PlatformManager.cs b/src/Avalonia.Controls/Platform/PlatformManager.cs index ef453274b8..19d034b4e2 100644 --- a/src/Avalonia.Controls/Platform/PlatformManager.cs +++ b/src/Avalonia.Controls/Platform/PlatformManager.cs @@ -34,7 +34,7 @@ namespace Avalonia.Controls.Platform return s_designerMode ? (IWindowImpl)platform.CreateEmbeddableWindow() : platform.CreateWindow(); } - public static IEmbeddableWindowImpl CreateEmbeddableWindow() + public static IWindowImpl CreateEmbeddableWindow() { var platform = AvaloniaLocator.Current.GetService(); if (platform == null) diff --git a/src/Avalonia.Controls/Primitives/Popup.cs b/src/Avalonia.Controls/Primitives/Popup.cs index 685271263f..a4a9707625 100644 --- a/src/Avalonia.Controls/Primitives/Popup.cs +++ b/src/Avalonia.Controls/Primitives/Popup.cs @@ -265,8 +265,7 @@ namespace Avalonia.Controls.Primitives (x, handler) => x.Deactivated += handler, (x, handler) => x.Deactivated -= handler)); - if (window.PlatformImpl is IEmbeddableWindowImpl reportsFocus) - DeferCleanup(SubscribeToEventHandler(reportsFocus, WindowLostFocus, + DeferCleanup(SubscribeToEventHandler(window.PlatformImpl, WindowLostFocus, (x, handler) => x.LostFocus += handler, (x, handler) => x.LostFocus -= handler)); } diff --git a/src/Avalonia.Controls/Remote/RemoteServer.cs b/src/Avalonia.Controls/Remote/RemoteServer.cs index e116316904..4f5a7cd311 100644 --- a/src/Avalonia.Controls/Remote/RemoteServer.cs +++ b/src/Avalonia.Controls/Remote/RemoteServer.cs @@ -10,13 +10,13 @@ namespace Avalonia.Controls.Remote { private EmbeddableControlRoot _topLevel; - class EmbeddableRemoteServerTopLevelImpl : RemoteServerTopLevelImpl, IEmbeddableWindowImpl + class EmbeddableRemoteServerTopLevelImpl : RemoteServerTopLevelImpl { public EmbeddableRemoteServerTopLevelImpl(IAvaloniaRemoteTransportConnection transport) : base(transport) { } #pragma warning disable 67 - public event Action LostFocus; + public Action LostFocus { get; set; } } diff --git a/src/Avalonia.Controls/TopLevel.cs b/src/Avalonia.Controls/TopLevel.cs index 7acdcf71f0..315603e7c4 100644 --- a/src/Avalonia.Controls/TopLevel.cs +++ b/src/Avalonia.Controls/TopLevel.cs @@ -136,8 +136,7 @@ namespace Avalonia.Controls this); } - if (impl is IEmbeddableWindowImpl embeddableWindowImpl) - embeddableWindowImpl.LostFocus += PlatformImpl_LostFocus; + impl.LostFocus += PlatformImpl_LostFocus; } /// diff --git a/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs b/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs index 7480b3519c..e50a6b264c 100644 --- a/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs +++ b/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs @@ -10,7 +10,7 @@ using Avalonia.Threading; namespace Avalonia.DesignerSupport.Remote { - class PreviewerWindowImpl : RemoteServerTopLevelImpl, IWindowImpl, IEmbeddableWindowImpl + class PreviewerWindowImpl : RemoteServerTopLevelImpl, IWindowImpl { private readonly IAvaloniaRemoteTransportConnection _transport; @@ -45,11 +45,6 @@ namespace Avalonia.DesignerSupport.Remote public WindowState WindowState { get; set; } public Action WindowStateChanged { get; set; } public Size MaxClientSize { get; } = new Size(4096, 4096); - public event Action LostFocus - { - add {} - remove {} - } protected override void OnMessage(IAvaloniaRemoteTransportConnection transport, object obj) { diff --git a/src/Avalonia.DesignerSupport/Remote/PreviewerWindowingPlatform.cs b/src/Avalonia.DesignerSupport/Remote/PreviewerWindowingPlatform.cs index dcfcd42c04..fe4c580bbb 100644 --- a/src/Avalonia.DesignerSupport/Remote/PreviewerWindowingPlatform.cs +++ b/src/Avalonia.DesignerSupport/Remote/PreviewerWindowingPlatform.cs @@ -19,7 +19,7 @@ namespace Avalonia.DesignerSupport.Remote public IWindowImpl CreateWindow() => new WindowStub(); - public IEmbeddableWindowImpl CreateEmbeddableWindow() + public IWindowImpl CreateEmbeddableWindow() { if (s_lastWindow != null) { diff --git a/src/Avalonia.DesignerSupport/Remote/Stubs.cs b/src/Avalonia.DesignerSupport/Remote/Stubs.cs index 82950ce53b..692f6a23b0 100644 --- a/src/Avalonia.DesignerSupport/Remote/Stubs.cs +++ b/src/Avalonia.DesignerSupport/Remote/Stubs.cs @@ -29,6 +29,7 @@ namespace Avalonia.DesignerSupport.Remote public Action ScalingChanged { get; set; } public Func Closing { get; set; } public Action Closed { get; set; } + public Action LostFocus { get; set; } public IMouseDevice MouseDevice { get; } = new MouseDevice(); public IPopupImpl CreatePopup() => new WindowStub(this); diff --git a/src/Avalonia.Native/AvaloniaNativePlatform.cs b/src/Avalonia.Native/AvaloniaNativePlatform.cs index f1be2285d8..a6ae072281 100644 --- a/src/Avalonia.Native/AvaloniaNativePlatform.cs +++ b/src/Avalonia.Native/AvaloniaNativePlatform.cs @@ -112,7 +112,7 @@ namespace Avalonia.Native return new WindowImpl(_factory, _options, _glFeature); } - public IEmbeddableWindowImpl CreateEmbeddableWindow() + public IWindowImpl CreateEmbeddableWindow() { throw new NotImplementedException(); } diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs index 64d7581c65..2ab436714b 100644 --- a/src/Avalonia.Native/WindowImplBase.cs +++ b/src/Avalonia.Native/WindowImplBase.cs @@ -43,8 +43,7 @@ namespace Avalonia.Native } public abstract class WindowBaseImpl : IWindowBaseImpl, - IFramebufferPlatformSurface, ITopLevelImplWithNativeControlHost, - IEmbeddableWindowImpl + IFramebufferPlatformSurface, ITopLevelImplWithNativeControlHost { IInputRoot _inputRoot; IAvnWindowBase _native; @@ -122,7 +121,7 @@ namespace Avalonia.Native }, (int)w, (int)h, new Vector(dpi, dpi)); } - public event Action LostFocus; + public Action LostFocus { get; set; } public Action Paint { get; set; } public Action Resized { get; set; } diff --git a/src/Avalonia.X11/X11Platform.cs b/src/Avalonia.X11/X11Platform.cs index cd30b360d7..8e888a6bec 100644 --- a/src/Avalonia.X11/X11Platform.cs +++ b/src/Avalonia.X11/X11Platform.cs @@ -83,7 +83,7 @@ namespace Avalonia.X11 return new X11Window(this, null); } - public IEmbeddableWindowImpl CreateEmbeddableWindow() + public IWindowImpl CreateEmbeddableWindow() { throw new NotSupportedException(); } diff --git a/src/Avalonia.X11/X11Window.cs b/src/Avalonia.X11/X11Window.cs index be8c66fc9c..f531e301e0 100644 --- a/src/Avalonia.X11/X11Window.cs +++ b/src/Avalonia.X11/X11Window.cs @@ -310,6 +310,7 @@ namespace Avalonia.X11 public Action WindowStateChanged { get; set; } public Action Closed { get; set; } public Action PositionChanged { get; set; } + public Action LostFocus { get; set; } public IRenderer CreateRenderer(IRenderRoot root) { diff --git a/src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs b/src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs index 9844cdc03b..29ad19aa24 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs @@ -9,7 +9,7 @@ using Avalonia.Rendering; namespace Avalonia.LinuxFramebuffer { - class FramebufferToplevelImpl : IEmbeddableWindowImpl, IScreenInfoProvider + class FramebufferToplevelImpl : ITopLevelImpl, IScreenInfoProvider { private readonly IOutputBackend _outputBackend; private readonly IInputBackend _inputBackend; @@ -71,11 +71,7 @@ namespace Avalonia.LinuxFramebuffer public Action Resized { get; set; } public Action ScalingChanged { get; set; } public Action Closed { get; set; } - public event Action LostFocus - { - add {} - remove {} - } + public Action LostFocus { get; set; } public Size ScaledSize => _outputBackend.PixelSize.ToSize(Scaling); } diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index c01bc8e16d..e9315990a2 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -204,7 +204,7 @@ namespace Avalonia.Win32 return new WindowImpl(); } - public IEmbeddableWindowImpl CreateEmbeddableWindow() + public IWindowImpl CreateEmbeddableWindow() { var embedded = new EmbeddedWindowImpl(); embedded.Show(); diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 98210c6959..364b0ec139 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -19,8 +19,7 @@ namespace Avalonia.Win32 /// Window implementation for Win32 platform. /// public partial class WindowImpl : IWindowImpl, EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo, - ITopLevelImplWithNativeControlHost, - IEmbeddableWindowImpl + ITopLevelImplWithNativeControlHost { private static readonly List s_instances = new List(); @@ -126,7 +125,7 @@ namespace Avalonia.Win32 public Action WindowStateChanged { get; set; } - public event Action LostFocus; + public Action LostFocus { get; set; } public Thickness BorderThickness { diff --git a/src/iOS/Avalonia.iOS/EmbeddableImpl.cs b/src/iOS/Avalonia.iOS/EmbeddableImpl.cs index 838bf49846..d299ff99c1 100644 --- a/src/iOS/Avalonia.iOS/EmbeddableImpl.cs +++ b/src/iOS/Avalonia.iOS/EmbeddableImpl.cs @@ -4,7 +4,7 @@ using Avalonia.Platform; namespace Avalonia.iOS { - class EmbeddableImpl : TopLevelImpl, IEmbeddableWindowImpl + class EmbeddableImpl : TopLevelImpl { public void SetTitle(string title) { @@ -23,11 +23,5 @@ namespace Avalonia.iOS public void SetSystemDecorations(SystemDecorations enabled) { } - - public event Action LostFocus - { - add {} - remove {} - } } } diff --git a/src/iOS/Avalonia.iOS/TopLevelImpl.cs b/src/iOS/Avalonia.iOS/TopLevelImpl.cs index c5b6642982..83a68990d7 100644 --- a/src/iOS/Avalonia.iOS/TopLevelImpl.cs +++ b/src/iOS/Avalonia.iOS/TopLevelImpl.cs @@ -139,5 +139,7 @@ namespace Avalonia.iOS public ILockedFramebuffer Lock() => new EmulatedFramebuffer(this); public IPopupImpl CreatePopup() => null; + + public Action LostFocus { get; set; } } } diff --git a/src/iOS/Avalonia.iOS/WindowingPlatformImpl.cs b/src/iOS/Avalonia.iOS/WindowingPlatformImpl.cs index 9a40b7162e..aaca5f53d6 100644 --- a/src/iOS/Avalonia.iOS/WindowingPlatformImpl.cs +++ b/src/iOS/Avalonia.iOS/WindowingPlatformImpl.cs @@ -10,7 +10,7 @@ namespace Avalonia.iOS throw new NotSupportedException(); } - public IEmbeddableWindowImpl CreateEmbeddableWindow() + public WindowImpl CreateEmbeddableWindow() { throw new NotSupportedException(); } diff --git a/tests/Avalonia.Controls.UnitTests/WindowingPlatformMock.cs b/tests/Avalonia.Controls.UnitTests/WindowingPlatformMock.cs index a9c991b8b9..25e8c82b1a 100644 --- a/tests/Avalonia.Controls.UnitTests/WindowingPlatformMock.cs +++ b/tests/Avalonia.Controls.UnitTests/WindowingPlatformMock.cs @@ -20,11 +20,11 @@ namespace Avalonia.Controls.UnitTests return _windowImpl?.Invoke() ?? Mock.Of(x => x.Scaling == 1); } - public IEmbeddableWindowImpl CreateEmbeddableWindow() + public IWindowImpl CreateEmbeddableWindow() { throw new NotImplementedException(); } public IPopupImpl CreatePopup() => _popupImpl?.Invoke() ?? Mock.Of(x => x.Scaling == 1); } -} \ No newline at end of file +} diff --git a/tests/Avalonia.UnitTests/MockWindowingPlatform.cs b/tests/Avalonia.UnitTests/MockWindowingPlatform.cs index b3e4b4edbc..a525eed7d3 100644 --- a/tests/Avalonia.UnitTests/MockWindowingPlatform.cs +++ b/tests/Avalonia.UnitTests/MockWindowingPlatform.cs @@ -116,7 +116,7 @@ namespace Avalonia.UnitTests } } - public IEmbeddableWindowImpl CreateEmbeddableWindow() + public IWindowImpl CreateEmbeddableWindow() { throw new NotImplementedException(); }