From fcf629ba1cc40137dd4c16fd76330ce210ea9033 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford Date: Wed, 12 Dec 2018 17:07:04 -0800 Subject: [PATCH 1/2] Let scratch-gui handle 'onbeforeunload' --- src/renderer/index.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/renderer/index.js b/src/renderer/index.js index 427d3b9..15e5507 100644 --- a/src/renderer/index.js +++ b/src/renderer/index.js @@ -18,11 +18,6 @@ document.body.appendChild(appTarget); GUI.setAppElement(appTarget); const WrappedGui = AppStateHOC(GUI); -if (process.env.NODE_ENV === 'production' && typeof window === 'object') { - // Warn before navigating away - window.onbeforeunload = () => true; -} - const onStorageInit = storageInstance => { storageInstance.addHelper(new ElectronStorageHelper(storageInstance)); // storageInstance.addOfficialScratchWebStores(); // TODO: do we want this? From 64a06d5b8f1259facb42c0b1349811b8e0389a80 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford Date: Wed, 12 Dec 2018 17:10:41 -0800 Subject: [PATCH 2/2] Obey scratch-gui's onbeforeunload result The `scratch-gui` project saver uses `onbeforeunload` to request confirmation before navigating away from an unsaved project. Unfortunately Electron suppresses the confirmation dialog that browsers would normally display. Instead, Electron offers a `will-prevent-unload` event in the main process: this event fires when `onbeforeunload` requests a confirmation dialog. This change adds a handler for `will-prevent-unload` which displays a quit confirmation dialog so that the overall behavior is similar to what happens in a regular browser. --- src/main/index.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/index.js b/src/main/index.js index 1e0db01..a4c1734 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -1,4 +1,4 @@ -import {app, BrowserWindow} from 'electron'; +import {BrowserWindow, app, dialog} from 'electron'; import * as path from 'path'; import {format as formatUrl} from 'url'; @@ -67,4 +67,18 @@ app.on('activate', () => { // create main BrowserWindow when electron is ready app.on('ready', () => { mainWindow = createMainWindow(); + mainWindow.webContents.on('will-prevent-unload', ev => { + const choice = dialog.showMessageBox(mainWindow, { + type: 'question', + buttons: ['Stay', 'Leave'], + message: 'Leave Scratch?', + cancelId: 0, // closing the dialog means "stay" + defaultId: 0, // pressing enter or space without explicitly selecting something means "stay" + detail: 'Any unsaved changes will be lost.' + }); + const shouldQuit = (choice === 1); + if (shouldQuit) { + ev.preventDefault(); + } + }); });