Transform a pending repaint into a workspace repaint before destroying Deleted

The sliding popups effect schedules a repaint and then unreferences the
deleted window. The problem with doing so is that the scheduled repaint
will be effectively discarded because the Deleted will be destroyed once
we are back in the event loop.

This issue is most noticeable on Wayland. Not sure why. If you close
Kickoff, you may see its flickering ghost in background.

If it happens that a Deleted has a pending repaint, transform it into a
workspace repaint to avoid discarding any scheduled repaints.


(cherry picked from commit 2715cbc86c)
icc-effect-5.20.5
Vlad Zahorodnii 2020-10-29 10:48:10 +00:00
parent 022cc8a661
commit 3d40db866c
3 changed files with 13 additions and 0 deletions

View File

@ -47,6 +47,11 @@ Deleted::Deleted()
Deleted::~Deleted()
{
const QRegion dirty = repaints();
if (!dirty.isEmpty()) {
addWorkspaceRepaint(dirty);
}
if (delete_refcount != 0)
qCCritical(KWIN_CORE) << "Deleted client has non-zero reference count (" << delete_refcount << ")";
Q_ASSERT(delete_refcount == 0);

View File

@ -505,6 +505,13 @@ void Toplevel::addWorkspaceRepaint(const QRect& r2)
Compositor::self()->addRepaint(r2);
}
void Toplevel::addWorkspaceRepaint(const QRegion &region)
{
if (compositing()) {
Compositor::self()->addRepaint(region);
}
}
void Toplevel::setReadyForPainting()
{
if (!ready_for_painting) {

View File

@ -454,6 +454,7 @@ public:
// these call workspace->addRepaint(), but first transform the damage if needed
void addWorkspaceRepaint(const QRect& r);
void addWorkspaceRepaint(int x, int y, int w, int h);
void addWorkspaceRepaint(const QRegion &region);
QRegion repaints() const;
void resetRepaints();
QRegion damage() const;