2
* Animation plugin for compiz/beryl
6
* Copyright : (C) 2006 Erkin Bahceci
7
* E-mail : erkinbah@gmail.com
9
* Based on Wobbly and Minimize plugins by
11
* E-mail : davidr@novell.com>
13
* Particle system added by : (C) 2006 Dennis Kasprzyk
14
* E-mail : onestone@beryl-project.org
16
* Beam-Up added by : Florencio Guimaraes
17
* E-mail : florencio@nexcorp.com.br
19
* Hexagon tessellator added by : Mike Slegeir
20
* E-mail : mikeslegeir@mail.utexas.edu>
22
* This program is free software; you can redistribute it and/or
23
* modify it under the terms of the GNU General Public License
24
* as published by the Free Software Foundation; either version 2
25
* of the License, or (at your option) any later version.
27
* This program is distributed in the hope that it will be useful,
28
* but WITHOUT ANY WARRANTY; without even the implied warranty of
29
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30
* GNU General Public License for more details.
32
* You should have received a copy of the GNU General Public License
33
* along with this program; if not, write to the Free Software
34
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
39
// ===================== Restack =========================
41
RestackAnim::RestackAnim (CompWindow *w,
42
WindowEvent curWindowEvent,
44
const AnimEffect info,
45
const CompRect &icon) :
46
Animation::Animation (w, curWindowEvent, duration, info, icon)
48
mRestackData = static_cast<RestackPersistentData *>
49
(AnimWindow::get (w)->persistentData["restack"]);
53
RestackAnim::cleanUp (bool closing, bool destructing)
55
if (mRestackData->restackInfo ())
56
mRestackData->resetRestackInfo ();
58
bool thereIsUnfinishedChainElem = false;
60
// Look for still playing windows in parent-child chain
61
CompWindow *wCur = mRestackData->mMoreToBePaintedNext;
64
AnimWindow *awCur = AnimWindow::get (wCur);
66
if (awCur->curAnimation () &&
67
awCur->curAnimation ()->remainingTime () > 0)
69
thereIsUnfinishedChainElem = true;
72
RestackPersistentData *dataCur = static_cast<RestackPersistentData *>
73
(awCur->persistentData["restack"]);
74
wCur = dataCur->mMoreToBePaintedNext;
76
if (!thereIsUnfinishedChainElem)
78
wCur = mRestackData->mMoreToBePaintedPrev;
81
AnimWindow *awCur = AnimWindow::get (wCur);
83
if (awCur->curAnimation () &&
84
awCur->curAnimation ()->remainingTime () > 0)
86
thereIsUnfinishedChainElem = true;
89
RestackPersistentData *dataCur =
90
static_cast<RestackPersistentData *>
91
(awCur->persistentData["restack"]);
92
wCur = dataCur->mMoreToBePaintedPrev;
96
if (closing || destructing || !thereIsUnfinishedChainElem)
98
// Finish off all windows in parent-child chain
99
CompWindow *wCur = mRestackData->mMoreToBePaintedNext;
102
AnimWindow *awCur = AnimWindow::get (wCur);
103
RestackPersistentData *dataCur =
104
static_cast<RestackPersistentData *>
105
(awCur->persistentData["restack"]);
106
wCur = dataCur->mMoreToBePaintedNext;
107
static_cast<ExtensionPluginAnimation *>
108
(getExtensionPluginInfo ())->cleanUpParentChildChainItem (awCur);
113
AnimWindow *awCur = AnimWindow::get (wCur);
114
RestackPersistentData *dataCur =
115
static_cast<RestackPersistentData *>
116
(awCur->persistentData["restack"]);
117
wCur = dataCur->mMoreToBePaintedPrev;
118
static_cast<ExtensionPluginAnimation *>
119
(getExtensionPluginInfo ())->cleanUpParentChildChainItem (awCur);
123
ExtensionPluginAnimation *extPlugin =
124
static_cast<ExtensionPluginAnimation *> (getExtensionPluginInfo ());
125
extPlugin->decrementCurRestackAnimCount ();
129
RestackAnim::initiateRestackAnim (int duration)
131
CompWindow *wStart = 0;
132
CompWindow *wEnd = 0;
133
CompWindow *wOldAbove = 0;
138
ExtensionPluginAnimation *extPlugin =
139
static_cast<ExtensionPluginAnimation *> (getExtensionPluginInfo ());
140
extPlugin->incrementCurRestackAnimCount ();
142
// If a focus chain (application with open dialog, etc.) is the subject,
143
// in compiz++, their order changes during restack (which wasn't the case
144
// in compiz 0.8. e.g: (subject chain: a b, dodger: x) (a: secondary)
148
if (mRestackData->mIsSecondary)
150
if (!mRestackData->mMoreToBePaintedNext)
153
AnimWindow *awAbove =
154
AnimWindow::get (mRestackData->mMoreToBePaintedNext);
155
RestackPersistentData *dataAbove = static_cast<RestackPersistentData *>
156
(awAbove->persistentData["restack"]);
158
mTotalTime = awAbove->curAnimation ()->totalTime ();
159
mRemainingTime = mTotalTime;
161
if (dataAbove && dataAbove->mWinThisIsPaintedBefore)
163
// Host this subject instead, on the above subject's host
164
mRestackData->getHostedOnWin (mWindow,
165
dataAbove->mWinThisIsPaintedBefore);
167
// do basic secondary subject initialization
168
postInitiateRestackAnim (0, 0, 0, 0, false);
170
return true; // We're done here
173
RestackInfo *restackInfo = mRestackData->restackInfo ();
178
wStart = restackInfo->wStart;
179
wEnd = restackInfo->wEnd;
180
wOldAbove = restackInfo->wOldAbove;
181
raised = restackInfo->raised;
184
// Find union region of all windows that will be
185
// faded through by w. If the region is empty, don't
186
// run focus fade effect.
188
CompRegion fadeRegion;
190
int numSelectedCandidates = 0;
192
CompRegion subjectsRegion (unionRestackChain (mWindow));
194
// Compute subject win. region
196
// wCand: Dodge or Focus fade candidate window
197
for (CompWindow *wCand = wStart; wCand && wCand != wEnd->next;
200
RestackPersistentData *dataCand = static_cast<RestackPersistentData *>
201
(AnimWindow::get (wCand)->persistentData["restack"]);
202
if (!extPlugin->relevantForRestackAnim (wCand))
205
// Skip windows that have been restacked
206
if (wCand != wEnd && dataCand->restackInfo ())
209
if (wCand->minimized ())
212
if (!CompositeWindow::get (wCand)->pixmap ())
215
if (//skipSubjectWindows () &&
216
onSameRestackChain (mWindow, wCand))
219
// Compute intersection of this (wCand) with subject
220
CompRegion candidateWinRegion (wCand->inputRect ());
221
CompRegion candidateAndSubjectIntersection
222
(candidateWinRegion.intersected (subjectsRegion));
223
fadeRegion += candidateAndSubjectIntersection;
225
if (!candidateAndSubjectIntersection.isEmpty ())
226
processCandidate (wCand, mWindow, candidateAndSubjectIntersection,
227
numSelectedCandidates);
230
if (fadeRegion.isEmpty ())
232
// empty intersection -> won't be drawn
237
// Store this window in the next window
238
// so that this is drawn before that, i.e. in its old place
239
mRestackData->getHostedOnWin (mWindow, wOldAbove);
242
postInitiateRestackAnim (numSelectedCandidates, duration,
243
wStart, wEnd, raised);
245
// Handle other subjects down the chain if there are any
246
if (mRestackData->mMoreToBePaintedPrev)
248
RestackPersistentData *dataCur;
249
for (CompWindow *wCur = mRestackData->mMoreToBePaintedPrev; wCur;
250
wCur = dataCur->mMoreToBePaintedPrev)
252
dataCur = static_cast<RestackPersistentData *>
253
(AnimWindow::get (wCur)->persistentData["restack"]);
256
dataCur->mIsSecondary = true;
263
RestackAnim::onSameRestackChain (CompWindow *wSubject, CompWindow *wOther)
265
RestackPersistentData *dataCur;
266
for (CompWindow *wCur = wSubject; wCur;
267
wCur = dataCur->mMoreToBePaintedNext)
271
dataCur = static_cast<RestackPersistentData *>
272
(AnimWindow::get (wCur)->persistentData["restack"]);
277
RestackPersistentData *dataSubj = static_cast<RestackPersistentData *>
278
(AnimWindow::get (wSubject)->
279
persistentData["restack"]);
280
for (CompWindow *wCur = dataSubj->mMoreToBePaintedPrev; wCur;
281
wCur = dataCur->mMoreToBePaintedPrev)
285
dataCur = static_cast<RestackPersistentData *>
286
(AnimWindow::get (wCur)->persistentData["restack"]);
293
RestackAnim::overNewCopy ()
295
bool lowering = (mRestackData->restackInfo () &&
296
!mRestackData->restackInfo ()->raised);
298
// Reverse behavior if lowering (i.e. not raising)
299
return (!lowering && mRestackData->mVisitCount == 2 ||
300
lowering && mRestackData->mVisitCount == 1);
304
RestackAnim::unionRestackChain (CompWindow *w)
306
CompRegion unionRegion;
308
RestackPersistentData *dataCur;
309
for (CompWindow *wCur = w; wCur;
310
wCur = dataCur->mMoreToBePaintedNext)
312
unionRegion += wCur->inputRect ();
313
dataCur = static_cast<RestackPersistentData *>
314
(AnimWindow::get (wCur)->persistentData["restack"]);
319
RestackPersistentData *dataSubj = static_cast<RestackPersistentData *>
320
(AnimWindow::get (w)->
321
persistentData["restack"]);
322
for (CompWindow *wCur = dataSubj->mMoreToBePaintedPrev; wCur;
323
wCur = dataCur->mMoreToBePaintedPrev)
325
unionRegion += wCur->inputRect ();
326
dataCur = static_cast<RestackPersistentData *>
327
(AnimWindow::get (wCur)->persistentData["restack"]);
335
RestackInfo::RestackInfo (CompWindow *wRestacked,
338
CompWindow *wOldAbove,
340
wRestacked (wRestacked),
343
wOldAbove (wOldAbove),
348
RestackPersistentData::RestackPersistentData () :
351
mWinToBePaintedBeforeThis (0),
352
mWinThisIsPaintedBefore (0),
353
mMoreToBePaintedPrev (0),
354
mMoreToBePaintedNext (0),
355
mWinPassingThrough (0),
356
mWalkerOverNewCopy (false),
362
RestackPersistentData::~RestackPersistentData ()
369
RestackPersistentData::setRestackInfo (CompWindow *wRestacked,
372
CompWindow *wOldAbove,
378
new RestackInfo (wRestacked, wStart, wEnd, wOldAbove, raised);
381
/// Make this window be hosted on (i.e. drawn before) the given window.
383
RestackPersistentData::getHostedOnWin (CompWindow *wGuest, CompWindow *wHost)
385
RestackPersistentData *dataHost = static_cast<RestackPersistentData *>
386
(AnimWindow::get (wHost)->persistentData["restack"]);
387
dataHost->mWinToBePaintedBeforeThis = wGuest;
388
mWinThisIsPaintedBefore = wHost;