Add an X11 event handling function to the proxy

This commit is contained in:
Robbert van der Helm
2021-07-10 16:19:23 +02:00
parent b47a6e034b
commit d908db5476
3 changed files with 41 additions and 1 deletions
+4
View File
@@ -374,6 +374,10 @@ void Editor::handle_x11_events() const noexcept {
// function calls involving it will fail. All functions called from // function calls involving it will fail. All functions called from
// here should be able to handle that cleanly. // here should be able to handle that cleanly.
try { try {
// Pump X11 events for handling XDND client messages from the
// drag-and-drop proxy
dnd_proxy_handle.handle_x11_events();
std::unique_ptr<xcb_generic_event_t> generic_event; std::unique_ptr<xcb_generic_event_t> generic_event;
while (generic_event.reset(xcb_poll_for_event(x11_connection.get())), while (generic_event.reset(xcb_poll_for_event(x11_connection.get())),
generic_event != nullptr) { generic_event != nullptr) {
+18 -1
View File
@@ -188,6 +188,7 @@ void CALLBACK dnd_winevent_callback(HWINEVENTHOOK /*hWinEventHook*/,
WineXdndProxy::WineXdndProxy() WineXdndProxy::WineXdndProxy()
: x11_connection(xcb_connect(nullptr, nullptr), xcb_disconnect), : x11_connection(xcb_connect(nullptr, nullptr), xcb_disconnect),
proxy_window(xcb_generate_id(x11_connection.get())),
hook_handle( hook_handle(
SetWinEventHook(EVENT_OBJECT_CREATE, SetWinEventHook(EVENT_OBJECT_CREATE,
EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE,
@@ -196,7 +197,15 @@ WineXdndProxy::WineXdndProxy()
0, 0,
0, 0,
WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS), 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) {} WineXdndProxy::Handle::Handle(WineXdndProxy* proxy) : proxy(proxy) {}
@@ -214,6 +223,10 @@ WineXdndProxy::Handle::Handle(Handle&& o) noexcept : proxy(o.proxy) {
instance_reference_count += 1; instance_reference_count += 1;
} }
void WineXdndProxy::Handle::handle_x11_events() const noexcept {
proxy->handle_x11_events();
}
WineXdndProxy::Handle WineXdndProxy::get_handle() { WineXdndProxy::Handle WineXdndProxy::get_handle() {
// See the `instance` global above for an explanation on what's going on // See the `instance` global above for an explanation on what's going on
// here. // here.
@@ -223,3 +236,7 @@ WineXdndProxy::Handle WineXdndProxy::get_handle() {
return Handle(instance); return Handle(instance);
} }
void WineXdndProxy::handle_x11_events() const noexcept {
// TODO
}
+19
View File
@@ -65,6 +65,11 @@ class WineXdndProxy {
Handle(Handle&&) noexcept; Handle(Handle&&) noexcept;
Handle& operator=(Handle&&) noexcept = default; Handle& operator=(Handle&&) noexcept = default;
/**
* Handle X11 events for receiving XDND client messages.
*/
void handle_x11_events() const noexcept;
private: private:
WineXdndProxy* proxy; WineXdndProxy* proxy;
@@ -83,6 +88,9 @@ class WineXdndProxy {
* in a COM object, we can only handle drag-and-drop coming form this * in a COM object, we can only handle drag-and-drop coming form this
* process. * 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 * 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 * alive for as long as there are open editors in this process. This is done
* to avoid opening too many X11 connections. * to avoid opening too many X11 connections.
@@ -92,9 +100,20 @@ class WineXdndProxy {
*/ */
static WineXdndProxy::Handle get_handle(); static WineXdndProxy::Handle get_handle();
/**
* Handle X11 events for receiving XDND client messages.
*/
void handle_x11_events() const noexcept;
private: private:
std::unique_ptr<xcb_connection_t, decltype(&xcb_disconnect)> x11_connection; std::unique_ptr<xcb_connection_t, decltype(&xcb_disconnect)> 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 push
#pragma GCC diagnostic ignored "-Wignored-attributes" #pragma GCC diagnostic ignored "-Wignored-attributes"
std::unique_ptr<std::remove_pointer_t<HWINEVENTHOOK>, std::unique_ptr<std::remove_pointer_t<HWINEVENTHOOK>,