diff --git a/src/effects/invert/invert.cpp b/src/effects/invert/invert.cpp index ce7a41c50d..3805cd9d1b 100644 --- a/src/effects/invert/invert.cpp +++ b/src/effects/invert/invert.cpp @@ -58,6 +58,7 @@ InvertEffect::InvertEffect() KGlobalAccel::self()->setShortcut(c, QList()); connect(c, &QAction::triggered, this, &InvertEffect::toggleScreenInversion); + connect(effects, &EffectsHandler::windowAdded, this, &InvertEffect::slotWindowAdded); connect(effects, &EffectsHandler::windowClosed, this, &InvertEffect::slotWindowClosed); } @@ -68,6 +69,26 @@ bool InvertEffect::supported() return effects->compositingType() == OpenGLCompositing; } +bool InvertEffect::isInvertable(EffectWindow *window) const +{ + return m_allWindows != m_windows.contains(window); +} + +void InvertEffect::invert(EffectWindow *window) +{ + if (m_valid && !m_inited) { + m_valid = loadData(); + } + + redirect(window); + setShader(window, m_shader.get()); +} + +void InvertEffect::uninvert(EffectWindow *window) +{ + unredirect(window); +} + bool InvertEffect::loadData() { ensureResources(); @@ -82,25 +103,10 @@ bool InvertEffect::loadData() return true; } -void InvertEffect::drawWindow(EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data) +void InvertEffect::slotWindowAdded(KWin::EffectWindow *w) { - // Load if we haven't already - if (m_valid && !m_inited) { - m_valid = loadData(); - } - - bool useShader = m_valid && (m_allWindows != m_windows.contains(w)); - if (useShader) { - ShaderManager *shaderManager = ShaderManager::instance(); - shaderManager->pushShader(m_shader.get()); - - data.shader = m_shader.get(); - } - - effects->drawWindow(w, mask, region, data); - - if (useShader) { - ShaderManager::instance()->popShader(); + if (isInvertable(w)) { + invert(w); } } @@ -112,6 +118,16 @@ void InvertEffect::slotWindowClosed(EffectWindow *w) void InvertEffect::toggleScreenInversion() { m_allWindows = !m_allWindows; + + const auto windows = effects->stackingOrder(); + for (EffectWindow *window : windows) { + if (isInvertable(window)) { + invert(window); + } else { + uninvert(window); + } + } + effects->addRepaintFull(); } @@ -125,6 +141,11 @@ void InvertEffect::toggleWindow() } else { m_windows.removeOne(effects->activeWindow()); } + if (isInvertable(effects->activeWindow())) { + invert(effects->activeWindow()); + } else { + uninvert(effects->activeWindow()); + } effects->activeWindow()->addRepaintFull(); } diff --git a/src/effects/invert/invert.h b/src/effects/invert/invert.h index b59e294add..656c149801 100644 --- a/src/effects/invert/invert.h +++ b/src/effects/invert/invert.h @@ -11,7 +11,7 @@ #ifndef KWIN_INVERT_H #define KWIN_INVERT_H -#include +#include namespace KWin { @@ -21,17 +21,15 @@ class GLShader; /** * Inverts desktop's colors */ -class InvertEffect : public Effect +class InvertEffect : public OffscreenEffect { Q_OBJECT public: InvertEffect(); ~InvertEffect() override; - void drawWindow(EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data) override; bool isActive() const override; bool provides(Feature) override; - int requestedEffectChainPosition() const override; static bool supported(); @@ -39,12 +37,18 @@ public: public Q_SLOTS: void toggleScreenInversion(); void toggleWindow(); + + void slotWindowAdded(KWin::EffectWindow *w); void slotWindowClosed(KWin::EffectWindow *w); protected: bool loadData(); private: + bool isInvertable(EffectWindow *window) const; + void invert(EffectWindow *window); + void uninvert(EffectWindow *window); + bool m_inited; bool m_valid; std::unique_ptr m_shader;