Files
xiaohei 428644e286
Revalidate Docs / Revalidate Docs (push) Failing after 2s
E2E CI / Check Duplicate Run (push) Failing after 5s
Test CI / Check Duplicate Run (push) Failing after 6s
E2E CI / Test Web App (push) Has been skipped
Test CI / Test Packages (push) Has been skipped
Test CI / Test App (shard 1/3) (push) Has been skipped
Test CI / Test App (shard 2/3) (push) Has been skipped
Test CI / Test App (shard 3/3) (push) Has been skipped
Test CI / Test Desktop App (push) Has been skipped
🔄 Branch Synchronization / sync-branches (push) Failing after 11s
Test CI / Test Database (push) Has been skipped
Test CI / Merge and Upload App Coverage (push) Has been skipped
Database Schema Visualization CI / build (push) Failing after 4m14s
Enterprise AI Workspace prototype: LobeChat (de-branded) + Enterprise Gateway + Postgres/Redis stack
2026-04-21 12:58:00 +08:00

2.3 KiB

Desktop Menu Configuration Guide

Menu Types

  1. App Menu: Top of window (macOS) or title bar (Windows/Linux)
  2. Context Menu: Right-click menus
  3. Tray Menu: System tray icon menus

File Structure

apps/desktop/src/main/
├── menus/
│   ├── appMenu.ts        # App menu config
│   ├── contextMenu.ts    # Context menu config
│   └── factory.ts        # Menu factory functions
├── controllers/
│   ├── MenuCtr.ts        # Menu controller
│   └── TrayMenuCtr.ts    # Tray menu controller

App Menu Configuration

// apps/desktop/src/main/menus/appMenu.ts
import { BrowserWindow, Menu, MenuItemConstructorOptions } from 'electron';

export const createAppMenu = (win: BrowserWindow) => {
  const template: MenuItemConstructorOptions[] = [
    {
      label: 'File',
      submenu: [
        {
          label: 'New',
          accelerator: 'CmdOrCtrl+N',
          click: () => {
            /* ... */
          },
        },
        { type: 'separator' },
        { role: 'quit' },
      ],
    },
    // ...
  ];

  return Menu.buildFromTemplate(template);
};

// Register in MenuCtr.ts
Menu.setApplicationMenu(menu);

Context Menu

export const createContextMenu = () => {
  const template = [
    { label: 'Copy', role: 'copy' },
    { label: 'Paste', role: 'paste' },
  ];
  return Menu.buildFromTemplate(template);
};

// Show on right-click
const menu = createContextMenu();
menu.popup();

Tray Menu

// TrayMenuCtr.ts
this.tray = new Tray(trayIconPath);
const contextMenu = Menu.buildFromTemplate([
  { label: 'Show Window', click: this.showMainWindow },
  { type: 'separator' },
  { label: 'Quit', click: () => app.quit() },
]);
this.tray.setContextMenu(contextMenu);

i18n Support

import { i18n } from '../locales';

const template = [
  {
    label: i18n.t('menu.file'),
    submenu: [{ label: i18n.t('menu.new'), click: createNew }],
  },
];

Best Practices

  1. Use standard roles (role: 'copy') for native behavior
  2. Use CmdOrCtrl for cross-platform shortcuts
  3. Use { type: 'separator' } to group related items
  4. Handle platform differences with process.platform
if (process.platform === 'darwin') {
  template.unshift({ role: 'appMenu' });
}