frosty
frosty

Reputation: 21762

Electron: Close w X vs right click dock and quit

In my Electron app, I would like to do something that is done very often in other OSX apps. That is... I would like to NOT close the app of the red X is clicked in the top right. But, if they right click the app icon in the dock, and say Quit, then I would like to quit the app. How do I do this?

I have tried using the onbeforeunload event from the rendererProcess, as well as the browserWindow.on("close", fn) event to try and prevent this. The problem is that they both file the onbeforeunload event. And I can't tell the different between the red X being clicked and the dock icon being right clicked and told to quit. Any help would be nice. Has anyone else done this in Electron for OSX?

Upvotes: 7

Views: 8845

Answers (7)

Asif Isthiaq2
Asif Isthiaq2

Reputation: 67

This is how i solved it and this works perfectly.

import { app } from "electron";
let window: any;
let forceQuit = false;

app.on("ready", () => {
    window = //YOUR BROWSER WINDOW
    window.on("close", e => {
      if (process.platform === "darwin" && forceQuit) {
        window = null;
      } else {
        e.preventDefault();
        app.hide();
      }
});

app.on("activate", function() {
    app.show();
});

app.on("before-quit", function(event) {
    if (!forceQuit) {
      event.preventDefault();
      forceQuit = true;
      app.quit();
    }
});

Upvotes: 0

Snowman
Snowman

Reputation: 32071

This is the only answer that worked for me:

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

via https://discuss.atom.io/t/how-to-catch-the-event-of-clicking-the-app-windows-close-button-in-electron-app/21425/8

Upvotes: 7

Jeng Wittawat
Jeng Wittawat

Reputation: 326

try this

if (process.platform === 'darwin') {
  var forceQuit = false;
  app.on('before-quit', function() {
    forceQuit = true;
  });
  mainWindow.on('close', function(event) {
    if (!forceQuit) {
      event.preventDefault();

      /*
       * your process here
       */
    }
  });
}

Upvotes: 22

Philip
Philip

Reputation: 5021

You need to handle this from your main.js file, by checking if it's a darwin platform, on window-all-closed event and re-create the window on activate event.

// Quit when all windows are closed.
app.on('window-all-closed', function () {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', function () {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow();
  }
});

More info/Example: https://github.com/atom/electron-quick-start/blob/master/main.js

Upvotes: 0

martpie
martpie

Reputation: 6080

Have a look at the electron quick start guide

Please notice the two below solutions needs to be implemented in main.js, and not on the JS executed on your html page.

Specific window close

If you want to execute code when a specific BrowserWindow is closed:

mainWindow.on('closed', function() {
    // Your code to be executed before "really" stopping the app
});

All window close

If you want execute code when ALL the windows are closed (app API):

app.on('window-all-closed', function() {
    // do stuff here
});

Upvotes: 0

inukshuk
inukshuk

Reputation: 1457

Take a look at the window-all-closed event of app in the main process. This event is typically used to quit the app on Linux and Windows but not on OS X (for an example, see Electron's Quick Start Tutorial). On OS X you should then probably also handle the activate event to open a new window if there is currently no window open.

Upvotes: 0

frosty
frosty

Reputation: 21762

After much looking, I found the following solution. When you right click on the dock and select Quit, before that fires the onbeforeunload in the rendererProcess, it will first fire the close event on the app itself. So, in the rendererProcess you have an onbeforeunload listener. And you tell that to return false always. Returning false from that event will prevent the window from unloading/closing ever. Then in your mainProcess you add app.on('close',fn) listener. That listener can send an event to the rendererProcess telling it to allow the close. Perhaps you can set a global allowClose = true or something. Then in your onbeforeunload, you add the logic to not return true if allowClose is true.

Upvotes: 0

Related Questions