Since `snippets.add` can still be called from the window thread, we need
to retain the ability to parse the body without relying on the loading
task. But this commit only loads the parser in the window if it's actually
needed, instead of always loading it when the snippets extension is
loaded. This avoids the loading performance hit while still allowing
specs to pass and letting us call `snippets.add` manually in the window
if we want to.
Previously if the tree-view was open and was focused and no
editors were open and tab was pressed the document body would
become focused which would not allow events bound to root view
to be triggerable.
This ensures that the root-view always gets focus back when
another view is tabbed away from.
This commit makes all interactions between Task and Worker look
like method calls. The worker now has a global `callTaskMethod`
function that it can use to call methods on the Task object. And the
Task can use `callWorkerMethod` to call methods on a global `handler`
object in the worker. The worker's initial `handler` actually contains
the `start` method, which the Task initially calls to kick things off.
Then the global `handler` gets replaced with whatever `handlerPath`
is specified by the Task. The worker then calls `workerStarted` on its
parent Task object.
This commit also gets rid of the `onProgress` method with the reply
semantics, favoring a more explicit interaction. When `snippetsLoaded`
finishes adding the snippet data, we call `loadNextPackageSnippets`
explicitly rather than returning a reply message.
This prevents concurrent access to the same state from different
worker threads. We needed to treat windowState specially because we
explicitly want it to last beyond the life-span of a single context.
So we store it as a static variable in `native.mm` and synchronize
access with a static `NSLock`. Good enough for now.