Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

tray

StatusNotifierItem: registered tray items with artwork, status and menus.

list {
    direction = "Horizontal",
    spacing = 4,
    source = mantle.tray:map(function(tray)
        return tray and tray.items or {}
    end),
    key = function(item) return item.id end,
    itemfn = function(item)
        return button {
            on_click = function(_, which)
                if which == "left" and not item.item_is_menu then
                    mantle.tray:activate(item.id, 0, 0) -- screen x, y; most apps ignore them
                end
            end,
            children = { icon { name = item.icon_name or item.icon_path or "", size = 16 } },
        }
    end,
}

State

mantle.tray:get() returns TrayState, nil before the first push. A field marked ? may be absent.

FieldTypeDescription
itemsTrayItem[]Registered items in registration order, oldest first; updates never reorder them.

One tray.items[].menu entry.

FieldTypeDescription
childrenMenuItem[]Submenu entries, empty for a leaf. An app that fills submenus lazily sends them only after menu_will_show.
enabledbooleanfalse for a greyed-out entry; draw it, but clicking does nothing.
icon_name?stringTheme icon name, or nil. Icon pixmaps are not carried.
idintegerDBusMenu id, the second argument of activate_menu_item and menu_will_show.
label?stringEntry text as sent, or nil. _ mnemonic markers remain ("_Quit"); strip them to draw.
menu_typestring"standard" (the default) or "separator", as the application sent it.
toggle_state?integer0 off, 1 on, -1 indeterminate or unreported; nil exactly when toggle_type is.
toggle_type?string"checkmark", "radio", or nil for an entry that is not a toggle.

TrayItem

FieldTypeDescription
attention_icon_name?stringArtwork to draw while status == "NeedsAttention", paired with attention_icon_path like the base icon; both nil when unset.
attention_icon_path?stringFile half of the attention artwork.
icon_name?stringTheme icon name for icon { name = ... }. At most one of it and icon_path is set.
icon_path?stringIcon file for image { source = ... }: one from the item’s IconThemePath, or its pixmap spooled to a PNG.
idstringItem identity for every tray action, e.g. "1.234/StatusNotifierItem". Opaque.
item_is_menubooleanLeft click should open menu instead of activate.
menu?MenuItem[]Top-level menu entries, or nil when the item exports no DBusMenu or its first fetch failed.
namestringSNI Title, or its Id when the title is empty.
overlay_icon_name?stringBadge to draw over the icon’s corner, paired with overlay_icon_path; both nil when unset.
overlay_icon_path?stringFile half of the badge.
statusstring"Active", "Passive" (the item asks to be hidden) or "NeedsAttention", as the item sent it.
tooltip?stringTooltip title and text joined by a newline, or nil when both are empty.

Actions

Call each as mantle.tray:<action>(arguments...); ? marks an argument you may omit.

ActionArgumentsDescription
activateid: string, x: integer, y: integerLeft-click activation at screen coordinates x, y; a no-op when item_is_menu.
secondary_activateid: string, x: integer, y: integerMiddle-click activation at screen coordinates x, y.
scrollid: string, delta: integer, orientation: stringScrolls the icon by delta; orientation is "vertical" or "horizontal", passed verbatim.
activate_menu_itemid: string, menu_item_id: integerClicks the item’s MenuItem.id.
menu_will_showid: string, submenu_id: integerTells the application submenu submenu_id is opening, then refetches the menu unless it answers that nothing changed.

Backend

Mantle hosts org.kde.StatusNotifierWatcher at /StatusNotifierWatcher on the session bus and registers itself as a host.

ContractBehavior
NameRequested without DoNotQueue: if another watcher owns it, Mantle queues behind it
AdoptionAt start, adopts items already on the bus at /StatusNotifierItem, /StatusNotifierItem/1 or /org/chromium/StatusNotifierItem/1, for apps that never re-register
RemovalAn item leaves, and its spooled PNGs are deleted, when its bus name loses its owner
IconIconName found in the item’s IconThemePath, then IconName as a theme name, then the largest valid pixmap: square, 1 to 128 px, exactly w × h × 4 ARGB bytes, spooled as a PNG under tray/
BoundsStrings 256 bytes; menus 1024 nodes, depth 32
Menuscom.canonical.dbusmenu. menu_will_show sends AboutToShow, activate_menu_item sends Event("clicked")

Gotchas

TrapFix
activate does nothing on some itemsThe item set item_is_menu, and Mantle skips Activate for it. Open menu on left click
A submenu is emptySome apps fill submenus only after AboutToShow. Send menu_will_show with the submenu’s id before drawing it

See also: System tray with menu recipe.

Source: supervisor/src/capabilities/tray/