diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index 0e4c723a87d..a605e664ce7 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -139,8 +139,9 @@ bool DisplayServerX11::has_feature(Feature p_feature) const { #endif case FEATURE_CLIPBOARD_PRIMARY: case FEATURE_TEXT_TO_SPEECH: - case FEATURE_SCREEN_CAPTURE: return true; + case FEATURE_SCREEN_CAPTURE: + return !xwayland; default: { } } @@ -1494,9 +1495,20 @@ int DisplayServerX11::screen_get_dpi(int p_screen) const { return 96; } +int get_image_errorhandler(Display *dpy, XErrorEvent *ev) { + return 0; +} + Color DisplayServerX11::screen_get_pixel(const Point2i &p_position) const { Point2i pos = p_position; + if (xwayland) { + return Color(); + } + + int (*old_handler)(Display *, XErrorEvent *) = XSetErrorHandler(&get_image_errorhandler); + + Color color; int number_of_screens = XScreenCount(x11_display); for (int i = 0; i < number_of_screens; i++) { Window root = XRootWindow(x11_display, i); @@ -1509,12 +1521,15 @@ Color DisplayServerX11::screen_get_pixel(const Point2i &p_position) const { c.pixel = XGetPixel(image, 0, 0); XFree(image); XQueryColor(x11_display, XDefaultColormap(x11_display, i), &c); - return Color(float(c.red) / 65535.0, float(c.green) / 65535.0, float(c.blue) / 65535.0, 1.0); + color = Color(float(c.red) / 65535.0, float(c.green) / 65535.0, float(c.blue) / 65535.0, 1.0); + break; } } } - return Color(); + XSetErrorHandler(old_handler); + + return color; } Ref DisplayServerX11::screen_get_image(int p_screen) const { @@ -1533,6 +1548,12 @@ Ref DisplayServerX11::screen_get_image(int p_screen) const { ERR_FAIL_COND_V(p_screen < 0, Ref()); + if (xwayland) { + return Ref(); + } + + int (*old_handler)(Display *, XErrorEvent *) = XSetErrorHandler(&get_image_errorhandler); + XImage *image = nullptr; bool found = false; @@ -1575,6 +1596,8 @@ Ref DisplayServerX11::screen_get_image(int p_screen) const { } } + XSetErrorHandler(old_handler); + Ref img; if (image) { int width = image->width; @@ -5815,6 +5838,8 @@ static ::XIMStyle _get_best_xim_style(const ::XIMStyle &p_style_a, const ::XIMSt DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) { KeyMappingX11::initialize(); + xwayland = OS::get_singleton()->get_environment("XDG_SESSION_TYPE").to_lower() == "wayland"; + native_menu = memnew(NativeMenu); context = p_context; diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h index f0b18119869..341ba5f079f 100644 --- a/platform/linuxbsd/x11/display_server_x11.h +++ b/platform/linuxbsd/x11/display_server_x11.h @@ -330,6 +330,7 @@ class DisplayServerX11 : public DisplayServer { bool xrandr_ext_ok = true; bool xinerama_ext_ok = true; bool xshaped_ext_ok = true; + bool xwayland = false; struct Property { unsigned char *data;