2.8 KiB
Cross-platform Linux/Windows/MacOS Tray
Cross-platform, super tiny C99 implementation of a system tray icon with a popup menu.
Works well on:
- Linux/Gtk (libappindicator)
- Windows XP or newer (shellapi.h)
- MacOS (Cocoa/AppKit)
The code is C++ friendly and will compile fine in C++98 and up.
This fork is intended to bring together the original work of Serge Zaitsev and the most interesting forks and PRs of respectable contributors:
- Only process messages coming from the tray window on Windows
- Become C++-friendly
- Fix all menu items have a check box
- Add support for tooltip
- Darwin implementation translated from C to Objective C adapted from @trevex fork
Prerequisites
- CMake
- Ninja, in order to have the same build commands on all platforms
- AppIndicator on Linux:
sudo apt install libappindicator3-dev
Building
mkdir build
cd build
cmake -G Ninja ..
ninja
Demo
Execute the tray_example application:
./tray_example
API
A tray is defined by an icon, an optional tooltip and a menu. The menu is a NULL-terminated array of items. Each menu item can be disabled, checked, represented as a checkbox and invoke a callback with an optional context pointer.
struct tray {
const char *icon;
char *tooltip;
struct tray_menu *menu;
};
struct tray_menu {
const char *text;
int disabled;
int checked;
int checkbox;
void (*cb)(struct tray_menu *);
void *context;
struct tray_menu *submenu;
};
int tray_init(struct tray *)- creates the tray icon and its menu. Returns-1if the tray icon or menu cannot be created.void tray_update(struct tray *)- updates the tray icon, tooltip and menu state.int tray_loop(int blocking)- runs one iteration of the UI loop. Returns-1aftertray_exit()has been called.void tray_exit(void)- terminates the UI loop and cleans up tray resources.
All functions are meant to be called from the UI thread only.
Menu arrays must be terminated with a NULL item, i.e. the last item in the
array must have text == NULL.
Notes
tooltipis optional.- A separator is created by using
text = "-". - Some behavior may depend on the underlying backend or desktop environment. Keep the public API generic and treat platform-specific interaction details as backend-specific implementation behavior.
License
This software is distributed under MIT license, so feel free to integrate it in your commercial products.