From 99913bab5d40553b01a88e15db59b56db41dc7db Mon Sep 17 00:00:00 2001 From: Eric Edlund Date: Wed, 25 May 2022 19:13:11 -0400 Subject: [PATCH] Make EffectWindowVisibleRef mandatory when refrencing window visibility in effects This should prevent a stray visiblity unrefrence in an effect from crashing kwin. --- src/effects.cpp | 8 ++++---- src/effects.h | 6 +++--- src/libkwineffects/kwineffects.h | 24 ++++++++++++++++-------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/effects.cpp b/src/effects.cpp index 666db56838..be0f1c506c 100644 --- a/src/effects.cpp +++ b/src/effects.cpp @@ -1931,14 +1931,14 @@ EffectWindowImpl::~EffectWindowImpl() { } -void EffectWindowImpl::refVisible(int reason) +void EffectWindowImpl::refVisible(const EffectWindowVisibleRef *holder) { - m_windowItem->refVisible(reason); + m_windowItem->refVisible(holder->reason()); } -void EffectWindowImpl::unrefVisible(int reason) +void EffectWindowImpl::unrefVisible(const EffectWindowVisibleRef *holder) { - m_windowItem->unrefVisible(reason); + m_windowItem->unrefVisible(holder->reason()); } void EffectWindowImpl::addRepaint(const QRect &r) diff --git a/src/effects.h b/src/effects.h index b08c16ba4e..a31d7331e4 100644 --- a/src/effects.h +++ b/src/effects.h @@ -380,9 +380,6 @@ public: explicit EffectWindowImpl(Window *window); ~EffectWindowImpl() override; - void refVisible(int reason) override; - void unrefVisible(int reason) override; - void addRepaint(const QRect &r) override; void addRepaintFull() override; void addLayerRepaint(const QRect &r) override; @@ -505,6 +502,9 @@ public: QVariant data(int role) const override; private: + void refVisible(const EffectWindowVisibleRef *holder) override; + void unrefVisible(const EffectWindowVisibleRef *holder) override; + Window *m_window; WindowItem *m_windowItem; // This one is used only during paint pass. QHash dataMap; diff --git a/src/libkwineffects/kwineffects.h b/src/libkwineffects/kwineffects.h index 27d34ffc29..3b9bebee45 100644 --- a/src/libkwineffects/kwineffects.h +++ b/src/libkwineffects/kwineffects.h @@ -2019,6 +2019,7 @@ Q_SIGNALS: void changed(); }; +class EffectWindowVisibleRef; /** * @short Representation of a window used by/for Effect classes. * @@ -2342,9 +2343,6 @@ public: virtual void refWindow() = 0; virtual void unrefWindow() = 0; - virtual void refVisible(int reason) = 0; - virtual void unrefVisible(int reason) = 0; - virtual bool isDeleted() const = 0; virtual bool isMinimized() const = 0; @@ -2698,6 +2696,11 @@ public: */ virtual void unreferencePreviousWindowPixmap() = 0; +protected: + friend EffectWindowVisibleRef; + virtual void refVisible(const EffectWindowVisibleRef *holder) = 0; + virtual void unrefVisible(const EffectWindowVisibleRef *holder) = 0; + private: class Private; QScopedPointer d; @@ -2773,7 +2776,7 @@ public: : m_window(window) , m_reason(reason) { - m_window->refVisible(reason); + m_window->refVisible(this); } EffectWindowVisibleRef(const EffectWindowVisibleRef &other) @@ -2781,24 +2784,29 @@ public: , m_reason(other.m_reason) { if (m_window) { - m_window->refVisible(m_reason); + m_window->refVisible(this); } } ~EffectWindowVisibleRef() { if (m_window) { - m_window->unrefVisible(m_reason); + m_window->unrefVisible(this); } } + int reason() const + { + return m_reason; + } + EffectWindowVisibleRef &operator=(const EffectWindowVisibleRef &other) { if (other.m_window) { - other.m_window->refVisible(other.m_reason); + other.m_window->refVisible(&other); } if (m_window) { - m_window->unrefVisible(m_reason); + m_window->unrefVisible(this); } m_window = other.m_window; m_reason = other.m_reason;