From 94125f9eab52093558294ef685095b7a36be2edc Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sat, 10 Jul 2021 23:50:39 +0200 Subject: [PATCH] Announce XdndEnter and XdndLeave --- src/wine-host/xdnd-proxy.cpp | 38 ++++++++++++++++++++++++++++++++++++ src/wine-host/xdnd-proxy.h | 7 +++++++ 2 files changed, 45 insertions(+) diff --git a/src/wine-host/xdnd-proxy.cpp b/src/wine-host/xdnd-proxy.cpp index 18303c7c..116bd089 100644 --- a/src/wine-host/xdnd-proxy.cpp +++ b/src/wine-host/xdnd-proxy.cpp @@ -43,6 +43,12 @@ constexpr char OLEDD_DRAGTRACKERCLASS[] = "WineDragDropTracker32"; constexpr char xdnd_selection_name[] = "XdndSelection"; // xdnd_aware_property_name is defined in `editor.h`` constexpr char xdnd_proxy_property_name[] = "XdndProxy"; +constexpr char xdnd_enter_message_name[] = "XdndEnter"; +constexpr char xdnd_leave_message_name[] = "XdndLeave"; + +// Mime types for use in XDND +constexpr char mime_text_uri_list_name[] = "text/uri-list"; +constexpr char mime_text_plain_name[] = "text/plain"; /** * We're doing a bit of a hybrid between a COM-style reference counted smart @@ -124,6 +130,15 @@ WineXdndProxy::WineXdndProxy() get_atom_by_name(*x11_connection, xdnd_aware_property_name); xcb_xdnd_proxy_property = get_atom_by_name(*x11_connection, xdnd_proxy_property_name); + xcb_xdnd_enter_message = + get_atom_by_name(*x11_connection, xdnd_enter_message_name); + xcb_xdnd_leave_message = + get_atom_by_name(*x11_connection, xdnd_leave_message_name); + + xcb_mime_text_uri_list = + get_atom_by_name(*x11_connection, mime_text_uri_list_name); + xcb_mime_text_plain = + get_atom_by_name(*x11_connection, mime_text_plain_name); } WineXdndProxy::Handle::Handle(WineXdndProxy* proxy) : proxy(proxy) {} @@ -240,6 +255,29 @@ void WineXdndProxy::run_xdnd_loop() { continue; } + // When transitioning between windows we need to announce this to both + // windows + if (last_window != xdnd_window_query->child) { + if (last_window) { + // FIXME: For some reason you get a -Wmaybe-uninitialized false + // positive with GCC 11.1.0 if you just dereference + // `last_window` here + send_xdnd_message(last_window.value_or(0), + xcb_xdnd_leave_message, 0, 0, 0, 0); + } + + // We need to announce which file formats we support. There are a + // couple more common ones, but with `text/uri-list` and + // `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); + + xcb_flush(x11_connection.get()); + } + // TODO: Fetch the window under the mouse cursor, send messages to it // according to the XDND protocol last_window = xdnd_window_query->child; diff --git a/src/wine-host/xdnd-proxy.h b/src/wine-host/xdnd-proxy.h index 239b832f..7893ae42 100644 --- a/src/wine-host/xdnd-proxy.h +++ b/src/wine-host/xdnd-proxy.h @@ -249,4 +249,11 @@ class WineXdndProxy { xcb_atom_t xcb_xdnd_selection; xcb_atom_t xcb_xdnd_aware_property; xcb_atom_t xcb_xdnd_proxy_property; + xcb_atom_t xcb_xdnd_enter_message; + xcb_atom_t xcb_xdnd_leave_message; + + // Mime types for use in XDND, we'll only support dragging links since that + // is the foramt the Windows OLE drag-and-drop provides us + xcb_atom_t xcb_mime_text_uri_list; + xcb_atom_t xcb_mime_text_plain; };