How to catch the event of clicking the app window's close button in Electron app?


#1

I wish to catch the event of clicking the app window’s close button in Electron app.

I’m trying to develope Electron app for Mac OSX.
I want to hide the app window, not to terminate the app when a user clicks the window’s close button like other Mac apps.

However, I can not detect wether the system should be terminated or it should be hidden, because in any case, a close event of browser-window is called when a close button is clicked, and when the OS is shut down or the app is terminated with quit command, Cmd+Q.

To detect the event of clicking a close button, I tried this code

var app = require('app');
var BrowserWindow = require('browser-window');
var Menu = require('menu');

var force_quit = false;

var menu = Menu.buildFromTemplate([
  {
    label: 'Sample',
    submenu: [
      {label: 'About App', selector: 'orderFrontStandardAboutPanel:'},
      {label: 'Quit', accelerator: 'CmdOrCtrl+Q', click: function() {force_quit=true; app.quit();}}
    ]
  }]);

app.on('window-all-closed', function(){
    if(process.platform != 'darwin')
        app.quit();
});

app.on('ready', function(){

    Menu.setApplicationMenu(menu);

    mainWindow = new BrowserWindow({width:800, height:600});

    mainWindow.on('close', function(e){
        if(!force_quit){
            e.preventDefault();
            mainWindow.hide();
        }
    });

    mainWindow.on('closed', function(){
        console.log("closed");
        mainWindow = null;
        app.quit();
    });

    app.on('activate-with-no-open-windows', function(){
        mainWindow.show();
    });
});

With this code, the app is hidden when a close button of the app window is clicked, and the app is terminated when Cmd+Q is typed. However, when I try to shut down the OS, the shutdown event is prevented.

Is there any way to catch the event of clicking the app window’s close button in Electron app?

Thank you for your help.


How to use the 'Before Quit' event on App
#2

What about using the beforeunload event?

window.onbeforeunload = function (e) { return false }

#3

Thank you for your reply!
I tried your advice, and I found the app works well, Thank you.


#4

I am having the exact same issue, and I don’t see how this solves the issue. Can you explain to me how this solves it? @john @yukib

Is it that you are simply catching the close with the onbeforeunload, so the OS is free to fire the close event when it wants to?


#5

@yukib @john

I have the same question as @aaronfrost. How does overriding help fix this?

Basically what I want:

  1. Hide Window when user hits the X button on Mac.
  2. Close the app entirely if the user taps CMD+Q, uses the menu to exit.
  3. Don’t prevent the system from shutting down.

I can achieve the first two, but I’m not sure how to deal with the third.


#6

So I figured out how it helps. In the code being ran inside the BrowserWindow, if you have an onbeforeload listener, you can do a return false in the cases that you aren’t expecting the window to close: IE someone clicking the red X. Returing false will have an affect on how electron works.

When a BrowserWindow closes, a series of events will fire. I am not 100% sure about the order, but it goes like this:

  • onbeforeunload (renderer process)
  • onunload (renderer process)
  • close (main process on browserwindow)
  • closed (main process on browserwindow)

From my understanding, if any of these return a false, the subsequent events will not fire. So, by returning false in your onbeforelunload you are preventing the window from closing.

When you are developing around, this you may have to get created as the onbeforeunload event fires more often than when the page is unloaded. When you change pages, it will call the onbeforeunload. So if you have more than one page, you will need to have an onbeforeunload listener on both/all pages.

These were some of the things I learned when I tried to do what you are doing. Currently, it is working fine. So… you may have to just try to make it work for a while longer.


#7

This works well, but we noticed that if you right click on the dock and choose Quit, the app hides. Are you all seeing this too?


#8

I think I’ve found a way to make this work:

const electron = require('electron');
const app = electron.app;

let willQuitApp = false;
let window;

app.on('ready', () => {
  window = new electron.BrowserWindow();

  window.on('close', (e) => {
    if (willQuitApp) {
      /* the user tried to quit the app */
      window = null;
    } else {
      /* the user only tried to close the window */
      e.preventDefault();
      window.hide();
    }
  });

  window.loadURL('foobar'); /* load your page */
});

/* 'activate' is emitted when the user clicks the Dock icon (OS X) */
app.on('activate', () => window.show());

/* 'before-quit' is emitted when Electron receives 
 * the signal to exit and wants to start closing windows */
app.on('before-quit', () => willQuitApp = true);

I’ve been using it successfully for my iTunes-like Electron app.


#9

Finally someone broke all the logic and make it happened :slight_smile: