Diese Änderung stellt sicher, dass alle relevanten Windows API-Aufrufe und Datenstrukturen die Wide-Character (W-) Versionen verwenden. Dies gewährleistet eine konsistente und robuste Behandlung von Unicode-Zeichen, insbesondere nach der Einführung der UTF-8-Unterstützung für Menütexte und Tooltips. Zusätzlich wird die erzwungene statische Verlinkung der C-Laufzeitbibliothek (`/MT`) entfernt, um die Kompatibilität zu verbessern und die Binärgröße zu reduzieren, indem die standardmäßige dynamische Verlinkung ermöglicht wird.
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 repository started as a fork of the original work by Serge Zaitsev, but it is now maintained as a separate continuation. It keeps the small public C API and cross-platform focus, while carrying its own fixes and behavior changes.
Compared to the original upstream, this fork already includes and continues work around:
- improved Windows message handling
- C++-friendly headers and usage
- tooltip support
- checkbox/menu state fixes
- Darwin/AppKit support adapted from the @trevex fork
- support for left-click callbacks
- Windows UTF-8 tray text handling
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;
void *icon_handle;
int icon_is_shared;
void (*left_click_cb)(void *context);
void *left_click_context;
};
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.left_click_cbandleft_click_contextare optional.icon_handleandicon_is_sharedare backend-specific fields used internally by the Windows implementation and should usually be left untouched by callers.- 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.