diff options
Diffstat (limited to 'platform/linuxbsd')
-rw-r--r-- | platform/linuxbsd/detect.py | 24 | ||||
-rw-r--r-- | platform/linuxbsd/freedesktop_portal_desktop.cpp | 7 | ||||
-rw-r--r-- | platform/linuxbsd/wayland/display_server_wayland.cpp | 25 | ||||
-rw-r--r-- | platform/linuxbsd/wayland/display_server_wayland.h | 6 | ||||
-rw-r--r-- | platform/linuxbsd/wayland/wayland_thread.h | 3 | ||||
-rw-r--r-- | platform/linuxbsd/x11/display_server_x11.cpp | 105 | ||||
-rw-r--r-- | platform/linuxbsd/x11/display_server_x11.h | 6 |
7 files changed, 121 insertions, 55 deletions
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index a8b8d2934a..303a88ab26 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -1,11 +1,11 @@ import os import platform import sys -from methods import print_warning, print_error, get_compiler_version, using_gcc -from platform_methods import detect_arch - from typing import TYPE_CHECKING +from methods import get_compiler_version, print_error, print_warning, using_gcc +from platform_methods import detect_arch + if TYPE_CHECKING: from SCons.Script.SConscript import SConsEnvironment @@ -50,7 +50,7 @@ def get_opts(): BoolVariable("wayland", "Enable Wayland display", True), BoolVariable("libdecor", "Enable libdecor support", True), BoolVariable("touch", "Enable touch events", True), - BoolVariable("execinfo", "Use libexecinfo on systems where glibc is not available", None), + BoolVariable("execinfo", "Use libexecinfo on systems where glibc is not available", False), ] @@ -65,10 +65,10 @@ def get_doc_path(): def get_flags(): - return [ - ("arch", detect_arch()), - ("supported", ["mono"]), - ] + return { + "arch": detect_arch(), + "supported": ["mono"], + } def configure(env: "SConsEnvironment"): @@ -491,16 +491,12 @@ def configure(env: "SConsEnvironment"): env.Append(LIBS=["dl"]) if platform.libc_ver()[0] != "glibc": - # The default crash handler depends on glibc, so if the host uses - # a different libc (BSD libc, musl), fall back to libexecinfo. - if not "execinfo" in env: - print("Note: Using `execinfo=yes` for the crash handler as required on platforms where glibc is missing.") - env["execinfo"] = True - if env["execinfo"]: env.Append(LIBS=["execinfo"]) env.Append(CPPDEFINES=["CRASH_HANDLER_ENABLED"]) else: + # The default crash handler depends on glibc, so if the host uses + # a different libc (BSD libc, musl), libexecinfo is required. print("Note: Using `execinfo=no` disables the crash handler on platforms where glibc is missing.") else: env.Append(CPPDEFINES=["CRASH_HANDLER_ENABLED"]) diff --git a/platform/linuxbsd/freedesktop_portal_desktop.cpp b/platform/linuxbsd/freedesktop_portal_desktop.cpp index e65404a531..464c0e4286 100644 --- a/platform/linuxbsd/freedesktop_portal_desktop.cpp +++ b/platform/linuxbsd/freedesktop_portal_desktop.cpp @@ -597,7 +597,12 @@ void FreeDesktopPortalDesktop::_thread_monitor(void *p_ud) { void FreeDesktopPortalDesktop::_system_theme_changed_callback() { if (system_theme_changed.is_valid()) { - system_theme_changed.call(); + Variant ret; + Callable::CallError ce; + system_theme_changed.callp(nullptr, 0, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat("Failed to execute system theme changed callback: %s.", Variant::get_callable_error_text(system_theme_changed, nullptr, 0, ce))); + } } } diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index f7995472d0..12d3a6fd2f 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -1137,7 +1137,14 @@ void DisplayServerWayland::process_events() { WindowData wd = main_window; if (wd.drop_files_callback.is_valid()) { - wd.drop_files_callback.call(dropfiles_msg->files); + Variant v_files = dropfiles_msg->files; + const Variant *v_args[1] = { &v_files }; + Variant ret; + Callable::CallError ce; + wd.drop_files_callback.callp((const Variant **)&v_args, 1, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat("Failed to execute drop files callback: %s.", Variant::get_callable_error_text(wd.drop_files_callback, v_args, 1, ce))); + } } } } @@ -1209,6 +1216,15 @@ void DisplayServerWayland::set_context(Context p_context) { wayland_thread.window_set_app_id(MAIN_WINDOW_ID, app_id); } +bool DisplayServerWayland::is_window_transparency_available() const { +#if defined(RD_ENABLED) + if (rendering_device && !rendering_device->is_composite_alpha_supported()) { + return false; + } +#endif + return OS::get_singleton()->is_layered_allowed(); +} + Vector<String> DisplayServerWayland::get_rendering_drivers_func() { Vector<String> drivers; @@ -1224,8 +1240,8 @@ Vector<String> DisplayServerWayland::get_rendering_drivers_func() { return drivers; } -DisplayServer *DisplayServerWayland::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Error &r_error) { - DisplayServer *ds = memnew(DisplayServerWayland(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error)); +DisplayServer *DisplayServerWayland::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Context p_context, Error &r_error) { + DisplayServer *ds = memnew(DisplayServerWayland(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, p_context, r_error)); if (r_error != OK) { ERR_PRINT("Can't create the Wayland display server."); memdelete(ds); @@ -1235,7 +1251,7 @@ DisplayServer *DisplayServerWayland::create_func(const String &p_rendering_drive return ds; } -DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { +DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Context p_context, Error &r_error) { #ifdef GLES3_ENABLED #ifdef SOWRAP_ENABLED #ifdef DEBUG_ENABLED @@ -1247,6 +1263,7 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win #endif // GLES3_ENABLED r_error = ERR_UNAVAILABLE; + context = p_context; Error thread_err = wayland_thread.init(); diff --git a/platform/linuxbsd/wayland/display_server_wayland.h b/platform/linuxbsd/wayland/display_server_wayland.h index 1bad358462..c24eb0ee62 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.h +++ b/platform/linuxbsd/wayland/display_server_wayland.h @@ -280,12 +280,14 @@ public: virtual void set_context(Context p_context) override; - static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Error &r_error); + virtual bool is_window_transparency_available() const override; + + static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Context p_context, Error &r_error); static Vector<String> get_rendering_drivers_func(); static void register_wayland_driver(); - DisplayServerWayland(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error); + DisplayServerWayland(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Context p_context, Error &r_error); ~DisplayServerWayland(); }; diff --git a/platform/linuxbsd/wayland/wayland_thread.h b/platform/linuxbsd/wayland/wayland_thread.h index d35a5b7139..0756b6b0ea 100644 --- a/platform/linuxbsd/wayland/wayland_thread.h +++ b/platform/linuxbsd/wayland/wayland_thread.h @@ -43,6 +43,9 @@ #else #include <wayland-client-core.h> #include <wayland-cursor.h> +#ifdef GLES3_ENABLED +#include <wayland-egl.h> +#endif #include <xkbcommon/xkbcommon.h> #endif // SOWRAP_ENABLED diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index 9174b65b1b..b5d08a377c 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -1007,7 +1007,8 @@ int DisplayServerX11::get_screen_count() const { if (xinerama_ext_ok && XineramaQueryExtension(x11_display, &event_base, &error_base)) { XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count); XFree(xsi); - } else { + } + if (count == 0) { count = XScreenCount(x11_display); } @@ -1068,25 +1069,29 @@ Rect2i DisplayServerX11::_screen_get_rect(int p_screen) const { ERR_FAIL_COND_V(p_screen < 0, rect); // Using Xinerama Extension. + bool found = false; int event_base, error_base; if (xinerama_ext_ok && XineramaQueryExtension(x11_display, &event_base, &error_base)) { int count; XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count); - - // Check if screen is valid. - if (p_screen < count) { - rect.position.x = xsi[p_screen].x_org; - rect.position.y = xsi[p_screen].y_org; - rect.size.width = xsi[p_screen].width; - rect.size.height = xsi[p_screen].height; - } else { - ERR_PRINT("Invalid screen index: " + itos(p_screen) + "(count: " + itos(count) + ")."); - } - if (xsi) { + if (count > 0) { + // Check if screen is valid. + if (p_screen < count) { + rect.position.x = xsi[p_screen].x_org; + rect.position.y = xsi[p_screen].y_org; + rect.size.width = xsi[p_screen].width; + rect.size.height = xsi[p_screen].height; + found = true; + } else { + ERR_PRINT(vformat("Invalid screen index: %d (count: %d).", p_screen, count)); + } + } XFree(xsi); } - } else { + } + + if (!found) { int count = XScreenCount(x11_display); if (p_screen < count) { Window root = XRootWindow(x11_display, p_screen); @@ -1097,7 +1102,7 @@ Rect2i DisplayServerX11::_screen_get_rect(int p_screen) const { rect.size.width = xwa.width; rect.size.height = xwa.height; } else { - ERR_PRINT("Invalid screen index: " + itos(p_screen) + "(count: " + itos(count) + ")."); + ERR_PRINT(vformat("Invalid screen index: %d (count: %d).", p_screen, count)); } } @@ -1503,25 +1508,33 @@ Ref<Image> DisplayServerX11::screen_get_image(int p_screen) const { XImage *image = nullptr; + bool found = false; int event_base, error_base; if (xinerama_ext_ok && XineramaQueryExtension(x11_display, &event_base, &error_base)) { int xin_count; XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &xin_count); - if (p_screen < xin_count) { - int x_count = XScreenCount(x11_display); - for (int i = 0; i < x_count; i++) { - Window root = XRootWindow(x11_display, i); - XWindowAttributes root_attrs; - XGetWindowAttributes(x11_display, root, &root_attrs); - if ((xsi[p_screen].x_org >= root_attrs.x) && (xsi[p_screen].x_org <= root_attrs.x + root_attrs.width) && (xsi[p_screen].y_org >= root_attrs.y) && (xsi[p_screen].y_org <= root_attrs.y + root_attrs.height)) { - image = XGetImage(x11_display, root, xsi[p_screen].x_org, xsi[p_screen].y_org, xsi[p_screen].width, xsi[p_screen].height, AllPlanes, ZPixmap); - break; + if (xsi) { + if (xin_count > 0) { + if (p_screen < xin_count) { + int x_count = XScreenCount(x11_display); + for (int i = 0; i < x_count; i++) { + Window root = XRootWindow(x11_display, i); + XWindowAttributes root_attrs; + XGetWindowAttributes(x11_display, root, &root_attrs); + if ((xsi[p_screen].x_org >= root_attrs.x) && (xsi[p_screen].x_org <= root_attrs.x + root_attrs.width) && (xsi[p_screen].y_org >= root_attrs.y) && (xsi[p_screen].y_org <= root_attrs.y + root_attrs.height)) { + found = true; + image = XGetImage(x11_display, root, xsi[p_screen].x_org, xsi[p_screen].y_org, xsi[p_screen].width, xsi[p_screen].height, AllPlanes, ZPixmap); + break; + } + } + } else { + ERR_PRINT(vformat("Invalid screen index: %d (count: %d).", p_screen, xin_count)); } } - } else { - ERR_FAIL_V_MSG(Ref<Image>(), "Invalid screen index: " + itos(p_screen) + "(count: " + itos(xin_count) + ")."); + XFree(xsi); } - } else { + } + if (!found) { int x_count = XScreenCount(x11_display); if (p_screen < x_count) { Window root = XRootWindow(x11_display, p_screen); @@ -1531,7 +1544,7 @@ Ref<Image> DisplayServerX11::screen_get_image(int p_screen) const { image = XGetImage(x11_display, root, root_attrs.x, root_attrs.y, root_attrs.width, root_attrs.height, AllPlanes, ZPixmap); } else { - ERR_FAIL_V_MSG(Ref<Image>(), "Invalid screen index: " + itos(p_screen) + "(count: " + itos(x_count) + ")."); + ERR_PRINT(vformat("Invalid screen index: %d (count: %d).", p_screen, x_count)); } } @@ -4193,7 +4206,10 @@ void DisplayServerX11::popup_close(WindowID p_window) { WindowID win_id = E->get(); popup_list.erase(E); - _send_window_event(windows[win_id], DisplayServerX11::WINDOW_EVENT_CLOSE_REQUEST); + if (win_id != p_window) { + // Only request close on related windows, not this window. We are already processing it. + _send_window_event(windows[win_id], DisplayServerX11::WINDOW_EVENT_CLOSE_REQUEST); + } E = F; } } @@ -4995,7 +5011,14 @@ void DisplayServerX11::process_events() { } if (windows[window_id].drop_files_callback.is_valid()) { - windows[window_id].drop_files_callback.call(files); + Variant v_files = files; + const Variant *v_args[1] = { &v_files }; + Variant ret; + Callable::CallError ce; + windows[window_id].drop_files_callback.callp((const Variant **)&v_args, 1, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat("Failed to execute drop files callback: %s.", Variant::get_callable_error_text(windows[window_id].drop_files_callback, v_args, 1, ce))); + } } //Reply that all is well. @@ -5179,6 +5202,23 @@ void DisplayServerX11::set_context(Context p_context) { } } +bool DisplayServerX11::is_window_transparency_available() const { + CharString net_wm_cm_name = vformat("_NET_WM_CM_S%d", XDefaultScreen(x11_display)).ascii(); + Atom net_wm_cm = XInternAtom(x11_display, net_wm_cm_name.get_data(), False); + if (net_wm_cm == None) { + return false; + } + if (XGetSelectionOwner(x11_display, net_wm_cm) == None) { + return false; + } +#if defined(RD_ENABLED) + if (rendering_device && !rendering_device->is_composite_alpha_supported()) { + return false; + } +#endif + return OS::get_singleton()->is_layered_allowed(); +} + void DisplayServerX11::set_native_icon(const String &p_filename) { WARN_PRINT("Native icon not supported by this display server."); } @@ -5320,8 +5360,8 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() { return drivers; } -DisplayServer *DisplayServerX11::create_func(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, Error &r_error) { - DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error)); +DisplayServer *DisplayServerX11::create_func(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) { + DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, r_error)); if (r_error != OK) { if (p_rendering_driver == "vulkan") { String executable_name = OS::get_singleton()->get_executable_path().get_file(); @@ -5752,10 +5792,11 @@ static ::XIMStyle _get_best_xim_style(const ::XIMStyle &p_style_a, const ::XIMSt return p_style_a; } -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, Error &r_error) { +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(); native_menu = memnew(NativeMenu); + context = p_context; #ifdef SOWRAP_ENABLED #ifdef DEBUG_ENABLED diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h index 8a7062857c..7c69df3df0 100644 --- a/platform/linuxbsd/x11/display_server_x11.h +++ b/platform/linuxbsd/x11/display_server_x11.h @@ -530,15 +530,17 @@ public: virtual void set_context(Context p_context) override; + virtual bool is_window_transparency_available() const override; + virtual void set_native_icon(const String &p_filename) override; virtual void set_icon(const Ref<Image> &p_icon) override; - static DisplayServer *create_func(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, Error &r_error); + static DisplayServer *create_func(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); static Vector<String> get_rendering_drivers_func(); static void register_x11_driver(); - 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, Error &r_error); + 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); ~DisplayServerX11(); }; |