Tray
Create trays in the main process. Images may be absolute paths or bundled
views:// URLs.
import { Tray } from "electrobun/main";
const tray = new Tray({ title: "My app", image: "views://assets/tray-icon.png", template: true, width: 32, height: 32,});
const menuState: Record<string, boolean> = { notifications: true,};
function updateTrayMenu() { tray.setMenu([ { type: "normal", label: "Notifications", action: "notifications", checked: menuState.notifications, }, { type: "separator" }, { type: "normal", label: "Quit", action: "quit", }, ]);}
// Install the menu before listening for interaction. This is required for the// supported Linux AppIndicator interaction path and works on every platform.updateTrayMenu();
type TrayClickEvent = { data: { id: number; action: string; data?: unknown };};
tray.on("tray-clicked", (event: unknown) => { const { action } = (event as TrayClickEvent).data; if (action === "notifications") { menuState.notifications = !menuState.notifications; updateTrayMenu(); }});import { Tray } from "electrobun/main";
const tray = new Tray({ title: "My app", image: "views://assets/tray-icon.png", template: true, width: 32, height: 32,});
const menuState: Record<string, boolean> = { notifications: true,};
function updateTrayMenu() { tray.setMenu([ { type: "normal", label: "Notifications", action: "notifications", checked: menuState.notifications, }, { type: "separator" }, { type: "normal", label: "Quit", action: "quit", }, ]);}
// Install the menu before listening for interaction. This is required for the// supported Linux AppIndicator interaction path and works on every platform.updateTrayMenu();
type TrayClickEvent = { data: { id: number; action: string; data?: unknown };};
tray.on("tray-clicked", (event: unknown) => { const { action } = (event as TrayClickEvent).data; if (action === "notifications") { menuState.notifications = !menuState.notifications; updateTrayMenu(); }});const tray_id = try core.createTray(.{ .title = "My app", .image = "", // absolute path to an icon file, or empty for text-only .is_template = true, .width = 32, .height = 32,});
try core.setTrayTitle(tray_id, "Ready");const bounds = try core.getTrayBounds(tray_id);_ = bounds;try core.hideTray(tray_id);try core.showTray(tray_id);try core.removeTray(tray_id);let tray_id = core.create_tray(TrayOptions { title: "My app", image: "", // absolute path to an icon file, or empty for text-only is_template: true, width: 32, height: 32,})?;
core.set_tray_title(tray_id, "Ready")?;let bounds = core.get_tray_bounds(tray_id)?;core.hide_tray(tray_id)?;core.show_tray(tray_id)?;core.remove_tray(tray_id)?;trayID, err := core.CreateTray(electrobun.TrayOptions{ Title: "My app", Image: "", // absolute path to an icon file, or empty for text-only IsTemplate: true, Width: 32, Height: 32, Handler: func(id uint32, action string) { fmt.Printf("tray %d activated: %s\n", id, action) },})
err = core.SetTrayTitle(trayID, "Ready")bounds, err := core.GetTrayBounds(trayID)err = core.HideTray(trayID)err = core.ShowTray(trayID)err = core.RemoveTray(trayID)tray_options := electrobun.defaultTrayOptions("") // image path, or empty for text-onlytray_options.title = "My app"tray_options.is_template = truetray_options.width = 32tray_options.height = 32tray_id, tray_err := electrobun.createTray(core, tray_options)
_ = electrobun.setTrayTitle(core, tray_id, "Ready")bounds, bounds_err := electrobun.getTrayBounds(core, tray_id)_ = electrobun.hideTray(core, tray_id)_ = electrobun.showTray(core, tray_id)_ = electrobun.removeTray(core, tray_id)Constructor options
| Option | Type | Default | Purpose |
|---|---|---|---|
title | string | "" | Text shown by the tray backend. |
image | string | "" | views:// URL or absolute image path. |
template | boolean | true | Treat the image as a macOS template image. |
width | number | 16 | Requested image width. |
height | number | 16 | Requested image height. |
Methods and lookup
import { Tray } from "electrobun/main";
const tray = new Tray({ title: "Status", image: "views://assets/tray-icon.png",});
tray.setTitle("Ready");tray.setImage("views://assets/tray-ready.png");tray.setVisible(false);tray.setVisible(true);
const bounds = tray.getBounds();const sameTray = Tray.getById(tray.id);const allTrays = Tray.getAll();
void bounds;void sameTray;void allTrays;
tray.remove();Use Tray.removeById(id) instead when only a stored tray ID is available.
setMenu() replaces the current menu. Tray menu normal items require type: "normal" and label; they also support action, data, submenu, enabled,
checked, hidden, and tooltip.
Platform behavior
Ayatana AppIndicator backend supports tray menus and their actions but does not
expose raw primary icon activation. Linux apps should use setMenu() and handle
menu actions; do not wait for an icon-only click to install the menu. A backend
that exposes raw activation may emit
tray-clicked with an empty action; portable apps should use explicit menu
actions.