1
/********************************************************************
2
KWin - the KDE window manager
3
This file is part of the KDE project.
5
Copyright (C) 2007 Philip Falkner <philip.falkner@gmail.com>
6
Copyright (C) 2009 Martin Gräßlin <kde@martin-graesslin.com>
7
Copyright (C) 2010 Alexandre Pereira <pereira.alex@gmail.com>
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU General Public License for more details.
19
You should have received a copy of the GNU General Public License
20
along with this program. If not, see <http://www.gnu.org/licenses/>.
21
*********************************************************************/
25
#include <kconfiggroup.h>
26
#include <QtCore/QTimeLine>
28
// Effect is based on fade effect by Philip Falkner
33
KWIN_EFFECT(glide, GlideEffect)
34
KWIN_EFFECT_SUPPORTED(glide, GlideEffect::supported())
36
static const int IsGlideWindow = 0x22A982D4;
38
GlideEffect::GlideEffect()
40
reconfigure(ReconfigureAll);
41
connect(effects, SIGNAL(windowAdded(EffectWindow*)), this, SLOT(slotWindowAdded(EffectWindow*)));
42
connect(effects, SIGNAL(windowClosed(EffectWindow*)), this, SLOT(slotWindowClosed(EffectWindow*)));
43
connect(effects, SIGNAL(windowDeleted(EffectWindow*)), this, SLOT(slotWindowDeleted(EffectWindow*)));
46
bool GlideEffect::supported()
48
return effects->compositingType() == OpenGLCompositing;
51
void GlideEffect::reconfigure(ReconfigureFlags)
53
KConfigGroup conf = effects->effectConfig("Glide");
54
duration = animationTime(conf, "AnimationTime", 350);
55
effect = (EffectStyle) conf.readEntry("GlideEffect", 0);
56
angle = conf.readEntry("GlideAngle", -90);
59
void GlideEffect::prePaintScreen(ScreenPrePaintData& data, int time)
61
if (!windows.isEmpty())
62
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
63
effects->prePaintScreen(data, time);
66
void GlideEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
68
InfoHash::iterator info = windows.find(w);
69
if (info != windows.end()) {
70
data.setTransformed();
72
info->timeLine->setCurrentTime(info->timeLine->currentTime() + time);
73
else if (info->closed) {
74
info->timeLine->setCurrentTime(info->timeLine->currentTime() - time);
76
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE);
80
effects->prePaintWindow(w, data, time);
82
// if the window isn't to be painted, then let's make sure
83
// to track its progress
84
if (info != windows.end() && !w->isPaintingEnabled() && !effects->activeFullScreenEffect())
88
void GlideEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
90
InfoHash::const_iterator info = windows.constFind(w);
91
if (info != windows.constEnd()) {
92
const double progress = info->timeLine->currentValue();
94
rot.axis = RotationData::XAxis;
95
rot.angle = angle * (1 - progress);
97
data.opacity *= progress;
103
else if (info->closed)
112
case GlideIn: glideIn(w, data); break;
113
case GlideOut: glideOut(w, data); break;
116
effects->paintWindow(w, mask, region, data);
119
void GlideEffect::glideIn(EffectWindow* w, WindowPaintData& data)
121
InfoHash::const_iterator info = windows.constFind(w);
122
if (info == windows.constEnd())
124
const double progress = info->timeLine->currentValue();
125
data.xScale *= progress;
126
data.yScale *= progress;
127
data.zScale *= progress;
128
data.xTranslate += int(w->width() / 2 * (1 - progress));
129
data.yTranslate += int(w->height() / 2 * (1 - progress));
132
void GlideEffect::glideOut(EffectWindow* w, WindowPaintData& data)
134
InfoHash::const_iterator info = windows.constFind(w);
135
if (info == windows.constEnd())
137
const double progress = info->timeLine->currentValue();
138
data.xScale *= (2 - progress);
139
data.yScale *= (2 - progress);
140
data.zScale *= (2 - progress);
141
data.xTranslate -= int(w->width() / 2 * (1 - progress));
142
data.yTranslate -= int(w->height() / 2 * (1 - progress));
145
void GlideEffect::postPaintWindow(EffectWindow* w)
147
InfoHash::iterator info = windows.find(w);
148
if (info != windows.end()) {
149
if (info->added && info->timeLine->currentValue() == 1.0) {
151
effects->addRepaintFull();
152
} else if (info->closed && info->timeLine->currentValue() == 0.0) {
153
info->closed = false;
158
effects->addRepaintFull();
160
if (info->added || info->closed)
163
effects->postPaintWindow(w);
166
void GlideEffect::slotWindowAdded(EffectWindow* w)
168
if (!isGlideWindow(w))
170
w->setData(IsGlideWindow, true);
171
const void *addGrab = w->data(WindowAddedGrabRole).value<void*>();
172
if (addGrab && addGrab != this)
174
w->setData(WindowAddedGrabRole, QVariant::fromValue(static_cast<void*>(this)));
176
InfoHash::iterator it = windows.find(w);
177
WindowInfo *info = (it == windows.end()) ? &windows[w] : &it.value();
179
info->closed = false;
180
info->deleted = false;
181
delete info->timeLine;
182
info->timeLine = new QTimeLine(duration);
183
info->timeLine->setCurveShape(QTimeLine::EaseOutCurve);
187
void GlideEffect::slotWindowClosed(EffectWindow* w)
189
if (!isGlideWindow(w))
191
const void *closeGrab = w->data(WindowClosedGrabRole).value<void*>();
192
if (closeGrab && closeGrab != this)
195
w->setData(WindowClosedGrabRole, QVariant::fromValue(static_cast<void*>(this)));
197
InfoHash::iterator it = windows.find(w);
198
WindowInfo *info = (it == windows.end()) ? &windows[w] : &it.value();
201
info->deleted = true;
202
delete info->timeLine;
203
info->timeLine = new QTimeLine(duration);
204
info->timeLine->setCurveShape(QTimeLine::EaseInCurve);
205
info->timeLine->setCurrentTime(info->timeLine->duration());
209
void GlideEffect::slotWindowDeleted(EffectWindow* w)
214
bool GlideEffect::isGlideWindow(EffectWindow* w)
216
if (effects->activeFullScreenEffect())
218
if (w->data(IsGlideWindow).toBool())
220
if (w->hasDecoration())
222
if (!w->isManaged() || w->isMenu() || w->isNotification() || w->isDesktop() ||
223
w->isDock() || w->isSplash() || w->isTopMenu() || w->isToolbar() ||
224
w->windowClass() == "dashboard dashboard")
229
GlideEffect::WindowInfo::WindowInfo()
237
GlideEffect::WindowInfo::~WindowInfo()