using System.Threading; using System.Threading.Tasks; using EtoFormsApplication = Eto.Forms.Application; using EtoPlatform = Eto.Platform; namespace System.Application.UI { public class NotifyIcon : INotifyIcon { public event EventHandler? Click; public event EventHandler? DoubleClick; public event EventHandler? RightClick; LinuxTrayIcon? lti; internal LinuxTrayIcon? LtiProp { get => lti; set => lti = value; } public Task? TrayIconTask { get; private set; } CancellationTokenSource? canTok; /// /// Gets or sets the icon for the notify icon. Either a file system path /// or a resm: manifest resource path can be specified. /// string _iconPath = ""; public string IconPath { get => _iconPath; set { _iconPath = value; UpdateMenu(); } } string _toolTip = ""; /// /// Gets or sets the tooltip text for the notify icon. /// public string ToolTipText { get => _toolTip; set { _toolTip = value; UpdateMenu(); } } TContextMenu? _menu; /// /// Gets or sets the context menu for the notify icon. /// public TContextMenu? ContextMenu { get => _menu; set { _menu = value; UpdateMenu(); } } /// /// Gets or sets if the notify icon is visible in the /// taskbar notification area or not. /// public bool Visible { get; set; } public void Remove() { MainThreadDesktop.BeginInvokeOnMainThread(() => { lti?._tray?.Hide(); canTok?.Cancel(); }); } void UpdateMenu() { if (!string.IsNullOrEmpty(IconPath) && !string.IsNullOrEmpty(ToolTipText) && ContextMenu != null) { canTok = new CancellationTokenSource(); MainThreadDesktop.BeginInvokeOnMainThread(() => { // Because of the way that Linux works this needs to run on its own Thread. TrayIconTask = Task.Factory.StartNew(() => { new EtoFormsApplication(EtoPlatform.Detect) .Run(LtiProp = new LinuxTrayIcon(ToolTipText, IconPath, ContextMenu)); } , canTok.Token, TaskCreationOptions.AttachedToParent, TaskScheduler.Default); }, MainThreadDesktop.DispatcherPriority.MaxValue, true); } } } }