diff --git a/autotests/integration/kwin_wayland_test.cpp b/autotests/integration/kwin_wayland_test.cpp index fa674c9e5d..fe07f1de23 100644 --- a/autotests/integration/kwin_wayland_test.cpp +++ b/autotests/integration/kwin_wayland_test.cpp @@ -83,23 +83,18 @@ WaylandTestApplication::~WaylandTestApplication() if (effects) { static_cast(effects)->unloadAllEffects(); } - - // 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(); - + if (m_xwayland) { + // needs to be done before workspace gets destroyed + m_xwayland->prepareDestroy(); + } destroyWorkspace(); - + waylandServer()->dispatch(); 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 index 60d6a7b4d4..40336ae741 100644 --- a/main_wayland.cpp +++ b/main_wayland.cpp @@ -128,23 +128,20 @@ ApplicationWayland::~ApplicationWayland() if (effects) { static_cast(effects)->unloadAllEffects(); } - - // 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(); - + if (m_xwayland) { + // needs to be done before workspace gets destroyed + m_xwayland->prepareDestroy(); + } destroyWorkspace(); + waylandServer()->dispatch(); 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 index b24c675b64..fd2edaef19 100644 --- a/shell_client.cpp +++ b/shell_client.cpp @@ -425,9 +425,11 @@ void ShellClient::destroyClient() if (isMoveResize()) { leaveMoveResize(); } - - Deleted *deleted = Deleted::create(this); - emit windowClosed(this, deleted); + Deleted *del = nullptr; + if (workspace()) { + del = Deleted::create(this); + } + emit windowClosed(this, del); // Remove Force Temporarily rules. RuleBook::self()->discardUsed(this, true); @@ -435,22 +437,25 @@ void ShellClient::destroyClient() destroyWindowManagementInterface(); destroyDecoration(); - 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; + 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; + } } } - waylandServer()->removeClient(this); - deleted->unrefWindow(); + if (del) { + del->unrefWindow(); + } m_shellSurface = nullptr; m_xdgShellSurface = nullptr; m_xdgShellPopup = nullptr; diff --git a/xwl/xwayland.cpp b/xwl/xwayland.cpp index 35fbe1dfe6..5f17d3923c 100644 --- a/xwl/xwayland.cpp +++ b/xwl/xwayland.cpp @@ -88,9 +88,6 @@ Xwayland::Xwayland(ApplicationWaylandAbstract *app, QObject *parent) Xwayland::~Xwayland() { - delete m_dataBridge; - m_dataBridge = nullptr; - disconnect(m_xwaylandFailConnection); if (m_app->x11Connection()) { Xcb::setInputFocus(XCB_INPUT_FOCUS_POINTER_ROOT); @@ -181,6 +178,12 @@ void Xwayland::init() close(pipeFds[1]); } +void Xwayland::prepareDestroy() +{ + delete m_dataBridge; + m_dataBridge = nullptr; +} + void Xwayland::createX11Connection() { int screenNumber = 0; diff --git a/xwl/xwayland.h b/xwl/xwayland.h index ef228ee312..b759e6af55 100644 --- a/xwl/xwayland.h +++ b/xwl/xwayland.h @@ -47,6 +47,7 @@ public: ~Xwayland() override; void init(); + void prepareDestroy(); xcb_screen_t *xcbScreen() const { return m_xcbScreen;