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
This commit is contained in:
parent
7073b0af40
commit
563dc7fb8e
4 changed files with 20 additions and 10 deletions
11
client.cpp
11
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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue