feat: modules moved and engine moved to submodule
This commit is contained in:
parent
dfb5e645cd
commit
c33d2130cc
5136 changed files with 225275 additions and 64485 deletions
|
|
@ -60,25 +60,23 @@ typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display *, GLXFBConfig, GLX
|
|||
// To prevent shadowing warnings
|
||||
#undef glGetString
|
||||
|
||||
struct vendor {
|
||||
const char *glxvendor = nullptr;
|
||||
int priority = 0;
|
||||
};
|
||||
int silent_error_handler(Display *display, XErrorEvent *error) {
|
||||
static char message[1024];
|
||||
XGetErrorText(display, error->error_code, message, sizeof(message));
|
||||
print_verbose(vformat("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), (uint64_t)error->request_code, (uint64_t)error->minor_code, (uint64_t)error->serial));
|
||||
|
||||
vendor vendormap[] = {
|
||||
{ "Advanced Micro Devices, Inc.", 30 },
|
||||
{ "AMD", 30 },
|
||||
{ "NVIDIA Corporation", 30 },
|
||||
{ "X.Org", 30 },
|
||||
{ "Intel Open Source Technology Center", 20 },
|
||||
{ "Intel", 20 },
|
||||
{ "nouveau", 10 },
|
||||
{ "Mesa Project", 0 },
|
||||
{ nullptr, 0 }
|
||||
};
|
||||
quick_exit(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Runs inside a child. Exiting will not quit the engine.
|
||||
void create_context() {
|
||||
void DetectPrimeX11::create_context() {
|
||||
XSetErrorHandler(&silent_error_handler);
|
||||
|
||||
Display *x11_display = XOpenDisplay(nullptr);
|
||||
Window x11_window;
|
||||
GLXContext glx_context;
|
||||
|
|
@ -137,20 +135,7 @@ void create_context() {
|
|||
XFree(vi);
|
||||
}
|
||||
|
||||
int silent_error_handler(Display *display, XErrorEvent *error) {
|
||||
static char message[1024];
|
||||
XGetErrorText(display, error->error_code, message, sizeof(message));
|
||||
print_verbose(vformat("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), (uint64_t)error->request_code, (uint64_t)error->minor_code, (uint64_t)error->serial));
|
||||
|
||||
quick_exit(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int detect_prime() {
|
||||
int DetectPrimeX11::detect_prime() {
|
||||
pid_t p;
|
||||
int priorities[2] = {};
|
||||
String vendors[2];
|
||||
|
|
@ -202,7 +187,6 @@ int detect_prime() {
|
|||
// cleaning up these processes, and fork() makes a copy
|
||||
// of all globals.
|
||||
CoreGlobals::leak_reporting_enabled = false;
|
||||
XSetErrorHandler(&silent_error_handler);
|
||||
|
||||
char string[201];
|
||||
|
||||
|
|
@ -253,7 +237,7 @@ int detect_prime() {
|
|||
}
|
||||
|
||||
for (int i = 1; i >= 0; --i) {
|
||||
vendor *v = vendormap;
|
||||
const Vendor *v = vendor_map;
|
||||
while (v->glxvendor) {
|
||||
if (v->glxvendor == vendors[i]) {
|
||||
priorities[i] = v->priority;
|
||||
|
|
|
|||
|
|
@ -28,13 +28,33 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DETECT_PRIME_X11_H
|
||||
#define DETECT_PRIME_X11_H
|
||||
#pragma once
|
||||
|
||||
#if defined(X11_ENABLED) && defined(GLES3_ENABLED)
|
||||
|
||||
int detect_prime();
|
||||
class DetectPrimeX11 {
|
||||
private:
|
||||
struct Vendor {
|
||||
const char *glxvendor = nullptr;
|
||||
int priority = 0;
|
||||
};
|
||||
|
||||
static constexpr Vendor vendor_map[] = {
|
||||
{ "Advanced Micro Devices, Inc.", 30 },
|
||||
{ "AMD", 30 },
|
||||
{ "NVIDIA Corporation", 30 },
|
||||
{ "X.Org", 30 },
|
||||
{ "Intel Open Source Technology Center", 20 },
|
||||
{ "Intel", 20 },
|
||||
{ "nouveau", 10 },
|
||||
{ "Mesa Project", 0 },
|
||||
{ nullptr, 0 }
|
||||
};
|
||||
|
||||
public:
|
||||
static void create_context();
|
||||
|
||||
static int detect_prime();
|
||||
};
|
||||
|
||||
#endif // X11_ENABLED && GLES3_ENABLED
|
||||
|
||||
#endif // DETECT_PRIME_X11_H
|
||||
|
|
|
|||
|
|
@ -39,9 +39,12 @@
|
|||
#include "core/math/math_funcs.h"
|
||||
#include "core/string/print_string.h"
|
||||
#include "core/string/ustring.h"
|
||||
#include "core/version.h"
|
||||
#include "drivers/png/png_driver_common.h"
|
||||
#include "main/main.h"
|
||||
|
||||
#include "servers/rendering/dummy/rasterizer_dummy.h"
|
||||
|
||||
#if defined(VULKAN_ENABLED)
|
||||
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
|
||||
#endif
|
||||
|
|
@ -50,6 +53,10 @@
|
|||
#include "drivers/gles3/rasterizer_gles3.h"
|
||||
#endif
|
||||
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
#include "drivers/accesskit/accessibility_driver_accesskit.h"
|
||||
#endif
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -111,8 +118,7 @@ struct Hints {
|
|||
static String get_atom_name(Display *p_disp, Atom p_atom) {
|
||||
char *name = XGetAtomName(p_disp, p_atom);
|
||||
ERR_FAIL_NULL_V_MSG(name, String(), "Atom is invalid.");
|
||||
String ret;
|
||||
ret.parse_utf8(name);
|
||||
String ret = String::utf8(name);
|
||||
XFree(name);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -156,6 +162,9 @@ bool DisplayServerX11::has_feature(Feature p_feature) const {
|
|||
case FEATURE_NATIVE_DIALOG_FILE_MIME: {
|
||||
return (portal_desktop && portal_desktop->is_supported() && portal_desktop->is_file_chooser_supported());
|
||||
} break;
|
||||
case FEATURE_NATIVE_COLOR_PICKER: {
|
||||
return (portal_desktop && portal_desktop->is_supported() && portal_desktop->is_screenshot_supported());
|
||||
} break;
|
||||
#endif
|
||||
case FEATURE_SCREEN_CAPTURE: {
|
||||
return !xwayland;
|
||||
|
|
@ -167,6 +176,12 @@ bool DisplayServerX11::has_feature(Feature p_feature) const {
|
|||
} break;
|
||||
#endif
|
||||
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
case FEATURE_ACCESSIBILITY_SCREEN_READER: {
|
||||
return (accessibility_driver != nullptr);
|
||||
} break;
|
||||
#endif
|
||||
|
||||
default: {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -338,38 +353,63 @@ void DisplayServerX11::_flush_mouse_motion() {
|
|||
|
||||
#ifdef SPEECHD_ENABLED
|
||||
|
||||
void DisplayServerX11::initialize_tts() const {
|
||||
const_cast<DisplayServerX11 *>(this)->tts = memnew(TTS_Linux);
|
||||
}
|
||||
|
||||
bool DisplayServerX11::tts_is_speaking() const {
|
||||
ERR_FAIL_NULL_V_MSG(tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech.");
|
||||
if (unlikely(!tts)) {
|
||||
initialize_tts();
|
||||
}
|
||||
ERR_FAIL_NULL_V(tts, false);
|
||||
return tts->is_speaking();
|
||||
}
|
||||
|
||||
bool DisplayServerX11::tts_is_paused() const {
|
||||
ERR_FAIL_NULL_V_MSG(tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech.");
|
||||
if (unlikely(!tts)) {
|
||||
initialize_tts();
|
||||
}
|
||||
ERR_FAIL_NULL_V(tts, false);
|
||||
return tts->is_paused();
|
||||
}
|
||||
|
||||
TypedArray<Dictionary> DisplayServerX11::tts_get_voices() const {
|
||||
ERR_FAIL_NULL_V_MSG(tts, TypedArray<Dictionary>(), "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech.");
|
||||
if (unlikely(!tts)) {
|
||||
initialize_tts();
|
||||
}
|
||||
ERR_FAIL_NULL_V(tts, TypedArray<Dictionary>());
|
||||
return tts->get_voices();
|
||||
}
|
||||
|
||||
void DisplayServerX11::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) {
|
||||
ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech.");
|
||||
if (unlikely(!tts)) {
|
||||
initialize_tts();
|
||||
}
|
||||
ERR_FAIL_NULL(tts);
|
||||
tts->speak(p_text, p_voice, p_volume, p_pitch, p_rate, p_utterance_id, p_interrupt);
|
||||
}
|
||||
|
||||
void DisplayServerX11::tts_pause() {
|
||||
ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech.");
|
||||
if (unlikely(!tts)) {
|
||||
initialize_tts();
|
||||
}
|
||||
ERR_FAIL_NULL(tts);
|
||||
tts->pause();
|
||||
}
|
||||
|
||||
void DisplayServerX11::tts_resume() {
|
||||
ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech.");
|
||||
if (unlikely(!tts)) {
|
||||
initialize_tts();
|
||||
}
|
||||
ERR_FAIL_NULL(tts);
|
||||
tts->resume();
|
||||
}
|
||||
|
||||
void DisplayServerX11::tts_stop() {
|
||||
ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech.");
|
||||
if (unlikely(!tts)) {
|
||||
initialize_tts();
|
||||
}
|
||||
ERR_FAIL_NULL(tts);
|
||||
tts->stop();
|
||||
}
|
||||
|
||||
|
|
@ -398,30 +438,34 @@ bool DisplayServerX11::is_dark_mode() const {
|
|||
}
|
||||
}
|
||||
|
||||
Color DisplayServerX11::get_accent_color() const {
|
||||
return portal_desktop->get_appearance_accent_color();
|
||||
}
|
||||
|
||||
void DisplayServerX11::set_system_theme_change_callback(const Callable &p_callable) {
|
||||
portal_desktop->set_system_theme_change_callback(p_callable);
|
||||
}
|
||||
|
||||
Error DisplayServerX11::file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback) {
|
||||
WindowID window_id = last_focused_window;
|
||||
Error DisplayServerX11::file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback, WindowID p_window_id) {
|
||||
WindowID window_id = p_window_id;
|
||||
|
||||
if (!windows.has(window_id)) {
|
||||
if (!windows.has(window_id) || windows[window_id].is_popup) {
|
||||
window_id = MAIN_WINDOW_ID;
|
||||
}
|
||||
|
||||
String xid = vformat("x11:%x", (uint64_t)windows[window_id].x11_window);
|
||||
return portal_desktop->file_dialog_show(last_focused_window, xid, p_title, p_current_directory, String(), p_filename, p_mode, p_filters, TypedArray<Dictionary>(), p_callback, false);
|
||||
return portal_desktop->file_dialog_show(p_window_id, xid, p_title, p_current_directory, String(), p_filename, p_mode, p_filters, TypedArray<Dictionary>(), p_callback, false);
|
||||
}
|
||||
|
||||
Error DisplayServerX11::file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback) {
|
||||
WindowID window_id = last_focused_window;
|
||||
Error DisplayServerX11::file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback, WindowID p_window_id) {
|
||||
WindowID window_id = p_window_id;
|
||||
|
||||
if (!windows.has(window_id)) {
|
||||
if (!windows.has(window_id) || windows[window_id].is_popup) {
|
||||
window_id = MAIN_WINDOW_ID;
|
||||
}
|
||||
|
||||
String xid = vformat("x11:%x", (uint64_t)windows[window_id].x11_window);
|
||||
return portal_desktop->file_dialog_show(last_focused_window, xid, p_title, p_current_directory, p_root, p_filename, p_mode, p_filters, p_options, p_callback, true);
|
||||
return portal_desktop->file_dialog_show(p_window_id, xid, p_title, p_current_directory, p_root, p_filename, p_mode, p_filters, p_options, p_callback, true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -578,7 +622,7 @@ BitField<MouseButtonMask> DisplayServerX11::mouse_get_button_state() const {
|
|||
int root_x, root_y, win_x, win_y;
|
||||
unsigned int mask;
|
||||
if (XQueryPointer(x11_display, XRootWindow(x11_display, i), &root, &child, &root_x, &root_y, &win_x, &win_y, &mask)) {
|
||||
BitField<MouseButtonMask> last_button_state = 0;
|
||||
BitField<MouseButtonMask> last_button_state = MouseButtonMask::NONE;
|
||||
|
||||
if (mask & Button1Mask) {
|
||||
last_button_state.set_flag(MouseButtonMask::LEFT);
|
||||
|
|
@ -599,7 +643,7 @@ BitField<MouseButtonMask> DisplayServerX11::mouse_get_button_state() const {
|
|||
return last_button_state;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return MouseButtonMask::NONE;
|
||||
}
|
||||
|
||||
void DisplayServerX11::clipboard_set(const String &p_text) {
|
||||
|
|
@ -759,7 +803,7 @@ String DisplayServerX11::_clipboard_get_impl(Atom p_source, Window x11_window, A
|
|||
}
|
||||
|
||||
if (success && (data_size > 0)) {
|
||||
ret.parse_utf8((const char *)incr_data.ptr(), data_size);
|
||||
ret.append_utf8((const char *)incr_data.ptr(), data_size);
|
||||
}
|
||||
} else if (bytes_left > 0) {
|
||||
// Data is ready and can be processed all at once.
|
||||
|
|
@ -769,7 +813,7 @@ String DisplayServerX11::_clipboard_get_impl(Atom p_source, Window x11_window, A
|
|||
&len, &dummy, &data);
|
||||
|
||||
if (result == Success) {
|
||||
ret.parse_utf8((const char *)data);
|
||||
ret.append_utf8((const char *)data);
|
||||
} else {
|
||||
print_verbose("Failed to get selection data.");
|
||||
}
|
||||
|
|
@ -1912,6 +1956,12 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
if (accessibility_driver) {
|
||||
accessibility_driver->window_destroy(p_id);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (wd.xic) {
|
||||
XDestroyIC(wd.xic);
|
||||
wd.xic = nullptr;
|
||||
|
|
@ -2061,7 +2111,7 @@ void DisplayServerX11::_update_window_mouse_passthrough(WindowID p_window) {
|
|||
Region region = XCreateRegion();
|
||||
XShapeCombineRegion(x11_display, windows[p_window].x11_window, ShapeInput, 0, 0, region, ShapeSet);
|
||||
XDestroyRegion(region);
|
||||
} else if (region_path.size() == 0) {
|
||||
} else if (region_path.is_empty()) {
|
||||
XShapeCombineMask(x11_display, windows[p_window].x11_window, ShapeInput, 0, 0, None, ShapeSet);
|
||||
} else {
|
||||
XPoint *points = (XPoint *)memalloc(sizeof(XPoint) * region_path.size());
|
||||
|
|
@ -2284,6 +2334,40 @@ void DisplayServerX11::_update_size_hints(WindowID p_window) {
|
|||
XFree(xsh);
|
||||
}
|
||||
|
||||
void DisplayServerX11::_update_actions_hints(WindowID p_window) {
|
||||
WindowData &wd = windows[p_window];
|
||||
|
||||
Atom prop = XInternAtom(x11_display, "_NET_WM_ALLOWED_ACTIONS", False);
|
||||
if (prop != None) {
|
||||
Atom wm_act_max_horz = XInternAtom(x11_display, "_NET_WM_ACTION_MAXIMIZE_HORZ", False);
|
||||
Atom wm_act_max_vert = XInternAtom(x11_display, "_NET_WM_ACTION_MAXIMIZE_VERT", False);
|
||||
Atom wm_act_min = XInternAtom(x11_display, "_NET_WM_ACTION_MINIMIZE", False);
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long len;
|
||||
unsigned long remaining;
|
||||
unsigned char *data = nullptr;
|
||||
if (XGetWindowProperty(x11_display, wd.x11_window, prop, 0, 1024, False, XA_ATOM, &type, &format, &len, &remaining, &data) == Success) {
|
||||
Atom *atoms = (Atom *)data;
|
||||
Vector<Atom> new_atoms;
|
||||
for (uint64_t i = 0; i < len; i++) {
|
||||
if (atoms[i] != wm_act_max_horz && atoms[i] != wm_act_max_vert && atoms[i] != wm_act_min) {
|
||||
new_atoms.push_back(atoms[i]);
|
||||
}
|
||||
}
|
||||
if (!wd.no_max_btn) {
|
||||
new_atoms.push_back(wm_act_max_horz);
|
||||
new_atoms.push_back(wm_act_max_vert);
|
||||
}
|
||||
if (!wd.no_min_btn) {
|
||||
new_atoms.push_back(wm_act_min);
|
||||
}
|
||||
XChangeProperty(x11_display, wd.x11_window, prop, XA_ATOM, 32, PropModeReplace, (unsigned char *)new_atoms.ptrw(), new_atoms.size());
|
||||
XFree(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Point2i DisplayServerX11::window_get_position(WindowID p_window) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
|
@ -2338,6 +2422,7 @@ void DisplayServerX11::window_set_position(const Point2i &p_position, WindowID p
|
|||
return;
|
||||
}
|
||||
|
||||
wd.position = p_position;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
if (!window_get_flag(WINDOW_FLAG_BORDERLESS, p_window)) {
|
||||
|
|
@ -2563,7 +2648,8 @@ bool DisplayServerX11::_window_maximize_check(WindowID p_window, const char *p_a
|
|||
Atom *atoms = (Atom *)data;
|
||||
Atom wm_act_max_horz;
|
||||
Atom wm_act_max_vert;
|
||||
if (strcmp(p_atom_name, "_NET_WM_STATE") == 0) {
|
||||
bool checking_state = strcmp(p_atom_name, "_NET_WM_STATE") == 0;
|
||||
if (checking_state) {
|
||||
wm_act_max_horz = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
|
||||
wm_act_max_vert = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
|
||||
} else {
|
||||
|
|
@ -2581,9 +2667,16 @@ bool DisplayServerX11::_window_maximize_check(WindowID p_window, const char *p_a
|
|||
found_wm_act_max_vert = true;
|
||||
}
|
||||
|
||||
if (found_wm_act_max_horz || found_wm_act_max_vert) {
|
||||
retval = true;
|
||||
break;
|
||||
if (checking_state) {
|
||||
if (found_wm_act_max_horz && found_wm_act_max_vert) {
|
||||
retval = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (found_wm_act_max_horz || found_wm_act_max_vert) {
|
||||
retval = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2961,6 +3054,18 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
|
|||
WindowData &wd = windows[p_window];
|
||||
|
||||
switch (p_flag) {
|
||||
case WINDOW_FLAG_MAXIMIZE_DISABLED: {
|
||||
wd.no_max_btn = p_enabled;
|
||||
_update_actions_hints(p_window);
|
||||
|
||||
XFlush(x11_display);
|
||||
} break;
|
||||
case WINDOW_FLAG_MINIMIZE_DISABLED: {
|
||||
wd.no_min_btn = p_enabled;
|
||||
_update_actions_hints(p_window);
|
||||
|
||||
XFlush(x11_display);
|
||||
} break;
|
||||
case WINDOW_FLAG_RESIZE_DISABLED: {
|
||||
if (p_enabled && wd.embed_parent) {
|
||||
print_line("Embedded window resize can't be disabled.");
|
||||
|
|
@ -2969,6 +3074,7 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
|
|||
|
||||
wd.resize_disabled = p_enabled;
|
||||
_update_size_hints(p_window);
|
||||
_update_actions_hints(p_window);
|
||||
|
||||
XFlush(x11_display);
|
||||
} break;
|
||||
|
|
@ -3055,6 +3161,12 @@ bool DisplayServerX11::window_get_flag(WindowFlags p_flag, WindowID p_window) co
|
|||
const WindowData &wd = windows[p_window];
|
||||
|
||||
switch (p_flag) {
|
||||
case WINDOW_FLAG_MAXIMIZE_DISABLED: {
|
||||
return wd.no_max_btn;
|
||||
} break;
|
||||
case WINDOW_FLAG_MINIMIZE_DISABLED: {
|
||||
return wd.no_min_btn;
|
||||
} break;
|
||||
case WINDOW_FLAG_RESIZE_DISABLED: {
|
||||
return wd.resize_disabled;
|
||||
} break;
|
||||
|
|
@ -3244,6 +3356,22 @@ void DisplayServerX11::window_set_ime_position(const Point2i &p_pos, WindowID p_
|
|||
}
|
||||
}
|
||||
|
||||
int DisplayServerX11::accessibility_should_increase_contrast() const {
|
||||
#ifdef DBUS_ENABLED
|
||||
return portal_desktop->get_high_contrast();
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
int DisplayServerX11::accessibility_screen_reader_active() const {
|
||||
#ifdef DBUS_ENABLED
|
||||
if (atspi_monitor->is_supported()) {
|
||||
return atspi_monitor->is_active();
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
Point2i DisplayServerX11::ime_get_selection() const {
|
||||
return im_selection;
|
||||
}
|
||||
|
|
@ -3355,6 +3483,10 @@ void DisplayServerX11::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu
|
|||
}
|
||||
}
|
||||
|
||||
bool DisplayServerX11::get_swap_cancel_ok() {
|
||||
return swap_cancel_ok;
|
||||
}
|
||||
|
||||
int DisplayServerX11::keyboard_get_layout_count() const {
|
||||
int _group_count = 0;
|
||||
XkbDescRec *kbd = XkbAllocKeyboard();
|
||||
|
|
@ -3496,6 +3628,17 @@ Key DisplayServerX11::keyboard_get_label_from_physical(Key p_keycode) const {
|
|||
return (Key)(key | modifiers);
|
||||
}
|
||||
|
||||
bool DisplayServerX11::color_picker(const Callable &p_callback) {
|
||||
WindowID window_id = last_focused_window;
|
||||
|
||||
if (!windows.has(window_id)) {
|
||||
window_id = MAIN_WINDOW_ID;
|
||||
}
|
||||
|
||||
String xid = vformat("x11:%x", (uint64_t)windows[window_id].x11_window);
|
||||
return portal_desktop->color_picker(xid, p_callback);
|
||||
}
|
||||
|
||||
DisplayServerX11::Property DisplayServerX11::_read_property(Display *p_display, Window p_window, Atom p_property) {
|
||||
Atom actual_type = None;
|
||||
int actual_format = 0;
|
||||
|
|
@ -3657,8 +3800,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
|
|||
keycode -= 'a' - 'A';
|
||||
}
|
||||
|
||||
String tmp;
|
||||
tmp.parse_utf8(utf8string, utf8bytes);
|
||||
String tmp = String::utf8(utf8string, utf8bytes);
|
||||
for (int i = 0; i < tmp.length(); i++) {
|
||||
Ref<InputEventKey> k;
|
||||
k.instantiate();
|
||||
|
|
@ -3738,8 +3880,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
|
|||
char str_xkb[256] = {};
|
||||
int str_xkb_size = xkb_compose_state_get_utf8(wd.xkb_state, str_xkb, 255);
|
||||
|
||||
String tmp;
|
||||
tmp.parse_utf8(str_xkb, str_xkb_size);
|
||||
String tmp = String::utf8(str_xkb, str_xkb_size);
|
||||
for (int i = 0; i < tmp.length(); i++) {
|
||||
Ref<InputEventKey> k;
|
||||
k.instantiate();
|
||||
|
|
@ -3961,7 +4102,7 @@ Atom DisplayServerX11::_process_selection_request_target(Atom p_target, Window p
|
|||
32,
|
||||
PropModeReplace,
|
||||
(unsigned char *)&data,
|
||||
sizeof(data) / sizeof(data[0]));
|
||||
std::size(data));
|
||||
return p_property;
|
||||
} else if (p_target == XInternAtom(x11_display, "SAVE_TARGETS", 0)) {
|
||||
// Request to check if SAVE_TARGETS is supported, nothing special to do.
|
||||
|
|
@ -4094,7 +4235,7 @@ void DisplayServerX11::_xim_preedit_draw_callback(::XIM xim, ::XPointer client_d
|
|||
if (xim_text->encoding_is_wchar) {
|
||||
changed_text = String(xim_text->string.wide_char);
|
||||
} else {
|
||||
changed_text.parse_utf8(xim_text->string.multi_byte);
|
||||
changed_text.append_utf8(xim_text->string.multi_byte);
|
||||
}
|
||||
|
||||
if (call_data->chg_length < 0) {
|
||||
|
|
@ -4789,6 +4930,9 @@ void DisplayServerX11::process_events() {
|
|||
XSync(x11_display, False);
|
||||
XGetWindowAttributes(x11_display, wd.x11_window, &xwa);
|
||||
|
||||
_update_actions_hints(window_id);
|
||||
XFlush(x11_display);
|
||||
|
||||
// Set focus when menu window is started.
|
||||
// RevertToPointerRoot is used to make sure we don't lose all focus in case
|
||||
// a subwindow and its parent are both destroyed.
|
||||
|
|
@ -4878,6 +5022,11 @@ void DisplayServerX11::process_events() {
|
|||
static unsigned int focus_order = 0;
|
||||
wd.focus_order = ++focus_order;
|
||||
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
if (accessibility_driver) {
|
||||
accessibility_driver->accessibility_set_window_focused(window_id, true);
|
||||
}
|
||||
#endif
|
||||
_send_window_event(wd, WINDOW_EVENT_FOCUS_IN);
|
||||
|
||||
if (mouse_mode_grab) {
|
||||
|
|
@ -4929,6 +5078,11 @@ void DisplayServerX11::process_events() {
|
|||
wd.focused = false;
|
||||
|
||||
Input::get_singleton()->release_pressed_events();
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
if (accessibility_driver) {
|
||||
accessibility_driver->accessibility_set_window_focused(window_id, false);
|
||||
}
|
||||
#endif
|
||||
_send_window_event(wd, WINDOW_EVENT_FOCUS_OUT);
|
||||
|
||||
if (mouse_mode_grab) {
|
||||
|
|
@ -5164,7 +5318,7 @@ void DisplayServerX11::process_events() {
|
|||
pos = Point2i(windows[focused_window_id].size.width / 2, windows[focused_window_id].size.height / 2);
|
||||
}
|
||||
|
||||
BitField<MouseButtonMask> last_button_state = 0;
|
||||
BitField<MouseButtonMask> last_button_state = MouseButtonMask::NONE;
|
||||
if (event.xmotion.state & Button1Mask) {
|
||||
last_button_state.set_flag(MouseButtonMask::LEFT);
|
||||
}
|
||||
|
|
@ -5268,7 +5422,7 @@ void DisplayServerX11::process_events() {
|
|||
Vector<String> files = String((char *)p.data).split("\r\n", false);
|
||||
XFree(p.data);
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
files.write[i] = files[i].replace("file://", "").uri_decode();
|
||||
files.write[i] = files[i].replace("file://", "").uri_file_decode();
|
||||
}
|
||||
|
||||
if (windows[window_id].drop_files_callback.is_valid()) {
|
||||
|
|
@ -5385,7 +5539,7 @@ void DisplayServerX11::process_events() {
|
|||
|
||||
#ifdef DBUS_ENABLED
|
||||
if (portal_desktop) {
|
||||
portal_desktop->process_file_dialog_callbacks();
|
||||
portal_desktop->process_callbacks();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -6030,6 +6184,7 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() {
|
|||
drivers.push_back("opengl3");
|
||||
drivers.push_back("opengl3_es");
|
||||
#endif
|
||||
drivers.push_back("dummy");
|
||||
|
||||
return drivers;
|
||||
}
|
||||
|
|
@ -6178,6 +6333,15 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V
|
|||
if (dead_tbl && xkb_loaded_v05p) {
|
||||
wd.xkb_state = xkb_compose_state_new(dead_tbl, XKB_COMPOSE_STATE_NO_FLAGS);
|
||||
}
|
||||
#endif
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
if (accessibility_driver && !accessibility_driver->window_create(id, nullptr)) {
|
||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||
ERR_PRINT("Can't create an accessibility adapter for window, accessibility support disabled!");
|
||||
}
|
||||
memdelete(accessibility_driver);
|
||||
accessibility_driver = nullptr;
|
||||
}
|
||||
#endif
|
||||
// Enable receiving notification when the window is initialized (MapNotify)
|
||||
// so the focus can be set at the right time.
|
||||
|
|
@ -6466,8 +6630,12 @@ 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, int64_t p_parent_window, Error &r_error) {
|
||||
KeyMappingX11::initialize();
|
||||
|
||||
String current_desk = OS::get_singleton()->get_environment("XDG_CURRENT_DESKTOP").to_lower();
|
||||
String session_desk = OS::get_singleton()->get_environment("XDG_SESSION_DESKTOP").to_lower();
|
||||
swap_cancel_ok = (current_desk.contains("kde") || session_desk.contains("kde") || current_desk.contains("lxqt") || session_desk.contains("lxqt"));
|
||||
|
||||
xwayland = OS::get_singleton()->get_environment("XDG_SESSION_TYPE").to_lower() == "wayland";
|
||||
kde5_embed_workaround = OS::get_singleton()->get_environment("XDG_CURRENT_DESKTOP").to_lower() == "kde" && OS::get_singleton()->get_environment("KDE_SESSION_VERSION") == "5";
|
||||
kde5_embed_workaround = current_desk == "kde" && OS::get_singleton()->get_environment("KDE_SESSION_VERSION") == "5";
|
||||
|
||||
native_menu = memnew(NativeMenu);
|
||||
context = p_context;
|
||||
|
|
@ -6757,7 +6925,17 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
|
|||
// Init TTS
|
||||
bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech");
|
||||
if (tts_enabled) {
|
||||
tts = memnew(TTS_Linux);
|
||||
initialize_tts();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
if (accessibility_get_mode() != DisplayServer::AccessibilityMode::ACCESSIBILITY_DISABLED) {
|
||||
accessibility_driver = memnew(AccessibilityDriverAccessKit);
|
||||
if (accessibility_driver->init() != OK) {
|
||||
memdelete(accessibility_driver);
|
||||
accessibility_driver = nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -6770,6 +6948,11 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
|
|||
|
||||
// Initialize context and rendering device.
|
||||
|
||||
if (rendering_driver == "dummy") {
|
||||
RasterizerDummy::make_current();
|
||||
driver_found = true;
|
||||
}
|
||||
|
||||
#if defined(RD_ENABLED)
|
||||
#if defined(VULKAN_ENABLED)
|
||||
if (rendering_driver == "vulkan") {
|
||||
|
|
@ -6844,7 +7027,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
|
|||
|
||||
if (use_prime == -1) {
|
||||
print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic.");
|
||||
use_prime = detect_prime();
|
||||
use_prime = DetectPrimeX11::detect_prime();
|
||||
}
|
||||
|
||||
if (use_prime) {
|
||||
|
|
@ -6931,7 +7114,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
|
|||
window_set_flag(WindowFlags(i), true, main_window);
|
||||
}
|
||||
}
|
||||
show_window(main_window);
|
||||
|
||||
#if defined(RD_ENABLED)
|
||||
if (rendering_context) {
|
||||
|
|
@ -7101,8 +7283,8 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
|
|||
screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on"));
|
||||
|
||||
portal_desktop = memnew(FreeDesktopPortalDesktop);
|
||||
atspi_monitor = memnew(FreeDesktopAtSPIMonitor);
|
||||
#endif // DBUS_ENABLED
|
||||
|
||||
XSetErrorHandler(&default_window_error_handler);
|
||||
|
||||
r_error = OK;
|
||||
|
|
@ -7142,6 +7324,12 @@ DisplayServerX11::~DisplayServerX11() {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
if (accessibility_driver) {
|
||||
accessibility_driver->window_destroy(E.key);
|
||||
}
|
||||
#endif
|
||||
|
||||
WindowData &wd = E.value;
|
||||
if (wd.xic) {
|
||||
XDestroyIC(wd.xic);
|
||||
|
|
@ -7216,7 +7404,11 @@ DisplayServerX11::~DisplayServerX11() {
|
|||
if (xmbstring) {
|
||||
memfree(xmbstring);
|
||||
}
|
||||
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
if (accessibility_driver) {
|
||||
memdelete(accessibility_driver);
|
||||
}
|
||||
#endif
|
||||
#ifdef SPEECHD_ENABLED
|
||||
if (tts) {
|
||||
memdelete(tts);
|
||||
|
|
@ -7226,6 +7418,7 @@ DisplayServerX11::~DisplayServerX11() {
|
|||
#ifdef DBUS_ENABLED
|
||||
memdelete(screensaver);
|
||||
memdelete(portal_desktop);
|
||||
memdelete(atspi_monitor);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DISPLAY_SERVER_X11_H
|
||||
#define DISPLAY_SERVER_X11_H
|
||||
#pragma once
|
||||
|
||||
#ifdef X11_ENABLED
|
||||
|
||||
|
|
@ -66,6 +65,7 @@
|
|||
#endif
|
||||
|
||||
#if defined(DBUS_ENABLED)
|
||||
#include "freedesktop_at_spi_monitor.h"
|
||||
#include "freedesktop_portal_desktop.h"
|
||||
#include "freedesktop_screensaver.h"
|
||||
#endif
|
||||
|
|
@ -123,7 +123,7 @@ typedef struct _xrr_monitor_info {
|
|||
#undef CursorShape
|
||||
|
||||
class DisplayServerX11 : public DisplayServer {
|
||||
// No need to register with GDCLASS, it's platform-specific and nothing is added.
|
||||
GDSOFTCLASS(DisplayServerX11, DisplayServer);
|
||||
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
|
|
@ -160,6 +160,7 @@ class DisplayServerX11 : public DisplayServer {
|
|||
|
||||
#if defined(DBUS_ENABLED)
|
||||
FreeDesktopPortalDesktop *portal_desktop = nullptr;
|
||||
FreeDesktopAtSPIMonitor *atspi_monitor = nullptr;
|
||||
#endif
|
||||
|
||||
struct WindowData {
|
||||
|
|
@ -200,6 +201,8 @@ class DisplayServerX11 : public DisplayServer {
|
|||
bool on_top = false;
|
||||
bool borderless = false;
|
||||
bool resize_disabled = false;
|
||||
bool no_min_btn = false;
|
||||
bool no_max_btn = false;
|
||||
Vector2i last_position_before_fs;
|
||||
bool focused = true;
|
||||
bool minimized = false;
|
||||
|
|
@ -353,6 +356,7 @@ class DisplayServerX11 : public DisplayServer {
|
|||
bool _window_minimize_check(WindowID p_window) const;
|
||||
void _validate_mode_on_map(WindowID p_window);
|
||||
void _update_size_hints(WindowID p_window);
|
||||
void _update_actions_hints(WindowID p_window);
|
||||
void _set_wm_fullscreen(WindowID p_window, bool p_enabled, bool p_exclusive);
|
||||
void _set_wm_maximized(WindowID p_window, bool p_enabled);
|
||||
void _set_wm_minimized(WindowID p_window, bool p_enabled);
|
||||
|
|
@ -360,6 +364,7 @@ class DisplayServerX11 : public DisplayServer {
|
|||
void _update_context(WindowData &wd);
|
||||
|
||||
Context context = CONTEXT_ENGINE;
|
||||
bool swap_cancel_ok = false;
|
||||
|
||||
WindowID _get_focused_window_or_popup() const;
|
||||
bool _window_focus_check();
|
||||
|
|
@ -395,6 +400,8 @@ class DisplayServerX11 : public DisplayServer {
|
|||
void _set_window_taskbar_pager_enabled(Window p_window, bool p_enabled);
|
||||
Rect2i _screens_get_full_rect() const;
|
||||
|
||||
void initialize_tts() const;
|
||||
|
||||
protected:
|
||||
void _window_changed(XEvent *event);
|
||||
|
||||
|
|
@ -420,10 +427,11 @@ public:
|
|||
#if defined(DBUS_ENABLED)
|
||||
virtual bool is_dark_mode_supported() const override;
|
||||
virtual bool is_dark_mode() const override;
|
||||
virtual Color get_accent_color() const override;
|
||||
virtual void set_system_theme_change_callback(const Callable &p_callable) override;
|
||||
|
||||
virtual Error file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback) override;
|
||||
virtual Error file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback) override;
|
||||
virtual Error file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback, WindowID p_window_id) override;
|
||||
virtual Error file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback, WindowID p_window_id) override;
|
||||
#endif
|
||||
|
||||
virtual void beep() const override;
|
||||
|
|
@ -530,6 +538,9 @@ public:
|
|||
virtual void window_set_ime_active(const bool p_active, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||
virtual void window_set_ime_position(const Point2i &p_pos, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||
|
||||
virtual int accessibility_should_increase_contrast() const override;
|
||||
virtual int accessibility_screen_reader_active() const override;
|
||||
|
||||
virtual Point2i ime_get_selection() const override;
|
||||
virtual String ime_get_text() const override;
|
||||
|
||||
|
|
@ -548,6 +559,8 @@ public:
|
|||
virtual CursorShape cursor_get_shape() const override;
|
||||
virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) override;
|
||||
|
||||
virtual bool get_swap_cancel_ok() override;
|
||||
|
||||
virtual int keyboard_get_layout_count() const override;
|
||||
virtual int keyboard_get_current_layout() const override;
|
||||
virtual void keyboard_set_current_layout(int p_index) override;
|
||||
|
|
@ -556,6 +569,8 @@ public:
|
|||
virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override;
|
||||
virtual Key keyboard_get_label_from_physical(Key p_keycode) const override;
|
||||
|
||||
virtual bool color_picker(const Callable &p_callback) override;
|
||||
|
||||
virtual void process_events() override;
|
||||
|
||||
virtual void release_rendering_thread() override;
|
||||
|
|
@ -578,5 +593,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // X11_ENABLED
|
||||
|
||||
#endif // DISPLAY_SERVER_X11_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GL_MANAGER_X11_H
|
||||
#define GL_MANAGER_X11_H
|
||||
#pragma once
|
||||
|
||||
#if defined(X11_ENABLED) && defined(GLES3_ENABLED)
|
||||
|
||||
|
|
@ -134,5 +133,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // X11_ENABLED && GLES3_ENABLED
|
||||
|
||||
#endif // GL_MANAGER_X11_H
|
||||
|
|
|
|||
|
|
@ -28,12 +28,10 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GL_MANAGER_X11_EGL_H
|
||||
#define GL_MANAGER_X11_EGL_H
|
||||
#pragma once
|
||||
|
||||
#if defined(X11_ENABLED) && defined(GLES3_ENABLED)
|
||||
|
||||
#include "core/error/error_list.h"
|
||||
#include "core/os/os.h"
|
||||
#include "core/templates/local_vector.h"
|
||||
#include "drivers/egl/egl_manager.h"
|
||||
|
|
@ -57,5 +55,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // X11_ENABLED && GLES3_ENABLED
|
||||
|
||||
#endif // GL_MANAGER_X11_EGL_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef KEY_MAPPING_X11_H
|
||||
#define KEY_MAPPING_X11_H
|
||||
#pragma once
|
||||
|
||||
#include "core/os/keyboard.h"
|
||||
#include "core/templates/hash_map.h"
|
||||
|
|
@ -68,5 +67,3 @@ public:
|
|||
static char32_t get_unicode_from_keysym(KeySym p_keysym);
|
||||
static KeyLocation get_location(unsigned int p_code);
|
||||
};
|
||||
|
||||
#endif // KEY_MAPPING_X11_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RENDERING_CONTEXT_DRIVER_VULKAN_X11_H
|
||||
#define RENDERING_CONTEXT_DRIVER_VULKAN_X11_H
|
||||
#pragma once
|
||||
|
||||
#ifdef VULKAN_ENABLED
|
||||
|
||||
|
|
@ -55,5 +54,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // VULKAN_ENABLED
|
||||
|
||||
#endif // RENDERING_CONTEXT_DRIVER_VULKAN_X11_H
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue