This is a pretty huge change that will be important for being able to
handle nested or mutually recursive `dispatch()` and `audioMaster()`
calls. This sadly all had to be done in a single commit, so here's a
summary:
- `src/common/sockets.h:Sockets` contains all sockets on both the plugin
and the Wine host side, and is used to both listen on and connect to
the sockets.
- Sockets and other temporary files respect `$XDG_RUNTIME_DIR` instead
of being dumped in `/tmp`.
- All sockets now have a unique endpoint in
`/run/user/<uid>/yabridge-<plugin_name>-<random_id>/`. This is
important for when we want to have multiple socket connections for
handling `dispatch()` and `audioMaster()`.
- Because of the above, we no longer clean up the socket endpoint files
after the connection gets established during initialization. Instead
we'll remove the socket base directory when shutting down.
I'm still really curious why this double reparent would be needed
though. Everything works fine on any other i3 config I've tried, and
even the exact same config in a VM works fine for me.
I'm not sure how many people use WMs that don't implement
`_NET_ACTIVE_WINDOW`, but at least this will give those people some way
to grab input focus, even if it's not as good as the new method.
These things should not fail (and I've never seen one of these thing
error out with yabridge), but in the case they do an assertion is at
least a lot trace down than a segfault.
This fixes keyboard focus not returning when closing dialogs in Melda
plugins. I'll have to do some more testing to see if this does not
introduce any unwanted side effects.
This is not ideal since it requires the user to know about this option
and to create a config file, but I think it's the best we can do without
compromising on yabridge's transparency and 'zero hacks' philosophy.
See #29 and #32.
This works around Waves plugins causing an infinite message loop. Since
we run the loop 30 times per second anyways splitting the loop up into
chunks of 20 shouldn't be an issue.
This significantly reduces the latency with no real drawbacks from what
I've noticed. Wineserver is still run using the normal scheduling
policies because from my testing running that with realtime priority
that can actually increase latencies, although doing so will greatly
reduce the variance in processing time.
This sounds like it would the simplest way to work around the issue of
E27 calculating its own coordinates based on the parent window's
coordinates. I have not noticed any weird issues with having this
enabled all the time, but less moving parts is always better so it's
still behind an option.
It's a bit clearer this way. I would prefer using jthreads here, but we
would still need this try-catch block since there's no way to cancel
synchronous Boost.Asio socket operations other than closing the socket.
I did not know that `std::optional::value()` did checked access. And I
still prefer a more explicit .has_value() over boolean conversion, but
this seems to be the accepted way to do this.
This cleans up the PluginBridge significantly by getting rid of all
fields and handling that was only needed for connecting to plugin
groups. This was also the last thing I wanted to refactor before
releasing the plugin groups feature with yabridge 1.2.
This reverts commit 0c047f9a66.
This workaround was needed because of the weird threading behavior with
the Win32 APIs, std::thread and winelib. Now that the actual
`active_plugins.erase()` call is done from within the plugin
context/main thread, this hack is no longer needed.
Not sure why I made this more complicated than it needed to be to begin
with. And just like in `Vst2Bridge`, we can't reliably run third party
code inside of an `std::thread` so the IO context and initialization has
to be run on the main thread.
Running the audio processing and midi dispatcher loops in a regular
`std::thread` causes weird memory corruption issues (likely because of
calling conventions are not being respected). Luckily this does not
cause any issues here, so we can get rid of a lot of ugly glue code and
manual memory management.
This makes the individual plugin host slightly more complex, but now
both individually hosted plugins and plugin groups handle both
dispatcher events and GUI events in the exact same way.
Should not matter that much, but a potential situation where you would
want to have handled the X11 events first is when the editor enters a
blocking message loop while it is waiting on a GUI component just as the
window gets moved by an external program or window manager.
At a 30 fps rate with a limit on the number of window messages per
frame. This is somehow needed for Melda plugins, as they otherwise
dispatch tiemr messages indefinitely after opening a second editor with
seemingly no way around it.
With this and some refactoring #15 should be almost done.