Make EffectWindowVisibleRef mandatory when refrencing window visibility in effects

This should prevent a stray visiblity unrefrence in an effect from crashing kwin.
This commit is contained in:
Eric Edlund 2022-05-25 19:13:11 -04:00
parent b81f16fbd5
commit 99913bab5d
3 changed files with 23 additions and 15 deletions

View file

@ -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)

View file

@ -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<int, QVariant> dataMap;

View file

@ -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<Private> 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;