-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Crash sometimes when window is hidden/minimized on Linux/X11/XMonad #65425
Comments
I can confirm this happens in beta1 on Xmonad (Ubuntu 20.04). Super quick to reproduce by holding Alt+Tab in the Fullscreen layout with a second window. Also happens in the project manager window that you get at the start. |
Tried both methods, can't reproduce. |
Can you reproduce this when starting the editor with the |
Yes. Still crashes. I'm on beta 4 and XMonad 0.17.1. |
I tested again with the default xmonad config and it wouldn't crash if you have borders on fullscreen windows. I need lessborders (no borders for fullscreen windows) to be active to reproduce this. import XMonad
import XMonad.Layout.NoBorders
main = do
xmonad (defaultConfig {layoutHook = lessBorders Screen Full}) |
Same here. I'm normally using Rémi, please don't close this issue. This is not a fix since it also affects games built with Godot 4. Preferably, we don't want our games to crash because of some common user setting that is out of our control. |
I can confirm the issue with Godot 4 beta 10 and an XMonad config with Summary
DebuggingIn order to debug this issue I recompiled the engine with the following patch: diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index 57f125a754..64055d9f27 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -78,7 +78,7 @@
#define VALUATOR_TILTX 3
#define VALUATOR_TILTY 4
-//#define DISPLAY_SERVER_X11_DEBUG_LOGS_ENABLED
+#define DISPLAY_SERVER_X11_DEBUG_LOGS_ENABLED
#ifdef DISPLAY_SERVER_X11_DEBUG_LOGS_ENABLED
#define DEBUG_LOG_X11(...) printf(__VA_ARGS__)
#else
@@ -3762,6 +3762,9 @@ void DisplayServerX11::process_events() {
XSync(x11_display, False);
XGetWindowAttributes(x11_display, wd.x11_window, &xwa);
+ printf("Border width: %d, Map state: %d (%s)\n", xwa.border_width, xwa.map_state,
+ xwa.map_state == 0 ? "IsUnmapped" : xwa.map_state == 1 ? "IsUnviewable" : "IsViewable");
+
// 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.
@@ -3916,6 +3919,9 @@ void DisplayServerX11::process_events() {
XSync(x11_display, False);
XGetWindowAttributes(x11_display, wd.x11_window, &xwa);
+ printf("Border width: %d, Map state: %d (%s)\n", xwa.border_width, xwa.map_state,
+ xwa.map_state == 0 ? "IsUnmapped" : xwa.map_state == 1 ? "IsUnviewable" : "IsViewable");
+
// Set focus when menu window is re-used.
// RevertToPointerRoot is used to make sure we don't lose all focus in case
// a subwindow and its parent are both destroyed.
Here are the logs with
The Here are the logs with
As can be seen by the When things go wrong:
In this case, FixThe following patch disables processing of requests from other connections (i.e. XMonad), ensuring that the diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index 57f125a754..d989712917 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -3914,6 +3914,9 @@ void DisplayServerX11::process_events() {
XWindowAttributes xwa;
XSync(x11_display, False);
+
+ // Grab the server to avoid map_state changes between calling XGetWindowAttributes and XSetInputFocus.
+ XGrabServer(x11_display);
XGetWindowAttributes(x11_display, wd.x11_window, &xwa);
// Set focus when menu window is re-used.
@@ -3922,6 +3925,7 @@ void DisplayServerX11::process_events() {
if ((xwa.map_state == IsViewable) && !wd.no_focus && !wd.is_popup) {
XSetInputFocus(x11_display, wd.x11_window, RevertToPointerRoot, CurrentTime);
}
+ XUngrabServer(x11_display); // Very important to ungrab the server otherwise X11 becomes unresponsive.
_window_changed(&event);
} break;
Logs after applying this patch:
|
Grabbing the XServer does still crash for me for some reason. One other way to work around this is to set a default error handler with Since this is an invalid call during an race-condition state and another valid call comes in just after/before it when the border modified again, it should be fair to just ignore the X error and move on. Here is a patch default_error_handler.patch (.txt because github won't let me upload patch files for some reason atm) Not crashing on X errors by default is probably better for users imo. So even if things get weird from an unhandled error they might still save their changes and restart. But maybe there is a better way to print the error So that it looks like the default X error again. |
If anyone wants to improve that patch's error logging and make a PR, feel free to do so. I'm too busy atm and probably won't submit one. |
The default behaviour for X11 is to crash even on non-fatal errors when there is no error handler set. This change allows the window to stay open and may enable users to save their work when things go wrong. This acts as a workaround for godotengine#65425 and godotengine#68471
This problem has been greatly mitigated by #75099. Now, instead of crashing when switching workspaces I just get an error in the editor console. That's mildly annoying but obviously much better than a crash. Thank you @mxnemu for this workaround. I assume this is the best we can hope for so I'm closing the issue. |
Godot version
v4.0.alpha.custom_build [7a620e3]
System information
Debian Bookworm/Test, XMonad 0.17.0
Issue description
Both release builds and the editor are affected.
This is could very well be an XMonad specific race condition, but I've never had this issue with any other program. It does not happen with Godot 3.5.
I will sometimes get this crash in either of these scenarios:
The fix in #58891 ought to take care of this, but there seem to be a race condition where it's not enough. It added a check for
IsViewable
before callingXSetInputFocus
but oddly enough the state is sometimesIsViewable
for me even when switching away from Godot, and that's when I get the crash.godot/platform/linuxbsd/display_server_x11.cpp
Lines 3686 to 3688 in 0f62e35
Steps to reproduce
Minimal reproduction project
No response
The text was updated successfully, but these errors were encountered: