summaryrefslogtreecommitdiffstats
path: root/platform/linuxbsd
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linuxbsd')
-rw-r--r--platform/linuxbsd/detect.py24
-rw-r--r--platform/linuxbsd/freedesktop_portal_desktop.cpp7
-rw-r--r--platform/linuxbsd/wayland/display_server_wayland.cpp25
-rw-r--r--platform/linuxbsd/wayland/display_server_wayland.h6
-rw-r--r--platform/linuxbsd/wayland/wayland_thread.h3
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp105
-rw-r--r--platform/linuxbsd/x11/display_server_x11.h6
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();
};