Skip to content

Commit

Permalink
[Linux/X11] Add a default error handler for X11 to avoid crashes.
Browse files Browse the repository at this point in the history
The default behaviour for X11 is to crash even on non-fatal errors
when there is no error handler set. This change allows the window to
stay open and may enable users to save their work when things go
wrong.

This acts as a workaround for godotengine#65425 and godotengine#68471
  • Loading branch information
nee committed Jun 5, 2023
1 parent e5cc494 commit b13c82e
Showing 1 changed file with 20 additions and 1 deletion.
21 changes: 20 additions & 1 deletion platform/linuxbsd/x11/display_server_x11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -821,12 +821,30 @@ Size2i DisplayServerX11::screen_get_size(int p_screen) const {
return _screen_get_rect(p_screen).size;
}

// A Handler to avoid crashing on non-fatal X errors by default.
//
// The original X11 error formatter `_XPrintDefaultError` is defined here:
// https://gitlab.freedesktop.org/xorg/lib/libx11/-/blob/e45ca7b41dcd3ace7681d6897505f85d374640f2/src/XlibInt.c#L1322
// It is not exposed through the API, accesses X11 internals,
// and is much more complex, so this is a less complete simplified error X11 printer.
int default_window_error_handler(Display *display, XErrorEvent *error) {
static char message[1024];
XGetErrorText(display, error->error_code, message, sizeof(message));

ERR_PRINT(vformat("Unhandled XServer error: %s"
"\n Major opcode of failed request: %d"
"\n Serial number of failed request: %d"
"\n Current serial number in output stream: %d",
String::utf8(message), error->request_code, error->minor_code, error->serial));
return 0;
}

bool g_bad_window = false;
int bad_window_error_handler(Display *display, XErrorEvent *error) {
if (error->error_code == BadWindow) {
g_bad_window = true;
} else {
ERR_PRINT("Unhandled XServer error code: " + itos(error->error_code));
return default_window_error_handler(display, error);
}
return 0;
}
Expand Down Expand Up @@ -5746,6 +5764,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode

portal_desktop = memnew(FreeDesktopPortalDesktop);
#endif
XSetErrorHandler(&default_window_error_handler);

r_error = OK;
}
Expand Down

0 comments on commit b13c82e

Please sign in to comment.