# Menus

Menus are reusable objects that can be attached to four different contexts: a **context menu** (right-click), a **tray menu**, a **dock menu** (macOS), or a **menu bar** (application menu on macOS, window menu bar on Windows/Linux).

The creation flow is the same for all four: you define a menu template (array of items) and pass it to the matching `create*` method. Each method returns a `menuId` you can use later to destroy, re-attach, or detach the menu.

{% hint style="info" %}
**Templates** can be defined inline (passed directly to a `create*` method) or stored once and reused via [templateId](#add-menu-template). Templates are useful when the same menu structure is used in multiple contexts.
{% endhint %}

{% hint style="warning" %}
**macOS specifics:** On macOS, the menu bar is a single application-wide menu, not per-window. Clipboard shortcuts (Cut/Copy/Paste/Select All) only work when the application menu is configured with those roles — consider always defining at least a minimal Edit submenu on macOS.
{% endhint %}

## Methods

### <mark style="color:purple;">Create Context Menu</mark>

Creates a context menu that shows up when the user right-clicks.

{% tabs %}
{% tab title="JavaScript" %}

```javascript
await window.deskifier.menus.createContext({ arguments })
```

**Arguments**

* `template` <mark style="color:green;">Array</mark>\
  Array of [<mark style="color:blue;">Electron.MenuItem</mark>](https://www.electronjs.org/docs/latest/api/menu-item) entries. Required unless `templateId` is provided.
* `templateId` <mark style="color:green;">String</mark>\
  ID of a previously-stored template (see [Add Menu Template](#add-menu-template)). Required unless `template` is provided.
* `id` <mark style="color:green;">String</mark>\
  The ID for this menu. If omitted, one will be generated.
* `selectors` <mark style="color:green;">Array Of Strings</mark>\
  An optional list of CSS selectors that control when the context menu is shown. When selectors are provided, the context menu will only appear when the user right-clicks on an element that matches one of the specified selectors. Default behavior is to show the context menu on any right-click target.

**Returns**

* `menuId` <mark style="color:green;">String</mark>\
  The ID of the new menu.
* `success` <mark style="color:green;">Boolean</mark>\
  If the action was successful.
* `message` <mark style="color:green;">String</mark>\
  Additional confirmation, or error details if action was unsuccessful.

**Example**

<pre class="language-javascript" data-overflow="wrap"><code class="lang-javascript">const template = [
    {
        label: "File",
        submenu: [
            { label: "New", accelerator: "CmdOrCtrl+N" },
            { label: "Open", accelerator: "CmdOrCtrl+O" },
            { type: "separator" },
            { role: "quit" }
        ]
    },
    {
        label: "View",
        submenu: [
            { role: "toggledevtools" },
            { role: "reload" },
            { type: "separator" },
            { role: "togglefullscreen" }
        ]
    },
    {
        label: "Settings",
        submenu: [
            { label: "Dark Mode", type: "checkbox", checked: false },
            { label: "Enable Notifications", type: "radio", checked: true }
        ]
    }
];


<strong>const menu = await window.deskifier.menus.createContext({
</strong><strong>    template,
</strong><strong>    selectors: ['#specificId', '.class1', '.class2']
</strong><strong>});
</strong>
console.log(menu.menuId)
// '7795d507-bf71-41d2-a505-16a0e48fe651'
</code></pre>

{% endtab %}
{% endtabs %}

***

### <mark style="color:purple;">Create Tray Menu</mark>

Creates a menu and attaches it to an existing tray icon.

{% tabs %}
{% tab title="JavaScript" %}

```javascript
await window.deskifier.menus.createTray({ arguments })
```

**Arguments**

* `template` <mark style="color:green;">Array</mark>\
  Array of [<mark style="color:blue;">Electron.MenuItem</mark>](https://www.electronjs.org/docs/latest/api/menu-item) entries. Required unless `templateId` is provided.
* `templateId` <mark style="color:green;">String</mark>\
  ID of a previously-stored template. Required unless `template` is provided.
* `trayId` <mark style="color:green;">String</mark> (Required)\
  The ID of the tray to attach the menu to.
* `id` <mark style="color:green;">String</mark>\
  The ID for this menu. If omitted, one will be generated.

**Returns**

* `menuId` <mark style="color:green;">String</mark>\
  The ID of the new menu.
* `success` <mark style="color:green;">Boolean</mark>\
  If the action was successful.
* `message` <mark style="color:green;">String</mark>\
  Additional confirmation, or error details if action was unsuccessful.
  {% endtab %}
  {% endtabs %}

***

### <mark style="color:purple;">Create Dock Menu</mark>

<mark style="color:purple;background-color:purple;">**macOS**</mark> Creates a dock menu. This appears when the user right-clicks the app's dock icon on macOS.

{% tabs %}
{% tab title="JavaScript" %}

```javascript
await window.deskifier.menus.createDock({ arguments })
```

**Arguments**

* `template` <mark style="color:green;">Array</mark>\
  Array of [<mark style="color:blue;">Electron.MenuItem</mark>](https://www.electronjs.org/docs/latest/api/menu-item) entries. Required unless `templateId` is provided.
* `templateId` <mark style="color:green;">String</mark>\
  ID of a previously-stored template. Required unless `template` is provided.
* `id` <mark style="color:green;">String</mark>\
  The ID for this menu. If omitted, one will be generated.

**Returns**

* `menuId` <mark style="color:green;">String</mark>\
  The ID of the new menu.
* `success` <mark style="color:green;">Boolean</mark>\
  If the action was successful.
* `message` <mark style="color:green;">String</mark>\
  Additional confirmation, or error details if action was unsuccessful.

**Example**

{% code overflow="wrap" %}

```javascript
await window.deskifier.menus.createDock({
    template: [
        { id: 'new-window', label: 'New Window' },
        { id: 'preferences', label: 'Preferences...' },
        { type: 'separator' },
        { role: 'quit' }
    ]
});
```

{% endcode %}
{% endtab %}
{% endtabs %}

### <mark style="color:purple;">Create Menubar Menu</mark>

Creates a menu for use in a menu bar or an application menu.

{% hint style="info" %}
Menu bars are per-window on **Windows** and **Linux**. On **macOS**, this sets the application menu — all windows share it, and the `windowId` argument is ignored.
{% endhint %}

{% tabs %}
{% tab title="JavaScript" %}

```javascript
await window.deskifier.menus.createMenubar({ arguments })
```

**Arguments**

* `template` <mark style="color:green;">Array</mark>\
  Array of [<mark style="color:blue;">Electron.MenuItem</mark>](https://www.electronjs.org/docs/latest/api/menu-item) entries. Required unless `templateId` is provided.
* `templateId` <mark style="color:green;">String</mark>\
  ID of a previously-stored template. Required unless `template` is provided.
* `windowId` <mark style="color:green;">String</mark>\
  The ID of the window the menu bar should be attached to. Defaults to the current window. Ignored on macOS — the application menu is set instead.
* `id` <mark style="color:green;">String</mark>\
  The ID for this menu. If omitted, one will be generated.

**Returns**

* `menuId` <mark style="color:green;">String</mark>\
  The ID of the new menu.
* `success` <mark style="color:green;">Boolean</mark>\
  If the action was successful.
* `message` <mark style="color:green;">String</mark>\
  Additional confirmation, or error details if action was unsuccessful.

**Example**

<pre class="language-javascript" data-overflow="wrap"><code class="lang-javascript">const template = [
    {
        label: "File",
        submenu: [
            { label: "New", accelerator: "CmdOrCtrl+N" },
            { label: "Open", accelerator: "CmdOrCtrl+O" },
            { type: "separator" },
            { role: "quit" }
        ]
    }
];


<strong>const menu = await window.deskifier.menus.createMenubar({
</strong><strong>    template
</strong><strong>});
</strong>
console.log(menu.menuId)
// '7795d507-bf71-41d2-a505-16a0e48fe651'

</code></pre>

{% endtab %}
{% endtabs %}

### <mark style="color:purple;">Destroy Menu</mark>

Destroys a menu. Automatically detaches it from any tray, dock, menu bar, or context it was attached to.

{% tabs %}
{% tab title="JavaScript" %}

```javascript
await window.deskifier.menus.destroy({ arguments })
```

**Arguments**

* `menuId` <mark style="color:green;">String</mark> (Required)

**Returns**

* `success` <mark style="color:green;">Boolean</mark>\
  If the action was successful.
* `message` <mark style="color:green;">String</mark>\
  Additional confirmation, or error details if action was unsuccessful.
  {% endtab %}
  {% endtabs %}

***

### <mark style="color:purple;">Attach Menu</mark>

Attaches an existing menu to a new context. Useful for swapping a menu's role at runtime — for example, turning a context menu into a tray menu, or re-attaching a menu bar to a different window.

{% tabs %}
{% tab title="JavaScript" %}

```javascript
await window.deskifier.menus.attach({ arguments })
```

**Arguments**

* `menuId` <mark style="color:green;">String</mark> (Required)\
  The menu to attach.
* `type` <mark style="color:green;">String</mark> (Required)\
  Target context type. Possible values:
  * `menuBar` — attach as the menu bar. On macOS this sets the application menu; otherwise attaches to `windowId` (or the sender window).
  * `contextMenu` — attach as a context (right-click) menu. Can be scoped with `selectors`.
  * `trayMenu` — attach to the tray specified by `trayId`.
  * `dockMenu` — attach as the macOS dock menu.
* `trayId` <mark style="color:green;">String</mark>\
  Required when `type` is `trayMenu`.
* `windowId` <mark style="color:green;">String</mark>\
  Used when `type` is `menuBar` on Windows/Linux. Defaults to the sender window.
* `selectors` <mark style="color:green;">Array Of Strings</mark>\
  Used when `type` is `contextMenu`. CSS selectors that gate when the menu appears.

**Returns**

* `success` <mark style="color:green;">Boolean</mark>\
  If the action was successful.
* `message` <mark style="color:green;">String</mark>\
  Additional confirmation, or error details if action was unsuccessful.
  {% endtab %}
  {% endtabs %}

***

### <mark style="color:purple;">Detach Menu</mark>

Detaches a menu from a context without destroying it. The menu can be re-attached later via [Attach Menu](#attach-menu).

{% tabs %}
{% tab title="JavaScript" %}

```javascript
await window.deskifier.menus.detach({ arguments })
```

**Arguments**

* `menuId` <mark style="color:green;">String</mark> (Required)
* `type` <mark style="color:green;">String</mark> (Required)\
  The context type to detach from. Possible values: `menuBar`, `contextMenu`, `trayMenu`, `dockMenu`.

**Returns**

* `success` <mark style="color:green;">Boolean</mark>\
  If the action was successful.
* `message` <mark style="color:green;">String</mark>\
  Additional confirmation, or error details if action was unsuccessful.
  {% endtab %}
  {% endtabs %}

***

### <mark style="color:purple;">Popup Menu</mark>

Programmatically opens a menu at a specified location. Fires the [Popup Menu Closed](#popup-menu-closed) event when dismissed.

{% tabs %}
{% tab title="JavaScript" %}

```javascript
await window.deskifier.menus.popup({ arguments })
```

**Arguments**

* `menuId` <mark style="color:green;">String</mark> (Required)
* `windowId` <mark style="color:green;">String</mark>\
  Optional. Defaults to the sender window.
* `x` <mark style="color:green;">Number</mark>\
  Optional. Default is current mouse cursor position. Required if `y` is declared.
* `y` <mark style="color:green;">Number</mark>\
  Optional. Default is current mouse cursor position. Required if `x` is declared.

**Returns**

* `success` <mark style="color:green;">Boolean</mark>\
  If the action was successful.
  {% endtab %}
  {% endtabs %}

***

### <mark style="color:purple;">Add Menu Template</mark>

Stores a menu template for reuse. Once added, any `create*` method can reference it by `templateId` instead of inlining the template.

{% tabs %}
{% tab title="JavaScript" %}

```javascript
await window.deskifier.menus.addTemplate({ arguments })
```

**Arguments**

* `id` <mark style="color:green;">String</mark> (Required)\
  The ID to store this template under.
* `template` <mark style="color:green;">Array</mark> (Required)\
  Array of [<mark style="color:blue;">Electron.MenuItem</mark>](https://www.electronjs.org/docs/latest/api/menu-item) entries.
* `name` <mark style="color:green;">String</mark>\
  Optional human-readable name shown in [Get Available Menu Templates](#get-available-menu-templates).
* `menuType` <mark style="color:green;">String</mark>\
  Optional hint about which context this template is intended for. Possible values: `menuBar`, `contextMenu`, `trayMenu`, `dockMenu`. Purely informational.

**Returns**

* `success` <mark style="color:green;">Boolean</mark>\
  If the action was successful.
* `message` <mark style="color:green;">String</mark>\
  Additional confirmation, or error details if action was unsuccessful.
  {% endtab %}
  {% endtabs %}

***

### <mark style="color:purple;">Delete Menu Template</mark>

Removes a stored template. Does not affect menus already created from it.

{% tabs %}
{% tab title="JavaScript" %}

```javascript
await window.deskifier.menus.deleteTemplate({ arguments })
```

**Arguments**

* `id` <mark style="color:green;">String</mark> (Required)

**Returns**

* `success` <mark style="color:green;">Boolean</mark>\
  If the action was successful.
* `message` <mark style="color:green;">String</mark>\
  Additional confirmation, or error details if action was unsuccessful.
  {% endtab %}
  {% endtabs %}

***

## Properties

### <mark style="color:purple;">Get Menus</mark>

Returns details about all active menus.

{% tabs %}
{% tab title="JavaScript" %}

```javascript
await window.deskifier.menus.getAll()
```

**Returns**

* `menus` <mark style="color:green;">Array of Objects</mark>
  * `id` <mark style="color:green;">String</mark>\
    ID of the menu.
  * `menuType` <mark style="color:green;">String</mark>\
    Possible values: `menuBar`, `trayMenu`, `contextMenu`, `dockMenu`, or `null` if the menu has been created but not yet attached.
  * `items` Array of [<mark style="color:blue;">Electron.MenuItem</mark>](https://www.electronjs.org/docs/latest/api/menu-item)
    * `checked` <mark style="color:green;">Boolean</mark>\
      If the type is a checkbox or radio button this will indicate the value.
    * `enabled` <mark style="color:green;">Boolean</mark>
    * `id` <mark style="color:green;">String</mark>\
      ID of the Menu Item.
    * `label` <mark style="color:green;">String</mark>\
      Label of the Menu Item.
    * `submenu` Array of [<mark style="color:blue;">Electron.MenuItem</mark>](https://www.electronjs.org/docs/latest/api/menu-item)
    * `type` <mark style="color:green;">String</mark>\
      Possible values: `normal`, `separator`, `submenu`, `checkbox`, `radio`.
  * `trayId` <mark style="color:green;">String</mark>\
    The tray ID if the `menuType` is `trayMenu`. Otherwise `null`.
  * `selectors` <mark style="color:green;">Array Of Strings</mark>\
    CSS selectors that gate when a `contextMenu` is shown. Empty means match any right-click target.
  * `windowId` <mark style="color:green;">String</mark>\
    The window a menu bar is attached to. Empty on macOS since menu bars are app-wide.
* `success` <mark style="color:green;">Boolean</mark>\
  If the action was successful.
* `message` <mark style="color:green;">String</mark>\
  Additional confirmation, or error details if action was unsuccessful.

**Example**

```javascript
const menus = await window.deskifier.menus.getAll();

console.log(menus.menus)

/*
[
{
    "id": "056dc6eb-c0d1-4b7d-91b4-7041a82f3a5e",
    "menuType": "trayMenu",
    "items": [{
        checked: false,
        enabled: true,
        id: "id-i6naztjkh",
        label: "File",
        submenu: [],
        type: "normal"
    }],
    "trayId": "dca8a7f9-fcfc-4284-9353-c567491adb11",
    "windowId": null,
    "selectors": []
}
]
*/
```

{% endtab %}
{% endtabs %}

***

### <mark style="color:purple;">Get Available Menu Templates</mark>

Returns all menu templates previously stored via [Add Menu Template](#add-menu-template).

{% tabs %}
{% tab title="JavaScript" %}

```javascript
await window.deskifier.menus.getAvailableTemplates()
```

**Returns**

* `templates` <mark style="color:green;">Array of Objects</mark>\
  Each object represents a stored template with its `id`, optional `name`, optional `menuType`, and the template structure itself.
* `success` <mark style="color:green;">Boolean</mark>\
  If the action was successful.
* `message` <mark style="color:green;">String</mark>\
  Additional confirmation, or error details if action was unsuccessful.
  {% endtab %}
  {% endtabs %}

***

## Events

### <mark style="color:purple;">Menu Item Clicked</mark>

Fires when a menu item is clicked. Also fires for checkbox/radio state changes.

{% tabs %}
{% tab title="JavaScript" %}

```javascript
window.deskifier.menus.onItemClicked((data) => {})
```

**Arguments**

* `menuId` <mark style="color:green;">String</mark>\
  The menu ID.
* `itemId` <mark style="color:green;">String</mark>\
  The menu item ID.
* `contextId` <mark style="color:green;">String</mark>\
  The parent context ID (e.g., if the click came from a tray menu, this is the `trayId`). May be undefined.
* `label` <mark style="color:green;">String</mark>\
  The menu item label.
* `checked` <mark style="color:green;">Boolean</mark>\
  If the menu item is a checkbox or radio button, this is its state.

**Example**

```javascript
window.deskifier.menus.onItemClicked((data) => {
    console.log(data);
});

/*
{
    "menuId": "490b59d9-27c1-410d-99be-e4ed39ab6c32",
    "itemId": "exampleMenuItem",
    "contextId": "ed4b2aec-6a06-4589-9734-ee8ce3a06a86",
    "label": "New",
    "checked": false
}
*/
```

{% endtab %}
{% endtabs %}

***

### <mark style="color:purple;">Context Menu Opened</mark>

Fires when a custom context menu opens in response to a right-click.

{% tabs %}
{% tab title="JavaScript" %}

```javascript
window.deskifier.menus.onContextMenuOpened((data) => {})
```

**Arguments**

* `menuId` <mark style="color:green;">String</mark>\
  The menu ID. `null` for native/built-in context menus that aren't tied to a custom menu.
  {% endtab %}
  {% endtabs %}

***

### <mark style="color:purple;">Context Menu Closed</mark>

Fires when a context menu is dismissed.

{% tabs %}
{% tab title="JavaScript" %}

```javascript
window.deskifier.menus.onContextMenuClosed((data) => {})
```

**Arguments**

* `menuId` <mark style="color:green;">String</mark>\
  The menu ID. `null` for native/built-in context menus.
  {% endtab %}
  {% endtabs %}

***

### <mark style="color:purple;">Popup Menu Closed</mark>

Fires when a menu opened via [Popup Menu](#popup-menu) is dismissed.

{% tabs %}
{% tab title="JavaScript" %}

```javascript
window.deskifier.menus.onPopupClosed((data) => {})
```

**Arguments**

* `menuId` <mark style="color:green;">String</mark>\
  The menu ID.
  {% endtab %}
  {% endtabs %}

***

### <mark style="color:purple;">Menu Object Updated</mark>

Fires whenever the set of menus changes — a menu is created, destroyed, attached, or detached. Useful for keeping a list of known menus in sync without polling.

{% tabs %}
{% tab title="JavaScript" %}

```javascript
window.deskifier.menus.onObjectUpdated((data) => {})
```

**Arguments**

* `menus` <mark style="color:green;">Array of Objects</mark>\
  The full current menu list, same shape as [Get Menus](#get-menus).
  {% endtab %}
  {% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://deskifier.gitbook.io/deskifier/menus.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
