Request to save / close before closing the window

  • I am making a written expression. Users can open the application, write text, save their work, etc.
  • I'm trying to make sure that when you click the window close button, the user is prompted to (a) save his work (if necessary) or (b) just exit.
  • I try to use window.beforeunload to achieve this, but I find window.beforeunload stuck in a loop where the same prompt appears indefinitely when I try to "exit".

Here is some code:

 windowCloseCheck() { window.onbeforeunload = function(e) { e.returnValue = false; // window.alert('try to close me'); if(file.isUnsaved() || file.hasChanged()) { // prompt - save or just quit? file.fileWarning('You have unsaveeed work.', 'Save', 'Quit', function(){ // OPTION A - save file.save(); }, function() { // OPTION B: Quit. ipcRenderer.send('quitter') }) } else { // file is saved and no new work has been done: ipcRenderer.send('quitter') } 

windowCloseCheck is called when the application is configured, triggering an event listener to close the window. My condition checks if the file is unsaved or has changed from the original.

fileWarning is a function that simply wraps an electronic dialog box, resulting in a popup window with two options and corresponding functions to call for each option.

The rest of the code is available if I (possibly) omit the necessary information. I would be glad to clarify if I am not very clear.

+14
electron
source share
5 answers

Please add the following block inside the function where you defined the browser window (in my case, the createWindow () function is declared in main.js)

  // Create the browser window. mainWindow = new BrowserWindow({width: 400, height: 400}) mainWindow.on('close', function(e){ var choice = require('electron').dialog.showMessageBox(this, { type: 'question', buttons: ['Yes', 'No'], title: 'Confirm', message: 'Are you sure you want to quit?' }); if(choice == 1){ e.preventDefault(); } }); 
+20
source share

You can add a local variable to avoid mainWindow.destroy (), for example:

  let showExitPrompt = true; // ask renderer process whether should close the app (mainWindow) mainWindow.on('close', e => { if (showExitPrompt) { e.preventDefault(); // Prevents the window from closing mainWindow.webContents.send('on-app-closing'); } }); // renderer allows the app to close ipcMain.on('quitter', (e) => { showExitPrompt = false; mainWindow.close(); }) 
+2
source share

I ended up using window.destroy() to split the rendering process into bits (from the main process):

 ipcMain.on('quitter', (e) => { mainWindow.destroy(); // necessary to bypass the repeat-quit-check in the render process. app.quit() }) 

Not sure if this is recommended, as there seem to be better ways to exit the electronic application correctly. Still happy to receive any feedback if you know the best answer!

/ shrugging!

+1
source share

Awijeet's solution is just perfect! Bth, thanks Awijeet: he saved me a watch !; -)

Also, if you need to go further, be aware that e.preventDefault() spread throughout the code. After properly managing preventDefault() you need to turn the e.defaultPrevented = false variable to return to the natural behavior of your application.

In fact, it seems that the e.preventDefault() function disables the e.defaultPrevented variable to true until you change its value.

+1
source share

If the user selects the save button, we must save the data and close the window using window.close() . But, with this approach, we get an infinite loop that asks to save unsaved work, because window.close() will again generate a close window event.

To solve this problem, we need to declare a new boolean type var forceQuit , which is initially set to false , then we set it to true after saving the data or if the user decided to just close without saving the data.

 import { app, BrowserWindow, dialog } from 'electron'; let win = null; let forceQuit = false; app.on('ready', () => { win = new BrowserWindow({ // Your window options.. }); mainWindow.on('close', e => { if (!forceQuit) { const clickedButtonId = dialog.showMessageBox(mainWindow, { type: 'warning', buttons: ['Save', 'Cancel', 'Don't save'], cancelId: 1, title: 'Confirm', message: 'You have unsaved work!' }); if (clickedButtonId === 0) { e.preventDefault(); console.log('Saving...'); /** Here do your data saving logic */ forceQuit = true; win.close(); } else if (clickedButtonId === 1) { e.preventDefault(); } else if (clickedButtonId === 2) { forceQuit = true; win.close(); } } }); }); 
0
source share

All Articles