diff --git a/src/20-Services/Wtq.Services.WinForms/TrayIcon.cs b/src/20-Services/Wtq.Services.WinForms/TrayIcon.cs index cad36b08..8b93a6fe 100644 --- a/src/20-Services/Wtq.Services.WinForms/TrayIcon.cs +++ b/src/20-Services/Wtq.Services.WinForms/TrayIcon.cs @@ -4,19 +4,27 @@ namespace Wtq.Services.WinForms; public sealed class TrayIcon : IDisposable { + private readonly IHostApplicationLifetime _lifetime; + private readonly IWtqBus _bus; + private NotifyIcon? _notificationIcon; [SuppressMessage("Usage", "VSTHRD002:Avoid problematic synchronous waits", Justification = "MvdO: Replace with simple tray icon?")] - public TrayIcon(Action exitHandler) + public TrayIcon( + IHostApplicationLifetime lifetime, + IWtqBus bus) { + _lifetime = Guard.Against.Null(lifetime); + _bus = Guard.Against.Null(bus); + var waiter = new TaskCompletionSource(); var notifyThread = new Thread(() => { var contextMenu = new ContextMenuStrip(); - contextMenu.Items.AddRange(new ToolStripItem[] - { + contextMenu.Items.AddRange( + [ CreateVersionItem(), new ToolStripSeparator(), @@ -25,12 +33,14 @@ public TrayIcon(Action exitHandler) CreateOpenSettingsItem(), + CreateOpenSettingsFileItem(), + CreateOpenSettingsDirItem(), CreateOpenLogItem(), - CreateExitItem(exitHandler), - }); + CreateExitItem(), + ]); // Tray Icon _notificationIcon = new NotifyIcon() @@ -55,7 +65,10 @@ public static void OpenBrowser(Uri uri) { Guard.Against.Null(uri); - Process.Start(new ProcessStartInfo(uri.ToString()) { UseShellExecute = true }); + Process.Start(new ProcessStartInfo(uri.ToString()) + { + UseShellExecute = true, + }); } public void Dispose() @@ -64,30 +77,43 @@ public void Dispose() _notificationIcon = null; } - private static ToolStripMenuItem CreateExitItem(Action exitHandler) + private ToolStripMenuItem CreateExitItem() { - Guard.Against.Null(exitHandler); - var mnuExit = new ToolStripMenuItem("Exit"); - mnuExit.Click += new EventHandler(exitHandler); + mnuExit.Click += (s, a) => _lifetime.StopApplication(); return mnuExit; } private static Icon CreateIcon() { - using var str = new MemoryStream(Resources.Resources.icon); + using var str = new MemoryStream(Resources.Resources.icon_v2_64); return new Icon(str); } - private static ToolStripMenuItem CreateOpenSettingsItem() + private ToolStripMenuItem CreateOpenSettingsItem() { var mnuOpenSettings = new ToolStripMenuItem("Open settings") { Enabled = true, }; + mnuOpenSettings.Click += (s, a) => + { + _bus.Publish(new WtqUIRequestedEvent()); + }; + + return mnuOpenSettings; + } + + private static ToolStripMenuItem CreateOpenSettingsFileItem() + { + var mnuOpenSettings = new ToolStripMenuItem("Open settings file") + { + Enabled = true, + }; + mnuOpenSettings.Click += (s, a) => { Process.Start(new ProcessStartInfo() diff --git a/src/20-Services/Wtq.Services.WinForms/WinFormsTrayIconService.cs b/src/20-Services/Wtq.Services.WinForms/WinFormsTrayIconService.cs index 05a37003..a2f6a8aa 100644 --- a/src/20-Services/Wtq.Services.WinForms/WinFormsTrayIconService.cs +++ b/src/20-Services/Wtq.Services.WinForms/WinFormsTrayIconService.cs @@ -1,19 +1,14 @@ -using Microsoft.Extensions.Hosting; - namespace Wtq.Services.WinForms; -#pragma warning disable CA1812 // Avoid uninstantiated internal classes // MvdO: Instantiated through DI. -internal sealed class WinFormsTrayIconService : IDisposable, IHostedService -#pragma warning restore CA1812 // Avoid uninstantiated internal classes +internal sealed class WinFormsTrayIconService( + IHostApplicationLifetime lifetime, + IWtqBus bus) + : IDisposable, IHostedService { - private readonly IHostApplicationLifetime _lifetime; + private readonly IHostApplicationLifetime _lifetime = Guard.Against.Null(lifetime); + private readonly IWtqBus _bus = Guard.Against.Null(bus); private TrayIcon? _icon; - public WinFormsTrayIconService(IHostApplicationLifetime lifetime) - { - _lifetime = lifetime ?? throw new ArgumentNullException(nameof(lifetime)); - } - public void Dispose() { _icon?.Dispose(); @@ -21,20 +16,14 @@ public void Dispose() public Task StartAsync(CancellationToken cancellationToken) { - _icon = new TrayIcon((s, a) => - { - _lifetime.StopApplication(); - - // TODO: Remove this, though currently not all threads exit properly. - Application.Exit(); - }); + _icon = new TrayIcon(_lifetime, _bus); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { - _icon?.Dispose(); + Dispose(); return Task.CompletedTask; }