File indexing completed on 2025-12-07 12:25:07
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 "kwinglutils.h" 0012 0013 #include <QDBusConnection> 0014 #include <QTimer> 0015 0016 namespace KWin 0017 { 0018 BlendChanges::BlendChanges() 0019 : CrossFadeEffect() 0020 { 0021 QDBusConnection::sessionBus().registerObject(QStringLiteral("/org/kde/KWin/BlendChanges"), 0022 QStringLiteral("org.kde.KWin.BlendChanges"), 0023 this, 0024 QDBusConnection::ExportAllSlots); 0025 0026 m_timeline.setEasingCurve(QEasingCurve::InOutCubic); 0027 } 0028 0029 BlendChanges::~BlendChanges() = default; 0030 0031 bool BlendChanges::supported() 0032 { 0033 return effects->compositingType() == OpenGLCompositing && effects->animationsSupported(); 0034 } 0035 0036 void KWin::BlendChanges::start(int delay) 0037 { 0038 int animationDuration = animationTime(400); 0039 0040 if (!supported() || m_state != Off) { 0041 return; 0042 } 0043 if (effects->hasActiveFullScreenEffect()) { 0044 return; 0045 } 0046 0047 const EffectWindowList allWindows = effects->stackingOrder(); 0048 for (auto window : allWindows) { 0049 if (!window->isFullScreen()) { 0050 redirect(window); 0051 } 0052 } 0053 0054 QTimer::singleShot(delay, this, [this, animationDuration]() { 0055 m_timeline.setDuration(std::chrono::milliseconds(animationDuration)); 0056 effects->addRepaintFull(); 0057 m_state = Blending; 0058 }); 0059 0060 m_state = ShowingCache; 0061 } 0062 0063 bool BlendChanges::isActive() const 0064 { 0065 return m_state != Off; 0066 } 0067 0068 void BlendChanges::postPaintScreen() 0069 { 0070 if (m_timeline.done()) { 0071 m_timeline.reset(); 0072 m_state = Off; 0073 0074 const EffectWindowList allWindows = effects->stackingOrder(); 0075 for (auto window : allWindows) { 0076 unredirect(window); 0077 } 0078 } 0079 effects->addRepaintFull(); 0080 } 0081 0082 void BlendChanges::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) 0083 { 0084 data.setCrossFadeProgress(m_timeline.value()); 0085 effects->paintWindow(w, mask, region, data); 0086 } 0087 0088 void BlendChanges::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) 0089 { 0090 if (m_state == Off) { 0091 return; 0092 } 0093 if (m_state == Blending) { 0094 m_timeline.advance(presentTime); 0095 } 0096 0097 effects->prePaintScreen(data, presentTime); 0098 } 0099 0100 } // namespace KWin