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

Finestre Multiple e Gestione Focus

Le applicazioni Electron possono avere più finestre aperte contemporaneamente, ognuna con il proprio Renderer Process. Gestire correttamente le finestre multiple è essenziale per applicazioni complesse.

Creare Finestre Multiple

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

let mainWindow;
let settingsWindow;

function createMainWindow() {
  mainWindow = new BrowserWindow({
    width: 1200,
    height: 800,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
    },
  });

  mainWindow.loadFile('index.html');

  mainWindow.on('closed', () => {
    mainWindow = null;
  });
}

function createSettingsWindow() {
  // Evita di aprire più finestre settings
  if (settingsWindow && !settingsWindow.isDestroyed()) {
    settingsWindow.focus();
    return;
  }

  settingsWindow = new BrowserWindow({
    width: 600,
    height: 400,
    parent: mainWindow,          // Finestra genitore
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
    },
  });

  settingsWindow.loadFile('settings.html');

  settingsWindow.on('closed', () => {
    settingsWindow = null;
  });
}

Pattern Singleton per Finestre

Per assicurarsi che una finestra venga creata una sola volta:

const windows = new Map();

function getOrCreateWindow(name, options, filePath) {
  // Se la finestra esiste già, portala in primo piano
  if (windows.has(name)) {
    const existingWindow = windows.get(name);
    if (!existingWindow.isDestroyed()) {
      existingWindow.focus();
      return existingWindow;
    }
  }

  // Crea una nuova finestra
  const win = new BrowserWindow({
    ...options,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      ...options.webPreferences,
    },
  });

  win.loadFile(filePath);

  win.on('closed', () => {
    windows.delete(name);
  });

  windows.set(name, win);
  return win;
}

// Uso
getOrCreateWindow('settings', { width: 600, height: 400 }, 'settings.html');
getOrCreateWindow('about', { width: 400, height: 300 }, 'about.html');

Finestre Figlie (Child Windows)

Una finestra figlia è legata alla finestra genitore: si muove con essa e viene chiusa quando il genitore viene chiuso.

function createChildWindow() {
  const child = new BrowserWindow({
    width: 500,
    height: 400,
    parent: mainWindow,    // Lega alla finestra principale
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
    },
  });

  child.loadFile('child.html');
  return child;
}

Gestione del Focus

// Portare una finestra in primo piano
win.focus();

// Verificare il focus
if (win.isFocused()) {
  console.log('La finestra ha il focus');
}

// Ascoltare eventi di focus
win.on('focus', () => {
  console.log('Focus acquisito');
  // Aggiorna il menu, la barra del titolo, etc.
});

win.on('blur', () => {
  console.log('Focus perso');
});

// Ottenere la finestra con il focus
const focused = BrowserWindow.getFocusedWindow();

Comunicazione tra Finestre

Le finestre comunicano tra loro passando dal Main Process:

// main.js
const { ipcMain, BrowserWindow } = require('electron');

// Broadcast a tutte le finestre
function broadcastToAll(channel, data) {
  BrowserWindow.getAllWindows().forEach((win) => {
    if (!win.isDestroyed()) {
      win.webContents.send(channel, data);
    }
  });
}

// La finestra settings invia un aggiornamento
ipcMain.on('settings:changed', (_event, settings) => {
  // Inoltra a tutte le altre finestre
  BrowserWindow.getAllWindows().forEach((win) => {
    if (win.webContents !== _event.sender && !win.isDestroyed()) {
      win.webContents.send('settings:updated', settings);
    }
  });
});

Chiudere Tutte le Finestre

// Chiudi tutte le finestre
BrowserWindow.getAllWindows().forEach((win) => {
  win.close();
});

// Oppure forza la chiusura
BrowserWindow.getAllWindows().forEach((win) => {
  win.destroy();
});

Ottenere la Lista delle Finestre

// Tutte le finestre aperte
const all = BrowserWindow.getAllWindows();
console.log(`${all.length} finestre aperte`);

// Iterare sulle finestre
all.forEach((win) => {
  console.log(`Finestra #${win.id}: ${win.getTitle()}`);
});

// Trovare una finestra per ID
const win = BrowserWindow.fromId(2);