diff --git a/shell_client.h b/shell_client.h --- a/shell_client.h +++ b/shell_client.h @@ -300,6 +300,8 @@ bool m_compositingSetup = false; bool m_isInitialized = false; + + friend class Workspace; }; } diff --git a/shell_client.cpp b/shell_client.cpp --- a/shell_client.cpp +++ b/shell_client.cpp @@ -423,37 +423,34 @@ if (isMoveResize()) { leaveMoveResize(); } - Deleted *del = nullptr; - if (workspace()) { - del = Deleted::create(this); - } - emit windowClosed(this, del); + + // Replace ShellClient with an instance of Deleted in the stacking order. + 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/workspace.cpp b/workspace.cpp --- a/workspace.cpp +++ b/workspace.cpp @@ -556,6 +556,19 @@ desktops.removeAll(c); } Client::cleanupX11(); + + if (waylandServer()) { + const QList shellClients = waylandServer()->clients(); + for (ShellClient *shellClient : shellClients) { + shellClient->destroyClient(); + } + + const QList internalClients = waylandServer()->internalClients(); + for (ShellClient *internalClient : internalClients) { + internalClient->destroyClient(); + } + } + for (UnmanagedList::iterator it = unmanaged.begin(), end = unmanaged.end(); it != end; ++it) (*it)->release(ReleaseReason::KWinShutsDown);