InfiniFrame.Tray
0.1.0
dotnet add package InfiniFrame.Tray --version 0.1.0
NuGet\Install-Package InfiniFrame.Tray -Version 0.1.0
<PackageReference Include="InfiniFrame.Tray" Version="0.1.0" />
<PackageVersion Include="InfiniFrame.Tray" Version="0.1.0" />
<PackageReference Include="InfiniFrame.Tray" />
paket add InfiniFrame.Tray --version 0.1.0
#r "nuget: InfiniFrame.Tray, 0.1.0"
#:package InfiniFrame.Tray@0.1.0
#addin nuget:?package=InfiniFrame.Tray&version=0.1.0
#tool nuget:?package=InfiniFrame.Tray&version=0.1.0
InfiniFrame.Tray
System tray (Windows) and menu bar (macOS) icons for InfiniFrame windows. Use it to send an InfiniFrame app to the tray: close or minimize to the tray, start hidden, click the icon to bring the window back, plus a tray menu.
InfiniFrame itself has no tray support. Its Taskbar feature only does taskbar progress and flashing. This library
adds the tray icon and builds on InfiniFrame's window events.
| Platform | Tray icon | Implementation |
|---|---|---|
| Windows 10/11 | Notification area | Shell_NotifyIcon on its own thread (no WinForms/WPF) |
| macOS 11+ | Menu bar | NSStatusItem via the Objective-C runtime (no macOS workload or Xamarin bindings) |
| Linux | None | Does nothing (TrayIcon.IsSupported is false), so the app still runs |
Targets net8.0, net9.0 and net10.0 (same as InfiniFrame). It is AOT/trim compatible: all interop is
LibraryImport / function pointers. Depends on InfiniLore.InfiniFrame 0.62.1.
Quick start
using InfiniFrame;
using InfiniFrame.Tray;
[STAThread]
static void Main()
{
using var tray = new TrayIcon("My App", TrayIconImage.FromFile("tray.ico"));
tray.Menu = new TrayMenu
{
{ "Open", tray.ShowWindow },
TrayMenuItem.Separator(),
{ "Quit", tray.ExitApplication },
};
var window = InfiniFrameWindowBuilder.Create()
.SetTitle("My App")
.SetStartPageUrl("https://example.com")
.UseTray(tray, o =>
{
o.CloseToTray = true; // X hides the window (default)
o.MinimizeToTray = true; // minimize hides it too
o.StartHidden = false; // true = start in the tray
})
.Build();
window.WaitForClose(); // returns after "Quit"
}
See samples/InfiniFrame.Tray.Sample for checkable items, submenus and
updating the menu just before it opens.
API
TrayIcon
| Member | |
|---|---|
new TrayIcon(tooltip?, icon?, logger?) |
Shows the icon right away. A null icon uses the app's own icon (the exe's ApplicationIcon on Windows, the app icon on macOS). |
Icon, Tooltip, Visible |
Can be changed at any time, from any thread. On Windows the tooltip is cut to 127 characters. |
Menu |
A TrayMenu. The native menu is rebuilt every time it opens, so just change the items. |
ShowMenuOnLeftClick |
Defaults to true on macOS (menu bar convention) and false on Windows. Right-click and control-click always open the menu. |
Clicked, DoubleClicked, MenuOpening |
Events. Use MenuOpening to refresh items just before the menu is shown. |
ShowWindow(), HideWindow(), ToggleWindow() |
Act on the window attached with UseTray. |
ExitApplication() |
Removes the icon and really closes the window (bypassing close-to-tray), so WaitForClose returns. |
Dispose() |
Removes the icon. After this the window no longer closes to the tray. |
TrayMenu / TrayMenuItem
TrayMenuItem has Text, Enabled, Checked, Visible, Submenu and a Clicked event. Hidden items are left out,
and the separators that would be left over are dropped too. An & in the text shows literally on both platforms.
TrayMenu is thread-safe and works with collection initializers ({ "Text", action }).
TrayIconImage
| Factory | |
|---|---|
FromFile(path), FromBytes(data), FromStream(stream) |
ICO or PNG. Any other format throws right away. On Windows the best size is picked from an ICO (16/24/32 px at 100/150/200% scaling). |
FromMacSystemSymbol("printer.fill", fallback) |
An SF Symbol on macOS 11+. Windows and older macOS versions use fallback. |
.AsTemplate() |
macOS: a template image, so the menu bar tints it for light and dark mode. Use this for black-on-transparent icons. |
UseTray(tray, options) and TrayWindowOptions
UseTray works on an IInfiniFrameWindowBuilder, or on an IInfiniFrameWindow that is already built. A tray icon
can be attached to one window.
| Option | Default | |
|---|---|---|
CloseToTray |
true |
Closing the window (X, Alt+F4, Cmd+W) hides it instead. |
MinimizeToTray |
false |
Minimizing hides the window. |
StartHidden |
false |
Hides the window as soon as InfiniFrame has created it. |
ShowWindowOnClick |
true |
Clicked shows the window. |
MacDockIcon |
WhileWindowVisible |
Always, WhileWindowVisible or Never. Never makes it a menu-bar-only app, like LSUIElement. |
Threading
- Every member can be called from any thread. Changes are applied in order on the tray's UI thread.
- Events and menu
Clickedhandlers run on the tray's UI thread:- Windows: a dedicated background thread with its own message loop. This keeps the icon independent of the InfiniFrame window thread, so it can exist before the window does and after it closes.
- macOS: the main thread (through the main dispatch queue).
- A handler that throws is logged through the
ILoggeryou passed in. Handlers run inside native callbacks, where an unhandled exception would terminate the process. - On macOS the icon appears once the main run loop runs, which is when
WaitForClose()starts.
Caveats
- Start hidden can flash. InfiniFrame shows a window while it creates it, so with
StartHiddenthe window may be visible for a moment before it is hidden. - Shutting down. With
CloseToTray, InfiniFrame's own close requests are also turned into "hide". Exit withtray.ExitApplication(), or dispose the tray first. - macOS has not been run on real hardware yet. The backend compiles, and the Windows behaviour it mirrors is tested, but the AppKit interop has not been run on a Mac. Test the sample on a Mac before relying on it.
- Windows balloon notifications are not included. Use InfiniFrame's
Notificationsfeature (window.Features.Notifications.ShowNotification), which works on every platform.
Development
dotnet build InfiniFrameTray.slnx
dotnet test --project tests/InfiniFrame.Tray.Tests # runs anywhere (Linux uses the no-op backend)
dotnet run --project samples/InfiniFrame.Tray.Sample # Windows or macOS
dotnet pack src/InfiniFrame.Tray -c Release
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- InfiniLore.InfiniFrame (>= 0.62.1)
-
net8.0
- InfiniLore.InfiniFrame (>= 0.62.1)
-
net9.0
- InfiniLore.InfiniFrame (>= 0.62.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0 | 54 | 10/7/2026 |