If any package takes longer than one second (the
`saveStateDebounceInterval`) to deactivate, and the unload was triggered
by a key or mouse down, mouse event, you can end up in a situation where
sate is serialized _after_ the packages are deactivated.
The result in a bug where panes, such as the File Tree, will randomly
be closed when you reload or reopen Atom.
This can be reproduced by creating a package that has an artificially
slow `deactivate` method. With such a package enabled, every reload ends
up serializing a state where all panes are closed.
I'm a bit nervous about this exact fix, since we have to track every
place where it's possible for `prepare-to-unload` to be fired, without
the window actually closing.
I handled the only instance I saw, but the logic is complex enough, that
I'm not 100% confident there are not other instances.
If it did happen that `prepare-to-unload` was fired and some other logic
caused the window to not actually close, we could end up in a state
where mousedown/keydown events were no longer causing state to get
serialized.
This commit fixes a race condition in the
`attemptRestoreProjectStateForPaths` function that could cause a file to
be opened more than once within the same workspace pane.
In particular, when opening some file into an empty window, Atom tries
to recover the state for the project containing the file (if there is
one). However, we were previously not waiting until the
`AtomEnvironment`'s state had been fully deserialized before trying to
load the requested file into the workspace. If the same file also
existed in the serialized representation of the workspace, it could end
up being opened twice.
With this commit we will now wait until the environment has been fully
deserialized before honoring the user's request of loading new files
into an empty window. Also, tests have been restructured to test more
thoroughly this interaction.