Instead of ignoring all `NonlinearVirtual` events. This lets us release
focus when instantly moving the mouse from a plugin GUI to something
else. This generates `NonlinearVirtual` event, and previously we ignored
those because that also happens when opening a dropdown menu in a TDR
plugin (which uses popup windows instead of actual dropdowns).
We'll need this for the `LeaveNotify` because `GetCursorPos()` updates
only once every 100 ms, which means that it would still point to the old
window we're actually leaving.
This will let us detect other, non-wrapper windows to the right and to
the bottom of a plugin GUI. Useful for drag-and-drop so we don't end up
overriding Wine's internal drag-and-drop mechanism.
Wine is weird. The whole reason why we're doing these weird things is
because Wine somehow tries to delete the window twice. If we don't call
`xcb_query_tree()` here (and get an error back), then we're back at the
error we tried to solve. Apparently this works, and given that noone
dares touching Wine's X11drv code I won't ask any further questions.
This reverts commit d3d21c65f4.
On second thought, Wine actually handles things better this way. We want
to avoid both hangs and the Wine window becoming visible, and this
achieves both of those things. We should just silence the warning.
We still need to make sure this window resizes properly, but this should
prevent the host from interacting with the full screen `ConfigureNotify`
events we keep sending to `wine_window`.
I've seen this happen once or twice. Earlier on (in #40) we could get
away with just reparenting the window another time. But here both
reparents succeed, and the issue still happens. But a reparent notify
for `parent_window` did appear on system affected by this issue, which
is very odd. Hopefully this will help.
This is the same way (minus the mapping check part) that `xprop` and
`xwininfo` filter windows when clicking on them. REAPER's toplevel
window apparently doesn't process any keyboard input when the mouse
cursor is located outside of that window.
REAPER initializes the plugin's editor first before reparenting the
parent window to the FX window, so our `topmost_window` didn't actually
refer to the FX window.
This should have been fixed as of yabridge 3.2.0 by adding doing a
reparent with a last second flush. Or at least, I haven't heard any
reports about this still being an issue.
We cannot integrate this into our event loop like we planned, because
Wine a) grabs the mouse pointer so we cannot do that, and b) blocks the
GUI thread. So instead we will spawn our own thread and do polling based
XDND. When Wine's tracker window gets destroyed, we know that the left
mouse button has been released.
Apparently X11 connections are a scarce resource, so it seems like a
good idea to not hang on to them for too long. Now this is sort of a
hybrid between COM-style memory management and a singleton.
We did this before implementing the deferred close in yabridge 3.0.0. It
didn't seem necessary anymore so we got rid of it, but without this
closing an iZotope Rx plugin's editor in Renoise was guaranteed to
trigger an X11 error and crash Renoise. Doing this reparent doesn't seem
to cause any slowdown but it does at least fix the specific combination
of iZotope Rx and Renoise.
It's pretty hard to find a solution that checks all of the boxes. I want
something that:
- Closes instantly when you close the editor, and in REAPER you should
be able to instantly switch between docked and floating modes
- Where there should not be a delay in user interaction when quickly
reopening the editor (or doing that switching thing in REAPER since that's
the same thing)
- Where the window manager should not try to reparent the window during
the losing process as that can cause some jarring flickering
- And, of course, there should be no weird Wine X11Drv crashes
And it should do all of that in Bitwig, REAPER, Carla, Ardour and
Renoise. Apparently it's quite the task to find an approach that checks
all the boxes there.
Although it hasn't shown up, this will get rid of the possibility of
off-thread effEditIdle calls causing issues. And since we need some way
to run call this function while the event loop is running anyways, doing
it entirely from a timer similar to how hosts on Windows would do it
seems like the best solution.
I've also tried a lot of other things, but none of the solutions I've
tried work 100% of the time. It sounds like a better idea to have
something that doesn't work consistently than to have something that
inconsistently sort of works. Setting the size in `WM_WINDOWPOSCHANGING`
to (0, 0) fixes the drifting, but the mouse coordinates are still wrong
and `SetWindowPos()` breaks the reparenting.
This reverts commit db2cc5800a.
I think some rounding in Wine is causing this issue, but then again
we're not supposed to send these ConfigureNotify events to the window
directly anyways.