diff options
author | Adam Endrodi <ext-adam.endrodi@nokia.com> | 2010-12-10 20:53:54 +0200 |
---|---|---|
committer | Adam Endrodi <ext-adam.endrodi@nokia.com> | 2010-12-14 16:25:24 +0200 |
commit | ddb2c4ab4fbc42d9e9d5a3cc59b2cde73c1f3b3d (patch) | |
tree | bca1188e8e25d5077cc8ae4e43490929bc719ddf | |
parent | 38b19a36779a46d7b37d141640c46bfa37f22c89 (diff) |
combined fix of segfaults, leaks and invisible windows
Test case: while :; do create window; read; destroy window; done
The culprit is that the new window might get the same XID as the
just-destroyed one, confusing the window manager.
* src/mwindowpropertycache.cpp (MWindowPropertyCache::~MWindowPropertyCache):
Stop tracking damages, ensuring that the Damage object is destroyed.
* src/mdecoratorframe.cpp (MDecoratorFrame::setManagedWindow):
Disconnect from the managed window's destroyed() signal properly.
* src/mcompositemanager.cpp (MCompositeManagerPrivate::destroyEvent):
Remove the destroyed window's MWindowPropertyCache from the list of
caches, because we don't want to and shouldn't reuse it.
* src/mcompositewindow.cpp (MCompositeWindow::~MCompositeWindow):
-- delete timers
-- stop damage tracking
-- do not attempt to remove ourselves from the stacking_list,
because there might be already another object with the same XID.
-rw-r--r-- | src/mcompositemanager.cpp | 5 | ||||
-rw-r--r-- | src/mcompositewindow.cpp | 5 | ||||
-rw-r--r-- | src/mdecoratorframe.cpp | 3 | ||||
-rw-r--r-- | src/mwindowpropertycache.cpp | 1 |
4 files changed, 11 insertions, 3 deletions
diff --git a/src/mcompositemanager.cpp b/src/mcompositemanager.cpp index 5ce457d..6241d19 100644 --- a/src/mcompositemanager.cpp +++ b/src/mcompositemanager.cpp @@ -926,7 +926,10 @@ void MCompositeManagerPrivate::destroyEvent(XDestroyWindowEvent *e) if (item) { item->deleteLater(); removeWindow(item->window()); - // PC deleted with the MCompositeWindow + prop_caches.remove(item->window()); + // PC deleted with the MCompositeWindow. Till then we've made sure + // that we can't reuse it, even if a window with the same XID is + // created before @item is actually destroyed. } else { // We got a destroy event from a framed window (or a window that was // never mapped) diff --git a/src/mcompositewindow.cpp b/src/mcompositewindow.cpp index 62b116a..b3f60e6 100644 --- a/src/mcompositewindow.cpp +++ b/src/mcompositewindow.cpp @@ -119,17 +119,20 @@ MCompositeWindow::MCompositeWindow(Qt::HANDLE window, MCompositeWindow::~MCompositeWindow() { MCompositeManager *p = (MCompositeManager *) qApp; - p->d->removeWindow(window()); if (window() && (t_ping || t_reappear)) { stopPing(); + delete t_ping; + delete t_reappear; t_ping = t_reappear = 0; } endAnimation(); anim = 0; + delete damage_timer; if (pc) { + pc->damageTracking(false); p->d->prop_caches.remove(window()); pc->deleteLater(); } diff --git a/src/mdecoratorframe.cpp b/src/mdecoratorframe.cpp index bd7012c..3ae6e80 100644 --- a/src/mdecoratorframe.cpp +++ b/src/mdecoratorframe.cpp @@ -92,7 +92,8 @@ void MDecoratorFrame::setManagedWindow(MCompositeWindow *cw, if (client == cw) return; - disconnect(this, SLOT(destroyClient())); + if (client) + disconnect(client, SIGNAL(destroyed()), this, SLOT(destroyClient())); client = cw; qulonglong winid = client ? client->window() : 0; diff --git a/src/mwindowpropertycache.cpp b/src/mwindowpropertycache.cpp index ce31f77..8e9d131 100644 --- a/src/mwindowpropertycache.cpp +++ b/src/mwindowpropertycache.cpp @@ -280,6 +280,7 @@ MWindowPropertyCache::~MWindowPropertyCache() shapeRegion(); if (!net_wm_state_valid) netWmState(); + damageTracking(false); } bool MWindowPropertyCache::hasAlpha() |