Note: "clean window" is defined as 1) having an empty project and 2)
having no pane items or only empty unnamed buffers
When project is empty and there is saved state associated with the
opened/added folders...
* Open a file or folder (from command line or Open menu)
* If we have a clean window, restore project state in window
* If window is dirty, restore saved state in new window
Note: "clean window" is defined as 1) having an empty project and 2)
having no pane items or only empty unnamed buffers
Adding folder(s)
* If we have a clean window, restore project state in window
* If window is dirty, prompt user to
* add folder to the existing window LOSING state
* OR open project folder in a new window
Previously, we used to save the window's state in the renderer process
`beforeunload` event handler: because of the synchronous nature of event
handlers and the asynchronous design of IndexedDB, this could
potentially not save anything if windows close fast enough to prevent
IndexedDB from committing the pending transaction containing the state.
(Ref.: https://mzl.la/2bXCXDn)
With this commit, we will intercept the `before-quit` events on
`electron.app` and the `close` event on `BrowserWindow` (which will fire
respectively before quitting the application and before closing a
window), and prevent them from performing the default action. We will
then ask each renderer process to save its state and, finally, close the
window and/or the app.
This fixes an annoying problem that prevented the state of marker layers
from being saved when the window was reloaded either via `Cmd+R` in
DevTools or via `Ctrl+Option+Cmd+L` in Atom.
The issue was that we were *always* scheduling `saveState` on an idle
callback: `window.onbeforeunload`, however, doesn't wait for that event
before closing the window, and thus that state was never saved in those
situations.
The solution is to use idle callbacks only during the critical code path
(i.e. on mousedown and keydown), but save it synchronously otherwise.
Saving something to IndexedDB is actually asynchronous too, but it seems
like Chrome fulfills `put` requests that get executed right during
`onbeforeunload`.
This is because we have made the `project.serialize(options)` parameter optional
for backwards compatibility (i.e. #11111), and we want to make sure we don't
make the mistake of not passing it internally.