'Electron - Catch when window is closed using the "x" button

The setup

Looking at the BrowserWindow Events Docs, the close event is...

Emitted when the window is going to be closed

and the closed event is...

Emitted when the window is closed.

The problem

Both events are triggered when I close the window manually (i.e. clicking the "x" in the menu bar), as well as when I programmatically close the window (i.e. window.close());

This window requires different handling, depending on whether I am closing the window programmatically, or manually closing it (quit the app entirely if using the "x", or do some stuffs otherwise).

So, how do I...

How can I differentiate between the two?



Solution 1:[1]

As the documentation states, you cannot make difference between window.close() and clicking on X

win.close() Try to close the window. This has the same effect as a user manually clicking the close button of the window.

However, you can use window.destroy(), which generates slightly different events

win.destroy() Force closing the window, the unload and beforeunload event won't be emitted for the web page, and close event will also not be emitted for this window, but it guarantees the closed event will be emitted.

A simple example to exploit this difference would be something like the following:

const { app, BrowserWindow } = require('electron')

app.once('ready', () => {
  let win = new BrowserWindow()
  let isRegularClose = false
  setTimeout(() => {
    if (win) win.destroy()
  }, 5000)
  win.on('close', (event) => {
    isRegularClose = true
  })
  win.on('closed', (event) => {
    console.log(isRegularClose
      ? 'win closed (X)'
      : 'win destroyed (code)')
    win = null
  })
})

Solution 2:[2]

IPC is the solution for you answer.

const {app, BrowserWindow, Menu, ipcMain} = electron;

let mainApp;

app.on('ready', () => {
  mainApp = new BrowserWindow({ frame: false });
  mainApp.loadURL(url.format({
    pathname: path.join(__dirname, 'public/mainApp2.html'),
    protocol: 'file:',
    slashes: true
  }));
  mainApp.on('closed', () => {
    app.quit();
  });
});

ipcMain.on('command:close', (event, arg) => {
  app.quit();
});

And on click

const {ipcRenderer} = require('electron');
let $ = require("jquery");



// Click Events
$("#action-close").click(() => {
    ipcRenderer.send("command:close");
});

Solution 3:[3]

okay so:

  1. win.destroy() is equal to the X system native application close button according to the docs and it will always make sure the closed event is fired and close event is NOT
  2. when clicking the X system native application close button you will have the close event fired first then the closed event comes after.
  3. close event comes before the beforeunload and unload DOM events

TIPS:

  1. as per dosc use the closed event to get rid of the BrowserWindow instance (your main window or any window created using new BrowserWindow()). this is etter than garbage collection. see this here

5. I used the closed event to shutdown a local database server before quiting the app. So you can use it to accomplish similar step, like this:

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 pergy
Solution 2 Mohd Asim Suhail
Solution 3 lys