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);
1921
cScreen->damagePending ();
1924
aw->mState = aw->mNewState;
1928
PrivateAnimScreen::initiateShadeAnim (PrivateAnimWindow *aw)
1930
CompWindow *w = aw->mWindow;
1933
AnimEffect chosenEffect =
1934
getMatchingAnimSelection (w, AnimEventShade, &duration);
1936
aw->setShaded (true);
1938
if (chosenEffect != AnimEffectNone)
1940
bool startingNew = true;
1941
WindowEvent curWindowEvent = WindowEventNone;
1942
if (aw->curAnimation ())
1943
curWindowEvent = aw->curAnimation ()->curWindowEvent ();
1945
if (curWindowEvent != WindowEventNone)
1947
if (curWindowEvent != WindowEventUnshade)
1949
aw->postAnimationCleanUpPrev (false, false);
1953
startingNew = false;
1954
aw->reverseAnimation ();
1960
AnimEffect effectToBePlayed =
1961
getActualEffect (chosenEffect, AnimEventShade);
1963
// handle empty random effect list
1964
if (effectToBePlayed == AnimEffectNone)
1968
effectToBePlayed->create (w, WindowEventShade, duration,
1969
effectToBePlayed, getIcon (w, false));
1970
aw->enablePainting (true);
1973
activateEvent (true);
1974
aw->notifyAnimation (true);
1977
w->incrementUnmapReference ();
1979
cScreen->damagePending ();
1984
PrivateAnimScreen::initiateOpenAnim (PrivateAnimWindow *aw)
1986
CompWindow *w = aw->mWindow;
1989
AnimEffect chosenEffect;
1991
aw->mNewState = NormalState;
1993
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
1994
extPlugin->preInitiateOpenAnim (aw->mAWindow);
1996
WindowEvent curWindowEvent = WindowEventNone;
1997
if (aw->curAnimation ())
1998
curWindowEvent = aw->curAnimation ()->curWindowEvent ();
2000
if (!shouldIgnoreWindowForAnim (w, false) &&
2003
getMatchingAnimSelection (w, AnimEventOpen, &duration)) ||
2005
curWindowEvent == WindowEventClose))
2007
bool startingNew = true;
2008
bool playEffect = true;
2010
if (curWindowEvent != WindowEventNone)
2012
if (curWindowEvent != WindowEventClose)
2014
aw->postAnimationCleanUpPrev (false, false);
2018
startingNew = false;
2019
aw->reverseAnimation ();
2025
AnimEffect effectToBePlayed =
2026
getActualEffect (chosenEffect, AnimEventOpen);
2028
// handle empty random effect list
2029
if (effectToBePlayed == AnimEffectNone)
2035
effectToBePlayed->create (w, WindowEventOpen, duration,
2038
aw->mCurAnimation->adjustPointerIconSize ();
2039
aw->enablePainting (true);
2045
activateEvent (true);
2046
aw->notifyAnimation (true);
2047
cScreen->damagePending ();
2053
PrivateAnimScreen::initiateUnminimizeAnim (PrivateAnimWindow *aw)
2055
CompWindow *w = aw->mWindow;
2057
if (aw->mWindow->destroyed ())
2060
aw->mAWindow->mSavedRectsValid = false;
2063
AnimEffect chosenEffect =
2064
getMatchingAnimSelection (w, AnimEventMinimize, &duration);
2066
aw->mNewState = NormalState;
2068
if (chosenEffect != AnimEffectNone &&
2069
!mPluginActive[3]) // fadedesktop
2071
bool startingNew = true;
2072
bool playEffect = true;
2074
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
2075
extPlugin->preInitiateUnminimizeAnim (aw->mAWindow);
2077
// TODO Refactor the rest? (almost the same in other initiateX methods)
2078
WindowEvent curWindowEvent = WindowEventNone;
2079
if (aw->curAnimation ())
2080
curWindowEvent = aw->curAnimation ()->curWindowEvent ();
2082
if (curWindowEvent != WindowEventNone)
2084
if (curWindowEvent != WindowEventMinimize)
2086
aw->postAnimationCleanUpPrev (false, false);
2090
startingNew = false;
2091
aw->reverseAnimation ();
2097
AnimEffect effectToBePlayed =
2098
getActualEffect (chosenEffect, AnimEventMinimize);
2100
// handle empty random effect list
2101
if (effectToBePlayed == AnimEffectNone)
2107
effectToBePlayed->create (w, WindowEventUnminimize,
2108
duration, effectToBePlayed,
2109
getIcon (w, false));
2110
aw->enablePainting (true);
2116
activateEvent (true);
2117
aw->notifyAnimation (true);
2118
cScreen->damagePending ();
2124
PrivateAnimScreen::initiateUnshadeAnim (PrivateAnimWindow *aw)
2126
CompWindow *w = aw->mWindow;
2128
aw->mAWindow->mSavedRectsValid = false;
2130
aw->setShaded (false);
2132
aw->mNewState = NormalState;
2135
AnimEffect chosenEffect =
2136
getMatchingAnimSelection (w, AnimEventShade, &duration);
2138
if (chosenEffect != AnimEffectNone)
2140
bool startingNew = true;
2141
bool playEffect = true;
2143
WindowEvent curWindowEvent = WindowEventNone;
2144
if (aw->curAnimation ())
2145
curWindowEvent = aw->curAnimation ()->curWindowEvent ();
2147
if (curWindowEvent != WindowEventNone)
2149
if (curWindowEvent != WindowEventShade)
2151
aw->postAnimationCleanUpPrev (false, false);
2155
startingNew = false;
2156
aw->reverseAnimation ();
2162
AnimEffect effectToBePlayed =
2163
getActualEffect (chosenEffect, AnimEventShade);
2165
// handle empty random effect list
2166
if (effectToBePlayed == AnimEffectNone)
2172
effectToBePlayed->create (w, WindowEventUnshade,
2173
duration, effectToBePlayed,
2174
getIcon (w, false));
2175
aw->enablePainting (true);
2181
activateEvent (true);
2182
aw->notifyAnimation (true);
2183
cScreen->damagePending ();
2189
PrivateAnimScreen::initiateFocusAnim (PrivateAnimWindow *aw)
2191
CompWindow *w = aw->mWindow;
2194
if (aw->curAnimation () || otherPluginsActive () ||
2195
// Check the "switcher post-wait" counter that effectively prevents
2196
// focus animation to be initiated when the zoom option value is low
2201
AnimEffect chosenEffect =
2202
getMatchingAnimSelection (w, AnimEventFocus, &duration);
2204
if (chosenEffect != AnimEffectNone)
2206
aw->createFocusAnimation (chosenEffect, duration);
2208
if (chosenEffect->isRestackAnim &&
2209
!(dynamic_cast<RestackAnim *> (aw->mCurAnimation)->
2210
initiateRestackAnim (duration)))
2212
aw->postAnimationCleanUp ();
2216
activateEvent (true);
2217
aw->notifyAnimation (true);
2218
cScreen->damagePending ();
2225
PrivateAnimWindow::resizeNotify (int dx,
2230
if (mUnshadePending)
2232
mUnshadePending = false;
2233
mPAScreen->initiateUnshadeAnim (this);
2235
else if (mCurAnimation && mCurAnimation->inProgress () &&
2236
// Don't let transient window open anim be interrupted with a resize notify
2237
!(mCurAnimation->curWindowEvent () == WindowEventOpen &&
2238
(mWindow->wmType () &
2239
(CompWindowTypeDropdownMenuMask |
2240
CompWindowTypePopupMenuMask |
2241
CompWindowTypeMenuMask |
2242
CompWindowTypeTooltipMask |
2243
CompWindowTypeNotificationMask |
2244
CompWindowTypeComboMask |
2245
CompWindowTypeDndMask))) &&
2246
// Ignore resize with dx=0, dy=0, dwidth=0, dheight=0
2247
!(dx == 0 && dy == 0 && dwidth == 0 && dheight == 0) &&
2248
!mCurAnimation->resizeUpdate (dx, dy, dwidth, dheight))
2250
postAnimationCleanUp ();
2251
mPAScreen->updateAnimStillInProgress ();
2254
mWindow->resizeNotify (dx, dy, dwidth, dheight);
2258
PrivateAnimScreen::updateAnimStillInProgress ()
2260
bool animStillInProgress = false;
2261
foreach (CompWindow *w, ::screen->windows ())
2263
PrivateAnimWindow *aw = AnimWindow::get (w)->priv;
2264
if (aw->curAnimation () &&
2265
aw->curAnimation ()->inProgress ())
2267
animStillInProgress = true;
2272
aw->notifyAnimation (false);
2276
if (!animStillInProgress)
2277
activateEvent (false);
2281
PrivateAnimWindow::moveNotify (int dx,
2285
if (mCurAnimation && mCurAnimation->inProgress () &&
2286
(mGrabbed || !mCurAnimation->moveUpdate (dx, dy)))
2288
// Stop the animation
2289
postAnimationCleanUp ();
2290
mPAScreen->updateAnimStillInProgress ();
2293
mWindow->moveNotify (dx, dy, immediate);
2297
PrivateAnimWindow::grabNotify (int x,
2304
mWindow->grabNotify (x, y, state, mask);
2308
PrivateAnimWindow::ungrabNotify ()
2312
mWindow->ungrabNotify ();
2316
PrivateAnimScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
2317
const GLMatrix &matrix,
2318
const CompRegion ®ion,
2322
assert (mAnimInProgress);
2324
mStartingNewPaintRound = true;
2326
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
2327
extPlugin->prePaintOutput (output);
2329
mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
2333
return gScreen->glPaintOutput (attrib, matrix, region, output, mask);
2336
AnimEffectInfo::AnimEffectInfo (const char *name,
2337
bool usedO, bool usedC, bool usedM,
2338
bool usedS, bool usedF,
2339
CreateAnimFunc create,
2340
bool isRestackAnim) :
2343
isRestackAnim (isRestackAnim)
2345
usedForEvents[AnimEventOpen] = usedO;
2346
usedForEvents[AnimEventClose] = usedC;
2347
usedForEvents[AnimEventMinimize] = usedM;
2348
usedForEvents[AnimEventShade] = usedS;
2349
usedForEvents[AnimEventFocus] = usedF;
2353
AnimEffectInfo::matchesEffectName (const CompString &animName)
2355
return (0 == strcasecmp (animName.c_str (), name));
2359
AnimEffectInfo::matchesPluginName (const CompString &pluginName)
2361
return (0 == strncmp (pluginName.c_str (), name, pluginName.length ()));
2364
AnimEffect animEffects[NUM_EFFECTS];
2366
ExtensionPluginAnimation animExtensionPluginInfo (CompString ("animation"),
2367
NUM_EFFECTS, animEffects, 0,
2368
NUM_NONEFFECT_OPTIONS);
2369
ExtensionPluginInfo *
2370
Animation::getExtensionPluginInfo ()
2372
return &animExtensionPluginInfo;
2375
AnimEffect AnimEffectNone;
2376
AnimEffect AnimEffectRandom;
2377
AnimEffect AnimEffectCurvedFold;
2378
AnimEffect AnimEffectDodge;
2379
AnimEffect AnimEffectDream;
2380
AnimEffect AnimEffectFade;
2381
AnimEffect AnimEffectFocusFade;
2382
AnimEffect AnimEffectGlide1;
2383
AnimEffect AnimEffectGlide2;
2384
AnimEffect AnimEffectHorizontalFolds;
2385
AnimEffect AnimEffectMagicLamp;
2386
AnimEffect AnimEffectMagicLampWavy;
2387
AnimEffect AnimEffectRollUp;
2388
AnimEffect AnimEffectSidekick;
2389
AnimEffect AnimEffectWave;
2390
AnimEffect AnimEffectZoom;
2392
PrivateAnimScreen::PrivateAnimScreen (CompScreen *s, AnimScreen *as) :
2393
cScreen (CompositeScreen::get (s)),
2394
gScreen (GLScreen::get (s)),
2396
mLastRedrawTimeFresh (false),
2397
mSwitcherPostWait (0),
2398
mStartCountdown (20), // start the countdown
2399
mLastActiveWindow (0),
2400
mAnimInProgress (false),
2401
mStartingNewPaintRound (false),
2402
mPrePaintWindowsBackToFrontEnabled (false),
2405
for (int i = 0; i < WatchedScreenPluginNum; i++)
2406
mPluginActive[i] = false;
2408
// Never animate screen-dimming layer of logout window and gksu.
2409
mNeverAnimateMatch |= "title=gksu";
2410
mNeverAnimateMatch |= "title=x-session-manager";
2411
mNeverAnimateMatch |= "title=gnome-session";
2412
mNeverAnimateMatch.update ();
2414
// Set-up option notifiers
2416
#define MATCHES_BIND \
2417
boost::bind (&PrivateAnimScreen::eventMatchesChanged, this, _1, _2)
2418
#define OPTIONS_BIND \
2419
boost::bind (&PrivateAnimScreen::eventOptionsChanged, this, _1, _2)
2420
#define EFFECTS_BIND \
2421
boost::bind (&PrivateAnimScreen::eventEffectsChanged, this, _1, _2)
2422
#define RANDOM_EFFECTS_BIND \
2423
boost::bind (&PrivateAnimScreen::eventRandomEffectsChanged, this, _1, _2)
2425
optionSetOpenMatchesNotify (MATCHES_BIND);
2426
optionSetCloseMatchesNotify (MATCHES_BIND);
2427
optionSetMinimizeMatchesNotify (MATCHES_BIND);
2428
optionSetFocusMatchesNotify (MATCHES_BIND);
2429
optionSetShadeMatchesNotify (MATCHES_BIND);
2431
optionSetOpenOptionsNotify (OPTIONS_BIND);
2432
optionSetCloseOptionsNotify (OPTIONS_BIND);
2433
optionSetMinimizeOptionsNotify (OPTIONS_BIND);
2434
optionSetFocusOptionsNotify (OPTIONS_BIND);
2435
optionSetShadeOptionsNotify (OPTIONS_BIND);
2437
optionSetOpenEffectsNotify (EFFECTS_BIND);
2438
optionSetCloseEffectsNotify (EFFECTS_BIND);
2439
optionSetMinimizeEffectsNotify (EFFECTS_BIND);
2440
optionSetFocusEffectsNotify (EFFECTS_BIND);
2441
optionSetShadeEffectsNotify (EFFECTS_BIND);
2443
optionSetOpenRandomEffectsNotify (RANDOM_EFFECTS_BIND);
2444
optionSetCloseRandomEffectsNotify (RANDOM_EFFECTS_BIND);
2445
optionSetMinimizeRandomEffectsNotify (RANDOM_EFFECTS_BIND);
2446
optionSetShadeRandomEffectsNotify (RANDOM_EFFECTS_BIND);
2448
ScreenInterface::setHandler (::screen);
2449
CompositeScreenInterface::setHandler (cScreen, false);
2450
GLScreenInterface::setHandler (gScreen, false);
2453
PrivateAnimScreen::~PrivateAnimScreen ()
2455
if (mAnimInProgress)
2456
activateEvent (false);
2458
for (int i = 0; i < NUM_EFFECTS; i++)
2459
delete animEffects[i];
2463
PrivateAnimScreen::initAnimationList ()
2466
animEffects[i++] = AnimEffectNone =
2467
new AnimEffectInfo ("animation:None",
2468
true, true, true, true, true, 0);
2469
animEffects[i++] = AnimEffectRandom =
2470
new AnimEffectInfo ("animation:Random",
2471
true, true, true, true, false, 0);
2472
animEffects[i++] = AnimEffectCurvedFold =
2473
new AnimEffectInfo ("animation:Curved Fold",
2474
true, true, true, true, false,
2475
&createAnimation<CurvedFoldAnim>);
2476
animEffects[i++] = AnimEffectDodge =
2477
new AnimEffectInfo ("animation:Dodge",
2478
false, false, false, false, true,
2479
&createAnimation<DodgeAnim>,
2481
animEffects[i++] = AnimEffectDream =
2482
new AnimEffectInfo ("animation:Dream",
2483
true, true, true, false, false,
2484
&createAnimation<DreamAnim>);
2485
animEffects[i++] = AnimEffectFade =
2486
new AnimEffectInfo ("animation:Fade",
2487
true, true, true, false, false,
2488
&createAnimation<FadeAnim>);
2489
animEffects[i++] = AnimEffectFocusFade =
2490
new AnimEffectInfo ("animation:Focus Fade",
2491
false, false, false, false, true,
2492
&createAnimation<FocusFadeAnim>,
2494
animEffects[i++] = AnimEffectGlide1 =
2495
new AnimEffectInfo ("animation:Glide 1",
2496
true, true, true, false, false,
2497
&createAnimation<GlideAnim>);
2498
animEffects[i++] = AnimEffectGlide2 =
2499
new AnimEffectInfo ("animation:Glide 2",
2500
true, true, true, false, false,
2501
&createAnimation<Glide2Anim>);
2502
animEffects[i++] = AnimEffectHorizontalFolds =
2503
new AnimEffectInfo ("animation:Horizontal Folds",
2504
true, true, true, true, false,
2505
&createAnimation<HorizontalFoldsAnim>);
2506
animEffects[i++] = AnimEffectMagicLamp =
2507
new AnimEffectInfo ("animation:Magic Lamp",
2508
true, true, true, false, false,
2509
&createAnimation<MagicLampAnim>);
2510
animEffects[i++] = AnimEffectMagicLampWavy =
2511
new AnimEffectInfo ("animation:Magic Lamp Wavy",
2512
true, true, true, false, false,
2513
&createAnimation<MagicLampWavyAnim>);
2514
animEffects[i++] = AnimEffectRollUp =
2515
new AnimEffectInfo ("animation:Roll Up",
2516
false, false, false, true, false,
2517
&createAnimation<RollUpAnim>);
2518
animEffects[i++] = AnimEffectSidekick =
2519
new AnimEffectInfo ("animation:Sidekick",
2520
true, true, true, false, false,
2521
&createAnimation<SidekickAnim>);
2522
animEffects[i++] = AnimEffectWave =
2523
new AnimEffectInfo ("animation:Wave",
2524
true, true, true, false, true,
2525
&createAnimation<WaveAnim>);
2526
animEffects[i++] = AnimEffectZoom =
2527
new AnimEffectInfo ("animation:Zoom",
2528
true, true, true, false, false,
2529
&createAnimation<ZoomAnim>);
2531
animExtensionPluginInfo.effectOptions = &getOptions ();
2533
// Extends itself with the basic set of animation effects.
2534
addExtension (&animExtensionPluginInfo, false);
2536
for (int e = 0; e < AnimEventNum; e++) // for each anim event
2537
updateOptionSets ((AnimEvent)e);
2539
updateAllEventEffects ();
2541
cScreen->preparePaintSetEnabled (this, true);
2544
PrivateAnimWindow::PrivateAnimWindow (CompWindow *w,
2546
gWindow (GLWindow::get (w)),
2549
mPAScreen (AnimScreen::get (::screen)->priv),
2551
mUnshadePending (false),
2552
mEventNotOpenClose (false),
2557
mIgnoreDamage (false),
2558
mFinishingAnim (false),
2559
mCurAnimSelectionRow (-1)
2561
mBB.x1 = mBB.y1 = MAXSHORT;
2562
mBB.x2 = mBB.y2 = MINSHORT;
2564
for (int i = 0; i < WatchedWindowPluginNum; i++)
2565
mPluginActive[i] = false;
2567
if (w->minimized ())
2569
mState = mNewState = IconicState;
2571
else if (w->shaded ())
2573
mState = mNewState = NormalState;
2578
mState = mNewState = getState ();
2581
WindowInterface::setHandler (mWindow, true);
2582
GLWindowInterface::setHandler (gWindow, false);
2585
PrivateAnimWindow::~PrivateAnimWindow ()
2587
notifyAnimation (false);
2588
postAnimationCleanUpCustom (false, true, true);
2592
PrivateAnimWindow::windowNotify (CompWindowNotify n)
2596
case CompWindowNotifyEnterShowDesktopMode:
2597
case CompWindowNotifyMinimize:
2598
mPAScreen->initiateMinimizeAnim (this);
2599
mEventNotOpenClose = true;
2601
case CompWindowNotifyShade:
2602
mPAScreen->initiateShadeAnim (this);
2603
mEventNotOpenClose = true;
2605
case CompWindowNotifyLeaveShowDesktopMode:
2606
case CompWindowNotifyUnminimize:
2607
mPAScreen->initiateUnminimizeAnim (this);
2608
mEventNotOpenClose = true;
2610
case CompWindowNotifyUnshade:
2613
mCurAnimation->curWindowEvent () == WindowEventShade)
2614
mPAScreen->initiateUnshadeAnim (this); // reverse the shade anim
2616
case CompWindowNotifyClose:
2617
if (!(mCurAnimation &&
2618
(mCurAnimation->curWindowEvent () == WindowEventClose ||
2619
mCurAnimation->curWindowEvent () == WindowEventUnminimize)))
2620
mPAScreen->initiateCloseAnim (this);
2622
case CompWindowNotifyShow:
2623
case CompWindowNotifyBeforeMap:
2624
// Prevent dialog disappearing when a dialog is reopened during
2625
// its close animation.
2626
if (mCurAnimation &&
2627
mCurAnimation->curWindowEvent () == WindowEventClose)
2629
mPAScreen->initiateOpenAnim (this);
2630
mEventNotOpenClose = false;
2633
case CompWindowNotifyMap:
2635
mUnshadePending = true;
2636
else if (!mUnshadePending &&
2637
!mEventNotOpenClose &&
2638
!mPAScreen->mStartCountdown &&
2640
(mCurAnimation->curWindowEvent () ==
2641
WindowEventUnminimize ||
2642
mCurAnimation->curWindowEvent () == WindowEventOpen)))
2643
mPAScreen->initiateOpenAnim (this);
2644
mEventNotOpenClose = false;
2646
case CompWindowNotifyBeforeUnmap:
2647
if (mCurAnimation && mCurAnimation->curWindowEvent () == WindowEventMinimize)
2650
mWindow->incrementUnmapReference ();
2653
case CompWindowNotifyBeforeDestroy:
2654
if (!mFinishingAnim)
2658
if (mPAScreen->shouldIgnoreWindowForAnim (mWindow, true))
2661
if (AnimEffectNone ==
2662
mPAScreen->getMatchingAnimSelection (mWindow,
2668
mWindow->incrementDestroyReference ();
2671
case CompWindowNotifyUnreparent:
2672
if (!mFinishingAnim)
2674
if (mPAScreen->shouldIgnoreWindowForAnim (mWindow, false))
2678
case CompWindowNotifyFocusChange:
2679
if (!mPAScreen->mLastActiveWindow ||
2680
mPAScreen->mLastActiveWindow != mWindow->id ())
2682
mPAScreen->mLastActiveWindow = mWindow->id ();
2684
if (mPAScreen->mStartCountdown) // Don't animate at startup
2688
AnimEffect chosenEffect =
2689
mPAScreen->getMatchingAnimSelection (mWindow,
2694
chosenEffect != AnimEffectNone &&
2695
!chosenEffect->isRestackAnim)
2696
mPAScreen->initiateFocusAnim (this);
2700
case CompWindowNotifyRestack:
2702
// Prevent menu disappearing when a menu is reopened during
2703
// its close animation. In that case a restack notify is thrown
2705
if (mCurAnimation &&
2706
mCurAnimation->curWindowEvent () == WindowEventClose)
2708
mPAScreen->initiateOpenAnim (this);
2709
mEventNotOpenClose = false;
2713
// Handle CompWindowNotifyRestack only when necessary.
2714
if (!mPAScreen->isRestackAnimPossible ())
2717
if (mPAScreen->mStartCountdown) // Don't animate at startup
2720
foreach (ExtensionPluginInfo *extPlugin,
2721
mPAScreen->mExtensionPlugins)
2722
extPlugin->handleRestackNotify (mAWindow);
2730
mWindow->windowNotify (n);
2734
AnimWindow::curAnimation ()
2736
return priv->curAnimation ();
2740
AnimScreen::getMatchingAnimSelection (CompWindow *w,
2744
return priv->getMatchingAnimSelection (w, e, duration);
2748
AnimScreen::otherPluginsActive ()
2750
return priv->otherPluginsActive ();
2754
AnimScreen::isAnimEffectPossible (AnimEffect theEffect)
2756
return priv->isAnimEffectPossible (theEffect);
2760
AnimScreen::initiateFocusAnim (AnimWindow *aw)
2762
return priv->initiateFocusAnim (aw->priv);
2765
/// If duration is 0, it should be set to a positive value later.
2767
AnimWindow::createFocusAnimation (AnimEffect effect, int duration)
2769
priv->createFocusAnimation (effect, duration);
2773
AnimWindow::deletePersistentData (const char *name)
2775
PersistentDataMap::iterator itData =
2776
persistentData.find (name);
2777
if (itData != persistentData.end ()) // if found
2779
delete itData->second;
2780
persistentData.erase (itData);
2785
PrivateAnimWindow::createFocusAnimation (AnimEffect effect, int duration)
2788
effect->create (mWindow, WindowEventFocus,
2792
enablePainting (true);
2795
AnimScreen::AnimScreen (CompScreen *s) :
2796
PluginClassHandler<AnimScreen, CompScreen, ANIMATION_ABI> (s),
2797
priv (new PrivateAnimScreen (s, this))
2799
priv->initAnimationList ();
2802
AnimScreen::~AnimScreen ()
2807
AnimWindow::AnimWindow (CompWindow *w) :
2808
PluginClassHandler<AnimWindow, CompWindow, ANIMATION_ABI> (w),
2810
priv (new PrivateAnimWindow (w, this)),
2811
mSavedRectsValid (false)
2813
foreach (ExtensionPluginInfo *extPlugin, priv->mPAScreen->mExtensionPlugins)
2814
extPlugin->initPersistentData (this);
2817
AnimWindow::~AnimWindow ()
2821
// Destroy each persistent data object
2822
PersistentDataMap::iterator itData = persistentData.begin ();
2823
for (; itData != persistentData.end (); itData++)
2824
delete itData->second;
2826
persistentData.clear ();
2830
AnimPluginVTable::init ()
2832
if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) |
2833
!CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) |
2834
!CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
2838
p.uval = ANIMATION_ABI;
2839
::screen->storeValue ("animation_ABI", p);
2845
AnimPluginVTable::fini ()
2847
::screen->eraseValue ("animation_ABI");