File indexing completed on 2024-11-10 04:56:57

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2022 David Edmundson <davidedmundson@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 // own
0010 #include "blendchanges.h"
0011 #include "effect/effecthandler.h"
0012 #include "opengl/glutils.h"
0013 
0014 #include <QDBusConnection>
0015 #include <QTimer>
0016 
0017 namespace KWin
0018 {
0019 BlendChanges::BlendChanges()
0020     : CrossFadeEffect()
0021 {
0022     QDBusConnection::sessionBus().registerObject(QStringLiteral("/org/kde/KWin/BlendChanges"),
0023                                                  QStringLiteral("org.kde.KWin.BlendChanges"),
0024                                                  this,
0025                                                  QDBusConnection::ExportAllSlots);
0026 
0027     m_timeline.setEasingCurve(QEasingCurve::InOutCubic);
0028 }
0029 
0030 BlendChanges::~BlendChanges() = default;
0031 
0032 bool BlendChanges::supported()
0033 {
0034     return effects->compositingType() == OpenGLCompositing && effects->animationsSupported();
0035 }
0036 
0037 void KWin::BlendChanges::start(int delay)
0038 {
0039     int animationDuration = animationTime(400);
0040 
0041     if (!supported() || m_state != Off) {
0042         return;
0043     }
0044     if (effects->hasActiveFullScreenEffect()) {
0045         return;
0046     }
0047 
0048     const QList<EffectWindow *> allWindows = effects->stackingOrder();
0049     for (auto window : allWindows) {
0050         if (!window->isFullScreen()) {
0051             redirect(window);
0052         }
0053     }
0054 
0055     QTimer::singleShot(delay, this, [this, animationDuration]() {
0056         m_timeline.setDuration(std::chrono::milliseconds(animationDuration));
0057         effects->addRepaintFull();
0058         m_state = Blending;
0059     });
0060 
0061     m_state = ShowingCache;
0062 }
0063 
0064 bool BlendChanges::isActive() const
0065 {
0066     return m_state != Off;
0067 }
0068 
0069 void BlendChanges::postPaintScreen()
0070 {
0071     if (m_timeline.done()) {
0072         m_timeline.reset();
0073         m_state = Off;
0074 
0075         const QList<EffectWindow *> allWindows = effects->stackingOrder();
0076         for (auto window : allWindows) {
0077             unredirect(window);
0078         }
0079     }
0080     effects->addRepaintFull();
0081 }
0082 
0083 void BlendChanges::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
0084 {
0085     data.setCrossFadeProgress(m_timeline.value());
0086     effects->paintWindow(renderTarget, viewport, w, mask, region, data);
0087 }
0088 
0089 void BlendChanges::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
0090 {
0091     if (m_state == Off) {
0092         return;
0093     }
0094     if (m_state == Blending) {
0095         m_timeline.advance(presentTime);
0096     }
0097 
0098     effects->prePaintScreen(data, presentTime);
0099 }
0100 
0101 } // namespace KWin
0102 
0103 #include "moc_blendchanges.cpp"