Cross-platform, super tiny C99 implementation of a system tray icon with a popup menu and notifications.
The code is C++ friendly and will compile fine in C++98 and up. This is a fork of dmikushin/tray and is intended to add additional features required for our own Sunshine project.
This fork adds the following features:
- system tray notifications
- support for both linux appindicator versions
- unit tests
- code coverage
- refactored code, e.g. moved source code into the
src
directory - doxygen documentation, and readthedocs configuration
- Linux/Gtk (libayatana-appindicator3 or libappindicator3)
- Windows XP or newer (shellapi.h)
- MacOS (Cocoa/AppKit)
- CMake
- Ninja, in order to have the same build commands on all platforms
-
Arch
sudo pacman -S libayatana-appindicator
-
Debian/Ubuntu
sudo apt install libappindicator3-dev
-
Fedora
sudo dnf install libappindicator-gtk3-devel
mkdir -p build
cmake -G Ninja -B build -S .
ninja -C build
Execute the tray_example
application:
./build/tray_example
Execute the tests
application:
./build/tests/test_tray
Tray structure defines an icon and a menu. Menu is a NULL-terminated array of items. Menu item defines menu text, menu checked and disabled (grayed) flags and a callback with some optional context pointer.
struct tray {
char *icon;
struct tray_menu *menu;
};
struct tray_menu {
char *text;
int disabled;
int checked;
void (*cb)(struct tray_menu *);
void *context;
struct tray_menu *submenu;
};
int tray_init(struct tray *)
- creates tray icon. Returns -1 if tray icon/menu can't be created.void tray_update(struct tray *)
- updates tray icon and menu.int tray_loop(int blocking)
- runs one iteration of the UI loop. Returns -1 iftray_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.
This software is distributed under MIT license, so feel free to integrate it in your commercial products.