From 563dc7fb8ebef02cd76bece32b6410d8e4c0ffd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Sun, 22 Apr 2012 09:27:53 +0200 Subject: [PATCH] Do not create Deleted on Workspace Shutdown When the Workspace is shutting down the compositor is torn down before Clients and Unmanaged are released. This means that there is no need to create the Deleted windows. Furthermore creating the Deleted manipulates the stacking_order while Workspace dtor loops over this list to release all clients. This may cause crashes. BUG: 282933 FIXED-IN: 4.9.0 REVIEW: 104690 --- client.cpp | 11 ++++++++--- unmanaged.cpp | 15 ++++++++++----- unmanaged.h | 2 +- workspace.cpp | 2 +- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/client.cpp b/client.cpp index 5345356fc1..017d429213 100644 --- a/client.cpp +++ b/client.cpp @@ -240,7 +240,10 @@ void Client::releaseWindow(bool on_shutdown) { assert(!deleting); deleting = true; - Deleted* del = Deleted::create(this); + Deleted* del = NULL; + if (!on_shutdown) { + del = Deleted::create(this); + } if (moveResizeMode) emit clientFinishUserMovedResized(this); emit windowClosed(this, del); @@ -291,8 +294,10 @@ void Client::releaseWindow(bool on_shutdown) XDestroyWindow(display(), frameId()); //frame = None; --block_geometry_updates; // Don't use GeometryUpdatesBlocker, it would now set the geometry - disownDataPassedToDeleted(); - del->unrefWindow(); + if (!on_shutdown) { + disownDataPassedToDeleted(); + del->unrefWindow(); + } checkNonExistentClients(); deleteClient(this, Allowed); ungrabXServer(); diff --git a/unmanaged.cpp b/unmanaged.cpp index c1e8c1c5d1..e79004e719 100644 --- a/unmanaged.cpp +++ b/unmanaged.cpp @@ -80,9 +80,12 @@ bool Unmanaged::track(Window w) return true; } -void Unmanaged::release() +void Unmanaged::release(bool on_shutdown) { - Deleted* del = Deleted::create(this); + Deleted* del = NULL; + if (!on_shutdown) { + del = Deleted::create(this); + } emit windowClosed(this, del); finishCompositing(); workspace()->removeUnmanaged(this, Allowed); @@ -91,9 +94,11 @@ void Unmanaged::release() XShapeSelectInput(display(), window(), NoEventMask); XSelectInput(display(), window(), NoEventMask); } - addWorkspaceRepaint(del->visibleRect()); - disownDataPassedToDeleted(); - del->unrefWindow(); + if (!on_shutdown) { + addWorkspaceRepaint(del->visibleRect()); + disownDataPassedToDeleted(); + del->unrefWindow(); + } deleteUnmanaged(this, Allowed); } diff --git a/unmanaged.h b/unmanaged.h index a3bde27f26..b11d62b84c 100644 --- a/unmanaged.h +++ b/unmanaged.h @@ -35,7 +35,7 @@ class Unmanaged public: Unmanaged(Workspace *ws); bool windowEvent(XEvent* e); - void release(); + void release(bool on_shutdown = false); bool track(Window w); static void deleteUnmanaged(Unmanaged* c, allowed_t); virtual int desktop() const; diff --git a/workspace.cpp b/workspace.cpp index a9deaaa088..77dd708cde 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -503,7 +503,7 @@ Workspace::~Workspace() desktops.removeAll(c); } for (UnmanagedList::iterator it = unmanaged.begin(), end = unmanaged.end(); it != end; ++it) - (*it)->release(); + (*it)->release(true); delete m_outline; discardPopup(); XDeleteProperty(display(), rootWindow(), atoms->kwin_running);