Skip to content

Commit

Permalink
[WinForms] Tray icon - Better exit and UI prep
Browse files Browse the repository at this point in the history
  • Loading branch information
flyingpie committed Nov 23, 2024
1 parent 2a80c56 commit 30ba176
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 31 deletions.
50 changes: 38 additions & 12 deletions src/20-Services/Wtq.Services.WinForms/TrayIcon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<object?, EventArgs> exitHandler)
public TrayIcon(
IHostApplicationLifetime lifetime,
IWtqBus bus)
{
_lifetime = Guard.Against.Null(lifetime);
_bus = Guard.Against.Null(bus);

var waiter = new TaskCompletionSource<bool>();

var notifyThread = new Thread(() =>
{
var contextMenu = new ContextMenuStrip();

contextMenu.Items.AddRange(new ToolStripItem[]
{
contextMenu.Items.AddRange(
[
CreateVersionItem(),

new ToolStripSeparator(),
Expand All @@ -25,12 +33,14 @@ public TrayIcon(Action<object?, EventArgs> exitHandler)

CreateOpenSettingsItem(),

CreateOpenSettingsFileItem(),

CreateOpenSettingsDirItem(),

CreateOpenLogItem(),

CreateExitItem(exitHandler),
});
CreateExitItem(),
]);

// Tray Icon
_notificationIcon = new NotifyIcon()
Expand All @@ -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()
Expand All @@ -64,30 +77,43 @@ public void Dispose()
_notificationIcon = null;
}

private static ToolStripMenuItem CreateExitItem(Action<object?, EventArgs> 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()
Expand Down
27 changes: 8 additions & 19 deletions src/20-Services/Wtq.Services.WinForms/WinFormsTrayIconService.cs
Original file line number Diff line number Diff line change
@@ -1,40 +1,29 @@
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();
}

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;
}
Expand Down

0 comments on commit 30ba176

Please sign in to comment.