dispatchOnServerThread
Hand dispatch to the server thread, wait for it to run, then hold the capture window open. Split from run because scheduling is not command semantics: everything here is about GETTING to the server thread, and none of it varies with what the commands are.
Return
null once the window has closed, or the [mcp]-prefixed reason it did not — run returns that verbatim, which is how its "never throws" contract survives the split.