Yadciel fc77dda643 Migriere Windows Tray zu expliziten Wide-Character APIs
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.
2026-05-08 15:29:24 +02:00
2021-11-09 18:07:33 +01:00
2021-11-09 12:57:56 +01:00
2017-01-09 16:40:06 +02:00

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 -1 if 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 -1 after tray_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

  • tooltip is optional.
  • left_click_cb and left_click_context are optional.
  • icon_handle and icon_is_shared are 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.

Description
Cross-platform, super tiny C99 implementation of a system tray icon with a popup menu.
Readme MIT 1.1 MiB
Languages
C 71.3%
Objective-C 16.2%
CMake 12.5%