Instead of using `localStorage` to store and retrieve the project
history, with this commit we will use `StateStore` so that we can
retrieve state asynchronously without blocking Atom during startup.
This will still notify render processes when such events are triggered
without, however, incurring the additional cost of synchronously
retrieving a `BrowserWindow` (and its properties) via `remote` during
startup.
This commit will register the `display-added` and `display-removed`
events only once in the main process in order to disable zoom (see
https://github.com/atom/atom/pull/11345) directly instead of
unnecessarily paying for I/O in the renderer process during startup.
When accessing objects in the main process via the `remote` module,
Electron returns proxy objects that are references to the original ones.
This means that trying to access a remote object's property or function
results in a synchronous message exchange with the main process.
In Atom core we frequently access the load settings coming from the main
process, especially during startup. This caused a lot of synchronous I/O
which was blocking the renderer process for several milliseconds.
With this commit, instead of exposing load settings as a JavaScript
object, we serialize them to JSON in the main process and parse them
back to a JavaScript object in the renderer processes. This allows us to
get a full copy of the object locally and pay for I/O just once when
retrieving load settings from the main process for the first time.
Previously, when calling `destroy` on a `PanelContainer` containing
multiple panels, Atom would throw a `Cannot read property 'destroy' of
undefined` exception. This was due to iterating over the panels while at
the same time destroying them, which caused the iterated array to be
modified during the loop.
With this commit we slice the array before iterating over it so that
destroying a `PanelContainer` doesn't throw exceptions anymore.