InfiniFrame.Tray 0.1.0

dotnet add package InfiniFrame.Tray --version 0.1.0
                    
NuGet\Install-Package InfiniFrame.Tray -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="InfiniFrame.Tray" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="InfiniFrame.Tray" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="InfiniFrame.Tray" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add InfiniFrame.Tray --version 0.1.0
                    
#r "nuget: InfiniFrame.Tray, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package InfiniFrame.Tray@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=InfiniFrame.Tray&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=InfiniFrame.Tray&version=0.1.0
                    
Install as a Cake Tool

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 Clicked handlers 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 ILogger you 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 StartHidden the 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 with tray.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 Notifications feature (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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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 55 10/7/2026