Search code examples
javascriptelectrononbeforeunloadconfirm

Confirm beforeunload in Electron


i know that there are hundreds of questions like: "How can i prevent close event in electron" or something like that.
After implementing a confirmation box (electron message box) in the beforeunload event i was able to close my app and cancel the close event. Since the dev tools are always open, i didn't recognize that it doesn't work while the dev tools are closed...

window.onbeforeunload = e =>
{           
    // show a message box with "save", "don't save", and "cancel" button
    let warning = remote.dialog.showMessageBox(...) 

    switch(warning)
    {
        case 0:
            console.log("save");
            return;
        case 1:
            console.log("don't save");
            return;
        case 2:
            console.log("cancel");
            return false;
            // e.returnValue = "false";
            // e.returnValue = false;
    }
};

So, when the dev tools are opened, i can close the app with saving, without saving and cancel the event.
When the dev tools are closed, the cancel button doesn't work anymore.

Btw.:

window.onbeforeunload = e =>
{           
    return false;
    alert("foo");
};

will cancel the close event and obviously wouldn't show the message (doesn't matter if dev tools are open or closed)

window.onbeforeunload = e =>
{           
    alert("foo");
    return false;
};

will cancel the close event after pressing ok if dev tools are open and will close the app after pressing ok if dev tools are closed

Intentionally i'm using the synchronous api of the message box and while i'm writing this question i figured out that a two windowed app (new remote.BrowserWindow()) will behave exactly like with the dev tools.

Has anyone an idea how i can resolve this problem?
Many thanks in advance


Solution

  • Instead of onbeforeunload prefer working with the event close. From this event, you'll be able to catch the closing event before the whole closure process is completed (event closed). With close, you'll be able to take the control and stop whenever you need the completion of the closure.

    This is possible when you create your BrowserWindow, preferably in the main process:

    // Create the browser window.
    window = new BrowserWindow({});
    
    // Event 'close'
    window.on('close', (e) => {
        // Do your control here
        if (bToStop) {
            e.preventDefault();
        }
    })
    
    // Event 'closed'
    window.on('closed', (e) => {
        // Fired only if you didn't called e.preventDefault(); above!
    })
    

    In addition, be aware that the function e.preventDefault() is spreading in the whole code. If you need to be back to the natural behaviour of Electron, you need to toggle the variable e.defaultPrevented to false.

    Actually, it seems e.preventDefault() function is handling the variable e.defaultPrevented to true until any change on it.