When the calling code does not return to the event loop (like the CLI test)
we need to run the event loop internally to make sure `bufferOutput()` is
called as of ecd730fd49.
At least when using Qt 6 I could reproduce crashes very often when invoking
`syncthing -version` as part of the wizard's setup detection (inside
a `QIODevice::readAll()` call).
I suppose the problem is that the callback `bufferOutput()` is already
invoked on another thread and emitting the next `readyRead()` signal while
Qt is still handling the previous `readData()` call. Continuing reading
from the pipe only after `readData()` returns should fix it. At least it
does not crash anymore with that change in the wizard's setup detection.
A follow up to 0faacaa7c8 to cover the stop button within the launcher
and terminating Syncthing on shutdown/exit. To find the relevant connection
the connection settings are searched for a local URL where the port matches
the port from the Syncthing process log.
See comment; otherwise calls to `readAll()` with no `bytesAvailable()`
like done in the `syncthingctl` tests fail sporadically as async read
operations are started concurrently.
If there's a configured and local Syncthing connection and we're on a
non-UNIX platform which doesn't support SIGTERM (basically Windows) it
makes sense to use the REST-API instead. That's likely better than just
terminating the process forcefully.
This doesn't cover the stop button within the launcher settings yet because
from this context is isn't clear which connection is relevant as there can
be multiple tray icons/widgets but only one settings page.
Otherwise `QMetaMethod::invoke` wouldn't be able to handle it:
```
QMetaMethod::invoke: Unable to handle unregistered datatype 'QProcess::ProcessError'
```
* Use a process group / job object via Boost.Process to be able to
terminate sub processes as well
* Do not try to stop the process gracefully under Windows by posting
WM_CLOSE because this has no effect on Syncthing anyways
* See https://github.com/Martchus/syncthingtray/issues/94
* Pass program and arguments directly
* Prevent failure on white space in executable path
* Use own parser for arguments
* Make libsyncthing accessible from launcher
Add new SyncthingLauncher class which lauches Syncthing
under the hood via external SyncthingProcess or using
libsyncthing.
Note: Launching via libsyncthing is still experimental.