Support the older XDND versions 3 and 4

This is needed for Tracktion Waveform and other JUCE based hosts.
This commit is contained in:
Robbert van der Helm
2021-07-23 13:19:10 +02:00
parent 9e84352609
commit 7a2febfffb
3 changed files with 31 additions and 13 deletions
+7
View File
@@ -32,6 +32,9 @@ Versioning](https://semver.org/spec/v2.0.0.html).
window in an effort to detect the plugin's size on its own. This could cause
the editor window to grow to fit the entire screen in certain hosts under very
specific circumstances.
- We now support version 3 and 4 of the XDND specification for the Wine->X11
drag-and-drop support. Before this yabridge assumed every application
supported version 5, from 2002. JUCE based hosts only support XDND version 3.
### Fixed
@@ -58,6 +61,10 @@ Versioning](https://semver.org/spec/v2.0.0.html).
keyboard input when the FX window is active but the mouse is outside of the
window. We now use the same validation used in `xprop` and `xwininfo` to find
the host's window instead of always taking the topmost window.
- Fixed Wine->X11 drag-and-drop in **Tracktion Waveform**. Waveform only
supports an old 1998 version of the XDND specification, so it was ignoring our
messages since we assumed every application would support the most recent
version from 2002.
- Worked around a race condition in _Nimble Kick_, which would trigger a stack
overflow when loading the plugin if it wasn't already activated.
- Possibly fixed an obscure error where the editor would not render when using
+19 -8
View File
@@ -418,7 +418,9 @@ void WineXdndProxy::run_xdnd_loop() {
last_pointer_x = xdnd_window_query->root_x;
last_pointer_y = xdnd_window_query->root_y;
if (!is_xdnd_aware(xdnd_window_query->child)) {
const std::optional<unsigned char> supported_xdnd_version =
is_xdnd_aware(xdnd_window_query->child);
if (!supported_xdnd_version) {
maybe_leave_last_window();
last_xdnd_window.reset();
continue;
@@ -459,9 +461,14 @@ void WineXdndProxy::run_xdnd_loop() {
// `text/plain` we should cover most applications, and this is also
// the recommended format for links/paths elsewhere:
// https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#link
send_xdnd_message(xdnd_window_query->child, xcb_xdnd_enter_message,
5 << 24, xcb_mime_text_uri_list,
xcb_mime_text_plain, XCB_NONE);
// NOTE: In theory everything should support XDND version 5 since
// the spec dates from 2002, but JUCE only supports version 3.
// We'll just pretend no other changes are required.
send_xdnd_message(
xdnd_window_query->child, xcb_xdnd_enter_message,
std::clamp(static_cast<int>(*supported_xdnd_version), 3, 5)
<< 24,
xcb_mime_text_uri_list, xcb_mime_text_plain, XCB_NONE);
}
// When the pointer is being moved inside of a window, we should
@@ -610,7 +617,8 @@ WineXdndProxy::query_xdnd_aware_window_at_pointer(
return query_pointer_reply;
}
bool WineXdndProxy::is_xdnd_aware(xcb_window_t window) const noexcept {
std::optional<uint8_t> WineXdndProxy::is_xdnd_aware(
xcb_window_t window) const noexcept {
// Respect `XdndProxy`, if that's set
window = get_xdnd_proxy(window).value_or(window);
@@ -627,9 +635,12 @@ bool WineXdndProxy::is_xdnd_aware(xcb_window_t window) const noexcept {
// Since the spec dates from 2002, we won't even bother checking the
// supported version
return property_reply->type != XCB_NONE &&
*static_cast<xcb_atom_t*>(
xcb_get_property_value(property_reply.get())) != 0;
if (property_reply->type == XCB_NONE) {
return std::nullopt;
} else {
return *static_cast<xcb_atom_t*>(
xcb_get_property_value(property_reply.get()));
}
}
std::optional<xcb_window_t> WineXdndProxy::get_xdnd_proxy(
+5 -5
View File
@@ -182,12 +182,12 @@ class WineXdndProxy {
query_xdnd_aware_window_at_pointer(xcb_window_t window) const noexcept;
/**
* Check whether a window is XDND-aware, respecting `XdndProxy`. We should
* be checking the supported version as well and change our handling
* accordingly, but the XDND spec was last updated in 2002 so we'll just
* assume this won't cause any issues.
* Check whether a window is XDND-aware, respecting `XdndProxy`. This will
* return the supported XDND version. In theory we could just assume that
* everything supports version 5 of the spec since that came out in 20020,
* but for some reason JUCE only supports version 3 from 1998.
*/
bool is_xdnd_aware(xcb_window_t window) const noexcept;
std::optional<uint8_t> is_xdnd_aware(xcb_window_t window) const noexcept;
/**
* Return the XDND proxy window for `window` as specified in the `XdndProxy`