Tray
Add an icon, tooltip, title, and context menu to the system status bar / notification area (main process).
Tray adds an icon to the system status bar (macOS menu bar) or notification area (Linux). In Bunmaska the native status item is created eagerly in the constructor and reconfigured through forwarding methods, and the class extends Node’s EventEmitter so the listener API (on/once/…) matches Electron’s contract.
Platform support is uneven and honest about it:
- macOS - fully wired to a real
NSStatusItem. Works un-bundled (bun main.ts). Icon, tooltip, title, context menu, and theclickevent all function. - Linux - a
StatusNotifierItemexported over D-Bus (KDE, the GNOME AppIndicator extension, Waybar, swaybar, etc. draw the icon). It is gated behind theBUNMASKA_ENABLE_LINUX_TRAY=1environment variable. With the gate off, or when no session bus is reachable, the tray is an inert no-op rather than a throw - so cross-platform code can construct aTraysafely everywhere. Even when live,setContextMenuis not yet shown on Linux (thecom.canonical.dbusmenuservice is deferred). - Windows - not supported (Bunmaska is macOS + Linux only). Constructing a
TraythrowsUnsupportedPlatformError.
import { app, Menu, Tray } from 'bunmaska';
let tray: Tray | null = null;
app.whenReady().then(() => {
tray = new Tray('/path/to/iconTemplate.png');
const contextMenu = Menu.buildFromTemplate([
{ label: 'Item1', type: 'radio' },
{ label: 'Item2', type: 'radio' },
]);
tray.setToolTip('This is my application.');
tray.setContextMenu(contextMenu);
});
Constructor
new Tray(image)
imagestring - a filesystem path to the icon file.
Creates a status item and shows the icon immediately. Unlike Electron, the image argument is a path string only - a NativeImage is not accepted, and there is no guid parameter. A bad or unreadable path does not crash; the icon is simply not set. On macOS, pass a Template Image (a filename ending in Template) so the menu bar can invert it for light/dark mode.
import { Tray } from 'bunmaska';
const tray = new Tray('/path/to/iconTemplate.png');
Methods
tray.setToolTip(toolTip)
toolTipstring
Sets the hover text for the tray icon. No-op after destroy().
tray.setToolTip('Syncing - 3 items left');
tray.setTitle(title) macOS
titlestring
Sets the text shown next to the icon in the macOS status bar. On Linux this maps to the SNI Title (when the live tray is enabled) and is otherwise a no-op. Note the simplified signature: Bunmaska does not accept Electron’s options.fontType argument. No-op after destroy().
tray.setTitle('42');
tray.setImage(image)
imagestring - a filesystem path to the new icon.
Replaces the icon. As with the constructor, this takes a path string, not a NativeImage. No-op after destroy().
tray.setImage('/path/to/active-iconTemplate.png');
tray.setContextMenu(menu)
menuMenu | null
Attaches a context menu (shown on click) or clears it with null. No-op after destroy().
On macOS this installs a real NSMenu and works as expected. On Linux this is accepted but currently a soft no-op - the menu is not shown, because the dbusmenu service is deferred. It never throws, so the same code runs on both platforms.
import { Menu } from 'bunmaska';
const menu = Menu.buildFromTemplate([
{ label: 'Open', click: () => openWindow() },
{ type: 'separator' },
{ label: 'Quit', role: 'quit' },
]);
tray.setContextMenu(menu);
tray.destroy()
Removes the status item. Idempotent - calling it more than once is safe, and every other method becomes a no-op afterward.
tray.destroy();
tray.isDestroyed()
Returns boolean - whether destroy() has been called.
if (!tray.isDestroyed()) {
tray.setToolTip('still here');
}
Events
Event: ‘click’
Emitted when the tray icon is activated. Unlike Electron, the listener receives no arguments - there is no event, bounds, or position payload.
Platform nuance: on macOS, when a context menu is set, AppKit consumes the click to present the menu, so click fires only when no menu is set. On Linux, the host’s Activate action drives click (and only when the live tray is enabled).
tray.on('click', () => {
console.log('tray activated');
});
Not in Bunmaska (yet)
Compared with Electron’s Tray, the following are not implemented:
guidconstructor parameter - no UUID-based icon identity / position persistence.NativeImagearguments - the constructor,setImage, etc. take a path string only.clickevent payload - Bunmaska’sclickcarries noevent/bounds/position. Electron’sboundsandpositiondata are unavailable.right-click/double-click/middle-clickevents - deferred until a real event source is wired.- All mouse and drag events -
mouse-up,mouse-down,mouse-enter,mouse-leave,mouse-move,drop,drop-files,drop-text,drag-enter,drag-leave,drag-endare not emitted. setPressedImage(image)(macOS) - no pressed-state icon.getTitle()- title is write-only; there is no getter.setIgnoreDoubleClickEvents()/getIgnoreDoubleClickEvents()- not implemented.popUpContextMenu()/closeContextMenu()- no programmatic menu pop-up/dismiss.getBounds()- the icon’s screen rectangle is not exposed.getGUID()- no GUID support, so nothing to return.- Linux context menus -
setContextMenuis accepted but the menu is not yet drawn on Linux (dbusmenu deferred). - All Windows members -
displayBalloon,removeBalloon,focus,balloon-*events, etc. Bunmaska has no Windows backend at all.