diff --git a/scene.h b/scene.h --- a/scene.h +++ b/scene.h @@ -336,6 +336,7 @@ Shadow* shadow(); void referencePreviousPixmap(); void unreferencePreviousPixmap(); + void invalidateQuadsCache(); protected: WindowQuadList makeQuads(WindowQuadType type, const QRegion& reg, const QPoint &textureOffset = QPoint(0, 0), qreal textureScale = 1.0) const; WindowQuadList makeDecorationQuads(const QRect *rects, const QRegion ®ion, qreal textureScale = 1.0) const; diff --git a/scene.cpp b/scene.cpp --- a/scene.cpp +++ b/scene.cpp @@ -405,6 +405,11 @@ c->effectWindow()->setSceneWindow(w); c->getShadow(); w->updateShadow(c->shadow()); + connect(c, &Toplevel::shadowChanged, this, + [w] { + w->invalidateQuadsCache(); + } + ); } void Scene::windowClosed(Toplevel *c, Deleted *deleted) @@ -732,7 +737,7 @@ // it is created on-demand and cached, simply // reset the flag shape_valid = false; - cached_quad_list.reset(); + invalidateQuadsCache(); } // Find out the shape of the window using the XShape extension @@ -936,6 +941,11 @@ return list; } +void Scene::Window::invalidateQuadsCache() +{ + cached_quad_list.reset(); +} + WindowQuadList Scene::Window::makeQuads(WindowQuadType type, const QRegion& reg, const QPoint &textureOffset, qreal scale) const { WindowQuadList ret; diff --git a/shadow.cpp b/shadow.cpp --- a/shadow.cpp +++ b/shadow.cpp @@ -65,9 +65,7 @@ } if (toplevel->effectWindow() && toplevel->effectWindow()->sceneWindow()) { toplevel->effectWindow()->sceneWindow()->updateShadow(shadow); - } - if (toplevel->effectWindow()) { - toplevel->effectWindow()->buildQuads(true); + emit toplevel->shadowChanged(); } return shadow; } @@ -333,52 +331,52 @@ bool Shadow::updateShadow() { - auto clear = [this]() { - if (m_topLevel && m_topLevel->effectWindow() && m_topLevel->effectWindow()->sceneWindow() && - m_topLevel->effectWindow()->sceneWindow()->shadow()) { + auto clear = [this] { + if (m_topLevel && m_topLevel->shadow()) { auto w = m_topLevel->effectWindow(); // this also deletes the shadow w->sceneWindow()->updateShadow(nullptr); - w->buildQuads(true); + emit m_topLevel->shadowChanged(); } }; + + if (!m_topLevel) { + return false; + } + if (m_decorationShadow) { if (AbstractClient *c = qobject_cast(m_topLevel)) { if (c->decoration()) { if (init(c->decoration())) { - if (m_topLevel && m_topLevel->effectWindow()) - m_topLevel->effectWindow()->buildQuads(true); + emit m_topLevel->shadowChanged(); return true; } } } clear(); return false; } + if (waylandServer()) { if (m_topLevel && m_topLevel->surface()) { if (const auto &s = m_topLevel->surface()->shadow()) { if (init(s)) { - if (m_topLevel->effectWindow()) { - m_topLevel->effectWindow()->buildQuads(true); - } + emit m_topLevel->shadowChanged(); return true; } } } } - if (!m_topLevel) { - clear(); - return false; - } + auto data = Shadow::readX11ShadowProperty(m_topLevel->window()); if (data.isEmpty()) { clear(); return false; } + init(data); - if (m_topLevel && m_topLevel->effectWindow()) - m_topLevel->effectWindow()->buildQuads(true); + emit m_topLevel->shadowChanged(); + return true; } diff --git a/toplevel.h b/toplevel.h --- a/toplevel.h +++ b/toplevel.h @@ -518,6 +518,12 @@ */ void screenScaleChanged(); + /** + * Emitted whenever the client's shadow changes. + * @since 5.15 + **/ + void shadowChanged(); + protected Q_SLOTS: /** * Checks whether the screen number for this Toplevel changed and updates if needed.