summaryrefslogtreecommitdiff
path: root/platform/linuxbsd/display_server_x11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linuxbsd/display_server_x11.cpp')
-rw-r--r--platform/linuxbsd/display_server_x11.cpp32
1 files changed, 29 insertions, 3 deletions
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index e98d114267..9349d378d0 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -733,6 +733,16 @@ Size2i DisplayServerX11::screen_get_size(int p_screen) const {
return _screen_get_rect(p_screen).size;
}
+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 0;
+}
+
Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const {
_THREAD_SAFE_METHOD_
@@ -869,7 +879,13 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const {
if (desktop_valid) {
use_simple_method = false;
+ // Handle bad window errors silently because there's no other way to check
+ // that one of the windows has been destroyed in the meantime.
+ int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&bad_window_error_handler);
+
for (unsigned long win_index = 0; win_index < clients_len; ++win_index) {
+ g_bad_window = false;
+
// Remove strut size from desktop size to get a more accurate result.
bool strut_found = false;
unsigned long strut_len = 0;
@@ -881,7 +897,7 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const {
}
}
// Fallback to older strut property.
- if (!strut_found) {
+ if (!g_bad_window && !strut_found) {
Atom strut_prop = XInternAtom(x11_display, "_NET_WM_STRUT", True);
if (strut_prop != None) {
if (XGetWindowProperty(x11_display, windows_data[win_index], strut_prop, 0, LONG_MAX, False, XA_CARDINAL, &type, &format, &strut_len, &remaining, &strut_data) == Success) {
@@ -889,7 +905,7 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const {
}
}
}
- if (strut_found && (format == 32) && (strut_len >= 4) && strut_data) {
+ if (!g_bad_window && strut_found && (format == 32) && (strut_len >= 4) && strut_data) {
long *struts = (long *)strut_data;
long left = struts[0];
@@ -961,6 +977,9 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const {
XFree(strut_data);
}
}
+
+ // Restore default error handler.
+ XSetErrorHandler(oldHandler);
}
}
}
@@ -3666,11 +3685,18 @@ void DisplayServerX11::process_events() {
} break;
case KeyPress:
case KeyRelease: {
+#ifdef DISPLAY_SERVER_X11_DEBUG_LOGS_ENABLED
+ if (event.type == KeyPress) {
+ DEBUG_LOG_X11("[%u] KeyPress window=%lu (%u), keycode=%u, time=%lu \n", frame, event.xkey.window, window_id, event.xkey.keycode, event.xkey.time);
+ } else {
+ DEBUG_LOG_X11("[%u] KeyRelease window=%lu (%u), keycode=%u, time=%lu \n", frame, event.xkey.window, window_id, event.xkey.keycode, event.xkey.time);
+ }
+#endif
last_timestamp = event.xkey.time;
// key event is a little complex, so
// it will be handled in its own function.
- _handle_key_event(window_id, (XKeyEvent *)&event, events, event_index);
+ _handle_key_event(window_id, &event.xkey, events, event_index);
} break;
case SelectionNotify: