StirlingLabs.tray.native.linux-x64 23.8.1

Prefix Reserved
dotnet add package StirlingLabs.tray.native.linux-x64 --version 23.8.1                
NuGet\Install-Package StirlingLabs.tray.native.linux-x64 -Version 23.8.1                
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="StirlingLabs.tray.native.linux-x64" Version="23.8.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add StirlingLabs.tray.native.linux-x64 --version 23.8.1                
#r "nuget: StirlingLabs.tray.native.linux-x64, 23.8.1"                
#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.
// Install StirlingLabs.tray.native.linux-x64 as a Cake Addin
#addin nuget:?package=StirlingLabs.tray.native.linux-x64&version=23.8.1

// Install StirlingLabs.tray.native.linux-x64 as a Cake Tool
#tool nuget:?package=StirlingLabs.tray.native.linux-x64&version=23.8.1                


System Tray / Menu Bar / Indicator Icon

Cross-platform, super tiny C99[^1] implementation of a system tray/menu bar icon with popup menu.

[^1]: At least, it's super tiny and C99 on Mac & Windows.

The optional primary-click callback can hide/show a window while secondary-click shows a menu.
If no callback is specified, either click will show the menu. The system can be dynamically updated; icon, tooltip, menu items and status (checked/unchecked & enabled/disabled) can all be both queried and changed at runtime.

Code is C++ friendly and will compile fine in C99 or C++98 and up on Windows or Mac but requires C++17 on Linux.

Focussed PRs are welcome, especially improvements to the Linux implementation. The goal is to keep the code as simple as possible, so functionality beyond presenting a tray icon and menu is out of scope.


Works well on:

  • Windows XP or newer (shellapi.h)
  • MacOS (Cocoa/AppKit)
  • Linux/Gtk (Qt6)

Gnome has decided to deprecate the tray icon as a concept, except for system indicators. They have not only deprecated the tray-handling code but removed it entirely. Extensive investigation has failed to produce a reliable way to display tray icons, even using low-level X11 calls. Qt has worked out a way to do it, so we are currently using their implementation on Linux, which unfortunately requires C++ and much larger dependencies. All of the Qt code is isolated in the library, so use of Qt is not required in application code (although it will use the application's QApplication instance, should one exist).

PRs that resolve this situation are very welcome!


The tray structure defines the tray and a nested menu of NULL-terminated array of entries. tray_menu_item defines each menu entry text, menu checked and disabled (grayed) flags.

The tray and tray_menu_item each have an optional callback if they are selected.

struct tray {
  const char *icon_filepath;
  char *tooltip;
  void (*cb)(struct tray *); // called on left click, leave null to just open menu
  struct tray_menu_item *menu; // NULL-terminated array of menu items

struct tray_menu_item {
  char *text;
  int disabled;
  int checked;
  void (*cb)(struct tray_menu_item *);
  struct tray_menu_item *submenu; // NULL-terminated array of submenu items
  • int tray_init(struct tray *) - creates tray icon. Returns -1 if tray icon/menu can't be created.
  • struct tray * tray_get_instance() - returns the tray instance.
  • void tray_update(struct tray *) - updates tray icon and menu.
  • int tray_loop(int blocking) - runs one iteration of the UI loop. Returns -1 if tray_exit() has been called.
  • void tray_exit() - terminates UI loop.

All functions are meant to be called from the UI thread only.

Menu arrays must be terminated with a NULL item, e.g. the last item in the array must have text field set to NULL.


Icons are platform-specific but generally should have transparent backgrounds and be simple (since they are tiny).

Tray does not provide any theming or icon management. It is up to the application to respond to theme changes and supply appropriate icons e.g. dark mode.

Platform Icon format
Windows .ICO with 16x16 & 32x32 sizes included
MacOS .PNG with a notional 22pt height or vector-based .PDF (recommend black or white images)
Linux .PNG 24x24 pixels


  • CMake
  • Ninja, in order to have the same build commands on all platforms
  • Qt6 on Linux: sudo apt install build-essential libgl1-mesa-dev qt6-base-dev


mkdir build
cd build
cmake -G Ninja ..


Build & execute the tray_example application:



MacOS screenshot

Windows screenshot

Linux screenshot


This fork is predominantly to make the functionality available as a library, for use from other languages.

It based on a previous fork by dmikushin that brings together the original work of Serge Zaitsev and "the most interesting forks and PRs of respectable contributors" including:

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

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
23.8.1 375 8/8/2023
23.8.0 308 8/8/2023