00
:
00
:
00
:
00
Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

System Tray

Il System Tray (area di notifica) è la zona accanto all’orologio nella barra delle applicazioni. Electron permette di aggiungere un’icona con menu e interazioni personalizzate.

Creare un’Icona nella Tray

const { app, Tray, Menu, nativeImage, BrowserWindow } = require('electron');
const path = require('node:path');

let tray = null;
let mainWindow = null;

app.whenReady().then(() => {
  mainWindow = createWindow();

  // Crea l'icona nella tray
  const icon = nativeImage.createFromPath(
    path.join(__dirname, 'assets', 'tray-icon.png')
  );

  tray = new Tray(icon);
  tray.setToolTip('La Mia App');

  // Menu della tray
  const contextMenu = Menu.buildFromTemplate([
    {
      label: 'Mostra App',
      click: () => {
        mainWindow.show();
        mainWindow.focus();
      },
    },
    {
      label: 'Nascondi App',
      click: () => {
        mainWindow.hide();
      },
    },
    { type: 'separator' },
    {
      label: 'Esci',
      click: () => {
        app.quit();
      },
    },
  ]);

  tray.setContextMenu(contextMenu);
});

Icone per la Tray

Le icone della tray devono essere piccole e adatte alla piattaforma:

  • Windows: .ico o .png (16x16 o 32x32)
  • macOS: .png (16x16, template image consigliata)
  • Linux: .png (qualsiasi dimensione, consigliata 22x22)

Template Image (macOS)

Su macOS, le template images si adattano automaticamente al tema chiaro/scuro:

const icon = nativeImage.createFromPath(
  path.join(__dirname, 'assets', 'trayTemplate.png')
);
// Il nome deve finire con "Template" per il riconoscimento automatico

// Oppure imposta manualmente
icon.setTemplateImage(true);

tray = new Tray(icon);

Icona per Piattaforma

function getTrayIcon() {
  const iconName = process.platform === 'win32'
    ? 'tray-icon.ico'
    : process.platform === 'darwin'
    ? 'trayTemplate.png'
    : 'tray-icon.png';

  return path.join(__dirname, 'assets', iconName);
}

tray = new Tray(getTrayIcon());

Eventi della Tray

// Click sull'icona
tray.on('click', () => {
  if (mainWindow.isVisible()) {
    mainWindow.hide();
  } else {
    mainWindow.show();
    mainWindow.focus();
  }
});

// Doppio click
tray.on('double-click', () => {
  mainWindow.show();
  mainWindow.focus();
});

// Click destro (prima che il menu appaia)
tray.on('right-click', () => {
  console.log('Right click sulla tray');
});

Minimizzare nella Tray

Un pattern comune è minimizzare l’app nella tray invece di chiuderla:

let isQuitting = false;

app.on('before-quit', () => {
  isQuitting = true;
});

mainWindow.on('close', (event) => {
  if (!isQuitting) {
    event.preventDefault();
    mainWindow.hide();

    // Mostra un balloon/notifica la prima volta
    if (tray && !hasShownTrayNotice) {
      tray.displayBalloon({
        title: 'App ancora attiva',
        content: 'L\'applicazione continua a funzionare nella tray.',
      });
      hasShownTrayNotice = true;
    }
  }
});

Aggiornare la Tray Dinamicamente

// Cambiare l'icona
function updateTrayIcon(status) {
  const iconPath = path.join(__dirname, 'assets', `tray-${status}.png`);
  tray.setImage(iconPath);
}

updateTrayIcon('active');    // tray-active.png
updateTrayIcon('idle');      // tray-idle.png
updateTrayIcon('error');     // tray-error.png

// Cambiare il tooltip
tray.setToolTip('La Mia App - 3 notifiche');

// Aggiornare il menu
function updateTrayMenu(notifications) {
  const menu = Menu.buildFromTemplate([
    {
      label: `Notifiche (${notifications.length})`,
      submenu: notifications.map((n) => ({
        label: n.title,
        click: () => showNotification(n),
      })),
    },
    { type: 'separator' },
    { label: 'Esci', click: () => app.quit() },
  ]);

  tray.setContextMenu(menu);
}

Balloon (Windows)

Su Windows puoi mostrare notifiche balloon dalla tray:

tray.displayBalloon({
  iconType: 'info',        // 'none', 'info', 'warning', 'error'
  title: 'Aggiornamento disponibile',
  content: 'Una nuova versione è pronta per il download.',
  largeIcon: true,
  noSound: false,
  respectQuietTime: true,
});

tray.on('balloon-click', () => {
  // L'utente ha cliccato sul balloon
  mainWindow.show();
});

tray.on('balloon-closed', () => {
  // Il balloon è stato chiuso (timeout o dismissione)
});

Distruggere la Tray

// Rimuovi l'icona dalla tray
tray.destroy();
tray = null;

// Verifica se la tray è stata distrutta
if (tray && !tray.isDestroyed()) {
  // La tray è ancora attiva
}

Best Practice

  1. Mantieni la tray leggera — non aggiungere troppi menu item
  2. Usa template images su macOS — si adattano al tema del sistema
  3. Avvisa l’utente quando minimizzi nella tray (almeno la prima volta)
  4. Aggiorna l’icona per riflettere lo stato dell’app
  5. Distruggi la tray quando l’app viene chiusa per evitare icone fantasma