diff --git a/autotests/integration/kwin_wayland_test.cpp b/autotests/integration/kwin_wayland_test.cpp --- a/autotests/integration/kwin_wayland_test.cpp +++ b/autotests/integration/kwin_wayland_test.cpp @@ -83,18 +83,23 @@ if (effects) { static_cast(effects)->unloadAllEffects(); } - if (m_xwayland) { - // needs to be done before workspace gets destroyed - m_xwayland->prepareDestroy(); - } - destroyWorkspace(); + + // Kill Xwayland before terminating its connection. + delete m_xwayland; + m_xwayland = nullptr; + + // Terminate all client connections before Workspace is destroyed. + // Shell clients need to access RuleBook whose lifetime is bound + // to the Workspace class. + waylandServer()->terminateClientConnections(); waylandServer()->dispatch(); + + destroyWorkspace(); + if (QStyle *s = style()) { s->unpolish(this); } - // kill Xwayland before terminating its connection - delete m_xwayland; - waylandServer()->terminateClientConnections(); + destroyCompositor(); } diff --git a/main_wayland.cpp b/main_wayland.cpp --- a/main_wayland.cpp +++ b/main_wayland.cpp @@ -128,20 +128,23 @@ if (effects) { static_cast(effects)->unloadAllEffects(); } - if (m_xwayland) { - // needs to be done before workspace gets destroyed - m_xwayland->prepareDestroy(); - } - destroyWorkspace(); + + // Kill Xwayland before terminating its connection. + delete m_xwayland; + m_xwayland = nullptr; + + // Terminate all client connections before Workspace is destroyed. + // Shell clients need to access RuleBook whose lifetime is bound + // to the Workspace class. + waylandServer()->terminateClientConnections(); waylandServer()->dispatch(); + destroyWorkspace(); + if (QStyle *s = style()) { s->unpolish(this); } - // kill Xwayland before terminating its connection - delete m_xwayland; - m_xwayland = nullptr; - waylandServer()->terminateClientConnections(); + destroyCompositor(); } diff --git a/shell_client.cpp b/shell_client.cpp --- a/shell_client.cpp +++ b/shell_client.cpp @@ -425,37 +425,32 @@ if (isMoveResize()) { leaveMoveResize(); } - Deleted *del = nullptr; - if (workspace()) { - del = Deleted::create(this); - } - emit windowClosed(this, del); + + Deleted *deleted = Deleted::create(this); + emit windowClosed(this, deleted); // Remove Force Temporarily rules. RuleBook::self()->discardUsed(this, true); destroyWindowManagementInterface(); destroyDecoration(); - if (workspace()) { - StackingUpdatesBlocker blocker(workspace()); - if (transientFor()) { - transientFor()->removeTransient(this); - } - for (auto it = transients().constBegin(); it != transients().constEnd();) { - if ((*it)->transientFor() == this) { - removeTransient(*it); - it = transients().constBegin(); // restart, just in case something more has changed with the list - } else { - ++it; - } + StackingUpdatesBlocker blocker(workspace()); + if (transientFor()) { + transientFor()->removeTransient(this); + } + for (auto it = transients().constBegin(); it != transients().constEnd();) { + if ((*it)->transientFor() == this) { + removeTransient(*it); + it = transients().constBegin(); // restart, just in case something more has changed with the list + } else { + ++it; } } + waylandServer()->removeClient(this); - if (del) { - del->unrefWindow(); - } + deleted->unrefWindow(); m_shellSurface = nullptr; m_xdgShellSurface = nullptr; m_xdgShellPopup = nullptr; diff --git a/xwl/xwayland.h b/xwl/xwayland.h --- a/xwl/xwayland.h +++ b/xwl/xwayland.h @@ -47,7 +47,6 @@ ~Xwayland() override; void init(); - void prepareDestroy(); xcb_screen_t *xcbScreen() const { return m_xcbScreen; diff --git a/xwl/xwayland.cpp b/xwl/xwayland.cpp --- a/xwl/xwayland.cpp +++ b/xwl/xwayland.cpp @@ -88,6 +88,9 @@ Xwayland::~Xwayland() { + delete m_dataBridge; + m_dataBridge = nullptr; + disconnect(m_xwaylandFailConnection); if (m_app->x11Connection()) { Xcb::setInputFocus(XCB_INPUT_FOCUS_POINTER_ROOT); @@ -178,12 +181,6 @@ close(pipeFds[1]); } -void Xwayland::prepareDestroy() -{ - delete m_dataBridge; - m_dataBridge = nullptr; -} - void Xwayland::createX11Connection() { int screenNumber = 0;