KWin
Loading...
Searching...
No Matches
sheet.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2007 Philip Falkner <philip.falkner@gmail.com>
6 SPDX-FileCopyrightText: 2009 Martin Gräßlin <mgraesslin@kde.org>
7 SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
8
9 SPDX-License-Identifier: GPL-2.0-or-later
10*/
11
12// own
13#include "sheet.h"
14
15// KConfigSkeleton
16#include "sheetconfig.h"
17
18#include "core/renderviewport.h"
20
21// Qt
22#include <QMatrix4x4>
23#include <qmath.h>
24
25namespace KWin
26{
27
28static QMatrix4x4 createPerspectiveMatrix(const QRectF &rect, const qreal scale)
29{
30 QMatrix4x4 ret;
31
32 const float fovY = std::tan(qDegreesToRadians(60.0f) / 2);
33 const float aspect = 1.0f;
34 const float zNear = 0.1f;
35 const float zFar = 100.0f;
36
37 const float yMax = zNear * fovY;
38 const float yMin = -yMax;
39 const float xMin = yMin * aspect;
40 const float xMax = yMax * aspect;
41
42 ret.frustum(xMin, xMax, yMin, yMax, zNear, zFar);
43
44 const auto deviceRect = scaledRect(rect, scale);
45
46 const float scaleFactor = 1.1 * fovY / yMax;
47 ret.translate(xMin * scaleFactor, yMax * scaleFactor, -1.1);
48 ret.scale((xMax - xMin) * scaleFactor / deviceRect.width(),
49 -(yMax - yMin) * scaleFactor / deviceRect.height(),
50 0.001);
51 ret.translate(-deviceRect.x(), -deviceRect.y());
52
53 return ret;
54}
55
57{
58 SheetConfig::instance(effects->config());
60
61 connect(effects, &EffectsHandler::windowAdded, this, &SheetEffect::slotWindowAdded);
62 connect(effects, &EffectsHandler::windowClosed, this, &SheetEffect::slotWindowClosed);
63}
64
65void SheetEffect::reconfigure(ReconfigureFlags flags)
66{
67 SheetConfig::self()->read();
68
69 // TODO: Rename AnimationTime config key to Duration.
70 const int d = animationTime(SheetConfig::animationTime() != 0
71 ? SheetConfig::animationTime()
72 : 300);
73 m_duration = std::chrono::milliseconds(static_cast<int>(d));
74}
75
76void SheetEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
77{
79
80 effects->prePaintScreen(data, presentTime);
81}
82
83void SheetEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
84{
85 auto animationIt = m_animations.find(w);
86 if (animationIt != m_animations.end()) {
87 (*animationIt).timeLine.advance(presentTime);
88 data.setTransformed();
89 }
90
91 effects->prePaintWindow(w, data, presentTime);
92}
93
94void SheetEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
95{
96 auto animationIt = m_animations.constFind(w);
97 if (animationIt == m_animations.constEnd()) {
98 effects->paintWindow(renderTarget, viewport, w, mask, region, data);
99 return;
100 }
101
102 // Perspective projection distorts objects near edges of the viewport
103 // in undesired way. To fix this, the center of the window will be
104 // moved to the origin, after applying perspective projection, the
105 // center is moved back to its "original" projected position. Overall,
106 // this is how the window will be transformed:
107 // [move to the origin] -> [scale] -> [rotate] -> [translate] ->
108 // -> [perspective projection] -> [reverse "move to the origin"]
109 const QMatrix4x4 oldProjMatrix = createPerspectiveMatrix(viewport.renderRect(), viewport.scale());
110 const QRectF windowGeo = w->frameGeometry();
111 const QVector3D invOffset = oldProjMatrix.map(QVector3D(windowGeo.center()));
112 QMatrix4x4 invOffsetMatrix;
113 invOffsetMatrix.translate(invOffset.x(), invOffset.y());
114 data.setProjectionMatrix(invOffsetMatrix * oldProjMatrix);
115
116 // Move the center of the window to the origin.
117 const QRectF screenGeo = effects->virtualScreenGeometry();
118 const QPointF offset = screenGeo.center() - windowGeo.center();
119 data.translate(offset.x(), offset.y());
120
121 const qreal t = (*animationIt).timeLine.value();
122 data.setRotationAxis(Qt::XAxis);
123 data.setRotationAngle(interpolate(60.0, 0.0, t));
124 data *= QVector3D(1.0, t, t);
125 data.translate(0.0, -interpolate(w->y() - (*animationIt).parentY, 0.0, t));
126
127 data.multiplyOpacity(t);
128
129 effects->paintWindow(renderTarget, viewport, w, mask, region, data);
130}
131
133{
134 auto animationIt = m_animations.begin();
135 while (animationIt != m_animations.end()) {
136 EffectWindow *w = animationIt.key();
137 w->addRepaintFull();
138 if ((*animationIt).timeLine.done()) {
139 animationIt = m_animations.erase(animationIt);
140 } else {
141 ++animationIt;
142 }
143 }
144
145 if (m_animations.isEmpty()) {
147 }
148
150}
151
153{
154 return !m_animations.isEmpty();
155}
156
162
163void SheetEffect::slotWindowAdded(EffectWindow *w)
164{
166 return;
167 }
168
169 if (!isSheetWindow(w)) {
170 return;
171 }
172
173 Animation &animation = m_animations[w];
174 animation.parentY = 0;
175 animation.timeLine.reset();
176 animation.timeLine.setDuration(m_duration);
177 animation.timeLine.setDirection(TimeLine::Forward);
178 animation.timeLine.setEasingCurve(QEasingCurve::Linear);
179
180 const auto windows = effects->stackingOrder();
181 auto parentIt = std::find_if(windows.constBegin(), windows.constEnd(),
182 [w](EffectWindow *p) {
183 return p->findModal() == w;
184 });
185 if (parentIt != windows.constEnd()) {
186 animation.parentY = (*parentIt)->y();
187 }
188
189 w->setData(WindowAddedGrabRole, QVariant::fromValue(static_cast<void *>(this)));
190
191 w->addRepaintFull();
192}
193
194void SheetEffect::slotWindowClosed(EffectWindow *w)
195{
197 return;
198 }
199
200 if (!isSheetWindow(w) || w->skipsCloseAnimation()) {
201 return;
202 }
203
204 Animation &animation = m_animations[w];
205 animation.deletedRef = EffectWindowDeletedRef(w);
206 animation.timeLine.reset();
207 animation.parentY = 0;
208 animation.timeLine.setDuration(m_duration);
209 animation.timeLine.setDirection(TimeLine::Backward);
210 animation.timeLine.setEasingCurve(QEasingCurve::Linear);
211
212 const auto windows = effects->stackingOrder();
213 auto parentIt = std::find_if(windows.constBegin(), windows.constEnd(),
214 [w](EffectWindow *p) {
215 return p->findModal() == w;
216 });
217 if (parentIt != windows.constEnd()) {
218 animation.parentY = (*parentIt)->y();
219 }
220
221 w->setData(WindowClosedGrabRole, QVariant::fromValue(static_cast<void *>(this)));
222
223 w->addRepaintFull();
224}
225
226bool SheetEffect::isSheetWindow(EffectWindow *w) const
227{
228 return w->isModal();
229}
230
231} // namespace KWin
232
233#include "moc_sheet.cpp"
Representation of a window used by/for Effect classes.
Q_SCRIPTABLE void addRepaintFull()
Q_SCRIPTABLE void setData(int role, const QVariant &data)
QRectF frameGeometry() const
bool animationsSupported() const
void windowClosed(KWin::EffectWindow *w)
QList< EffectWindow * > stackingOrder
void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data)
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
bool isOpenGLCompositing() const
Whether the Compositor is OpenGL based (either GL 1 or 2).
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
KSharedConfigPtr config() const
void windowAdded(KWin::EffectWindow *w)
Q_SCRIPTABLE void addRepaintFull()
Effect * activeFullScreenEffect() const
void postPaintWindow(EffectWindow *w)
QRectF renderRect() const
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override
Definition sheet.cpp:76
void reconfigure(ReconfigureFlags flags) override
Definition sheet.cpp:65
void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override
Definition sheet.cpp:94
static bool supported()
Definition sheet.cpp:157
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override
Definition sheet.cpp:83
void postPaintWindow(EffectWindow *w) override
Definition sheet.cpp:132
bool isActive() const override
Definition sheet.cpp:152
void setRotationAngle(qreal angle)
Definition effect.cpp:161
void setProjectionMatrix(const QMatrix4x4 &matrix)
Definition effect.cpp:327
qreal multiplyOpacity(qreal factor)
Definition effect.cpp:309
void setRotationAxis(const QVector3D &axis)
Definition effect.cpp:181
static double interpolate(double x, double y, double a)
Definition effect.h:910
static double animationTime(const KConfigGroup &cfg, const QString &key, int defaultTime)
Definition effect.cpp:483
void translate(qreal x, qreal y=0.0, qreal z=0.0)
Definition effect.cpp:116
@ PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS
Definition effect.h:567
@ ReconfigureAll
Definition effect.h:601
@ WindowAddedGrabRole
@ WindowClosedGrabRole
KWIN_EXPORT QRectF scaledRect(const QRectF &rect, qreal scale)
Definition globals.h:243
EffectsHandler * effects