Commit 5df72c66 authored by Vlad Zahorodnii's avatar Vlad Zahorodnii
Browse files

Safely remove all internal clients and override-redirect windows

When we destroy all internal clients and override-redirect windows, we
assume that corresponding lists will be implicitly detached.

However, in some cases, that might be not the case. For example, if the
list is not shared, neither begin() nor end() will detach. Therefore, it
is possible to hit invalidated iterators if the list is modified inside
the loop.

This change prevents hitting invalidated iterators by making explicit
list copies.

CCBUG: 427373

(cherry picked from commit 08263b53)
parent bba28ff9
...@@ -469,7 +469,9 @@ void Workspace::cleanupX11() ...@@ -469,7 +469,9 @@ void Workspace::cleanupX11()
stacking_order.removeOne(client); stacking_order.removeOne(client);
} }
for (Unmanaged *overrideRedirect : m_unmanaged) { // We need a shadow copy because windows get removed as we go through them.
const QList<Unmanaged *> unmanaged = m_unmanaged;
for (Unmanaged *overrideRedirect : unmanaged) {
overrideRedirect->release(ReleaseReason::KWinShutsDown); overrideRedirect->release(ReleaseReason::KWinShutsDown);
unconstrained_stacking_order.removeOne(overrideRedirect); unconstrained_stacking_order.removeOne(overrideRedirect);
stacking_order.removeOne(overrideRedirect); stacking_order.removeOne(overrideRedirect);
...@@ -510,7 +512,9 @@ Workspace::~Workspace() ...@@ -510,7 +512,9 @@ Workspace::~Workspace()
} }
} }
for (InternalClient *client : m_internalClients) { // We need a shadow copy because clients get removed as we go through them.
const QList<InternalClient *> internalClients = m_internalClients;
for (InternalClient *client : internalClients) {
client->destroyClient(); client->destroyClient();
} }
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment