diff --git a/src/wine-host/editor.cpp b/src/wine-host/editor.cpp index 287d0e36..12addab4 100644 --- a/src/wine-host/editor.cpp +++ b/src/wine-host/editor.cpp @@ -349,19 +349,53 @@ Editor::Editor(MainContext& main_context, // of using the XEmbed protocol, we'll register a few events and manage // the child window ourselves. This is a hack to work around the issue's // described in `Editor`'s docstring'. - xcb_void_cookie_t reparent_cookie = xcb_reparent_window_checked( - x11_connection.get(), wine_window, parent_window, 0, 0); - if (std::unique_ptr error( - xcb_request_check(x11_connection.get(), reparent_cookie)); - error) { - std::cerr << "DEBUG: Reparent 1 failed:" << std::endl; - std::cerr << "Error code: " << error->error_code << std::endl; - std::cerr << "Major code: " << error->major_code << std::endl; - std::cerr << "Minor code: " << error->minor_code << std::endl; - } else { - std::cerr << "DEBUG: Reparent 1 succeeded" << std::endl; - } - xcb_flush(x11_connection.get()); + auto do_reparent = [&]() { + const xcb_void_cookie_t reparent_cookie = + xcb_reparent_window_checked(x11_connection.get(), wine_window, + parent_window, 0, 0); + if (std::unique_ptr reparent_error( + xcb_request_check(x11_connection.get(), reparent_cookie)); + reparent_error) { + std::cerr << "DEBUG: Reparent failed:" << std::endl; + std::cerr << "Error code: " << reparent_error->error_code + << std::endl; + std::cerr << "Major code: " << reparent_error->major_code + << std::endl; + std::cerr << "Minor code: " << reparent_error->minor_code + << std::endl; + + // Let's just check all of the reasons why the reparent could + // fail according to the spec in advance + xcb_generic_error_t* error = nullptr; + const xcb_query_pointer_cookie_t query_pointer_cookie = + xcb_query_pointer(x11_connection.get(), wine_window); + const std::unique_ptr + query_pointer_reply(xcb_query_pointer_reply( + x11_connection.get(), query_pointer_cookie, &error)); + if (error) { + free(error); + std::cerr << "DEBUG: Could not query pointer location" + << std::endl; + } else { + if (query_pointer_reply->same_screen) { + std::cerr + << "DEBUG: Pointer is on the same screen as the " + "Wine window, good" + << std::endl; + } else { + std::cerr + << "DEBUG: Pointer is not on the same screen as " + "the Wine window, oh no" + << std::endl; + } + } + } else { + std::cerr << "DEBUG: Reparent succeeded" << std::endl; + } + xcb_flush(x11_connection.get()); + }; + + do_reparent(); // If we're using the double embedding option, then the child window // should only be created after the parent window is visible @@ -387,19 +421,10 @@ Editor::Editor(MainContext& main_context, // trying! // // https://github.com/robbert-vdh/yabridge/issues/40 - reparent_cookie = xcb_reparent_window_checked( - x11_connection.get(), wine_window, parent_window, 0, 0); - if (std::unique_ptr error( - xcb_request_check(x11_connection.get(), reparent_cookie)); - error) { - std::cerr << "DEBUG: Reparent 2 failed:" << std::endl; - std::cerr << "Error code: " << error->error_code << std::endl; - std::cerr << "Major code: " << error->major_code << std::endl; - std::cerr << "Minor code: " << error->minor_code << std::endl; - } else { - std::cerr << "DEBUG: Reparent 2 succeeded" << std::endl; - } - xcb_flush(x11_connection.get()); + std::cerr + << "DEBUG: Reparent 2 is allowed to fail if the first one succeeded" + << std::endl; + do_reparent(); } } @@ -428,11 +453,12 @@ void Editor::handle_x11_events() noexcept { // check if the host's window has changed whenever the // parent window gets reparented. case XCB_REPARENT_NOTIFY: { + const auto event = + reinterpret_cast( + generic_event.get()); + std::cerr << "DEBUG: ReparentNotify for window " - << reinterpret_cast( - generic_event.get()) - ->window - << std::endl; + << event->window << std::endl; redetect_host_window(); } break; @@ -445,12 +471,12 @@ void Editor::handle_x11_events() noexcept { // check is sometimes necessary for using multiple editor // windows within a single plugin group. case XCB_CONFIGURE_NOTIFY: { - std::cerr - << "DEBUG: ConfigureNotify for window " - << reinterpret_cast( - generic_event.get()) - ->window - << std::endl; + const auto event = + reinterpret_cast( + generic_event.get()); + + std::cerr << "DEBUG: ConfigureNotify for window " + << event->window << std::endl; if (!use_xembed) { fix_local_coordinates(); @@ -460,12 +486,12 @@ void Editor::handle_x11_events() noexcept { // since most hosts will only show the window after the plugin // has embedded itself into it. case XCB_VISIBILITY_NOTIFY: { - std::cerr - << "DEBUG: VisibilityNotify for window " - << reinterpret_cast( - generic_event.get()) - ->window - << std::endl; + const auto event = + reinterpret_cast( + generic_event.get()); + + std::cerr << "DEBUG: VisibilityNotify for window " + << event->window << std::endl; if (use_xembed) { do_xembed();