diff --git a/autotests/integration/xwaylandserver_crash_test.cpp b/autotests/integration/xwaylandserver_crash_test.cpp index 8739b66c4e..77b4160773 100644 --- a/autotests/integration/xwaylandserver_crash_test.cpp +++ b/autotests/integration/xwaylandserver_crash_test.cpp @@ -5,8 +5,10 @@ */ #include "kwin_wayland_test.h" +#include "composite.h" #include "main.h" #include "platform.h" +#include "scene.h" #include "screens.h" #include "unmanaged.h" #include "wayland_server.h" @@ -124,6 +126,11 @@ void XwaylandServerCrashTest::testCrash() QCOMPARE(kwinApp()->x11DefaultScreen(), nullptr); QCOMPARE(kwinApp()->x11RootWindow(), XCB_WINDOW_NONE); QCOMPARE(kwinApp()->x11ScreenNumber(), -1); + + // Render a frame to ensure that the compositor doesn't crash. + Compositor::self()->addRepaintFull(); + QSignalSpy frameRenderedSpy(Compositor::self()->scene(), &Scene::frameRendered); + QVERIFY(frameRenderedSpy.wait()); } } // namespace KWin diff --git a/autotests/integration/xwaylandserver_restart_test.cpp b/autotests/integration/xwaylandserver_restart_test.cpp index 83895fd33e..d268320307 100644 --- a/autotests/integration/xwaylandserver_restart_test.cpp +++ b/autotests/integration/xwaylandserver_restart_test.cpp @@ -5,8 +5,10 @@ */ #include "kwin_wayland_test.h" +#include "composite.h" #include "main.h" #include "platform.h" +#include "scene.h" #include "screens.h" #include "wayland_server.h" #include "workspace.h" @@ -103,6 +105,11 @@ void XwaylandServerRestartTest::testRestart() QCOMPARE(client->windowId(), window); QVERIFY(client->isDecorated()); + // Render a frame to ensure that the compositor doesn't crash. + Compositor::self()->addRepaintFull(); + QSignalSpy frameRenderedSpy(Compositor::self()->scene(), &Scene::frameRendered); + QVERIFY(frameRenderedSpy.wait()); + // Destroy the test window. xcb_destroy_window(c.data(), window); xcb_flush(c.data()); diff --git a/main.h b/main.h index 43ffb6a909..4f4409fa56 100644 --- a/main.h +++ b/main.h @@ -159,6 +159,13 @@ public: return m_defaultScreen; } + /** + * Returns @c true if we're in the middle of destroying the X11 connection. + */ + bool isClosingX11Connection() const { + return m_isClosingX11Connection; + } + #ifdef KWIN_BUILD_ACTIVITIES bool usesKActivities() const { return m_useKActivities; @@ -234,6 +241,9 @@ protected: void setTerminating() { m_terminating = true; } + void setClosingX11Connection(bool set) { + m_isClosingX11Connection = set; + } protected: static int crashes; @@ -253,6 +263,7 @@ private: #endif Platform *m_platform = nullptr; bool m_terminating = false; + bool m_isClosingX11Connection = false; }; inline static Application *kwinApp() diff --git a/workspace.cpp b/workspace.cpp index 0ac1483038..ebce832d1c 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -1788,7 +1788,7 @@ bool Workspace::compositing() const void Workspace::markXStackingOrderAsDirty() { m_xStackingDirty = true; - if (kwinApp()->x11Connection()) { + if (kwinApp()->x11Connection() && !kwinApp()->isClosingX11Connection()) { m_xStackingQueryTree.reset(new Xcb::Tree(kwinApp()->x11RootWindow())); } } diff --git a/xwl/xwayland.cpp b/xwl/xwayland.cpp index bc6a69f5af..5bb08b1620 100644 --- a/xwl/xwayland.cpp +++ b/xwl/xwayland.cpp @@ -149,6 +149,8 @@ void Xwayland::stop() return; } + m_app->setClosingX11Connection(true); + // If Xwayland has crashed, we must deactivate the socket notifier and ensure that no X11 // events will be dispatched before blocking; otherwise we will simply hang... uninstallSocketNotifier(); @@ -169,6 +171,8 @@ void Xwayland::stop() m_xwaylandProcess = nullptr; waylandServer()->destroyXWaylandConnection(); // This one must be destroyed last! + + m_app->setClosingX11Connection(false); } void Xwayland::restart()