34

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, the OS is shut down or the app is terminated with quit command, Cmd+Q.

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

Thank you for your help.


Postscript

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.

yukib
  • 453
  • 1
  • 4
  • 6

2 Answers2

49

You can catch it by using the close event of the browser-window api. You can try the following to verify this...

var app = require('app');

var force_quit = false;

app.on('ready', function () {        
    mainWindow = new BrowserWindow({ width: 800, height: 600 });

    mainWindow.on('close', function() { //   <---- Catch close event

        // The dialog box below will open, instead of your app closing.
        require('dialog').showMessageBox({
            message: "Close button has been pressed!",
            buttons: ["OK"]
        });
    });
});

Update:

To separate functionality you can do the following...

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});

    // Continue to handle mainWindow "close" event here
    mainWindow.on('close', function(e){
        if(!force_quit){
            e.preventDefault();
            mainWindow.hide();
        }
    });

    // You can use 'before-quit' instead of (or with) the close event
    app.on('before-quit', function (e) {
        // Handle menu-item or keyboard shortcut quit here
        if(!force_quit){
            e.preventDefault();
            mainWindow.hide();
        }
    });

    // Remove mainWindow.on('closed'), as it is redundant

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

// This is another place to handle events after all windows are closed
app.on('will-quit', function () {
    // This is a good place to add tests insuring the app is still
    // responsive and all windows are closed.
    console.log("will-quit");
    mainWindow = null;
});

The above code uses the before-quit event handler to handle app "close" events on the app api. Browser-window "close" events are still handled on the browser-window api by mainWindow.on('close').

Additionally, the will-quit event is a better place to test for problems before the app closes completely.

Josh
  • 3,225
  • 25
  • 22
  • Thank you for your reply!! I tried your code, however I found that `close` event is catched when a close button is clicked or when `Cmd+Q` is typed. Moreover, this event is cached when an OS is shut down... I'd like to detect only `when a close button is clicked`... – yukib Oct 06 '15 at 16:14
  • When you call app.quit() the app attempts to close all windows before terminating. You have a second app.quit() on the mainWindow's "closed" event. This may cause a problem. See my updated answer with your code. – Josh Oct 07 '15 at 18:56
  • Thank you for your help again! I tried your code, and I found that only ``close'' event is called when a close button is clicked, and ``before-quit'' event and ``close'' event are called when the OS is shutdown. Thank you so much! – yukib Oct 12 '15 at 06:32
  • 'activate-with-no-open-windows' has been replaced with 'activate' – pronebird Nov 21 '16 at 00:07
0
app.on('ready', ()=> {
let win = new BrowserWindow({width:800, height:600}) 
win.loadURL('file://'+__dirname+'/index.html')
win.on('closed', () => {
    console.log(' ---- Bye Bye Electron ---- ')
  });
})

Thus You Can catch the Close Event

Rohit Goyal
  • 81
  • 1
  • 1