diff --git a/deleted.cpp b/deleted.cpp index f46515923a..e166bf1039 100644 --- a/deleted.cpp +++ b/deleted.cpp @@ -66,6 +66,15 @@ void Deleted::copyToDeleted(Toplevel* c) { assert(dynamic_cast< Deleted* >(c) == NULL); Toplevel::copyToDeleted(c); + // In some cases the window has been deleted before the sync request which marks + // the window ready for painting has finished. This is especially troublesome + // when effects reference the deleted window and the unreferencing is part of + // the rendering pass (e.g. Effect::postPaintScreen/postPaintWindow), which will + // never be executed because we remove it every time from the stacking list in + // Workspace::performCompositing. + if (!c->readyForPainting()) { + QTimer::singleShot(0, this, SLOT(discard())); + } desk = c->desktop(); activityList = c->activities(); contentsRect = QRect(c->clientPos(), c->clientSize()); diff --git a/deleted.h b/deleted.h index 1f98aaf9de..81012973e6 100644 --- a/deleted.h +++ b/deleted.h @@ -35,7 +35,6 @@ public: // used by effects to keep the window around for e.g. fadeout effects when it's destroyed void refWindow(); void unrefWindow(bool delay = false); - void discard(allowed_t); virtual int desktop() const; virtual QStringList activities() const; virtual QPoint clientPos() const; @@ -58,6 +57,8 @@ public: } void layoutDecorationRects(QRect &left, QRect &top, QRect &right, QRect &bottom) const; QRect decorationRect() const; +public slots: + void discard(allowed_t = Allowed); protected: virtual void debug(QDebug& stream) const; virtual bool shouldUnredirect() const;