From 786375aff9016f8c5bb95265a5f2edf4097e33f8 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 4 Oct 2021 18:08:48 +0100 Subject: [PATCH] handle platforms that return null for the trayiconimpl. --- .../Platform/IWindowingPlatform.cs | 4 +- .../Platform/PlatformManager.cs | 5 ++- src/Avalonia.Controls/TrayIcon.cs | 23 ++++++----- .../Remote/PreviewerWindowingPlatform.cs | 2 +- .../Remote/TrayIconStub.cs | 40 ------------------- .../AvaloniaHeadlessPlatform.cs | 5 +-- src/iOS/Avalonia.iOS/Stubs.cs | 2 +- .../WindowingPlatformMock.cs | 2 +- .../MockWindowingPlatform.cs | 2 +- 9 files changed, 24 insertions(+), 61 deletions(-) delete mode 100644 src/Avalonia.DesignerSupport/Remote/TrayIconStub.cs diff --git a/src/Avalonia.Controls/Platform/IWindowingPlatform.cs b/src/Avalonia.Controls/Platform/IWindowingPlatform.cs index 4efa92cc6b..21882b1271 100644 --- a/src/Avalonia.Controls/Platform/IWindowingPlatform.cs +++ b/src/Avalonia.Controls/Platform/IWindowingPlatform.cs @@ -1,3 +1,5 @@ +#nullable enable + namespace Avalonia.Platform { public interface IWindowingPlatform @@ -6,6 +8,6 @@ namespace Avalonia.Platform IWindowImpl CreateEmbeddableWindow(); - ITrayIconImpl CreateTrayIcon(); + ITrayIconImpl? CreateTrayIcon(); } } diff --git a/src/Avalonia.Controls/Platform/PlatformManager.cs b/src/Avalonia.Controls/Platform/PlatformManager.cs index fe83e37909..054f823d6d 100644 --- a/src/Avalonia.Controls/Platform/PlatformManager.cs +++ b/src/Avalonia.Controls/Platform/PlatformManager.cs @@ -1,8 +1,9 @@ using System; using System.Reactive.Disposables; -using Avalonia.Media; using Avalonia.Platform; +#nullable enable + namespace Avalonia.Controls.Platform { public static partial class PlatformManager @@ -22,7 +23,7 @@ namespace Avalonia.Controls.Platform { } - public static ITrayIconImpl CreateTrayIcon () + public static ITrayIconImpl? CreateTrayIcon () { var platform = AvaloniaLocator.Current.GetService(); diff --git a/src/Avalonia.Controls/TrayIcon.cs b/src/Avalonia.Controls/TrayIcon.cs index 5b10fa20ea..b98e342735 100644 --- a/src/Avalonia.Controls/TrayIcon.cs +++ b/src/Avalonia.Controls/TrayIcon.cs @@ -16,15 +16,18 @@ namespace Avalonia.Controls public class TrayIcon : AvaloniaObject, INativeMenuExporterProvider, IDisposable { - private readonly ITrayIconImpl _impl; + private readonly ITrayIconImpl? _impl; - private TrayIcon(ITrayIconImpl impl) + private TrayIcon(ITrayIconImpl? impl) { - _impl = impl; + if (impl != null) + { + _impl = impl; - _impl.SetIsVisible(IsVisible); + _impl.SetIsVisible(IsVisible); - _impl.OnClicked = () => Clicked?.Invoke(this, EventArgs.Empty); + _impl.OnClicked = () => Clicked?.Invoke(this, EventArgs.Empty); + } } public TrayIcon () : this(PlatformManager.CreateTrayIcon()) @@ -160,25 +163,25 @@ namespace Avalonia.Controls if(change.Property == IconProperty) { - _impl.SetIcon(Icon.PlatformImpl); + _impl?.SetIcon(Icon.PlatformImpl); } else if (change.Property == IsVisibleProperty) { - _impl.SetIsVisible(change.NewValue.GetValueOrDefault()); + _impl?.SetIsVisible(change.NewValue.GetValueOrDefault()); } else if (change.Property == ToolTipTextProperty) { - _impl.SetToolTipText(change.NewValue.GetValueOrDefault()); + _impl?.SetToolTipText(change.NewValue.GetValueOrDefault()); } else if (change.Property == MenuProperty) { - _impl.MenuExporter?.SetNativeMenu(change.NewValue.GetValueOrDefault()); + _impl?.MenuExporter?.SetNativeMenu(change.NewValue.GetValueOrDefault()); } } /// /// Disposes the tray icon (removing it from the tray area). /// - public void Dispose() => _impl.Dispose(); + public void Dispose() => _impl?.Dispose(); } } diff --git a/src/Avalonia.DesignerSupport/Remote/PreviewerWindowingPlatform.cs b/src/Avalonia.DesignerSupport/Remote/PreviewerWindowingPlatform.cs index caca15b3a3..ada63f5326 100644 --- a/src/Avalonia.DesignerSupport/Remote/PreviewerWindowingPlatform.cs +++ b/src/Avalonia.DesignerSupport/Remote/PreviewerWindowingPlatform.cs @@ -17,7 +17,7 @@ namespace Avalonia.DesignerSupport.Remote private static PreviewerWindowImpl s_lastWindow; public static List PreFlightMessages = new List(); - public ITrayIconImpl CreateTrayIcon() => new TrayIconStub(); + public ITrayIconImpl CreateTrayIcon() => null; public IWindowImpl CreateWindow() => new WindowStub(); diff --git a/src/Avalonia.DesignerSupport/Remote/TrayIconStub.cs b/src/Avalonia.DesignerSupport/Remote/TrayIconStub.cs deleted file mode 100644 index 88ca076f8a..0000000000 --- a/src/Avalonia.DesignerSupport/Remote/TrayIconStub.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using Avalonia.Controls; -using Avalonia.Controls.Platform; -using Avalonia.Platform; - -namespace Avalonia.DesignerSupport.Remote -{ - class TrayIconStub : ITrayIconImpl - { - public Action Clicked { get; set; } - public Action DoubleClicked { get; set; } - public Action RightClicked { get; set; } - - public INativeMenuExporter MenuExporter => null; - - public Action OnClicked { get; set; } - - public void Dispose() - { - throw new NotImplementedException(); - } - - public void SetIcon(IWindowIconImpl icon) - { - } - - public void SetIsVisible(bool visible) - { - } - - public void SetMenu(NativeMenu menu) - { - throw new NotImplementedException(); - } - - public void SetToolTipText(string text) - { - } - } -} diff --git a/src/Avalonia.Headless/AvaloniaHeadlessPlatform.cs b/src/Avalonia.Headless/AvaloniaHeadlessPlatform.cs index afaec3a8a0..4f0b9e9e8d 100644 --- a/src/Avalonia.Headless/AvaloniaHeadlessPlatform.cs +++ b/src/Avalonia.Headless/AvaloniaHeadlessPlatform.cs @@ -52,10 +52,7 @@ namespace Avalonia.Headless public IPopupImpl CreatePopup() => new HeadlessWindowImpl(true); - public ITrayIconImpl CreateTrayIcon() - { - throw new NotImplementedException(); - } + public ITrayIconImpl CreateTrayIcon() => return null; } internal static void Initialize() diff --git a/src/iOS/Avalonia.iOS/Stubs.cs b/src/iOS/Avalonia.iOS/Stubs.cs index b13dfd39e0..9c46aa78cc 100644 --- a/src/iOS/Avalonia.iOS/Stubs.cs +++ b/src/iOS/Avalonia.iOS/Stubs.cs @@ -22,7 +22,7 @@ namespace Avalonia.iOS public IWindowImpl CreateEmbeddableWindow() => throw new NotSupportedException(); - public ITrayIconImpl CreateTrayIcon() => throw new NotSupportedException(); + public ITrayIconImpl CreateTrayIcon() => null; } class PlatformIconLoaderStub : IPlatformIconLoader diff --git a/tests/Avalonia.Controls.UnitTests/WindowingPlatformMock.cs b/tests/Avalonia.Controls.UnitTests/WindowingPlatformMock.cs index 5c5ec8be90..e8471d41fb 100644 --- a/tests/Avalonia.Controls.UnitTests/WindowingPlatformMock.cs +++ b/tests/Avalonia.Controls.UnitTests/WindowingPlatformMock.cs @@ -27,7 +27,7 @@ namespace Avalonia.Controls.UnitTests public ITrayIconImpl CreateTrayIcon() { - throw new NotImplementedException(); + return null; } public IPopupImpl CreatePopup() => _popupImpl?.Invoke() ?? Mock.Of(x => x.RenderScaling == 1); diff --git a/tests/Avalonia.UnitTests/MockWindowingPlatform.cs b/tests/Avalonia.UnitTests/MockWindowingPlatform.cs index 4074885505..eb18030ca8 100644 --- a/tests/Avalonia.UnitTests/MockWindowingPlatform.cs +++ b/tests/Avalonia.UnitTests/MockWindowingPlatform.cs @@ -128,7 +128,7 @@ namespace Avalonia.UnitTests public ITrayIconImpl CreateTrayIcon() { - throw new NotImplementedException(); + return null; } private static void SetupToplevel(Mock mock) where T : class, ITopLevelImpl