diff --git a/src/wine-host/editor.cpp b/src/wine-host/editor.cpp index ad3805b0..ebdb38e3 100644 --- a/src/wine-host/editor.cpp +++ b/src/wine-host/editor.cpp @@ -374,6 +374,10 @@ void Editor::handle_x11_events() const noexcept { // function calls involving it will fail. All functions called from // here should be able to handle that cleanly. try { + // Pump X11 events for handling XDND client messages from the + // drag-and-drop proxy + dnd_proxy_handle.handle_x11_events(); + std::unique_ptr generic_event; while (generic_event.reset(xcb_poll_for_event(x11_connection.get())), generic_event != nullptr) { diff --git a/src/wine-host/xdnd-proxy.cpp b/src/wine-host/xdnd-proxy.cpp index 6c6c19e3..0ae35cdb 100644 --- a/src/wine-host/xdnd-proxy.cpp +++ b/src/wine-host/xdnd-proxy.cpp @@ -188,6 +188,7 @@ void CALLBACK dnd_winevent_callback(HWINEVENTHOOK /*hWinEventHook*/, WineXdndProxy::WineXdndProxy() : x11_connection(xcb_connect(nullptr, nullptr), xcb_disconnect), + proxy_window(xcb_generate_id(x11_connection.get())), hook_handle( SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE, @@ -196,7 +197,15 @@ WineXdndProxy::WineXdndProxy() 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS), - UnhookWinEvent) {} + UnhookWinEvent) { + // +} + +WineXdndProxy::~WineXdndProxy() noexcept { + // TODO: Move this to a RAII wrapper + xcb_destroy_window(x11_connection.get(), proxy_window); + xcb_flush(x11_connection.get()); +} WineXdndProxy::Handle::Handle(WineXdndProxy* proxy) : proxy(proxy) {} @@ -214,6 +223,10 @@ WineXdndProxy::Handle::Handle(Handle&& o) noexcept : proxy(o.proxy) { instance_reference_count += 1; } +void WineXdndProxy::Handle::handle_x11_events() const noexcept { + proxy->handle_x11_events(); +} + WineXdndProxy::Handle WineXdndProxy::get_handle() { // See the `instance` global above for an explanation on what's going on // here. @@ -223,3 +236,7 @@ WineXdndProxy::Handle WineXdndProxy::get_handle() { return Handle(instance); } + +void WineXdndProxy::handle_x11_events() const noexcept { + // TODO +} diff --git a/src/wine-host/xdnd-proxy.h b/src/wine-host/xdnd-proxy.h index e50522a3..2bd6a41b 100644 --- a/src/wine-host/xdnd-proxy.h +++ b/src/wine-host/xdnd-proxy.h @@ -65,6 +65,11 @@ class WineXdndProxy { Handle(Handle&&) noexcept; Handle& operator=(Handle&&) noexcept = default; + /** + * Handle X11 events for receiving XDND client messages. + */ + void handle_x11_events() const noexcept; + private: WineXdndProxy* proxy; @@ -83,6 +88,9 @@ class WineXdndProxy { * in a COM object, we can only handle drag-and-drop coming form this * process. * + * The handle's `handle_x11_events()` method should be periodically called + * to pump the X11 events for handling XDND client messages. + * * This is sort of a singleton but not quite, as the `WineXdndProxy` is only * alive for as long as there are open editors in this process. This is done * to avoid opening too many X11 connections. @@ -92,9 +100,20 @@ class WineXdndProxy { */ static WineXdndProxy::Handle get_handle(); + /** + * Handle X11 events for receiving XDND client messages. + */ + void handle_x11_events() const noexcept; + private: std::unique_ptr x11_connection; + /** + * We need an unmapped proxy window to send and receive client messages for + * the XDND protocol. + */ + xcb_window_t proxy_window; + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wignored-attributes" std::unique_ptr,