summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Ådahl <jadahl@gmail.com>2022-12-03 16:51:27 +0100
committerJonas Ådahl <jadahl@gmail.com>2022-12-03 17:07:39 +0100
commitc915945e990e7234b5e80a8194348769a4c2c24d (patch)
tree1c9e1858fb9b923c13e34820a6a7fbd168c168ff
parentf186b4a6ea1b5bbf7f911d9125c944e1c104cffd (diff)
downloadmutter-c915945e990e7234b5e80a8194348769a4c2c24d.tar.gz
display: Freeze stack when closing X11 display
If two X11 windows were the last two, we'd remove them from the stack while unmanaging them. That'd hit an assert in meta_stack_tracker_restack_managed(), resulting in the following crash when Xwayland exited unexpectedly with two or more X11 windows being the only windows on the stack: #1 g_assertion_message() at ../glib/gtestutils.c:3256 #2 g_assertion_message_expr() at ../glib/gtestutils.c:3282 #3 meta_stack_tracker_restack_managed() at ../src/core/stack-tracker.c:1210 #4 on_stack_changed() at ../src/core/stack.c:142 #5 _g_closure_invoke_va() at ../gobject/gclosure.c:895 #6 g_signal_emit_valist() at ../gobject/gsignal.c:3456 #7 g_signal_emit() at ../gobject/gsignal.c:3606 #8 meta_stack_changed() at ../src/core/stack.c:265 #9 meta_stack_remove() at ../src/core/stack.c:324 #10 meta_window_unmanage() at ../src/core/window.c:1542 #11 meta_x11_display_unmanage_windows() at ../src/x11/meta-x11-display.c:111 #12 meta_x11_display_dispose() at ../src/x11/meta-x11-display.c:141 #13 g_object_run_dispose() at ../gobject/gobject.c:1448 #14 meta_display_shutdown_x11() at ../src/core/display.c:831 The added test specifically checks that this scenario is handled gracefully. Related: https://bugzilla.redhat.com/show_bug.cgi?id=2143637 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2704>
-rw-r--r--src/core/display.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/src/core/display.c b/src/core/display.c
index 66b75b1e9..0c897ab36 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -826,9 +826,11 @@ meta_display_shutdown_x11 (MetaDisplay *display)
if (!display->x11_display)
return;
+ meta_stack_freeze (display->stack);
g_signal_emit (display, display_signals[X11_DISPLAY_CLOSING], 0);
g_object_run_dispose (G_OBJECT (display->x11_display));
g_clear_object (&display->x11_display);
+ meta_stack_thaw (display->stack);
}
MetaDisplay *