diff --git a/CHANGELOG.md b/CHANGELOG.md index 82609f52..f0e7f54a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/wine-host/xdnd-proxy.cpp b/src/wine-host/xdnd-proxy.cpp index 92416f90..202c0420 100644 --- a/src/wine-host/xdnd-proxy.cpp +++ b/src/wine-host/xdnd-proxy.cpp @@ -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 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(*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 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_get_property_value(property_reply.get())) != 0; + if (property_reply->type == XCB_NONE) { + return std::nullopt; + } else { + return *static_cast( + xcb_get_property_value(property_reply.get())); + } } std::optional WineXdndProxy::get_xdnd_proxy( diff --git a/src/wine-host/xdnd-proxy.h b/src/wine-host/xdnd-proxy.h index 9173ac48..31363c49 100644 --- a/src/wine-host/xdnd-proxy.h +++ b/src/wine-host/xdnd-proxy.h @@ -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 is_xdnd_aware(xcb_window_t window) const noexcept; /** * Return the XDND proxy window for `window` as specified in the `XdndProxy`