From 3ffec30d510dd7fe46683b776565f279f0c88bff Mon Sep 17 00:00:00 2001 From: norepro Date: Wed, 6 May 2026 22:55:24 -0700 Subject: [PATCH] Fix some X11 BadWindow errors not being ignored Godot suppresses X11 BadWindow errors during some operations because they can occur with normal usage. X11 errors are asynchronous. Sometimes, when a BadWindow error is sent, it is dequeued after the original non-BadWindow-suppressing error handler has been restored. This results in an error callstack being shown to the user. Call `XSync` before restoring the original error handler. This ensures that any queued BadWindow errors go to the suppressing handler. Fixes #117814 --- platform/linuxbsd/x11/display_server_x11.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index ee56be988b..212cbe0435 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -6065,6 +6065,9 @@ Window find_window_from_process_id(Display *p_display, pid_t p_process_id) { } } + // Suppress any pending bad window errors. + XSync(p_display, False); + // Restore default error handler. XSetErrorHandler(oldHandler); @@ -6114,6 +6117,9 @@ Error DisplayServerX11::embed_process(DisplayServerEnums::WindowID p_window, Pro DEBUG_LOG_X11("Starting embedding %ld to window %lu \n", p_pid, wd.x11_window); + // Handle bad window errors silently because the embedded window may be closed at any time. + int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&bad_window_error_handler); + EmbeddedProcessData *ep = nullptr; if (embedded_processes.has(p_pid)) { ep = embedded_processes.get(p_pid); @@ -6121,6 +6127,8 @@ Error DisplayServerX11::embed_process(DisplayServerEnums::WindowID p_window, Pro // New process, trying to find the window. Window process_window = find_window_from_process_id(x11_display, p_pid); if (!process_window) { + XSync(x11_display, False); + XSetErrorHandler(oldHandler); return ERR_DOES_NOT_EXIST; } DEBUG_LOG_X11("Process %ld window found: %lu \n", p_pid, process_window); @@ -6132,9 +6140,6 @@ Error DisplayServerX11::embed_process(DisplayServerEnums::WindowID p_window, Pro embedded_processes.insert(p_pid, ep); } - // Handle bad window errors silently because just in case the embedded window was closed. - int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&bad_window_error_handler); - if (p_visible) { // Resize and move the window to match the desired rectangle. // X11 does not allow moving the window entirely outside the screen boundaries. @@ -6236,6 +6241,9 @@ Error DisplayServerX11::embed_process(DisplayServerEnums::WindowID p_window, Pro } } + // Suppress any pending bad window errors. + XSync(x11_display, False); + // Restore default error handler. XSetErrorHandler(oldHandler); return OK; @@ -6268,6 +6276,9 @@ Error DisplayServerX11::request_close_embedded_process(ProcessID p_pid) { XSendEvent(x11_display, ep->process_window, False, NoEventMask, &ev); } + // Suppress any pending bad window errors. + XSync(x11_display, False); + // Restore default error handler. XSetErrorHandler(oldHandler);