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
* Airplane added by : Carlo Palma
14
* E-mail : carlopalma@salug.it
15
* Based on code originally written by Mark J. Kilgard
17
* Beam-Up added by : Florencio Guimaraes
18
* E-mail : florencio@nexcorp.com.br
20
* Fold and Skewer added by : Tomasz Kolodziejski
21
* E-mail : tkolodziejski@gmail.com
23
* Hexagon tessellator added by : Mike Slegeir
24
* E-mail : mikeslegeir@mail.utexas.edu>
26
* Particle system added by : (C) 2006 Dennis Kasprzyk
27
* E-mail : onestone@beryl-project.org
29
* This program is free software; you can redistribute it and/or
30
* modify it under the terms of the GNU General Public License
31
* as published by the Free Software Foundation; either version 2
32
* of the License, or (at your option) any later version.
34
* This program is distributed in the hope that it will be useful,
35
* but WITHOUT ANY WARRANTY; without even the implied warranty of
36
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37
* GNU General Public License for more details.
39
* You should have received a copy of the GNU General Public License
40
* along with this program; if not, write to the Free Software
41
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
47
* - Custom bounding box update function for Airplane
49
* - Auto direction option: Close in opposite direction of opening
50
* - Proper side surface normals for lighting
51
* - decoration shadows
52
* - shadow quad generation
53
* - shadow texture coords (from clip tex. matrices)
57
* - Voronoi tessellation
58
* - Brick tessellation
59
* - Triangle tessellation
60
* - Hexagonal tessellation
63
* - Circular action for tornado type fx
64
* - Tornado 3D (especially for minimize)
65
* - Helix 3D (hor. strips descend while they rotate and fade in)
67
* - Gaussian distr. points (for gradually increasing polygon size
68
* starting from center or near mouse pointer)
72
* - fix slowness during transparent cube with <100 opacity
73
* - fix occasional wrong side color in some windows
74
* - fix on top windows and panels
75
* (These two only matter for viewing during Rotate Cube.
76
* All windows should be painted with depth test on
77
* like 3d-plugin does)
78
* - play better with rotate (fix cube face drawn on top of polygons
79
* after 45 deg. rotation)
84
#include <core/atoms.h>
89
class AnimPluginVTable :
90
public CompPlugin::VTableForScreenAndWindow<AnimScreen, AnimWindow>
97
COMPIZ_PLUGIN_20090315 (animation, AnimPluginVTable);
99
#define FAKE_ICON_SIZE 4
101
const char *eventNames[AnimEventNum] =
102
{"Open", "Close", "Minimize", "Shade", "Focus"};
104
int chosenEffectOptionIds[AnimEventNum] =
106
AnimationOptions::OpenEffects,
107
AnimationOptions::CloseEffects,
108
AnimationOptions::MinimizeEffects,
109
AnimationOptions::ShadeEffects,
110
AnimationOptions::FocusEffects
113
int randomEffectOptionIds[AnimEventNum] =
115
AnimationOptions::OpenRandomEffects,
116
AnimationOptions::CloseRandomEffects,
117
AnimationOptions::MinimizeRandomEffects,
118
AnimationOptions::ShadeRandomEffects,
122
int customOptionOptionIds[AnimEventNum] =
124
AnimationOptions::OpenOptions,
125
AnimationOptions::CloseOptions,
126
AnimationOptions::MinimizeOptions,
127
AnimationOptions::ShadeOptions,
128
AnimationOptions::FocusOptions
131
int matchOptionIds[AnimEventNum] =
133
AnimationOptions::OpenMatches,
134
AnimationOptions::CloseMatches,
135
AnimationOptions::MinimizeMatches,
136
AnimationOptions::ShadeMatches,
137
AnimationOptions::FocusMatches
140
int durationOptionIds[AnimEventNum] =
142
AnimationOptions::OpenDurations,
143
AnimationOptions::CloseDurations,
144
AnimationOptions::MinimizeDurations,
145
AnimationOptions::ShadeDurations,
146
AnimationOptions::FocusDurations
149
// Bind each effect in the list of chosen effects for every event, to the
150
// corresponding animation effect (i.e. effect with that name) if it is
151
// provided by a plugin, otherwise set it to None.
153
PrivateAnimScreen::updateEventEffects (AnimEvent e,
157
CompOption::Value::Vector *listVal;
158
EffectSet *effectSet;
161
listVal = &getOptions ()[(unsigned)randomEffectOptionIds[e]].value ().
163
effectSet = &mRandomEffects[e];
167
listVal = &getOptions ()[(unsigned)chosenEffectOptionIds[e]].value ().
169
effectSet = &mEventEffects[e];
171
unsigned int n = listVal->size ();
173
effectSet->effects.clear ();
174
effectSet->effects.reserve (n);
176
AnimEffectVector &eventEffectsAllowed = mEventEffectsAllowed[e];
178
for (unsigned int r = 0; r < n; r++) // for each row
180
const CompString &animName = (*listVal)[r].s ();
182
// Find the animation effect with matching name
183
AnimEffectVector::iterator it =
184
find_if (eventEffectsAllowed.begin (),
185
eventEffectsAllowed.end (),
186
boost::bind (&AnimEffectInfo::matchesEffectName,
189
effectSet->effects.push_back (it == eventEffectsAllowed.end () ?
190
AnimEffectNone : *it);
195
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
196
extPlugin->postUpdateEventEffects (e, forRandom);
201
PrivateAnimScreen::updateAllEventEffects ()
203
// for each anim event
204
for (int e = 0; e < AnimEventNum; e++)
205
updateEventEffects ((AnimEvent)e, false);
207
// for each anim event except focus
208
for (int e = 0; e < AnimEventNum - 1; e++)
209
updateEventEffects ((AnimEvent)e, true);
213
PrivateAnimScreen::isAnimEffectInList (AnimEffect theEffect,
214
EffectSet &effectList)
216
for (unsigned int i = 0; i < effectList.effects.size (); i++)
217
if (effectList.effects[i] == theEffect)
223
PrivateAnimScreen::isAnimEffectPossibleForEvent (AnimEffect theEffect,
226
// Check all rows to see if the effect is chosen there
227
unsigned int nRows = mEventEffects[event].effects.size ();
228
for (unsigned int i = 0; i < nRows; i++)
230
AnimEffect chosenEffect = mEventEffects[event].effects[i];
231
// if chosen directly
232
if (chosenEffect == theEffect)
234
// if chosen in random pool
235
if (mRandomEffects[event].effects.size () &&
236
chosenEffect == AnimEffectRandom &&
237
isAnimEffectInList (theEffect, mRandomEffects[event]))
244
PrivateAnimScreen::isAnimEffectPossible (AnimEffect theEffect)
246
for (int e = 0; e < AnimEventNum; e++)
247
if (isAnimEffectPossibleForEvent (theEffect, (AnimEvent)e))
253
PrivateAnimScreen::isRestackAnimPossible ()
255
// Check all rows to see if the chosen effect is a restack animation
256
unsigned int nRows = mEventEffects[AnimEventFocus].effects.size ();
258
for (unsigned int i = 0; i < nRows; i++)
260
AnimEffect chosenEffect = mEventEffects[(unsigned)AnimEventFocus].
262
if (chosenEffect->isRestackAnim)
269
AnimScreen::isRestackAnimPossible ()
271
return priv->isRestackAnimPossible ();
274
// Extension functions
277
AnimScreen::addExtension (ExtensionPluginInfo *extensionPluginInfo)
279
priv->addExtension (extensionPluginInfo, true);
283
PrivateAnimScreen::addExtension (ExtensionPluginInfo *extensionPluginInfo,
284
bool shouldInitPersistentData)
286
mExtensionPlugins.push_back (extensionPluginInfo);
288
unsigned int nPluginEffects = extensionPluginInfo->nEffects;
290
bool eventEffectsNeedUpdate[AnimEventNum] =
291
{false, false, false, false, false};
293
// Put this plugin's effects into mEventEffects and
294
// mEventEffectsAllowed
295
for (unsigned int j = 0; j < nPluginEffects; j++)
297
const AnimEffect effect = extensionPluginInfo->effects[j];
299
// Update allowed effects for each event
300
for (int e = 0; e < AnimEventNum; e++)
302
if (effect->usedForEvents[e])
304
mEventEffectsAllowed[e].push_back (effect);
305
eventEffectsNeedUpdate[e] = true;
310
for (int e = 0; e < AnimEventNum; e++)
311
if (eventEffectsNeedUpdate[e])
313
updateEventEffects ((AnimEvent)e, false, false);
314
if (e != AnimEventFocus)
315
updateEventEffects ((AnimEvent)e, true, false);
318
if (shouldInitPersistentData)
320
// Initialize persistent window data for the extension plugin
321
foreach (CompWindow *w, ::screen->windows ())
323
AnimWindow *aw = AnimWindow::get (w);
324
extensionPluginInfo->initPersistentData (aw);
330
AnimScreen::removeExtension (ExtensionPluginInfo *extensionPluginInfo)
332
priv->removeExtension (extensionPluginInfo);
336
PrivateAnimScreen::removeExtension (ExtensionPluginInfo *extensionPluginInfo)
338
// Stop all ongoing animations
339
foreach (CompWindow *w, ::screen->windows ())
341
PrivateAnimWindow *aw = AnimWindow::get (w)->priv;
342
if (aw->curAnimation ())
343
aw->postAnimationCleanUp ();
346
// Find the matching plugin and delete it
348
ExtensionPluginVector::iterator it = find (mExtensionPlugins.begin (),
349
mExtensionPlugins.end (),
350
extensionPluginInfo);
352
if (it == mExtensionPlugins.end ())
353
return; // couldn't find that extension plugin
355
mExtensionPlugins.erase (it);
357
if (extensionPluginInfo->nEffects == 0)
358
return; // no animation effects -> we're done here
361
// Also delete the "allowed effect" entries for that plugin
363
for (int e = 0; e < AnimEventNum; e++)
365
AnimEffectVector &eventEffectsAllowed = mEventEffectsAllowed[e];
367
// Find the first animation effect with matching name
368
AnimEffectVector::iterator itBeginEffect =
369
find_if (eventEffectsAllowed.begin (),
370
eventEffectsAllowed.end (),
371
boost::bind (&AnimEffectInfo::matchesPluginName,
372
_1, extensionPluginInfo->name));
374
if (itBeginEffect == eventEffectsAllowed.end ())
375
continue; // plugin didn't provide any effects for this event
377
// Find the first animation effect with non-matching name,
378
// starting with itBeginEffect
379
AnimEffectVector::iterator itEndEffect =
380
find_if (itBeginEffect,
381
eventEffectsAllowed.end (),
382
boost::bind (&AnimEffectInfo::matchesPluginName,
383
_1, extensionPluginInfo->name) == false);
385
eventEffectsAllowed.erase (itBeginEffect, itEndEffect);
387
// Update event effects to complete removal
388
updateEventEffects ((AnimEvent)e, false);
389
if (e != AnimEventFocus)
390
updateEventEffects ((AnimEvent)e, true);
393
// Destroy persistent window data for the extension plugin
394
foreach (CompWindow *w, ::screen->windows ())
396
AnimWindow *aw = AnimWindow::get (w);
397
extensionPluginInfo->destroyPersistentData (aw);
401
ExtensionPluginInfo::ExtensionPluginInfo (const CompString &name,
402
unsigned int nEffects,
404
CompOption::Vector *effectOptions,
405
unsigned int firstEffectOptionIndex) :
409
effectOptions (effectOptions),
410
firstEffectOptionIndex (firstEffectOptionIndex)
414
// End of extension functions
416
Animation::Animation (CompWindow *w,
417
WindowEvent curWindowEvent,
419
const AnimEffect info,
420
const CompRect &icon) :
422
mAWindow (AnimWindow::get (w)),
423
mTotalTime (duration),
424
mRemainingTime (duration),
425
mTimeElapsedWithinTimeStep (0),
426
mOverrideProgressDir (0),
427
mCurPaintAttrib (GLWindow::defaultPaintAttrib),
428
mStoredOpacity (CompositeWindow::get (w)->opacity ()),
429
mCurWindowEvent (curWindowEvent),
430
mInitialized (false), // store window opacity
434
if (curWindowEvent == WindowEventShade ||
435
curWindowEvent == WindowEventUnshade)
437
mDecorTopHeight = w->output ().top;
438
mDecorBottomHeight = w->output ().bottom;
441
texturesCache = new GLTexture::List (GLWindow::get (w)->textures ());
442
PrivateAnimScreen *as = mAWindow->priv->paScreen ();
444
mTimestep = as->optionGetTimeStep ();
447
Animation::~Animation ()
449
delete texturesCache;
453
Animation::optVal (unsigned int optionId)
455
return mAWindow->pluginOptVal (getExtensionPluginInfo (), optionId, this);
458
/// Play the animation effect backwards from where it left off.
460
Animation::reverse ()
462
mRemainingTime = mTotalTime - mRemainingTime;
464
// avoid window remains
465
if (mRemainingTime <= 0)
468
switch (mCurWindowEvent) // the old event
470
case WindowEventOpen:
471
mCurWindowEvent = WindowEventClose;
473
case WindowEventClose:
474
mCurWindowEvent = WindowEventOpen;
476
case WindowEventMinimize:
477
mCurWindowEvent = WindowEventUnminimize;
479
case WindowEventUnminimize:
480
mCurWindowEvent = WindowEventMinimize;
482
case WindowEventShade:
483
mCurWindowEvent = WindowEventUnshade;
485
case WindowEventUnshade:
486
mCurWindowEvent = WindowEventShade;
492
// 1: forward, 2: backward (3 - progressDir is opposite direction)
495
switch (mCurWindowEvent) // the new event
497
case WindowEventClose:
498
case WindowEventMinimize:
499
case WindowEventShade:
506
if (mOverrideProgressDir == 0)
507
mOverrideProgressDir = progressDir;
508
else if (mOverrideProgressDir == 3 - progressDir)
509
mOverrideProgressDir = 0; // disable override
512
PartialWindowAnim::PartialWindowAnim (CompWindow *w,
513
WindowEvent curWindowEvent,
515
const AnimEffect info,
516
const CompRect &icon) :
517
Animation::Animation (w, curWindowEvent, duration, info, icon),
518
mUseDrawRegion (false),
524
PrivateAnimWindow::updateSelectionRow (unsigned int r)
526
mPrevAnimSelectionRow = mCurAnimSelectionRow;
527
mCurAnimSelectionRow = (int)r;
530
// Assumes events in the metadata are in
531
// [Open, Close, Minimize, Focus, Shade] order
532
// and effects among those are in alphabetical order
533
// but with "(Event) None" first and "(Event) Random" last.
535
PrivateAnimScreen::getMatchingAnimSelection (CompWindow *w,
539
PrivateAnimWindow *aw = AnimWindow::get (w)->priv;
541
EffectSet *eventEffects = &mEventEffects[e];
542
CompOption::Value &valMatch =
543
getOptions ()[(unsigned)matchOptionIds[e]].value ();
544
CompOption::Value &valDuration =
545
getOptions ()[(unsigned)durationOptionIds[e]].value ();
546
CompOption::Value &valCustomOptions =
547
getOptions ()[(unsigned)customOptionOptionIds[e]].value ();
549
unsigned int nRows = valMatch.list ().size ();
550
if (nRows != eventEffects->effects.size () ||
551
nRows != valDuration.list ().size () ||
552
nRows != valCustomOptions.list ().size ())
554
compLogMessage ("animation", CompLogLevelError,
555
"Animation settings mismatch in \"Animation "
556
"Selection\" list for %s event.", eventNames[e]);
557
return AnimEffectNone;
560
// Find the first row that matches this window for this event
561
for (unsigned int i = 0; i < nRows; i++)
563
if (!valMatch.list ()[i].match ().evaluate (w))
566
aw->updateSelectionRow (i);
569
*duration = valDuration.list ()[i].i ();
571
AnimEffect effect = eventEffects->effects[i];
573
return (effect ? effect : AnimEffectNone);
576
return AnimEffectNone;
580
PrivateAnimScreen::getActualEffect (AnimEffect effect,
583
bool allRandom = optionGetAllRandom ();
584
AnimEffectVector *randomEffects = &mRandomEffects[animEvent].effects;
585
unsigned int nRandomEffects = randomEffects->size ();
586
unsigned int nFirstRandomEffect = 0;
588
if ((effect == AnimEffectRandom) || allRandom)
590
if (nRandomEffects == 0) // no random animation selected, assume "all"
592
randomEffects = &mEventEffectsAllowed[animEvent];
594
// exclude None and Random
595
nFirstRandomEffect = 2;
596
nRandomEffects = randomEffects->size () - 2;
598
unsigned int index = nFirstRandomEffect +
599
(unsigned int)(nRandomEffects * (double)rand () / RAND_MAX);
600
return (*randomEffects)[index];
606
/// Converts animation direction (up, down, left, right, random, auto)
607
/// to an actual direction (up, down, left, or right).
609
Animation::getActualAnimDirection (AnimDirection dir,
612
if (dir == AnimDirectionRandom)
614
dir = (AnimDirection)(rand () % 4);
616
else if (dir == AnimDirectionAuto)
618
CompRect outRect (mAWindow->savedRectsValid () ?
619
mAWindow->savedOutRect () :
620
mWindow->outputRect ());
623
int centerX = outRect.x () + outRect.width () / 2 ;
624
int centerY = outRect.y () + outRect.height () / 2 ;
625
float relDiffX = ((float)centerX - mIcon.x ()) / outRect.width ();
626
float relDiffY = ((float)centerY - mIcon.y ()) / outRect.height ();
630
if (mCurWindowEvent == WindowEventMinimize ||
631
mCurWindowEvent == WindowEventUnminimize)
632
// min/unmin. should always result in +/- y direction
633
dir = (mIcon.y () < (int)::screen->height () - mIcon.y ()) ?
634
AnimDirectionDown : AnimDirectionUp;
635
else if (fabs (relDiffY) > fabs (relDiffX))
636
dir = relDiffY > 0 ? AnimDirectionDown : AnimDirectionUp;
638
dir = relDiffX > 0 ? AnimDirectionRight : AnimDirectionLeft;
642
if (mCurWindowEvent == WindowEventMinimize ||
643
mCurWindowEvent == WindowEventUnminimize)
644
// min/unmin. should always result in +/- y direction
645
dir = (mIcon.y () < (int)::screen->height () - mIcon.y ()) ?
646
AnimDirectionUp : AnimDirectionDown;
647
else if (fabs (relDiffY) > fabs (relDiffX))
648
dir = relDiffY > 0 ? AnimDirectionUp : AnimDirectionDown;
650
dir = relDiffX > 0 ? AnimDirectionLeft : AnimDirectionRight;
657
Animation::progressLinear ()
659
float forwardProgress =
660
1 - mRemainingTime / (mTotalTime - mTimestep);
661
forwardProgress = MIN (forwardProgress, 1);
662
forwardProgress = MAX (forwardProgress, 0);
664
if (mCurWindowEvent == WindowEventOpen ||
665
mCurWindowEvent == WindowEventUnminimize ||
666
mCurWindowEvent == WindowEventUnshade ||
667
mCurWindowEvent == WindowEventFocus)
668
forwardProgress = 1 - forwardProgress;
670
return forwardProgress;
674
Animation::progressEaseInEaseOut ()
676
float forwardProgress =
677
1 - mRemainingTime / (mTotalTime - mTimestep);
678
forwardProgress = MIN (forwardProgress, 1);
679
forwardProgress = MAX (forwardProgress, 0);
681
// Apply sigmoid and normalize
683
(sigmoid (forwardProgress) - sigmoid (0)) /
684
(sigmoid (1) - sigmoid (0));
686
if (mCurWindowEvent == WindowEventOpen ||
687
mCurWindowEvent == WindowEventUnminimize ||
688
mCurWindowEvent == WindowEventUnshade ||
689
mCurWindowEvent == WindowEventFocus)
690
forwardProgress = 1 - forwardProgress;
692
return forwardProgress;
695
/// Gives some acceleration (when closing a window)
696
/// or deceleration (when opening a window).
697
/// Applies a sigmoid with slope s,
698
/// where minx and maxx are the
699
/// starting and ending points on the sigmoid.
701
Animation::progressDecelerateCustom (float progress, float minx, float maxx)
703
float x = 1 - progress;
707
1 - ((sigmoid2 (minx + (x * (maxx - minx)), s) - sigmoid2 (minx, s)) /
708
(sigmoid2 (maxx, s) - sigmoid2 (minx, s)));
712
Animation::progressDecelerate (float progress)
714
return progressDecelerateCustom (progress, 0.5, 0.75);
724
AnimWindow::stepRegion ()
726
return priv->mStepRegion;
730
PrivateAnimWindow::copyResetStepRegion ()
732
mLastStepRegion = mStepRegion;
734
// Reset bounding box for current step
735
mBB.x1 = mBB.y1 = MAXSHORT;
736
mBB.x2 = mBB.y2 = MINSHORT;
740
AnimWindow::expandBBWithBox (Box &source)
742
Box &target = priv->BB ();
744
if (source.x1 < target.x1)
745
target.x1 = source.x1;
746
if (source.x2 > target.x2)
747
target.x2 = source.x2;
748
if (source.y1 < target.y1)
749
target.y1 = source.y1;
750
if (source.y2 > target.y2)
751
target.y2 = source.y2;
755
AnimWindow::expandBBWithPoint (float fx, float fy)
757
Box &target = priv->BB ();
759
short x = MAX (MIN (fx, MAXSHORT - 1), MINSHORT);
760
short y = MAX (MIN (fy, MAXSHORT - 1), MINSHORT);
762
if (target.x1 == MAXSHORT)
772
else if (x > target.x2)
777
else if (y > target.y2)
781
/// This will work for zoom-like 2D transforms,
782
/// but not for glide-like 3D transforms.
784
AnimWindow::expandBBWithPoint2DTransform (GLVector &coords,
785
GLMatrix &transformMat)
787
GLVector coordsTransformed = transformMat * coords;
788
expandBBWithPoint (coordsTransformed[GLVector::x],
789
coordsTransformed[GLVector::y]);
792
/// Either points or objects should be non-0.
794
AnimWindow::expandBBWithPoints3DTransform (CompOutput &output,
797
GridAnim::GridModel::GridObject *objects,
798
unsigned int nPoints)
801
GLdouble dProjection[16];
803
for (unsigned int i = 0; i < 16; i++)
805
dModel[i] = transform[i];
806
dProjection[i] = GLScreen::get (::screen)->projectionMatrix ()[i];
809
{output.region ()->extents.x1,
810
output.region ()->extents.y1,
814
if (points) // use points
816
for (; nPoints; nPoints--, points += 3)
818
if (!gluProject (points[0], points[1], points[2],
819
dModel, dProjection, viewport,
823
expandBBWithPoint (x + 0.5, (::screen->height () - y) + 0.5);
826
else // use grid model objects
828
GridAnim::GridModel::GridObject *object = objects;
829
for (; nPoints; nPoints--, object++)
831
if (!gluProject (object->position ().x (),
832
object->position ().y (),
833
object->position ().z (),
834
dModel, dProjection, viewport,
838
expandBBWithPoint (x + 0.5, (::screen->height () - y) + 0.5);
845
AnimWindow::expandBBWithWindow ()
847
CompRect outRect (savedRectsValid () ?
849
mWindow->outputRect ());
851
outRect.x (), outRect.x () + outRect.width (),
852
outRect.y (), outRect.y () + outRect.height ()
854
expandBBWithBox (windowBox);
858
AnimWindow::expandBBWithScreen ()
860
Box screenBox = {0, ::screen->width (),
861
0, ::screen->height ()};
862
expandBBWithBox (screenBox);
866
Animation::prepareTransform (CompOutput &output,
867
GLMatrix &resultTransform,
871
sTransform.toScreenSpace (&output, -DEFAULT_Z_CAMERA);
872
resultTransform = sTransform * transform;
876
AnimWindow::resetStepRegionWithBB ()
878
// Have a 1 pixel margin to prevent occasional 1 pixel line artifact
879
CompRegion region (priv->mBB.x1 - 1,
881
priv->mBB.x2 - priv->mBB.x1 + 2,
882
priv->mBB.y2 - priv->mBB.y1 + 2);
883
priv->mStepRegion = region;
886
/// Damage the union of window's bounding box
887
/// before and after animStepFunc does its job.
889
PrivateAnimWindow::damageThisAndLastStepRegion ()
891
// Find union of the regions for this step and last step
892
CompRegion totalRegionToDamage (mStepRegion + mLastStepRegion);
894
mPAScreen->cScreen->damageRegion (totalRegionToDamage);
898
AnimScreen::output ()
900
return priv->output ();
904
AnimScreen::getMousePointerXY (short *x, short *y)
911
(::screen->dpy (), ::screen->root (), &w1, &w2, &xj, &yj, &xp, &yp, &m))
921
PrivateAnimWindow::getState ()
925
unsigned long n, left;
927
unsigned int retval = WithdrawnState;
929
result = XGetWindowProperty (::screen->dpy (), mWindow->id (),
933
&actual, &format, &n, &left, &data);
935
if (result == Success && data)
938
memcpy (&retval, data, sizeof (int));
940
XFree ((void *)data);
947
AnimScreen::getOptions ()
949
return priv->getOptions ();
953
AnimScreen::setOption (const CompString &name,
954
CompOption::Value &value)
956
return priv->setOption (name, value);
960
PrivateAnimScreen::eventMatchesChanged (CompOption *opt,
961
AnimationOptions::Options num)
963
if (mExtensionPlugins.size () == 0)
964
initAnimationList ();
965
foreach (CompOption::Value &val, opt->value ().list ())
966
val.match ().update ();
970
PrivateAnimScreen::eventOptionsChanged (CompOption *opt,
971
AnimationOptions::Options num)
973
if (mExtensionPlugins.size () == 0)
974
initAnimationList ();
975
updateOptionSets (getCorrespondingAnimEvent (num));
979
PrivateAnimScreen::eventEffectsChanged (CompOption *opt,
980
AnimationOptions::Options num)
982
if (mExtensionPlugins.size () == 0)
983
initAnimationList ();
984
updateEventEffects (getCorrespondingAnimEvent (num), false);
988
PrivateAnimScreen::eventRandomEffectsChanged (CompOption *opt,
989
AnimationOptions::Options num)
991
if (mExtensionPlugins.size () == 0)
992
initAnimationList ();
993
updateEventEffects (getCorrespondingAnimEvent (num), true);
997
PrivateAnimWindow::postAnimationCleanUpCustom (bool closing,
999
bool clearMatchingRow)
1001
bool shouldDamageWindow = false;
1003
notifyAnimation (false);
1007
if (mCurAnimation->shouldDamageWindowOnEnd ())
1008
shouldDamageWindow = true;
1010
enablePainting (false);
1012
if (shouldDamageWindow)
1013
mAWindow->expandBBWithWindow ();
1015
if (shouldDamageWindow ||
1017
!mCurAnimation->stepRegionUsed () &&
1018
mAWindow->BB ()->x1 != MAXSHORT)) // BB intialized
1019
mAWindow->resetStepRegionWithBB ();
1021
damageThisAndLastStepRegion ();
1025
mCurAnimation->cleanUp (closing, destructing);
1026
delete mCurAnimation;
1030
mBB.x1 = mBB.y1 = MAXSHORT;
1031
mBB.x2 = mBB.y2 = MINSHORT;
1035
if (clearMatchingRow)
1036
mCurAnimSelectionRow = -1;
1038
mFinishingAnim = true;
1041
mIgnoreDamage = true;
1042
while (mUnmapCnt > 0)
1049
mIgnoreDamage = false;
1054
mWindow->destroy ();
1057
mFinishingAnim = false;
1059
foreach (ExtensionPluginInfo *extPlugin, mPAScreen->mExtensionPlugins)
1060
extPlugin->cleanUpAnimation (closing, destructing);
1064
AnimWindow::postAnimationCleanUp ()
1066
priv->postAnimationCleanUp ();
1070
PrivateAnimWindow::postAnimationCleanUp ()
1072
if (mCurAnimation->curWindowEvent () == WindowEventClose)
1073
postAnimationCleanUpCustom (true, false, true);
1075
postAnimationCleanUpCustom (false, false, true);
1079
PrivateAnimWindow::postAnimationCleanUpPrev (bool closing,
1080
bool clearMatchingRow)
1082
int curAnimSelectionRow = mCurAnimSelectionRow;
1083
// Use previous event's anim selection row
1084
mCurAnimSelectionRow = mPrevAnimSelectionRow;
1086
postAnimationCleanUpCustom (closing, false, clearMatchingRow);
1088
// Restore current event's anim selection row
1089
mCurAnimSelectionRow = curAnimSelectionRow;
1093
PrivateAnimScreen::activateEvent (bool activating)
1097
if (mAnimInProgress)
1102
// Animations have finished for all windows
1103
// (Keep preparePaint enabled)
1105
cScreen->getWindowPaintListSetEnabled (this, false);
1106
enablePrePaintWindowsBackToFront (false);
1108
cScreen->donePaintSetEnabled (this, activating);
1109
gScreen->glPaintOutputSetEnabled (this, activating);
1111
mAnimInProgress = activating;
1113
CompOption::Vector o (0);
1115
o.push_back (CompOption ("root", CompOption::TypeInt));
1116
o.push_back (CompOption ("active", CompOption::TypeBool));
1118
o[0].value ().set ((int) ::screen->root ());
1119
o[1].value ().set (activating);
1121
::screen->handleCompizEvent ("animation", "activate", o);
1125
PrivateAnimWindow::notifyAnimation (bool activation)
1127
CompOption::Vector o (0);
1132
o.push_back (CompOption ("root", CompOption::TypeInt));
1133
o.push_back (CompOption ("window", CompOption::TypeInt));
1134
o.push_back (CompOption ("type", CompOption::TypeString));
1135
o.push_back (CompOption ("active", CompOption::TypeBool));
1137
o[0].value ().set ((int) ::screen->root ());
1138
o[1].value ().set ((int) mWindow->id ());
1140
switch (mCurAnimation->curWindowEvent ())
1142
case WindowEventOpen:
1143
o[2].value ().set ("open");
1145
case WindowEventClose:
1146
o[2].value ().set ("close");
1148
case WindowEventMinimize:
1149
o[2].value ().set ("minimize");
1151
case WindowEventUnminimize:
1152
o[2].value ().set ("unminimize");
1154
case WindowEventShade:
1155
o[2].value ().set ("shade");
1157
case WindowEventUnshade:
1158
o[2].value ().set ("unshade");
1160
case WindowEventFocus:
1161
o[2].value ().set ("focus");
1163
case WindowEventNum:
1164
case WindowEventNone:
1166
o[2].value ().set ("none");
1170
o[3].value ().set (activation);
1172
screen->handleCompizEvent ("animation", "window_animation", o);
1176
PrivateAnimScreen::otherPluginsActive ()
1178
for (int i = 0; i < WatchedScreenPluginNum; i++)
1179
if (mPluginActive[i])
1185
Animation::shouldSkipFrame (int msSinceLastPaintActual)
1187
mTimeElapsedWithinTimeStep += msSinceLastPaintActual;
1188
if (mTimeElapsedWithinTimeStep < mTimestep) // if timestep not yet completed
1191
mTimeElapsedWithinTimeStep = fmod (mTimeElapsedWithinTimeStep, mTimestep);
1196
Animation::advanceTime (int msSinceLastPaint)
1198
mRemainingTime -= msSinceLastPaint;
1199
mRemainingTime = MAX (mRemainingTime, 0); // avoid sub-zero values
1201
mTimeSinceLastPaint = msSinceLastPaint;
1203
return (mRemainingTime > 0);
1207
PrivateAnimScreen::preparePaint (int msSinceLastPaint)
1209
// Check and update "switcher post wait" counter
1210
if (mSwitcherPostWait > 0)
1212
mSwitcherPostWait++;
1213
if (mSwitcherPostWait > 5) // wait over
1215
mSwitcherPostWait = 0;
1217
// Reset stacking related info since it will
1218
// cause problems because of the restacking
1219
// just done by Switcher.
1220
ExtensionPluginAnimation *extPlugin =
1221
static_cast<ExtensionPluginAnimation *> (mExtensionPlugins[0]);
1222
extPlugin->resetStackingInfo ();
1226
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
1227
extPlugin->prePreparePaintGeneral ();
1229
if (mAnimInProgress)
1231
int msSinceLastPaintActual;
1233
struct timeval curTime;
1234
gettimeofday (&curTime, 0);
1236
if (mLastRedrawTimeFresh)
1238
msSinceLastPaintActual = TIMEVALDIFF (&curTime, &mLastRedrawTime);
1239
// handle clock rollback
1240
if (msSinceLastPaintActual < 0)
1241
msSinceLastPaintActual = 0;
1244
msSinceLastPaintActual = 20; // assume 20 ms passed
1246
mLastRedrawTime = curTime; // Store current time for next time
1247
mLastRedrawTimeFresh = true;
1249
bool animStillInProgress = false;
1251
foreach (CompWindow *w, ::screen->windows ())
1253
AnimWindow *animWin = AnimWindow::get (w);
1254
PrivateAnimWindow *aw = animWin->priv;
1255
Animation *curAnim = aw->curAnimation ();
1259
if (!curAnim->initialized ())
1262
if (curAnim->prePreparePaint (msSinceLastPaint))
1263
animStillInProgress = true;
1265
/* TODO optimize grid model by reusing one GridModel
1266
if (aw->com.mModel &&
1267
(aw->com.mModel->winWidth != outRect.width () ||
1268
aw->com.mModel->winHeight != outRect.height ()))
1270
// mModel needs update
1272
if (!animEnsureModel (w))
1274
// Abort this window's animation
1275
postAnimationCleanUp (w);
1280
bool animShouldSkipFrame =
1281
(curAnim->shouldSkipFrame (msSinceLastPaintActual) &&
1282
// Skip only if we're not on the first animation frame
1283
curAnim->initialized ());
1285
// Skip only if we're not on the last animation frame
1286
animShouldSkipFrame &=
1287
curAnim->advanceTime (msSinceLastPaint);
1289
if (!animShouldSkipFrame)
1291
if (curAnim->updateBBUsed ())
1293
aw->copyResetStepRegion ();
1295
if (!curAnim->initialized () &&
1296
curAnim->shouldDamageWindowOnStart ())
1297
aw->aWindow ()->expandBBWithWindow ();
1300
if (!curAnim->initialized ())
1301
curAnim->setInitialized ();
1305
if (curAnim->updateBBUsed ())
1307
foreach (CompOutput &output, ::screen->outputDevs ())
1308
curAnim->updateBB (output);
1310
if (!curAnim->stepRegionUsed () &&
1311
aw->BB ().x1 != MAXSHORT) // BB initialized
1313
// BB is used instead of step region,
1314
// so reset step region here with BB.
1315
animWin->resetStepRegionWithBB ();
1317
if (!(cScreen->damageMask () &
1318
COMPOSITE_SCREEN_DAMAGE_ALL_MASK))
1319
aw->damageThisAndLastStepRegion ();
1323
bool finished = (curAnim->remainingTime () <= 0);
1324
if (finished) // Animation is done
1326
aw->notifyAnimation (false);
1327
aw->postAnimationCleanUp ();
1330
animStillInProgress = true;
1334
foreach (CompWindow *w, ::screen->windows ())
1336
PrivateAnimWindow *aw = AnimWindow::get (w)->priv;
1337
if (aw->curAnimation ())
1338
aw->curAnimation ()->postPreparePaint ();
1341
if (!animStillInProgress)
1343
activateEvent (false);
1344
mLastRedrawTimeFresh = false;
1346
// Reset stacking related info after all animations are done.
1347
ExtensionPluginAnimation *extPlugin =
1348
static_cast<ExtensionPluginAnimation *> (mExtensionPlugins[0]);
1349
extPlugin->resetStackingInfo ();
1353
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
1354
extPlugin->postPreparePaintGeneral ();
1356
cScreen->preparePaint (msSinceLastPaint);
1358
if (mStartCountdown)
1361
if (!mStartCountdown)
1363
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
1364
extPlugin->postStartupCountdown ();
1370
PrivateAnimScreen::donePaint ()
1372
assert (mAnimInProgress);
1374
cScreen->damagePending ();
1376
cScreen->donePaint ();
1380
PrivateAnimWindow::enablePainting (bool enabling)
1382
gWindow->glPaintSetEnabled (this, enabling);
1383
gWindow->glAddGeometrySetEnabled (this, enabling);
1384
gWindow->glDrawGeometrySetEnabled (this, enabling);
1385
gWindow->glDrawTextureSetEnabled (this, enabling);
1389
PrivateAnimWindow::glAddGeometry (const GLTexture::MatrixList &matrix,
1390
const CompRegion ®ion,
1391
const CompRegion &clip,
1392
unsigned int maxGridWidth,
1393
unsigned int maxGridHeight)
1395
// if window is being animated
1398
if (mCurAnimation->initialized ())
1399
mCurAnimation->addGeometry (matrix, region, clip,
1400
maxGridWidth, maxGridHeight);
1404
gWindow->glAddGeometry (matrix, region, clip,
1405
maxGridWidth, maxGridHeight);
1410
Animation::shouldDamageWindowOnStart ()
1412
return (mCurWindowEvent == WindowEventClose ||
1413
mCurWindowEvent == WindowEventMinimize ||
1414
mCurWindowEvent == WindowEventShade);
1418
Animation::shouldDamageWindowOnEnd ()
1420
return (mCurWindowEvent == WindowEventOpen ||
1421
mCurWindowEvent == WindowEventUnminimize ||
1422
mCurWindowEvent == WindowEventUnshade);
1426
Animation::addGeometry (const GLTexture::MatrixList &matrix,
1427
const CompRegion ®ion,
1428
const CompRegion &clip,
1429
unsigned int maxGridWidth,
1430
unsigned int maxGridHeight)
1432
mAWindow->priv->gWindow->glAddGeometry (matrix, region, clip,
1433
maxGridWidth, maxGridHeight);
1437
PartialWindowAnim::addGeometry (const GLTexture::MatrixList &matrix,
1438
const CompRegion ®ion,
1439
const CompRegion &clip,
1440
unsigned int maxGridWidth,
1441
unsigned int maxGridHeight)
1445
CompRegion awRegion (region.intersected (mDrawRegion));
1446
Animation::addGeometry (matrix, awRegion, clip,
1447
maxGridWidth, maxGridHeight);
1451
Animation::addGeometry (matrix, region, clip,
1452
maxGridWidth, maxGridHeight);
1457
PrivateAnimWindow::glDrawTexture (GLTexture *texture,
1458
GLFragment::Attrib &attrib,
1463
mCurAnimation->setCurPaintAttrib (attrib);
1466
gWindow->glDrawTexture (texture, attrib, mask);
1470
PrivateAnimWindow::glDrawGeometry ()
1474
if (mCurAnimation->initialized ())
1475
mCurAnimation->drawGeometry ();
1479
gWindow->glDrawGeometry ();
1484
Animation::drawTexture (GLTexture *texture,
1485
GLFragment::Attrib &attrib,
1488
mCurPaintAttrib = attrib;
1492
Animation::drawGeometry ()
1494
mAWindow->priv->gWindow->glDrawGeometry ();
1498
PrivateAnimWindow::glPaint (const GLWindowPaintAttrib &attrib,
1499
const GLMatrix &transform,
1500
const CompRegion ®ion, unsigned int mask)
1504
// Is this the first glPaint call this round
1505
// without the mask PAINT_WINDOW_OCCLUSION_DETECTION_MASK?
1506
if (mPAScreen->mStartingNewPaintRound &&
1507
!(mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK))
1509
mPAScreen->mStartingNewPaintRound = false;
1511
// Back-to-front painting of windows is starting now.
1512
if (mPAScreen->mPrePaintWindowsBackToFrontEnabled)
1513
mPAScreen->prePaintWindowsBackToFront ();
1516
assert (mCurAnimation);
1518
foreach (ExtensionPluginInfo *extPlugin, mPAScreen->mExtensionPlugins)
1520
if (extPlugin->paintShouldSkipWindow (mWindow))
1524
if (mCurAnimation->curWindowEvent () == WindowEventFocus &&
1525
mPAScreen->otherPluginsActive ())
1527
postAnimationCleanUp ();
1528
return gWindow->glPaint (attrib, transform, region, mask);
1531
GLWindowPaintAttrib wAttrib = attrib;
1532
GLMatrix wTransform (transform.getMatrix ());
1534
/* TODO check if this is still necessary
1535
if (mCurAnimation->addCustomGeometryFunc)
1537
// Use slightly smaller brightness to force core
1538
// to handle <max saturation case with <max brightness.
1539
// Otherwise polygon effects show fully unsaturated colors
1541
wAttrib.brightness = MAX (0, wAttrib.brightness - 1);
1544
//w->indexCount = 0; // TODO check if this is still necessary
1546
// TODO: should only happen for distorting effects
1547
mask |= PAINT_WINDOW_TRANSFORMED_MASK;
1549
wAttrib.xScale = 1.0f;
1550
wAttrib.yScale = 1.0f;
1552
mCurAnimation->updateAttrib (wAttrib);
1553
mCurAnimation->updateTransform (wTransform);
1554
mCurAnimation->prePaintWindow ();
1556
if (mCurAnimation->paintWindowUsed ())
1557
status = mCurAnimation->paintWindow (gWindow, wAttrib, wTransform, region, mask);
1559
status = gWindow->glPaint (wAttrib, wTransform, region, mask);
1561
if (mCurAnimation->postPaintWindowUsed ())
1563
// Transform to make post-paint coincide with the window
1565
glLoadMatrixf (wTransform.getMatrix ());
1567
mCurAnimation->postPaintWindow ();
1575
/// This is enabled only during restack animations.
1576
const CompWindowList &
1577
PrivateAnimScreen::getWindowPaintList ()
1579
ExtensionPluginAnimation *extPlugin =
1580
static_cast<ExtensionPluginAnimation *> (mExtensionPlugins[0]);
1581
return extPlugin->getWindowPaintList ();
1584
/// This is enabled only during restack animations.
1586
PrivateAnimScreen::prePaintWindowsBackToFront ()
1588
assert (mAnimInProgress);
1590
ExtensionPluginAnimation *extPlugin =
1591
static_cast<ExtensionPluginAnimation *> (mExtensionPlugins[0]);
1592
extPlugin->prePaintWindowsBackToFront ();
1596
PrivateAnimScreen::enablePrePaintWindowsBackToFront (bool enabled)
1598
mPrePaintWindowsBackToFrontEnabled = enabled;
1602
AnimScreen::enableCustomPaintList (bool enabled)
1604
priv->cScreen->getWindowPaintListSetEnabled (priv, enabled);
1605
priv->enablePrePaintWindowsBackToFront (enabled);
1608
static const PluginEventInfo watchedScreenPlugins[] =
1610
{"switcher", "activate"},
1611
{"ring", "activate"},
1612
{"shift", "activate"},
1613
{"scale", "activate"},
1614
{"group", "tabChangeActivate"},
1615
{"fadedesktop", "activate"}
1618
static const PluginEventInfo watchedWindowPlugins[] =
1620
{"kdecompat", "slide"},
1624
PrivateAnimScreen::handleCompizEvent (const char *pluginName,
1625
const char *eventName,
1626
CompOption::Vector &options)
1628
::screen->handleCompizEvent (pluginName, eventName, options);
1630
for (int i = 0; i < WatchedScreenPluginNum; i++)
1631
if (strcmp (pluginName, watchedScreenPlugins[i].pluginName) == 0)
1633
if (strcmp (eventName,
1634
watchedScreenPlugins[i].activateEventName) == 0)
1637
CompOption::getBoolOptionNamed (options, "active", false);
1639
if (!mPluginActive[i] &&
1640
(i == WatchedPluginSwitcher ||
1641
i == WatchedPluginRing ||
1642
i == WatchedPluginShift ||
1643
i == WatchedPluginScale))
1645
mSwitcherPostWait = 1;
1651
for (int i = 0; i < WatchedWindowPluginNum; i++)
1652
if (strcmp (pluginName,
1653
watchedWindowPlugins[i].pluginName) == 0)
1655
if (strcmp (eventName,
1656
watchedWindowPlugins[i].activateEventName) == 0)
1658
Window xid = CompOption::getIntOptionNamed (options,
1661
CompWindow *w = screen->findWindow (xid);
1665
AnimWindow *aw = AnimWindow::get (w);
1666
PrivateAnimWindow *pw = aw->priv;
1667
pw->mPluginActive[i] = CompOption::getBoolOptionNamed (
1677
/// Returns true for windows that don't have a pixmap or certain properties,
1678
/// like the dimming layer of gksudo and x-session-manager.
1680
PrivateAnimScreen::shouldIgnoreWindowForAnim (CompWindow *w, bool checkPixmap)
1682
AnimWindow *aw = AnimWindow::get (w);
1684
for (int i = 0; i < WatchedWindowPluginNum; i++)
1685
if (aw->priv->mPluginActive[i])
1688
return ((checkPixmap && !CompositeWindow::get (w)->pixmap ()) ||
1689
mNeverAnimateMatch.evaluate (w));
1693
PrivateAnimWindow::reverseAnimation ()
1695
mCurAnimation->reverse ();
1697
// Inflict the pending unmaps
1698
while (mUnmapCnt > 0)
1708
PrivateAnimScreen::initiateCloseAnim (PrivateAnimWindow *aw)
1710
CompWindow *w = aw->mWindow;
1712
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
1713
extPlugin->preInitiateCloseAnim (aw->mAWindow);
1715
if (shouldIgnoreWindowForAnim (w, true))
1718
AnimEffect chosenEffect =
1719
getMatchingAnimSelection (w, AnimEventClose, &duration);
1721
aw->mState = NormalState;
1722
aw->mNewState = WithdrawnState;
1724
if (chosenEffect != AnimEffectNone)
1726
bool startingNew = true;
1727
WindowEvent curWindowEvent = WindowEventNone;
1729
if (aw->curAnimation ())
1730
curWindowEvent = aw->curAnimation ()->curWindowEvent ();
1732
if (curWindowEvent != WindowEventNone)
1734
if (curWindowEvent == WindowEventOpen)
1736
startingNew = false;
1737
aw->reverseAnimation ();
1739
/* TODO check if necessary
1740
else if (aw->com.curWindowEvent == WindowEventClose)
1742
if (aw->com.animOverrideProgressDir == 2)
1744
aw->com.animRemainingTime = tmpSteps;
1745
startingNew = false;
1750
aw->postAnimationCleanUpPrev (true, false);
1756
AnimEffect effectToBePlayed =
1757
getActualEffect (chosenEffect, AnimEventClose);
1759
// handle empty random effect list
1760
if (effectToBePlayed && effectToBePlayed == AnimEffectNone)
1762
aw->mState = aw->mNewState;
1767
effectToBePlayed->create (w, WindowEventClose, duration,
1768
effectToBePlayed, getIcon (w, true));
1769
aw->mCurAnimation->adjustPointerIconSize ();
1770
aw->enablePainting (true);
1773
activateEvent (true);
1774
aw->notifyAnimation (true);
1776
// Increment 3 times to make sure close animation works
1777
// (e.g. for popup menus).
1778
for (int i = 0; i < 3; i++)
1781
w->incrementUnmapReference ();
1783
cScreen->damagePending ();
1785
/* TODO check if necessary
1786
else if (AnimEffectNone !=
1787
getMatchingAnimSelection (w, AnimEventOpen, &duration))
1789
// stop the current animation and prevent it from rewinding
1791
if (aw->com.animRemainingTime > 0 &&
1792
aw->com.curWindowEvent != WindowEventOpen)
1794
aw->com.animRemainingTime = 0;
1796
if ((aw->com.curWindowEvent != WindowEventNone) &&
1797
(aw->com.curWindowEvent != WindowEventClose))
1799
postAnimationCleanUp (w);
1801
// set some properties to make sure this window will use the
1802
// correct open effect the next time it's "opened"
1804
activateEvent (w->screen, true);
1805
aw->com.curWindowEvent = WindowEventClose;
1808
w->incrementUnmapRefCnt ();
1810
damagePendingOnScreen (w->screen);
1813
aw->mState = aw->mNewState;
1815
// Make sure non-animated closing windows get a damage.
1816
if (!aw->curAnimation ())
1818
aw->mAWindow->expandBBWithWindow ();
1823
PrivateAnimScreen::getIcon (CompWindow *w, bool alwaysUseMouse)
1827
if (!alwaysUseMouse)
1829
icon = w->iconGeometry ();
1831
if (alwaysUseMouse ||
1834
icon.width () == 0 &&
1835
icon.height () == 0)) // that is, couldn't get icon from window
1837
// Minimize to mouse pointer if there is no
1838
// window list or if the window skips taskbar
1840
if (!aScreen->getMousePointerXY (&x, &y))
1842
// Use screen center if can't get mouse coords
1843
x = ::screen->width () / 2;
1844
y = ::screen->height () / 2;
1848
icon.setWidth (FAKE_ICON_SIZE);
1849
icon.setHeight (FAKE_ICON_SIZE);
1856
PrivateAnimScreen::initiateMinimizeAnim (PrivateAnimWindow *aw)
1858
CompWindow *w = aw->mWindow;
1860
if (aw->mWindow->destroyed ())
1863
// Store window geometry for use during animation.
1864
aw->mAWindow->mSavedInRect = w->inputRect ();
1865
aw->mAWindow->mSavedOutRect = w->outputRect ();
1866
aw->mAWindow->mSavedOutExtents = w->output ();
1867
aw->mAWindow->mSavedWinRect = w->geometry ();
1868
aw->mAWindow->mSavedRectsValid = true;
1870
aw->mNewState = IconicState;
1872
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
1873
extPlugin->preInitiateMinimizeAnim (aw->mAWindow);
1876
AnimEffect chosenEffect =
1877
getMatchingAnimSelection (w, AnimEventMinimize, &duration);
1879
if (chosenEffect != AnimEffectNone)
1881
bool startingNew = true;
1882
WindowEvent curWindowEvent = WindowEventNone;
1884
if (aw->curAnimation ())
1885
curWindowEvent = aw->curAnimation ()->curWindowEvent ();
1887
if (curWindowEvent != WindowEventNone)
1889
if (curWindowEvent != WindowEventUnminimize)
1891
aw->postAnimationCleanUpPrev (false, false);
1895
startingNew = false;
1896
aw->reverseAnimation ();
1902
AnimEffect effectToBePlayed =
1903
getActualEffect (chosenEffect, AnimEventMinimize);
1905
// handle empty random effect list
1906
if (effectToBePlayed == AnimEffectNone)
1908
aw->mState = aw->mNewState;
1913
effectToBePlayed->create (w, WindowEventMinimize, duration,
1914
effectToBePlayed, getIcon (w, false));
1915
aw->enablePainting (true);
1918
activateEvent (true);
1919
aw->notifyAnimation (true);
1922
w->incrementUnmapReference ();
1924
cScreen->damagePending ();
1927
aw->mState = aw->mNewState;
1931
PrivateAnimScreen::initiateShadeAnim (PrivateAnimWindow *aw)
1933
CompWindow *w = aw->mWindow;
1936
AnimEffect chosenEffect =
1937
getMatchingAnimSelection (w, AnimEventShade, &duration);
1939
aw->setShaded (true);
1941
if (chosenEffect != AnimEffectNone)
1943
bool startingNew = true;
1944
WindowEvent curWindowEvent = WindowEventNone;
1945
if (aw->curAnimation ())
1946
curWindowEvent = aw->curAnimation ()->curWindowEvent ();
1948
if (curWindowEvent != WindowEventNone)
1950
if (curWindowEvent != WindowEventUnshade)
1952
aw->postAnimationCleanUpPrev (false, false);
1956
startingNew = false;
1957
aw->reverseAnimation ();
1963
AnimEffect effectToBePlayed =
1964
getActualEffect (chosenEffect, AnimEventShade);
1966
// handle empty random effect list
1967
if (effectToBePlayed == AnimEffectNone)
1971
effectToBePlayed->create (w, WindowEventShade, duration,
1972
effectToBePlayed, getIcon (w, false));
1973
aw->enablePainting (true);
1976
activateEvent (true);
1977
aw->notifyAnimation (true);
1980
w->incrementUnmapReference ();
1982
cScreen->damagePending ();
1987
PrivateAnimScreen::initiateOpenAnim (PrivateAnimWindow *aw)
1989
CompWindow *w = aw->mWindow;
1992
AnimEffect chosenEffect;
1994
aw->mNewState = NormalState;
1996
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
1997
extPlugin->preInitiateOpenAnim (aw->mAWindow);
1999
WindowEvent curWindowEvent = WindowEventNone;
2000
if (aw->curAnimation ())
2001
curWindowEvent = aw->curAnimation ()->curWindowEvent ();
2003
if (!shouldIgnoreWindowForAnim (w, false) &&
2006
getMatchingAnimSelection (w, AnimEventOpen, &duration)) ||
2008
curWindowEvent == WindowEventClose))
2010
bool startingNew = true;
2011
bool playEffect = true;
2013
if (curWindowEvent != WindowEventNone)
2015
if (curWindowEvent != WindowEventClose)
2017
aw->postAnimationCleanUpPrev (false, false);
2021
startingNew = false;
2022
aw->reverseAnimation ();
2028
AnimEffect effectToBePlayed =
2029
getActualEffect (chosenEffect, AnimEventOpen);
2031
// handle empty random effect list
2032
if (effectToBePlayed == AnimEffectNone)
2038
effectToBePlayed->create (w, WindowEventOpen, duration,
2041
aw->mCurAnimation->adjustPointerIconSize ();
2042
aw->enablePainting (true);
2048
activateEvent (true);
2049
aw->notifyAnimation (true);
2050
cScreen->damagePending ();
2056
PrivateAnimScreen::initiateUnminimizeAnim (PrivateAnimWindow *aw)
2058
CompWindow *w = aw->mWindow;
2060
if (aw->mWindow->destroyed ())
2063
aw->mAWindow->mSavedRectsValid = false;
2066
AnimEffect chosenEffect =
2067
getMatchingAnimSelection (w, AnimEventMinimize, &duration);
2069
aw->mNewState = NormalState;
2071
if (chosenEffect != AnimEffectNone &&
2072
!mPluginActive[3]) // fadedesktop
2074
bool startingNew = true;
2075
bool playEffect = true;
2077
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
2078
extPlugin->preInitiateUnminimizeAnim (aw->mAWindow);
2080
// TODO Refactor the rest? (almost the same in other initiateX methods)
2081
WindowEvent curWindowEvent = WindowEventNone;
2082
if (aw->curAnimation ())
2083
curWindowEvent = aw->curAnimation ()->curWindowEvent ();
2085
if (curWindowEvent != WindowEventNone)
2087
if (curWindowEvent != WindowEventMinimize)
2089
aw->postAnimationCleanUpPrev (false, false);
2093
startingNew = false;
2094
aw->reverseAnimation ();
2100
AnimEffect effectToBePlayed =
2101
getActualEffect (chosenEffect, AnimEventMinimize);
2103
// handle empty random effect list
2104
if (effectToBePlayed == AnimEffectNone)
2110
effectToBePlayed->create (w, WindowEventUnminimize,
2111
duration, effectToBePlayed,
2112
getIcon (w, false));
2113
aw->enablePainting (true);
2119
activateEvent (true);
2120
aw->notifyAnimation (true);
2121
cScreen->damagePending ();
2127
PrivateAnimScreen::initiateUnshadeAnim (PrivateAnimWindow *aw)
2129
CompWindow *w = aw->mWindow;
2131
aw->mAWindow->mSavedRectsValid = false;
2133
aw->setShaded (false);
2135
aw->mNewState = NormalState;
2138
AnimEffect chosenEffect =
2139
getMatchingAnimSelection (w, AnimEventShade, &duration);
2141
if (chosenEffect != AnimEffectNone)
2143
bool startingNew = true;
2144
bool playEffect = true;
2146
WindowEvent curWindowEvent = WindowEventNone;
2147
if (aw->curAnimation ())
2148
curWindowEvent = aw->curAnimation ()->curWindowEvent ();
2150
if (curWindowEvent != WindowEventNone)
2152
if (curWindowEvent != WindowEventShade)
2154
aw->postAnimationCleanUpPrev (false, false);
2158
startingNew = false;
2159
aw->reverseAnimation ();
2165
AnimEffect effectToBePlayed =
2166
getActualEffect (chosenEffect, AnimEventShade);
2168
// handle empty random effect list
2169
if (effectToBePlayed == AnimEffectNone)
2175
effectToBePlayed->create (w, WindowEventUnshade,
2176
duration, effectToBePlayed,
2177
getIcon (w, false));
2178
aw->enablePainting (true);
2184
activateEvent (true);
2185
aw->notifyAnimation (true);
2186
cScreen->damagePending ();
2192
PrivateAnimScreen::initiateFocusAnim (PrivateAnimWindow *aw)
2194
CompWindow *w = aw->mWindow;
2197
if (aw->curAnimation () || otherPluginsActive () ||
2198
// Check the "switcher post-wait" counter that effectively prevents
2199
// focus animation to be initiated when the zoom option value is low
2204
AnimEffect chosenEffect =
2205
getMatchingAnimSelection (w, AnimEventFocus, &duration);
2207
if (chosenEffect != AnimEffectNone)
2209
aw->createFocusAnimation (chosenEffect, duration);
2211
if (chosenEffect->isRestackAnim &&
2212
!(dynamic_cast<RestackAnim *> (aw->mCurAnimation)->
2213
initiateRestackAnim (duration)))
2215
aw->postAnimationCleanUp ();
2219
activateEvent (true);
2220
aw->notifyAnimation (true);
2221
cScreen->damagePending ();
2228
PrivateAnimWindow::resizeNotify (int dx,
2233
if (mUnshadePending)
2235
mUnshadePending = false;
2236
mPAScreen->initiateUnshadeAnim (this);
2238
else if (mCurAnimation && mCurAnimation->inProgress () &&
2239
// Don't let transient window open anim be interrupted with a resize notify
2240
!(mCurAnimation->curWindowEvent () == WindowEventOpen &&
2241
(mWindow->wmType () &
2242
(CompWindowTypeDropdownMenuMask |
2243
CompWindowTypePopupMenuMask |
2244
CompWindowTypeMenuMask |
2245
CompWindowTypeTooltipMask |
2246
CompWindowTypeNotificationMask |
2247
CompWindowTypeComboMask |
2248
CompWindowTypeDndMask))) &&
2249
// Ignore resize with dx=0, dy=0, dwidth=0, dheight=0
2250
!(dx == 0 && dy == 0 && dwidth == 0 && dheight == 0) &&
2251
!mCurAnimation->resizeUpdate (dx, dy, dwidth, dheight))
2253
postAnimationCleanUp ();
2254
mPAScreen->updateAnimStillInProgress ();
2257
mWindow->resizeNotify (dx, dy, dwidth, dheight);
2261
PrivateAnimScreen::updateAnimStillInProgress ()
2263
bool animStillInProgress = false;
2264
foreach (CompWindow *w, ::screen->windows ())
2266
PrivateAnimWindow *aw = AnimWindow::get (w)->priv;
2267
if (aw->curAnimation () &&
2268
aw->curAnimation ()->inProgress ())
2270
animStillInProgress = true;
2275
aw->notifyAnimation (false);
2279
if (!animStillInProgress)
2280
activateEvent (false);
2284
PrivateAnimWindow::moveNotify (int dx,
2288
if (mCurAnimation && mCurAnimation->inProgress () &&
2289
(mGrabbed || !mCurAnimation->moveUpdate (dx, dy)))
2291
// Stop the animation
2292
postAnimationCleanUp ();
2293
mPAScreen->updateAnimStillInProgress ();
2296
mWindow->moveNotify (dx, dy, immediate);
2300
PrivateAnimWindow::grabNotify (int x,
2307
mWindow->grabNotify (x, y, state, mask);
2311
PrivateAnimWindow::ungrabNotify ()
2315
mWindow->ungrabNotify ();
2319
PrivateAnimScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
2320
const GLMatrix &matrix,
2321
const CompRegion ®ion,
2325
assert (mAnimInProgress);
2327
mStartingNewPaintRound = true;
2329
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
2330
extPlugin->prePaintOutput (output);
2332
mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
2336
return gScreen->glPaintOutput (attrib, matrix, region, output, mask);
2339
AnimEffectInfo::AnimEffectInfo (const char *name,
2340
bool usedO, bool usedC, bool usedM,
2341
bool usedS, bool usedF,
2342
CreateAnimFunc create,
2343
bool isRestackAnim) :
2346
isRestackAnim (isRestackAnim)
2348
usedForEvents[AnimEventOpen] = usedO;
2349
usedForEvents[AnimEventClose] = usedC;
2350
usedForEvents[AnimEventMinimize] = usedM;
2351
usedForEvents[AnimEventShade] = usedS;
2352
usedForEvents[AnimEventFocus] = usedF;
2356
AnimEffectInfo::matchesEffectName (const CompString &animName)
2358
return (0 == strcasecmp (animName.c_str (), name));
2362
AnimEffectInfo::matchesPluginName (const CompString &pluginName)
2364
return (0 == strncmp (pluginName.c_str (), name, pluginName.length ()));
2367
AnimEffect animEffects[NUM_EFFECTS];
2369
ExtensionPluginAnimation animExtensionPluginInfo (CompString ("animation"),
2370
NUM_EFFECTS, animEffects, 0,
2371
NUM_NONEFFECT_OPTIONS);
2372
ExtensionPluginInfo *
2373
Animation::getExtensionPluginInfo ()
2375
return &animExtensionPluginInfo;
2378
AnimEffect AnimEffectNone;
2379
AnimEffect AnimEffectRandom;
2380
AnimEffect AnimEffectCurvedFold;
2381
AnimEffect AnimEffectDodge;
2382
AnimEffect AnimEffectDream;
2383
AnimEffect AnimEffectFade;
2384
AnimEffect AnimEffectFocusFade;
2385
AnimEffect AnimEffectGlide1;
2386
AnimEffect AnimEffectGlide2;
2387
AnimEffect AnimEffectHorizontalFolds;
2388
AnimEffect AnimEffectMagicLamp;
2389
AnimEffect AnimEffectMagicLampWavy;
2390
AnimEffect AnimEffectRollUp;
2391
AnimEffect AnimEffectSidekick;
2392
AnimEffect AnimEffectWave;
2393
AnimEffect AnimEffectZoom;
2395
PrivateAnimScreen::PrivateAnimScreen (CompScreen *s, AnimScreen *as) :
2396
cScreen (CompositeScreen::get (s)),
2397
gScreen (GLScreen::get (s)),
2399
mLastRedrawTimeFresh (false),
2400
mSwitcherPostWait (0),
2401
mStartCountdown (20), // start the countdown
2402
mLastActiveWindow (0),
2403
mAnimInProgress (false),
2404
mStartingNewPaintRound (false),
2405
mPrePaintWindowsBackToFrontEnabled (false),
2408
for (int i = 0; i < WatchedScreenPluginNum; i++)
2409
mPluginActive[i] = false;
2411
// Never animate screen-dimming layer of logout window and gksu.
2412
mNeverAnimateMatch |= "title=gksu";
2413
mNeverAnimateMatch |= "title=x-session-manager";
2414
mNeverAnimateMatch |= "title=gnome-session";
2415
mNeverAnimateMatch.update ();
2417
// Set-up option notifiers
2419
#define MATCHES_BIND \
2420
boost::bind (&PrivateAnimScreen::eventMatchesChanged, this, _1, _2)
2421
#define OPTIONS_BIND \
2422
boost::bind (&PrivateAnimScreen::eventOptionsChanged, this, _1, _2)
2423
#define EFFECTS_BIND \
2424
boost::bind (&PrivateAnimScreen::eventEffectsChanged, this, _1, _2)
2425
#define RANDOM_EFFECTS_BIND \
2426
boost::bind (&PrivateAnimScreen::eventRandomEffectsChanged, this, _1, _2)
2428
optionSetOpenMatchesNotify (MATCHES_BIND);
2429
optionSetCloseMatchesNotify (MATCHES_BIND);
2430
optionSetMinimizeMatchesNotify (MATCHES_BIND);
2431
optionSetFocusMatchesNotify (MATCHES_BIND);
2432
optionSetShadeMatchesNotify (MATCHES_BIND);
2434
optionSetOpenOptionsNotify (OPTIONS_BIND);
2435
optionSetCloseOptionsNotify (OPTIONS_BIND);
2436
optionSetMinimizeOptionsNotify (OPTIONS_BIND);
2437
optionSetFocusOptionsNotify (OPTIONS_BIND);
2438
optionSetShadeOptionsNotify (OPTIONS_BIND);
2440
optionSetOpenEffectsNotify (EFFECTS_BIND);
2441
optionSetCloseEffectsNotify (EFFECTS_BIND);
2442
optionSetMinimizeEffectsNotify (EFFECTS_BIND);
2443
optionSetFocusEffectsNotify (EFFECTS_BIND);
2444
optionSetShadeEffectsNotify (EFFECTS_BIND);
2446
optionSetOpenRandomEffectsNotify (RANDOM_EFFECTS_BIND);
2447
optionSetCloseRandomEffectsNotify (RANDOM_EFFECTS_BIND);
2448
optionSetMinimizeRandomEffectsNotify (RANDOM_EFFECTS_BIND);
2449
optionSetShadeRandomEffectsNotify (RANDOM_EFFECTS_BIND);
2451
ScreenInterface::setHandler (::screen);
2452
CompositeScreenInterface::setHandler (cScreen, false);
2453
GLScreenInterface::setHandler (gScreen, false);
2456
PrivateAnimScreen::~PrivateAnimScreen ()
2458
if (mAnimInProgress)
2459
activateEvent (false);
2461
for (int i = 0; i < NUM_EFFECTS; i++)
2462
delete animEffects[i];
2466
PrivateAnimScreen::initAnimationList ()
2469
animEffects[i++] = AnimEffectNone =
2470
new AnimEffectInfo ("animation:None",
2471
true, true, true, true, true, 0);
2472
animEffects[i++] = AnimEffectRandom =
2473
new AnimEffectInfo ("animation:Random",
2474
true, true, true, true, false, 0);
2475
animEffects[i++] = AnimEffectCurvedFold =
2476
new AnimEffectInfo ("animation:Curved Fold",
2477
true, true, true, true, false,
2478
&createAnimation<CurvedFoldAnim>);
2479
animEffects[i++] = AnimEffectDodge =
2480
new AnimEffectInfo ("animation:Dodge",
2481
false, false, false, false, true,
2482
&createAnimation<DodgeAnim>,
2484
animEffects[i++] = AnimEffectDream =
2485
new AnimEffectInfo ("animation:Dream",
2486
true, true, true, false, false,
2487
&createAnimation<DreamAnim>);
2488
animEffects[i++] = AnimEffectFade =
2489
new AnimEffectInfo ("animation:Fade",
2490
true, true, true, false, false,
2491
&createAnimation<FadeAnim>);
2492
animEffects[i++] = AnimEffectFocusFade =
2493
new AnimEffectInfo ("animation:Focus Fade",
2494
false, false, false, false, true,
2495
&createAnimation<FocusFadeAnim>,
2497
animEffects[i++] = AnimEffectGlide1 =
2498
new AnimEffectInfo ("animation:Glide 1",
2499
true, true, true, false, false,
2500
&createAnimation<GlideAnim>);
2501
animEffects[i++] = AnimEffectGlide2 =
2502
new AnimEffectInfo ("animation:Glide 2",
2503
true, true, true, false, false,
2504
&createAnimation<Glide2Anim>);
2505
animEffects[i++] = AnimEffectHorizontalFolds =
2506
new AnimEffectInfo ("animation:Horizontal Folds",
2507
true, true, true, true, false,
2508
&createAnimation<HorizontalFoldsAnim>);
2509
animEffects[i++] = AnimEffectMagicLamp =
2510
new AnimEffectInfo ("animation:Magic Lamp",
2511
true, true, true, false, false,
2512
&createAnimation<MagicLampAnim>);
2513
animEffects[i++] = AnimEffectMagicLampWavy =
2514
new AnimEffectInfo ("animation:Magic Lamp Wavy",
2515
true, true, true, false, false,
2516
&createAnimation<MagicLampWavyAnim>);
2517
animEffects[i++] = AnimEffectRollUp =
2518
new AnimEffectInfo ("animation:Roll Up",
2519
false, false, false, true, false,
2520
&createAnimation<RollUpAnim>);
2521
animEffects[i++] = AnimEffectSidekick =
2522
new AnimEffectInfo ("animation:Sidekick",
2523
true, true, true, false, false,
2524
&createAnimation<SidekickAnim>);
2525
animEffects[i++] = AnimEffectWave =
2526
new AnimEffectInfo ("animation:Wave",
2527
true, true, true, false, true,
2528
&createAnimation<WaveAnim>);
2529
animEffects[i++] = AnimEffectZoom =
2530
new AnimEffectInfo ("animation:Zoom",
2531
true, true, true, false, false,
2532
&createAnimation<ZoomAnim>);
2534
animExtensionPluginInfo.effectOptions = &getOptions ();
2536
// Extends itself with the basic set of animation effects.
2537
addExtension (&animExtensionPluginInfo, false);
2539
for (int e = 0; e < AnimEventNum; e++) // for each anim event
2540
updateOptionSets ((AnimEvent)e);
2542
updateAllEventEffects ();
2544
cScreen->preparePaintSetEnabled (this, true);
2547
PrivateAnimWindow::PrivateAnimWindow (CompWindow *w,
2549
gWindow (GLWindow::get (w)),
2552
mPAScreen (AnimScreen::get (::screen)->priv),
2554
mUnshadePending (false),
2555
mEventNotOpenClose (false),
2560
mIgnoreDamage (false),
2561
mFinishingAnim (false),
2562
mCurAnimSelectionRow (-1)
2564
mBB.x1 = mBB.y1 = MAXSHORT;
2565
mBB.x2 = mBB.y2 = MINSHORT;
2567
for (int i = 0; i < WatchedWindowPluginNum; i++)
2568
mPluginActive[i] = false;
2570
if (w->minimized ())
2572
mState = mNewState = IconicState;
2574
else if (w->shaded ())
2576
mState = mNewState = NormalState;
2581
mState = mNewState = getState ();
2584
WindowInterface::setHandler (mWindow, true);
2585
GLWindowInterface::setHandler (gWindow, false);
2588
PrivateAnimWindow::~PrivateAnimWindow ()
2590
notifyAnimation (false);
2591
postAnimationCleanUpCustom (false, true, true);
2595
PrivateAnimWindow::windowNotify (CompWindowNotify n)
2599
case CompWindowNotifyEnterShowDesktopMode:
2600
case CompWindowNotifyMinimize:
2601
mPAScreen->initiateMinimizeAnim (this);
2602
mEventNotOpenClose = true;
2604
case CompWindowNotifyShade:
2605
mPAScreen->initiateShadeAnim (this);
2606
mEventNotOpenClose = true;
2608
case CompWindowNotifyLeaveShowDesktopMode:
2609
case CompWindowNotifyUnminimize:
2610
mPAScreen->initiateUnminimizeAnim (this);
2611
mEventNotOpenClose = true;
2613
case CompWindowNotifyUnshade:
2616
mCurAnimation->curWindowEvent () == WindowEventShade)
2617
mPAScreen->initiateUnshadeAnim (this); // reverse the shade anim
2619
case CompWindowNotifyClose:
2620
if (!(mCurAnimation &&
2621
(mCurAnimation->curWindowEvent () == WindowEventClose ||
2622
mCurAnimation->curWindowEvent () == WindowEventUnminimize)))
2623
mPAScreen->initiateCloseAnim (this);
2625
case CompWindowNotifyShow:
2626
case CompWindowNotifyBeforeMap:
2627
// Prevent dialog disappearing when a dialog is reopened during
2628
// its close animation.
2629
if (mCurAnimation &&
2630
mCurAnimation->curWindowEvent () == WindowEventClose)
2632
mPAScreen->initiateOpenAnim (this);
2633
mEventNotOpenClose = false;
2636
case CompWindowNotifyMap:
2638
mUnshadePending = true;
2639
else if (!mUnshadePending &&
2640
!mEventNotOpenClose &&
2641
!mPAScreen->mStartCountdown &&
2643
(mCurAnimation->curWindowEvent () ==
2644
WindowEventUnminimize ||
2645
mCurAnimation->curWindowEvent () == WindowEventOpen)))
2646
mPAScreen->initiateOpenAnim (this);
2647
mEventNotOpenClose = false;
2649
case CompWindowNotifyBeforeUnmap:
2650
if (mCurAnimation && mCurAnimation->curWindowEvent () == WindowEventMinimize)
2653
mWindow->incrementUnmapReference ();
2656
case CompWindowNotifyBeforeDestroy:
2657
if (!mFinishingAnim)
2661
if (mPAScreen->shouldIgnoreWindowForAnim (mWindow, true))
2664
if (AnimEffectNone ==
2665
mPAScreen->getMatchingAnimSelection (mWindow,
2671
mWindow->incrementDestroyReference ();
2674
case CompWindowNotifyUnreparent:
2675
if (!mFinishingAnim)
2677
if (mPAScreen->shouldIgnoreWindowForAnim (mWindow, false))
2681
case CompWindowNotifyFocusChange:
2682
if (!mPAScreen->mLastActiveWindow ||
2683
mPAScreen->mLastActiveWindow != mWindow->id ())
2685
mPAScreen->mLastActiveWindow = mWindow->id ();
2687
if (mPAScreen->mStartCountdown) // Don't animate at startup
2691
AnimEffect chosenEffect =
2692
mPAScreen->getMatchingAnimSelection (mWindow,
2697
chosenEffect != AnimEffectNone &&
2698
!chosenEffect->isRestackAnim)
2699
mPAScreen->initiateFocusAnim (this);
2703
case CompWindowNotifyRestack:
2705
// Prevent menu disappearing when a menu is reopened during
2706
// its close animation. In that case a restack notify is thrown
2708
if (mCurAnimation &&
2709
mCurAnimation->curWindowEvent () == WindowEventClose)
2711
mPAScreen->initiateOpenAnim (this);
2712
mEventNotOpenClose = false;
2716
// Handle CompWindowNotifyRestack only when necessary.
2717
if (!mPAScreen->isRestackAnimPossible ())
2720
if (mPAScreen->mStartCountdown) // Don't animate at startup
2723
foreach (ExtensionPluginInfo *extPlugin,
2724
mPAScreen->mExtensionPlugins)
2725
extPlugin->handleRestackNotify (mAWindow);
2733
mWindow->windowNotify (n);
2737
AnimWindow::curAnimation ()
2739
return priv->curAnimation ();
2743
AnimScreen::getMatchingAnimSelection (CompWindow *w,
2747
return priv->getMatchingAnimSelection (w, e, duration);
2751
AnimScreen::otherPluginsActive ()
2753
return priv->otherPluginsActive ();
2757
AnimScreen::isAnimEffectPossible (AnimEffect theEffect)
2759
return priv->isAnimEffectPossible (theEffect);
2763
AnimScreen::initiateFocusAnim (AnimWindow *aw)
2765
return priv->initiateFocusAnim (aw->priv);
2768
/// If duration is 0, it should be set to a positive value later.
2770
AnimWindow::createFocusAnimation (AnimEffect effect, int duration)
2772
priv->createFocusAnimation (effect, duration);
2776
AnimWindow::deletePersistentData (const char *name)
2778
PersistentDataMap::iterator itData =
2779
persistentData.find (name);
2780
if (itData != persistentData.end ()) // if found
2782
delete itData->second;
2783
persistentData.erase (itData);
2788
PrivateAnimWindow::createFocusAnimation (AnimEffect effect, int duration)
2791
effect->create (mWindow, WindowEventFocus,
2795
enablePainting (true);
2798
AnimScreen::AnimScreen (CompScreen *s) :
2799
PluginClassHandler<AnimScreen, CompScreen, ANIMATION_ABI> (s),
2800
priv (new PrivateAnimScreen (s, this))
2802
priv->initAnimationList ();
2805
AnimScreen::~AnimScreen ()
2810
AnimWindow::AnimWindow (CompWindow *w) :
2811
PluginClassHandler<AnimWindow, CompWindow, ANIMATION_ABI> (w),
2813
priv (new PrivateAnimWindow (w, this)),
2814
mSavedRectsValid (false)
2816
foreach (ExtensionPluginInfo *extPlugin, priv->mPAScreen->mExtensionPlugins)
2817
extPlugin->initPersistentData (this);
2820
AnimWindow::~AnimWindow ()
2824
// Destroy each persistent data object
2825
PersistentDataMap::iterator itData = persistentData.begin ();
2826
for (; itData != persistentData.end (); itData++)
2827
delete itData->second;
2829
persistentData.clear ();
2833
AnimPluginVTable::init ()
2835
if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) |
2836
!CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) |
2837
!CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
2841
p.uval = ANIMATION_ABI;
2842
::screen->storeValue ("animation_ABI", p);
2848
AnimPluginVTable::fini ()
2850
::screen->eraseValue ("animation_ABI");