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
using namespace compiz::core;
91
class AnimPluginVTable :
92
public CompPlugin::VTableForScreenAndWindow<AnimScreen, AnimWindow>
99
COMPIZ_PLUGIN_20090315 (animation, AnimPluginVTable);
101
#define FAKE_ICON_SIZE 4
103
const char *eventNames[AnimEventNum] =
104
{"Open", "Close", "Minimize", "Shade", "Focus"};
106
int chosenEffectOptionIds[AnimEventNum] =
108
AnimationOptions::OpenEffects,
109
AnimationOptions::CloseEffects,
110
AnimationOptions::MinimizeEffects,
111
AnimationOptions::ShadeEffects,
112
AnimationOptions::FocusEffects
115
int randomEffectOptionIds[AnimEventNum] =
117
AnimationOptions::OpenRandomEffects,
118
AnimationOptions::CloseRandomEffects,
119
AnimationOptions::MinimizeRandomEffects,
120
AnimationOptions::ShadeRandomEffects,
124
int customOptionOptionIds[AnimEventNum] =
126
AnimationOptions::OpenOptions,
127
AnimationOptions::CloseOptions,
128
AnimationOptions::MinimizeOptions,
129
AnimationOptions::ShadeOptions,
130
AnimationOptions::FocusOptions
133
int matchOptionIds[AnimEventNum] =
135
AnimationOptions::OpenMatches,
136
AnimationOptions::CloseMatches,
137
AnimationOptions::MinimizeMatches,
138
AnimationOptions::ShadeMatches,
139
AnimationOptions::FocusMatches
142
int durationOptionIds[AnimEventNum] =
144
AnimationOptions::OpenDurations,
145
AnimationOptions::CloseDurations,
146
AnimationOptions::MinimizeDurations,
147
AnimationOptions::ShadeDurations,
148
AnimationOptions::FocusDurations
151
// Bind each effect in the list of chosen effects for every event, to the
152
// corresponding animation effect (i.e. effect with that name) if it is
153
// provided by a plugin, otherwise set it to None.
155
PrivateAnimScreen::updateEventEffects (AnimEvent e,
159
CompOption::Value::Vector *listVal;
160
EffectSet *effectSet;
163
listVal = &getOptions ()[(unsigned)randomEffectOptionIds[e]].value ().
165
effectSet = &mRandomEffects[e];
169
listVal = &getOptions ()[(unsigned)chosenEffectOptionIds[e]].value ().
171
effectSet = &mEventEffects[e];
173
unsigned int n = listVal->size ();
175
effectSet->effects.clear ();
176
effectSet->effects.reserve (n);
178
AnimEffectVector &eventEffectsAllowed = mEventEffectsAllowed[e];
180
for (unsigned int r = 0; r < n; r++) // for each row
182
const CompString &animName = (*listVal)[r].s ();
184
// Find the animation effect with matching name
185
AnimEffectVector::iterator it =
186
find_if (eventEffectsAllowed.begin (),
187
eventEffectsAllowed.end (),
188
boost::bind (&AnimEffectInfo::matchesEffectName,
191
effectSet->effects.push_back (it == eventEffectsAllowed.end () ?
192
AnimEffectNone : *it);
197
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
198
extPlugin->postUpdateEventEffects (e, forRandom);
203
PrivateAnimScreen::updateAllEventEffects ()
205
// for each anim event
206
for (int e = 0; e < AnimEventNum; e++)
207
updateEventEffects ((AnimEvent)e, false);
209
// for each anim event except focus
210
for (int e = 0; e < AnimEventNum - 1; e++)
211
updateEventEffects ((AnimEvent)e, true);
215
PrivateAnimScreen::isAnimEffectInList (AnimEffect theEffect,
216
EffectSet &effectList)
218
for (unsigned int i = 0; i < effectList.effects.size (); i++)
219
if (effectList.effects[i] == theEffect)
225
PrivateAnimScreen::isAnimEffectPossibleForEvent (AnimEffect theEffect,
228
// Check all rows to see if the effect is chosen there
229
unsigned int nRows = mEventEffects[event].effects.size ();
230
for (unsigned int i = 0; i < nRows; i++)
232
AnimEffect chosenEffect = mEventEffects[event].effects[i];
233
// if chosen directly
234
if (chosenEffect == theEffect)
236
// if chosen in random pool
237
if (mRandomEffects[event].effects.size () &&
238
chosenEffect == AnimEffectRandom &&
239
isAnimEffectInList (theEffect, mRandomEffects[event]))
246
PrivateAnimScreen::isAnimEffectPossible (AnimEffect theEffect)
248
for (int e = 0; e < AnimEventNum; e++)
249
if (isAnimEffectPossibleForEvent (theEffect, (AnimEvent)e))
255
PrivateAnimScreen::isRestackAnimPossible ()
257
// Check all rows to see if the chosen effect is a restack animation
258
unsigned int nRows = mEventEffects[AnimEventFocus].effects.size ();
260
for (unsigned int i = 0; i < nRows; i++)
262
AnimEffect chosenEffect = mEventEffects[(unsigned)AnimEventFocus].
264
if (chosenEffect->isRestackAnim)
271
AnimScreen::isRestackAnimPossible ()
273
return priv->isRestackAnimPossible ();
276
// Extension functions
279
AnimScreen::addExtension (ExtensionPluginInfo *extensionPluginInfo)
281
priv->addExtension (extensionPluginInfo, true);
285
PrivateAnimScreen::addExtension (ExtensionPluginInfo *extensionPluginInfo,
286
bool shouldInitPersistentData)
288
mExtensionPlugins.push_back (extensionPluginInfo);
290
unsigned int nPluginEffects = extensionPluginInfo->nEffects;
292
bool eventEffectsNeedUpdate[AnimEventNum] =
293
{false, false, false, false, false};
295
// Put this plugin's effects into mEventEffects and
296
// mEventEffectsAllowed
297
for (unsigned int j = 0; j < nPluginEffects; j++)
299
const AnimEffect effect = extensionPluginInfo->effects[j];
301
// Update allowed effects for each event
302
for (int e = 0; e < AnimEventNum; e++)
304
if (effect->usedForEvents[e])
306
mEventEffectsAllowed[e].push_back (effect);
307
eventEffectsNeedUpdate[e] = true;
312
for (int e = 0; e < AnimEventNum; e++)
313
if (eventEffectsNeedUpdate[e])
315
updateEventEffects ((AnimEvent)e, false, false);
316
if (e != AnimEventFocus)
317
updateEventEffects ((AnimEvent)e, true, false);
320
if (shouldInitPersistentData)
322
const CompWindowList &pl = pushLockedPaintList ();
323
// Initialize persistent window data for the extension plugin
324
foreach (CompWindow *w, pl)
326
AnimWindow *aw = AnimWindow::get (w);
327
extensionPluginInfo->initPersistentData (aw);
330
popLockedPaintList ();
335
AnimScreen::removeExtension (ExtensionPluginInfo *extensionPluginInfo)
337
priv->removeExtension (extensionPluginInfo);
341
PrivateAnimScreen::removeExtension (ExtensionPluginInfo *extensionPluginInfo)
343
// Stop all ongoing animations
344
const CompWindowList &pl = pushLockedPaintList ();
346
foreach (CompWindow *w, pl)
348
PrivateAnimWindow *aw = AnimWindow::get (w)->priv;
349
if (aw->curAnimation ())
350
aw->postAnimationCleanUp ();
353
popLockedPaintList ();
355
// Find the matching plugin and delete it
357
ExtensionPluginVector::iterator it = find (mExtensionPlugins.begin (),
358
mExtensionPlugins.end (),
359
extensionPluginInfo);
361
if (it == mExtensionPlugins.end ())
362
return; // couldn't find that extension plugin
364
mExtensionPlugins.erase (it);
366
if (extensionPluginInfo->nEffects == 0)
367
return; // no animation effects -> we're done here
370
// Also delete the "allowed effect" entries for that plugin
372
for (int e = 0; e < AnimEventNum; e++)
374
AnimEffectVector &eventEffectsAllowed = mEventEffectsAllowed[e];
376
// Find the first animation effect with matching name
377
AnimEffectVector::iterator itBeginEffect =
378
find_if (eventEffectsAllowed.begin (),
379
eventEffectsAllowed.end (),
380
boost::bind (&AnimEffectInfo::matchesPluginName,
381
_1, extensionPluginInfo->name));
383
if (itBeginEffect == eventEffectsAllowed.end ())
384
continue; // plugin didn't provide any effects for this event
386
// Find the first animation effect with non-matching name,
387
// starting with itBeginEffect
388
AnimEffectVector::iterator itEndEffect =
389
find_if (itBeginEffect,
390
eventEffectsAllowed.end (),
391
boost::bind (&AnimEffectInfo::matchesPluginName,
392
_1, extensionPluginInfo->name) == false);
394
eventEffectsAllowed.erase (itBeginEffect, itEndEffect);
396
// Update event effects to complete removal
397
updateEventEffects ((AnimEvent)e, false);
398
if (e != AnimEventFocus)
399
updateEventEffects ((AnimEvent)e, true);
402
const CompWindowList &cpl = pushLockedPaintList ();
404
// Destroy persistent window data for the extension plugin
405
foreach (CompWindow *w, cpl)
407
AnimWindow *aw = AnimWindow::get (w);
408
extensionPluginInfo->destroyPersistentData (aw);
411
popLockedPaintList ();
414
ExtensionPluginInfo::ExtensionPluginInfo (const CompString &name,
415
unsigned int nEffects,
417
CompOption::Vector *effectOptions,
418
unsigned int firstEffectOptionIndex) :
422
effectOptions (effectOptions),
423
firstEffectOptionIndex (firstEffectOptionIndex)
427
// End of extension functions
429
Animation::Animation (CompWindow *w,
430
WindowEvent curWindowEvent,
432
const AnimEffect info,
433
const CompRect &icon) :
435
mAWindow (AnimWindow::get (w)),
436
mTotalTime (duration),
437
mRemainingTime (duration),
438
mTimeElapsedWithinTimeStep (0),
439
mOverrideProgressDir (0),
440
mCurPaintAttrib (GLWindow::defaultPaintAttrib),
441
mStoredOpacity (CompositeWindow::get (w)->opacity ()),
442
mCurWindowEvent (curWindowEvent),
443
mInitialized (false), // store window opacity
447
if (curWindowEvent == WindowEventShade ||
448
curWindowEvent == WindowEventUnshade)
450
mDecorTopHeight = w->output ().top;
451
mDecorBottomHeight = w->output ().bottom;
454
texturesCache = new GLTexture::List (GLWindow::get (w)->textures ());
455
PrivateAnimScreen *as = mAWindow->priv->paScreen ();
457
mTimestep = as->optionGetTimeStep ();
460
Animation::~Animation ()
462
delete texturesCache;
466
Animation::optVal (unsigned int optionId)
468
return mAWindow->pluginOptVal (getExtensionPluginInfo (), optionId, this);
471
/// Play the animation effect backwards from where it left off.
473
Animation::reverse ()
475
mRemainingTime = mTotalTime - mRemainingTime;
477
// avoid window remains
478
if (mRemainingTime <= 0)
481
switch (mCurWindowEvent) // the old event
483
case WindowEventOpen:
484
mCurWindowEvent = WindowEventClose;
486
case WindowEventClose:
487
mCurWindowEvent = WindowEventOpen;
489
case WindowEventMinimize:
490
mCurWindowEvent = WindowEventUnminimize;
492
case WindowEventUnminimize:
493
mCurWindowEvent = WindowEventMinimize;
495
case WindowEventShade:
496
mCurWindowEvent = WindowEventUnshade;
498
case WindowEventUnshade:
499
mCurWindowEvent = WindowEventShade;
505
// 1: forward, 2: backward (3 - progressDir is opposite direction)
508
switch (mCurWindowEvent) // the new event
510
case WindowEventClose:
511
case WindowEventMinimize:
512
case WindowEventShade:
519
if (mOverrideProgressDir == 0)
520
mOverrideProgressDir = progressDir;
521
else if (mOverrideProgressDir == 3 - progressDir)
522
mOverrideProgressDir = 0; // disable override
525
PartialWindowAnim::PartialWindowAnim (CompWindow *w,
526
WindowEvent curWindowEvent,
528
const AnimEffect info,
529
const CompRect &icon) :
530
Animation::Animation (w, curWindowEvent, duration, info, icon),
531
mUseDrawRegion (false),
537
PrivateAnimWindow::updateSelectionRow (unsigned int r)
539
mPrevAnimSelectionRow = mCurAnimSelectionRow;
540
mCurAnimSelectionRow = (int)r;
543
// Assumes events in the metadata are in
544
// [Open, Close, Minimize, Focus, Shade] order
545
// and effects among those are in alphabetical order
546
// but with "(Event) None" first and "(Event) Random" last.
548
PrivateAnimScreen::getMatchingAnimSelection (CompWindow *w,
552
PrivateAnimWindow *aw = AnimWindow::get (w)->priv;
554
EffectSet *eventEffects = &mEventEffects[e];
555
CompOption::Value &valMatch =
556
getOptions ()[(unsigned)matchOptionIds[e]].value ();
557
CompOption::Value &valDuration =
558
getOptions ()[(unsigned)durationOptionIds[e]].value ();
559
CompOption::Value &valCustomOptions =
560
getOptions ()[(unsigned)customOptionOptionIds[e]].value ();
562
unsigned int nRows = valMatch.list ().size ();
563
if (nRows != eventEffects->effects.size () ||
564
nRows != valDuration.list ().size () ||
565
nRows != valCustomOptions.list ().size ())
567
compLogMessage ("animation", CompLogLevelError,
568
"Animation settings mismatch in \"Animation "
569
"Selection\" list for %s event.", eventNames[e]);
570
return AnimEffectNone;
573
// Find the first row that matches this window for this event
574
for (unsigned int i = 0; i < nRows; i++)
576
if (!valMatch.list ()[i].match ().evaluate (w))
579
aw->updateSelectionRow (i);
582
*duration = valDuration.list ()[i].i ();
584
AnimEffect effect = eventEffects->effects[i];
586
return (effect ? effect : AnimEffectNone);
589
return AnimEffectNone;
593
PrivateAnimScreen::getActualEffect (AnimEffect effect,
596
bool allRandom = optionGetAllRandom ();
597
AnimEffectVector *randomEffects = &mRandomEffects[animEvent].effects;
598
unsigned int nRandomEffects = randomEffects->size ();
599
unsigned int nFirstRandomEffect = 0;
601
if ((effect == AnimEffectRandom) || allRandom)
603
if (nRandomEffects == 0) // no random animation selected, assume "all"
605
randomEffects = &mEventEffectsAllowed[animEvent];
607
// exclude None and Random
608
nFirstRandomEffect = 2;
609
nRandomEffects = randomEffects->size () - 2;
611
unsigned int index = nFirstRandomEffect +
612
(unsigned int)(nRandomEffects * (double)rand () / RAND_MAX);
613
return (*randomEffects)[index];
619
/// Converts animation direction (up, down, left, right, random, auto)
620
/// to an actual direction (up, down, left, or right).
622
Animation::getActualAnimDirection (AnimDirection dir,
625
if (dir == AnimDirectionRandom)
627
dir = (AnimDirection)(rand () % 4);
629
else if (dir == AnimDirectionAuto)
631
CompRect outRect (mAWindow->savedRectsValid () ?
632
mAWindow->savedOutRect () :
633
mWindow->outputRect ());
636
int centerX = outRect.x () + outRect.width () / 2 ;
637
int centerY = outRect.y () + outRect.height () / 2 ;
638
float relDiffX = ((float)centerX - mIcon.x ()) / outRect.width ();
639
float relDiffY = ((float)centerY - mIcon.y ()) / outRect.height ();
643
if (mCurWindowEvent == WindowEventMinimize ||
644
mCurWindowEvent == WindowEventUnminimize)
645
// min/unmin. should always result in +/- y direction
646
dir = (mIcon.y () < (int)::screen->height () - mIcon.y ()) ?
647
AnimDirectionDown : AnimDirectionUp;
648
else if (fabs (relDiffY) > fabs (relDiffX))
649
dir = relDiffY > 0 ? AnimDirectionDown : AnimDirectionUp;
651
dir = relDiffX > 0 ? AnimDirectionRight : AnimDirectionLeft;
655
if (mCurWindowEvent == WindowEventMinimize ||
656
mCurWindowEvent == WindowEventUnminimize)
657
// min/unmin. should always result in +/- y direction
658
dir = (mIcon.y () < (int)::screen->height () - mIcon.y ()) ?
659
AnimDirectionUp : AnimDirectionDown;
660
else if (fabs (relDiffY) > fabs (relDiffX))
661
dir = relDiffY > 0 ? AnimDirectionUp : AnimDirectionDown;
663
dir = relDiffX > 0 ? AnimDirectionLeft : AnimDirectionRight;
670
Animation::progressLinear ()
672
float forwardProgress =
673
1 - mRemainingTime / (mTotalTime - mTimestep);
674
forwardProgress = MIN (forwardProgress, 1);
675
forwardProgress = MAX (forwardProgress, 0);
677
if (mCurWindowEvent == WindowEventOpen ||
678
mCurWindowEvent == WindowEventUnminimize ||
679
mCurWindowEvent == WindowEventUnshade ||
680
mCurWindowEvent == WindowEventFocus)
681
forwardProgress = 1 - forwardProgress;
683
return forwardProgress;
687
Animation::progressEaseInEaseOut ()
689
float forwardProgress =
690
1 - mRemainingTime / (mTotalTime - mTimestep);
691
forwardProgress = MIN (forwardProgress, 1);
692
forwardProgress = MAX (forwardProgress, 0);
694
// Apply sigmoid and normalize
696
(sigmoid (forwardProgress) - sigmoid (0)) /
697
(sigmoid (1) - sigmoid (0));
699
if (mCurWindowEvent == WindowEventOpen ||
700
mCurWindowEvent == WindowEventUnminimize ||
701
mCurWindowEvent == WindowEventUnshade ||
702
mCurWindowEvent == WindowEventFocus)
703
forwardProgress = 1 - forwardProgress;
705
return forwardProgress;
708
/// Gives some acceleration (when closing a window)
709
/// or deceleration (when opening a window).
710
/// Applies a sigmoid with slope s,
711
/// where minx and maxx are the
712
/// starting and ending points on the sigmoid.
714
Animation::progressDecelerateCustom (float progress, float minx, float maxx)
716
float x = 1 - progress;
720
1 - ((sigmoid2 (minx + (x * (maxx - minx)), s) - sigmoid2 (minx, s)) /
721
(sigmoid2 (maxx, s) - sigmoid2 (minx, s)));
725
Animation::progressDecelerate (float progress)
727
return progressDecelerateCustom (progress, 0.5, 0.75);
737
AnimWindow::stepRegion ()
739
return priv->mStepRegion;
743
PrivateAnimWindow::copyResetStepRegion ()
745
mLastStepRegion = mStepRegion;
747
// Reset bounding box for current step
748
mBB.x1 = mBB.y1 = MAXSHORT;
749
mBB.x2 = mBB.y2 = MINSHORT;
753
AnimWindow::expandBBWithBox (Box &source)
755
Box &target = priv->BB ();
757
if (source.x1 < target.x1)
758
target.x1 = source.x1;
759
if (source.x2 > target.x2)
760
target.x2 = source.x2;
761
if (source.y1 < target.y1)
762
target.y1 = source.y1;
763
if (source.y2 > target.y2)
764
target.y2 = source.y2;
768
AnimWindow::expandBBWithPoint (float fx, float fy)
770
Box &target = priv->BB ();
772
short x = MAX (MIN (fx, MAXSHORT - 1), MINSHORT);
773
short y = MAX (MIN (fy, MAXSHORT - 1), MINSHORT);
775
if (target.x1 == MAXSHORT)
785
else if (x > target.x2)
790
else if (y > target.y2)
794
/// This will work for zoom-like 2D transforms,
795
/// but not for glide-like 3D transforms.
797
AnimWindow::expandBBWithPoint2DTransform (GLVector &coords,
798
GLMatrix &transformMat)
800
GLVector coordsTransformed = transformMat * coords;
801
expandBBWithPoint (coordsTransformed[GLVector::x],
802
coordsTransformed[GLVector::y]);
805
/// Either points or objects should be non-0.
807
AnimWindow::expandBBWithPoints3DTransform (CompOutput &output,
810
GridAnim::GridModel::GridObject *objects,
811
unsigned int nPoints)
814
GLdouble dProjection[16];
816
for (unsigned int i = 0; i < 16; i++)
818
dModel[i] = transform[i];
819
dProjection[i] = GLScreen::get (::screen)->projectionMatrix ()[i];
822
{output.region ()->extents.x1,
823
output.region ()->extents.y1,
827
if (points) // use points
829
for (; nPoints; nPoints--, points += 3)
831
if (!gluProject (points[0], points[1], points[2],
832
dModel, dProjection, viewport,
836
expandBBWithPoint (x + 0.5, (::screen->height () - y) + 0.5);
839
else // use grid model objects
841
GridAnim::GridModel::GridObject *object = objects;
842
for (; nPoints; nPoints--, object++)
844
if (!gluProject (object->position ().x (),
845
object->position ().y (),
846
object->position ().z (),
847
dModel, dProjection, viewport,
851
expandBBWithPoint (x + 0.5, (::screen->height () - y) + 0.5);
858
AnimWindow::expandBBWithWindow ()
860
CompRect outRect (savedRectsValid () ?
862
mWindow->outputRect ());
864
outRect.x (), outRect.x () + outRect.width (),
865
outRect.y (), outRect.y () + outRect.height ()
867
expandBBWithBox (windowBox);
871
AnimWindow::expandBBWithScreen ()
873
Box screenBox = {0, ::screen->width (),
874
0, ::screen->height ()};
875
expandBBWithBox (screenBox);
879
Animation::prepareTransform (CompOutput &output,
880
GLMatrix &resultTransform,
884
sTransform.toScreenSpace (&output, -DEFAULT_Z_CAMERA);
885
resultTransform = sTransform * transform;
889
AnimWindow::resetStepRegionWithBB ()
891
// Have a 1 pixel margin to prevent occasional 1 pixel line artifact
892
CompRegion region (priv->mBB.x1 - 1,
894
priv->mBB.x2 - priv->mBB.x1 + 2,
895
priv->mBB.y2 - priv->mBB.y1 + 2);
896
priv->mStepRegion = region;
899
/// Damage the union of window's bounding box
900
/// before and after animStepFunc does its job.
902
PrivateAnimWindow::damageThisAndLastStepRegion ()
904
// Find union of the regions for this step and last step
905
CompRegion totalRegionToDamage (mStepRegion + mLastStepRegion);
907
mPAScreen->cScreen->damageRegion (totalRegionToDamage);
911
AnimScreen::output ()
913
return priv->output ();
917
AnimScreen::getMousePointerXY (short *x, short *y)
924
(::screen->dpy (), ::screen->root (), &w1, &w2, &xj, &yj, &xp, &yp, &m))
934
PrivateAnimWindow::getState ()
938
unsigned long n, left;
940
unsigned int retval = WithdrawnState;
942
result = XGetWindowProperty (::screen->dpy (), mWindow->id (),
946
&actual, &format, &n, &left, &data);
948
if (result == Success && data)
951
memcpy (&retval, data, sizeof (int));
953
XFree ((void *)data);
960
AnimScreen::getOptions ()
962
return priv->getOptions ();
966
AnimScreen::setOption (const CompString &name,
967
CompOption::Value &value)
969
return priv->setOption (name, value);
973
PrivateAnimScreen::eventMatchesChanged (CompOption *opt,
974
AnimationOptions::Options num)
976
if (mExtensionPlugins.size () == 0)
977
initAnimationList ();
978
foreach (CompOption::Value &val, opt->value ().list ())
979
val.match ().update ();
983
PrivateAnimScreen::eventOptionsChanged (CompOption *opt,
984
AnimationOptions::Options num)
986
if (mExtensionPlugins.size () == 0)
987
initAnimationList ();
988
updateOptionSets (getCorrespondingAnimEvent (num));
992
PrivateAnimScreen::eventEffectsChanged (CompOption *opt,
993
AnimationOptions::Options num)
995
if (mExtensionPlugins.size () == 0)
996
initAnimationList ();
997
updateEventEffects (getCorrespondingAnimEvent (num), false);
1001
PrivateAnimScreen::eventRandomEffectsChanged (CompOption *opt,
1002
AnimationOptions::Options num)
1004
if (mExtensionPlugins.size () == 0)
1005
initAnimationList ();
1006
updateEventEffects (getCorrespondingAnimEvent (num), true);
1010
PrivateAnimWindow::postAnimationCleanUpCustom (bool closing,
1012
bool clearMatchingRow)
1014
bool shouldDamageWindow = false;
1016
notifyAnimation (false);
1020
if (mCurAnimation->shouldDamageWindowOnEnd ())
1021
shouldDamageWindow = true;
1023
enablePainting (false);
1025
if (shouldDamageWindow)
1026
mAWindow->expandBBWithWindow ();
1028
if (shouldDamageWindow ||
1030
!mCurAnimation->stepRegionUsed () &&
1031
mAWindow->BB ()->x1 != MAXSHORT)) // BB intialized
1032
mAWindow->resetStepRegionWithBB ();
1034
damageThisAndLastStepRegion ();
1038
mCurAnimation->cleanUp (closing, destructing);
1039
delete mCurAnimation;
1043
mBB.x1 = mBB.y1 = MAXSHORT;
1044
mBB.x2 = mBB.y2 = MINSHORT;
1048
if (clearMatchingRow)
1049
mCurAnimSelectionRow = -1;
1051
mFinishingAnim = true;
1054
mIgnoreDamage = true;
1055
while (mUnmapCnt > 0)
1062
mIgnoreDamage = false;
1067
mWindow->destroy ();
1070
mFinishingAnim = false;
1072
foreach (ExtensionPluginInfo *extPlugin, mPAScreen->mExtensionPlugins)
1073
extPlugin->cleanUpAnimation (closing, destructing);
1077
AnimWindow::postAnimationCleanUp ()
1079
priv->postAnimationCleanUp ();
1083
PrivateAnimWindow::postAnimationCleanUp ()
1085
if (mCurAnimation->curWindowEvent () == WindowEventClose)
1086
postAnimationCleanUpCustom (true, false, true);
1088
postAnimationCleanUpCustom (false, false, true);
1092
PrivateAnimWindow::postAnimationCleanUpPrev (bool closing,
1093
bool clearMatchingRow)
1095
int curAnimSelectionRow = mCurAnimSelectionRow;
1096
// Use previous event's anim selection row
1097
mCurAnimSelectionRow = mPrevAnimSelectionRow;
1099
postAnimationCleanUpCustom (closing, false, clearMatchingRow);
1101
// Restore current event's anim selection row
1102
mCurAnimSelectionRow = curAnimSelectionRow;
1106
PrivateAnimScreen::activateEvent (bool activating)
1110
if (mAnimInProgress)
1115
// Animations have finished for all windows
1116
// (Keep preparePaint enabled)
1118
aScreen->enableCustomPaintList (false);
1120
cScreen->donePaintSetEnabled (this, activating);
1121
gScreen->glPaintOutputSetEnabled (this, activating);
1123
mAnimInProgress = activating;
1125
CompOption::Vector o (0);
1127
o.push_back (CompOption ("root", CompOption::TypeInt));
1128
o.push_back (CompOption ("active", CompOption::TypeBool));
1130
o[0].value ().set ((int) ::screen->root ());
1131
o[1].value ().set (activating);
1133
::screen->handleCompizEvent ("animation", "activate", o);
1137
PrivateAnimWindow::notifyAnimation (bool activation)
1139
CompOption::Vector o (0);
1144
o.push_back (CompOption ("root", CompOption::TypeInt));
1145
o.push_back (CompOption ("window", CompOption::TypeInt));
1146
o.push_back (CompOption ("type", CompOption::TypeString));
1147
o.push_back (CompOption ("active", CompOption::TypeBool));
1149
o[0].value ().set ((int) ::screen->root ());
1150
o[1].value ().set ((int) mWindow->id ());
1152
switch (mCurAnimation->curWindowEvent ())
1154
case WindowEventOpen:
1155
o[2].value ().set ("open");
1157
case WindowEventClose:
1158
o[2].value ().set ("close");
1160
case WindowEventMinimize:
1161
o[2].value ().set ("minimize");
1163
case WindowEventUnminimize:
1164
o[2].value ().set ("unminimize");
1166
case WindowEventShade:
1167
o[2].value ().set ("shade");
1169
case WindowEventUnshade:
1170
o[2].value ().set ("unshade");
1172
case WindowEventFocus:
1173
o[2].value ().set ("focus");
1175
case WindowEventNum:
1176
case WindowEventNone:
1178
o[2].value ().set ("none");
1182
o[3].value ().set (activation);
1184
screen->handleCompizEvent ("animation", "window_animation", o);
1188
PrivateAnimScreen::otherPluginsActive ()
1190
for (int i = 0; i < WatchedScreenPluginNum; i++)
1191
if (mPluginActive[i])
1197
Animation::shouldSkipFrame (int msSinceLastPaintActual)
1199
mTimeElapsedWithinTimeStep += msSinceLastPaintActual;
1200
if (mTimeElapsedWithinTimeStep < mTimestep) // if timestep not yet completed
1203
mTimeElapsedWithinTimeStep = fmod (mTimeElapsedWithinTimeStep, mTimestep);
1208
Animation::advanceTime (int msSinceLastPaint)
1210
mRemainingTime -= msSinceLastPaint;
1211
mRemainingTime = MAX (mRemainingTime, 0); // avoid sub-zero values
1213
mTimeSinceLastPaint = msSinceLastPaint;
1215
return (mRemainingTime > 0);
1219
PrivateAnimScreen::preparePaint (int msSinceLastPaint)
1221
// Check and update "switcher post wait" counter
1222
if (mSwitcherPostWait > 0)
1224
mSwitcherPostWait++;
1225
if (mSwitcherPostWait > 5) // wait over
1227
mSwitcherPostWait = 0;
1229
// Reset stacking related info since it will
1230
// cause problems because of the restacking
1231
// just done by Switcher.
1232
ExtensionPluginAnimation *extPlugin =
1233
static_cast<ExtensionPluginAnimation *> (mExtensionPlugins[0]);
1234
extPlugin->resetStackingInfo ();
1238
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
1239
extPlugin->prePreparePaintGeneral ();
1241
if (mAnimInProgress)
1243
int msSinceLastPaintActual;
1244
const CompWindowList &pl = pushLockedPaintList ();
1245
CompWindowList windowsFinishedAnimations;
1247
struct timeval curTime;
1248
gettimeofday (&curTime, 0);
1250
if (mLastRedrawTimeFresh)
1252
msSinceLastPaintActual = timer::timeval_diff (&curTime, &mLastRedrawTime);
1253
// handle clock rollback
1254
if (msSinceLastPaintActual < 0)
1255
msSinceLastPaintActual = 0;
1258
msSinceLastPaintActual = 20; // assume 20 ms passed
1260
mLastRedrawTime = curTime; // Store current time for next time
1261
mLastRedrawTimeFresh = true;
1263
bool animStillInProgress = false;
1265
/* Paint list includes destroyed windows */
1266
for (CompWindowList::const_reverse_iterator rit = pl.rbegin ();
1267
rit != pl.rend (); rit++)
1269
CompWindow *w = (*rit);
1270
AnimWindow *animWin = AnimWindow::get (w);
1271
PrivateAnimWindow *aw = animWin->priv;
1272
Animation *curAnim = aw->curAnimation ();
1276
if (!curAnim->initialized ())
1279
if (curAnim->prePreparePaint (msSinceLastPaint))
1280
animStillInProgress = true;
1282
/* TODO optimize grid model by reusing one GridModel
1283
if (aw->com.mModel &&
1284
(aw->com.mModel->winWidth != outRect.width () ||
1285
aw->com.mModel->winHeight != outRect.height ()))
1287
// mModel needs update
1289
if (!animEnsureModel (w))
1291
// Abort this window's animation
1292
postAnimationCleanUp (w);
1297
bool animShouldSkipFrame =
1298
(curAnim->shouldSkipFrame (msSinceLastPaintActual) &&
1299
// Skip only if we're not on the first animation frame
1300
curAnim->initialized ());
1302
// Skip only if we're not on the last animation frame
1303
animShouldSkipFrame &=
1304
curAnim->advanceTime (msSinceLastPaint);
1306
if (!animShouldSkipFrame)
1308
if (curAnim->updateBBUsed ())
1310
aw->copyResetStepRegion ();
1312
if (!curAnim->initialized () &&
1313
curAnim->shouldDamageWindowOnStart ())
1314
aw->aWindow ()->expandBBWithWindow ();
1317
if (!curAnim->initialized ())
1318
curAnim->setInitialized ();
1322
if (curAnim->updateBBUsed ())
1324
foreach (CompOutput &output, ::screen->outputDevs ())
1325
curAnim->updateBB (output);
1327
if (!curAnim->stepRegionUsed () &&
1328
aw->BB ().x1 != MAXSHORT) // BB initialized
1330
// BB is used instead of step region,
1331
// so reset step region here with BB.
1332
animWin->resetStepRegionWithBB ();
1334
if (!(cScreen->damageMask () &
1335
COMPOSITE_SCREEN_DAMAGE_ALL_MASK))
1336
aw->damageThisAndLastStepRegion ();
1340
bool finished = (curAnim->remainingTime () <= 0);
1341
if (finished) // Animation is done
1342
windowsFinishedAnimations.push_back (w);
1344
animStillInProgress = true;
1348
foreach (CompWindow *w, pl)
1350
PrivateAnimWindow *aw = AnimWindow::get (w)->priv;
1351
if (aw->curAnimation ())
1352
aw->curAnimation ()->postPreparePaint ();
1355
popLockedPaintList ();
1358
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
1359
extPlugin->postPreparePaintGeneral ();
1361
cScreen->preparePaint (msSinceLastPaint);
1363
if (mStartCountdown)
1366
if (!mStartCountdown)
1368
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
1369
extPlugin->postStartupCountdown ();
1375
PrivateAnimScreen::donePaint ()
1377
assert (mAnimInProgress);
1379
const CompWindowList &pl = pushLockedPaintList ();
1380
CompWindowList windowsFinishedAnimations;
1382
bool animStillInProgress = false;
1384
/* Paint list includes destroyed windows */
1385
for (CompWindowList::const_reverse_iterator rit = pl.rbegin ();
1386
rit != pl.rend (); rit++)
1388
CompWindow *w = (*rit);
1389
AnimWindow *animWin = AnimWindow::get (w);
1390
PrivateAnimWindow *aw = animWin->priv;
1391
Animation *curAnim = aw->curAnimation ();
1395
bool finished = (curAnim->remainingTime () <= 0);
1396
if (finished) // Animation is done
1397
windowsFinishedAnimations.push_back (w);
1399
animStillInProgress = true;
1403
popLockedPaintList ();
1405
foreach (CompWindow *w, windowsFinishedAnimations)
1407
AnimWindow *aw = AnimWindow::get (w);
1408
aw->priv->notifyAnimation (false);
1409
aw->priv->postAnimationCleanUp ();
1412
if (!animStillInProgress)
1414
activateEvent (false);
1415
mLastRedrawTimeFresh = false;
1417
// Reset stacking related info after all animations are done.
1418
ExtensionPluginAnimation *extPlugin =
1419
static_cast<ExtensionPluginAnimation *> (mExtensionPlugins[0]);
1420
extPlugin->resetStackingInfo ();
1423
cScreen->damagePending ();
1425
cScreen->donePaint ();
1429
PrivateAnimWindow::enablePainting (bool enabling)
1431
gWindow->glPaintSetEnabled (this, enabling);
1432
gWindow->glAddGeometrySetEnabled (this, enabling);
1433
gWindow->glDrawGeometrySetEnabled (this, enabling);
1434
gWindow->glDrawTextureSetEnabled (this, enabling);
1438
PrivateAnimWindow::glAddGeometry (const GLTexture::MatrixList &matrix,
1439
const CompRegion ®ion,
1440
const CompRegion &clip,
1441
unsigned int maxGridWidth,
1442
unsigned int maxGridHeight)
1444
// if window is being animated
1447
if (mCurAnimation->initialized ())
1448
mCurAnimation->addGeometry (matrix, region, clip,
1449
maxGridWidth, maxGridHeight);
1453
gWindow->glAddGeometry (matrix, region, clip,
1454
maxGridWidth, maxGridHeight);
1459
Animation::shouldDamageWindowOnStart ()
1461
return (mCurWindowEvent == WindowEventClose ||
1462
mCurWindowEvent == WindowEventMinimize ||
1463
mCurWindowEvent == WindowEventShade);
1467
Animation::shouldDamageWindowOnEnd ()
1469
return (mCurWindowEvent == WindowEventOpen ||
1470
mCurWindowEvent == WindowEventUnminimize ||
1471
mCurWindowEvent == WindowEventUnshade);
1475
Animation::addGeometry (const GLTexture::MatrixList &matrix,
1476
const CompRegion ®ion,
1477
const CompRegion &clip,
1478
unsigned int maxGridWidth,
1479
unsigned int maxGridHeight)
1481
mAWindow->priv->gWindow->glAddGeometry (matrix, region, clip,
1482
maxGridWidth, maxGridHeight);
1486
PartialWindowAnim::addGeometry (const GLTexture::MatrixList &matrix,
1487
const CompRegion ®ion,
1488
const CompRegion &clip,
1489
unsigned int maxGridWidth,
1490
unsigned int maxGridHeight)
1494
CompRegion awRegion (region.intersected (mDrawRegion));
1495
Animation::addGeometry (matrix, awRegion, clip,
1496
maxGridWidth, maxGridHeight);
1500
Animation::addGeometry (matrix, region, clip,
1501
maxGridWidth, maxGridHeight);
1506
PrivateAnimWindow::glDrawTexture (GLTexture *texture,
1507
GLFragment::Attrib &attrib,
1512
mCurAnimation->setCurPaintAttrib (attrib);
1515
gWindow->glDrawTexture (texture, attrib, mask);
1519
PrivateAnimWindow::glDrawGeometry ()
1523
if (mCurAnimation->initialized ())
1524
mCurAnimation->drawGeometry ();
1528
gWindow->glDrawGeometry ();
1533
Animation::drawTexture (GLTexture *texture,
1534
GLFragment::Attrib &attrib,
1537
mCurPaintAttrib = attrib;
1541
Animation::drawGeometry ()
1543
mAWindow->priv->gWindow->glDrawGeometry ();
1547
PrivateAnimWindow::glPaint (const GLWindowPaintAttrib &attrib,
1548
const GLMatrix &transform,
1549
const CompRegion ®ion, unsigned int mask)
1553
// Is this the first glPaint call this round
1554
// without the mask PAINT_WINDOW_OCCLUSION_DETECTION_MASK?
1555
if (mPAScreen->mStartingNewPaintRound &&
1556
!(mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK))
1558
mPAScreen->mStartingNewPaintRound = false;
1560
// Back-to-front painting of windows is starting now.
1561
if (mPAScreen->mPrePaintWindowsBackToFrontEnabled)
1562
mPAScreen->prePaintWindowsBackToFront ();
1565
assert (mCurAnimation);
1567
foreach (ExtensionPluginInfo *extPlugin, mPAScreen->mExtensionPlugins)
1569
if (extPlugin->paintShouldSkipWindow (mWindow))
1573
if (mCurAnimation->curWindowEvent () == WindowEventFocus &&
1574
mPAScreen->otherPluginsActive ())
1576
postAnimationCleanUp ();
1577
return gWindow->glPaint (attrib, transform, region, mask);
1580
GLWindowPaintAttrib wAttrib = attrib;
1581
GLMatrix wTransform (transform.getMatrix ());
1583
/* TODO check if this is still necessary
1584
if (mCurAnimation->addCustomGeometryFunc)
1586
// Use slightly smaller brightness to force core
1587
// to handle <max saturation case with <max brightness.
1588
// Otherwise polygon effects show fully unsaturated colors
1590
wAttrib.brightness = MAX (0, wAttrib.brightness - 1);
1593
//w->indexCount = 0; // TODO check if this is still necessary
1595
// TODO: should only happen for distorting effects
1596
mask |= PAINT_WINDOW_TRANSFORMED_MASK;
1598
wAttrib.xScale = 1.0f;
1599
wAttrib.yScale = 1.0f;
1601
mCurAnimation->updateAttrib (wAttrib);
1602
mCurAnimation->updateTransform (wTransform);
1603
mCurAnimation->prePaintWindow ();
1605
if (mCurAnimation->paintWindowUsed ())
1606
status = mCurAnimation->paintWindow (gWindow, wAttrib, wTransform, region, mask);
1608
status = gWindow->glPaint (wAttrib, wTransform, region, mask);
1610
if (mCurAnimation->postPaintWindowUsed ())
1612
// Transform to make post-paint coincide with the window
1614
glLoadMatrixf (wTransform.getMatrix ());
1616
mCurAnimation->postPaintWindow ();
1624
const CompWindowList &
1625
PrivateAnimScreen::pushLockedPaintList ()
1627
if (!mLockedPaintListCnt)
1629
mLockedPaintList = &cScreen->getWindowPaintList ();
1631
if (!mGetWindowPaintListEnableCnt)
1633
mGetWindowPaintListEnableCnt++;
1634
cScreen->getWindowPaintListSetEnabled (this, true);
1638
mLockedPaintListCnt++;
1639
return *mLockedPaintList;
1643
PrivateAnimScreen::popLockedPaintList ()
1645
mLockedPaintListCnt--;
1647
if (!mLockedPaintListCnt)
1649
mLockedPaintList = NULL;
1651
mGetWindowPaintListEnableCnt--;
1653
if (!mGetWindowPaintListEnableCnt)
1654
cScreen->getWindowPaintListSetEnabled (this, false);
1658
/// This is enabled only during restack animations.
1659
/// or when we need to lock it
1660
const CompWindowList &
1661
PrivateAnimScreen::getWindowPaintList ()
1663
if (mLockedPaintList)
1664
return *mLockedPaintList;
1666
ExtensionPluginAnimation *extPlugin =
1667
static_cast<ExtensionPluginAnimation *> (mExtensionPlugins[0]);
1668
return extPlugin->getWindowPaintList ();
1671
/// This is enabled only during restack animations.
1673
PrivateAnimScreen::prePaintWindowsBackToFront ()
1675
assert (mAnimInProgress);
1677
ExtensionPluginAnimation *extPlugin =
1678
static_cast<ExtensionPluginAnimation *> (mExtensionPlugins[0]);
1679
extPlugin->prePaintWindowsBackToFront ();
1683
PrivateAnimScreen::enablePrePaintWindowsBackToFront (bool enabled)
1685
mPrePaintWindowsBackToFrontEnabled = enabled;
1689
PrivateAnimScreen::pushPaintList ()
1691
if (!mGetWindowPaintListEnableCnt)
1692
cScreen->getWindowPaintListSetEnabled (this, true);
1694
mGetWindowPaintListEnableCnt++;
1698
PrivateAnimScreen::popPaintList ()
1700
mGetWindowPaintListEnableCnt--;
1702
if (!mGetWindowPaintListEnableCnt)
1703
cScreen->getWindowPaintListSetEnabled (this, false);
1707
AnimScreen::enableCustomPaintList (bool enabled)
1709
enabled ? priv->pushPaintList () : priv->popPaintList ();
1711
priv->enablePrePaintWindowsBackToFront (enabled);
1714
static const PluginEventInfo watchedScreenPlugins[] =
1716
{"switcher", "activate"},
1717
{"ring", "activate"},
1718
{"shift", "activate"},
1719
{"scale", "activate"},
1720
{"group", "tabChangeActivate"},
1721
{"fadedesktop", "activate"}
1724
static const PluginEventInfo watchedWindowPlugins[] =
1726
{"kdecompat", "slide"},
1730
PrivateAnimScreen::handleCompizEvent (const char *pluginName,
1731
const char *eventName,
1732
CompOption::Vector &options)
1734
::screen->handleCompizEvent (pluginName, eventName, options);
1736
for (int i = 0; i < WatchedScreenPluginNum; i++)
1737
if (strcmp (pluginName, watchedScreenPlugins[i].pluginName) == 0)
1739
if (strcmp (eventName,
1740
watchedScreenPlugins[i].activateEventName) == 0)
1743
CompOption::getBoolOptionNamed (options, "active", false);
1745
if (!mPluginActive[i] &&
1746
(i == WatchedPluginSwitcher ||
1747
i == WatchedPluginRing ||
1748
i == WatchedPluginShift ||
1749
i == WatchedPluginScale))
1751
mSwitcherPostWait = 1;
1757
for (int i = 0; i < WatchedWindowPluginNum; i++)
1758
if (strcmp (pluginName,
1759
watchedWindowPlugins[i].pluginName) == 0)
1761
if (strcmp (eventName,
1762
watchedWindowPlugins[i].activateEventName) == 0)
1764
Window xid = CompOption::getIntOptionNamed (options,
1767
CompWindow *w = screen->findWindow (xid);
1771
AnimWindow *aw = AnimWindow::get (w);
1772
PrivateAnimWindow *pw = aw->priv;
1773
pw->mPluginActive[i] = CompOption::getBoolOptionNamed (
1783
/// Returns true for windows that don't have a pixmap or certain properties,
1784
/// like the dimming layer of gksudo and x-session-manager.
1786
PrivateAnimScreen::shouldIgnoreWindowForAnim (CompWindow *w, bool checkPixmap)
1788
AnimWindow *aw = AnimWindow::get (w);
1790
for (int i = 0; i < WatchedWindowPluginNum; i++)
1791
if (aw->priv->mPluginActive[i])
1794
return ((checkPixmap && !CompositeWindow::get (w)->pixmap ()) ||
1795
mNeverAnimateMatch.evaluate (w));
1799
PrivateAnimWindow::reverseAnimation ()
1801
mCurAnimation->reverse ();
1803
// Inflict the pending unmaps
1804
while (mUnmapCnt > 0)
1814
PrivateAnimScreen::initiateCloseAnim (PrivateAnimWindow *aw)
1816
CompWindow *w = aw->mWindow;
1818
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
1819
extPlugin->preInitiateCloseAnim (aw->mAWindow);
1821
if (shouldIgnoreWindowForAnim (w, true))
1824
AnimEffect chosenEffect =
1825
getMatchingAnimSelection (w, AnimEventClose, &duration);
1827
aw->mState = NormalState;
1828
aw->mNewState = WithdrawnState;
1830
if (chosenEffect != AnimEffectNone)
1832
bool startingNew = true;
1833
WindowEvent curWindowEvent = WindowEventNone;
1835
if (aw->curAnimation ())
1836
curWindowEvent = aw->curAnimation ()->curWindowEvent ();
1838
if (curWindowEvent != WindowEventNone)
1840
if (curWindowEvent == WindowEventOpen)
1842
startingNew = false;
1843
aw->reverseAnimation ();
1845
/* TODO check if necessary
1846
else if (aw->com.curWindowEvent == WindowEventClose)
1848
if (aw->com.animOverrideProgressDir == 2)
1850
aw->com.animRemainingTime = tmpSteps;
1851
startingNew = false;
1856
aw->postAnimationCleanUpPrev (true, false);
1862
AnimEffect effectToBePlayed =
1863
getActualEffect (chosenEffect, AnimEventClose);
1865
// handle empty random effect list
1866
if (effectToBePlayed && effectToBePlayed == AnimEffectNone)
1868
aw->mState = aw->mNewState;
1873
effectToBePlayed->create (w, WindowEventClose, duration,
1874
effectToBePlayed, getIcon (w, true));
1875
aw->mCurAnimation->adjustPointerIconSize ();
1876
aw->enablePainting (true);
1879
activateEvent (true);
1880
aw->notifyAnimation (true);
1882
// Increment 3 times to make sure close animation works
1883
// (e.g. for popup menus).
1884
for (int i = 0; i < 3; i++)
1887
w->incrementUnmapReference ();
1889
cScreen->damagePending ();
1891
/* TODO check if necessary
1892
else if (AnimEffectNone !=
1893
getMatchingAnimSelection (w, AnimEventOpen, &duration))
1895
// stop the current animation and prevent it from rewinding
1897
if (aw->com.animRemainingTime > 0 &&
1898
aw->com.curWindowEvent != WindowEventOpen)
1900
aw->com.animRemainingTime = 0;
1902
if ((aw->com.curWindowEvent != WindowEventNone) &&
1903
(aw->com.curWindowEvent != WindowEventClose))
1905
postAnimationCleanUp (w);
1907
// set some properties to make sure this window will use the
1908
// correct open effect the next time it's "opened"
1910
activateEvent (w->screen, true);
1911
aw->com.curWindowEvent = WindowEventClose;
1914
w->incrementUnmapRefCnt ();
1916
damagePendingOnScreen (w->screen);
1919
aw->mState = aw->mNewState;
1921
// Make sure non-animated closing windows get a damage.
1922
if (!aw->curAnimation ())
1924
aw->mAWindow->expandBBWithWindow ();
1929
PrivateAnimScreen::getIcon (CompWindow *w, bool alwaysUseMouse)
1933
if (!alwaysUseMouse)
1935
icon = w->iconGeometry ();
1937
if (alwaysUseMouse ||
1940
icon.width () == 0 &&
1941
icon.height () == 0)) // that is, couldn't get icon from window
1943
// Minimize to mouse pointer if there is no
1944
// window list or if the window skips taskbar
1946
if (!aScreen->getMousePointerXY (&x, &y))
1948
// Use screen center if can't get mouse coords
1949
x = ::screen->width () / 2;
1950
y = ::screen->height () / 2;
1954
icon.setWidth (FAKE_ICON_SIZE);
1955
icon.setHeight (FAKE_ICON_SIZE);
1962
PrivateAnimScreen::initiateMinimizeAnim (PrivateAnimWindow *aw)
1964
CompWindow *w = aw->mWindow;
1966
if (aw->mWindow->destroyed ())
1969
// Store window geometry for use during animation.
1970
aw->mAWindow->mSavedInRect = w->inputRect ();
1971
aw->mAWindow->mSavedOutRect = w->outputRect ();
1972
aw->mAWindow->mSavedOutExtents = w->output ();
1973
aw->mAWindow->mSavedWinRect = w->geometry ();
1974
aw->mAWindow->mSavedRectsValid = true;
1976
aw->mNewState = IconicState;
1978
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
1979
extPlugin->preInitiateMinimizeAnim (aw->mAWindow);
1982
AnimEffect chosenEffect =
1983
getMatchingAnimSelection (w, AnimEventMinimize, &duration);
1985
if (chosenEffect != AnimEffectNone)
1987
bool startingNew = true;
1988
WindowEvent curWindowEvent = WindowEventNone;
1990
if (aw->curAnimation ())
1991
curWindowEvent = aw->curAnimation ()->curWindowEvent ();
1993
if (curWindowEvent != WindowEventNone)
1995
if (curWindowEvent != WindowEventUnminimize)
1997
aw->postAnimationCleanUpPrev (false, false);
2001
startingNew = false;
2002
aw->reverseAnimation ();
2008
AnimEffect effectToBePlayed =
2009
getActualEffect (chosenEffect, AnimEventMinimize);
2011
// handle empty random effect list
2012
if (effectToBePlayed == AnimEffectNone)
2014
aw->mState = aw->mNewState;
2019
effectToBePlayed->create (w, WindowEventMinimize, duration,
2020
effectToBePlayed, getIcon (w, false));
2021
aw->enablePainting (true);
2024
activateEvent (true);
2025
aw->notifyAnimation (true);
2027
cScreen->damagePending ();
2030
aw->mState = aw->mNewState;
2034
PrivateAnimScreen::initiateShadeAnim (PrivateAnimWindow *aw)
2036
CompWindow *w = aw->mWindow;
2039
AnimEffect chosenEffect =
2040
getMatchingAnimSelection (w, AnimEventShade, &duration);
2042
aw->setShaded (true);
2044
if (chosenEffect != AnimEffectNone)
2046
bool startingNew = true;
2047
WindowEvent curWindowEvent = WindowEventNone;
2048
if (aw->curAnimation ())
2049
curWindowEvent = aw->curAnimation ()->curWindowEvent ();
2051
if (curWindowEvent != WindowEventNone)
2053
if (curWindowEvent != WindowEventUnshade)
2055
aw->postAnimationCleanUpPrev (false, false);
2059
startingNew = false;
2060
aw->reverseAnimation ();
2066
AnimEffect effectToBePlayed =
2067
getActualEffect (chosenEffect, AnimEventShade);
2069
// handle empty random effect list
2070
if (effectToBePlayed == AnimEffectNone)
2074
effectToBePlayed->create (w, WindowEventShade, duration,
2075
effectToBePlayed, getIcon (w, false));
2076
aw->enablePainting (true);
2079
activateEvent (true);
2080
aw->notifyAnimation (true);
2083
w->incrementUnmapReference ();
2085
cScreen->damagePending ();
2090
PrivateAnimScreen::initiateOpenAnim (PrivateAnimWindow *aw)
2092
CompWindow *w = aw->mWindow;
2095
AnimEffect chosenEffect;
2097
aw->mNewState = NormalState;
2099
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
2100
extPlugin->preInitiateOpenAnim (aw->mAWindow);
2102
WindowEvent curWindowEvent = WindowEventNone;
2103
if (aw->curAnimation ())
2104
curWindowEvent = aw->curAnimation ()->curWindowEvent ();
2106
if (!shouldIgnoreWindowForAnim (w, false) &&
2109
getMatchingAnimSelection (w, AnimEventOpen, &duration)) ||
2111
curWindowEvent == WindowEventClose))
2113
bool startingNew = true;
2114
bool playEffect = true;
2116
if (curWindowEvent != WindowEventNone)
2118
if (curWindowEvent != WindowEventClose)
2120
aw->postAnimationCleanUpPrev (false, false);
2124
startingNew = false;
2125
aw->reverseAnimation ();
2131
AnimEffect effectToBePlayed =
2132
getActualEffect (chosenEffect, AnimEventOpen);
2134
// handle empty random effect list
2135
if (effectToBePlayed == AnimEffectNone)
2141
effectToBePlayed->create (w, WindowEventOpen, duration,
2144
aw->mCurAnimation->adjustPointerIconSize ();
2145
aw->enablePainting (true);
2151
activateEvent (true);
2152
aw->notifyAnimation (true);
2153
cScreen->damagePending ();
2159
PrivateAnimScreen::initiateUnminimizeAnim (PrivateAnimWindow *aw)
2161
CompWindow *w = aw->mWindow;
2163
if (aw->mWindow->destroyed ())
2166
aw->mAWindow->mSavedRectsValid = false;
2169
AnimEffect chosenEffect =
2170
getMatchingAnimSelection (w, AnimEventMinimize, &duration);
2172
aw->mNewState = NormalState;
2174
if (chosenEffect != AnimEffectNone &&
2175
!mPluginActive[3]) // fadedesktop
2177
bool startingNew = true;
2178
bool playEffect = true;
2180
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
2181
extPlugin->preInitiateUnminimizeAnim (aw->mAWindow);
2183
// TODO Refactor the rest? (almost the same in other initiateX methods)
2184
WindowEvent curWindowEvent = WindowEventNone;
2185
if (aw->curAnimation ())
2186
curWindowEvent = aw->curAnimation ()->curWindowEvent ();
2188
if (curWindowEvent != WindowEventNone)
2190
if (curWindowEvent != WindowEventMinimize)
2192
aw->postAnimationCleanUpPrev (false, false);
2196
startingNew = false;
2197
aw->reverseAnimation ();
2203
AnimEffect effectToBePlayed =
2204
getActualEffect (chosenEffect, AnimEventMinimize);
2206
// handle empty random effect list
2207
if (effectToBePlayed == AnimEffectNone)
2213
effectToBePlayed->create (w, WindowEventUnminimize,
2214
duration, effectToBePlayed,
2215
getIcon (w, false));
2216
aw->enablePainting (true);
2222
activateEvent (true);
2223
aw->notifyAnimation (true);
2224
cScreen->damagePending ();
2230
PrivateAnimScreen::initiateUnshadeAnim (PrivateAnimWindow *aw)
2232
CompWindow *w = aw->mWindow;
2234
aw->mAWindow->mSavedRectsValid = false;
2236
aw->setShaded (false);
2238
aw->mNewState = NormalState;
2241
AnimEffect chosenEffect =
2242
getMatchingAnimSelection (w, AnimEventShade, &duration);
2244
if (chosenEffect != AnimEffectNone)
2246
bool startingNew = true;
2247
bool playEffect = true;
2249
WindowEvent curWindowEvent = WindowEventNone;
2250
if (aw->curAnimation ())
2251
curWindowEvent = aw->curAnimation ()->curWindowEvent ();
2253
if (curWindowEvent != WindowEventNone)
2255
if (curWindowEvent != WindowEventShade)
2257
aw->postAnimationCleanUpPrev (false, false);
2261
startingNew = false;
2262
aw->reverseAnimation ();
2268
AnimEffect effectToBePlayed =
2269
getActualEffect (chosenEffect, AnimEventShade);
2271
// handle empty random effect list
2272
if (effectToBePlayed == AnimEffectNone)
2278
effectToBePlayed->create (w, WindowEventUnshade,
2279
duration, effectToBePlayed,
2280
getIcon (w, false));
2281
aw->enablePainting (true);
2287
activateEvent (true);
2288
aw->notifyAnimation (true);
2289
cScreen->damagePending ();
2295
PrivateAnimScreen::initiateFocusAnim (PrivateAnimWindow *aw)
2297
CompWindow *w = aw->mWindow;
2300
if (aw->curAnimation () || otherPluginsActive () ||
2301
// Check the "switcher post-wait" counter that effectively prevents
2302
// focus animation to be initiated when the zoom option value is low
2307
AnimEffect chosenEffect =
2308
getMatchingAnimSelection (w, AnimEventFocus, &duration);
2310
if (chosenEffect != AnimEffectNone)
2312
aw->createFocusAnimation (chosenEffect, duration);
2314
if (chosenEffect->isRestackAnim &&
2315
!(dynamic_cast<RestackAnim *> (aw->mCurAnimation)->
2316
initiateRestackAnim (duration)))
2318
aw->postAnimationCleanUp ();
2322
activateEvent (true);
2323
aw->notifyAnimation (true);
2324
cScreen->damagePending ();
2331
PrivateAnimWindow::resizeNotify (int dx,
2336
if (mUnshadePending)
2338
mUnshadePending = false;
2339
mPAScreen->initiateUnshadeAnim (this);
2341
else if (mCurAnimation && mCurAnimation->inProgress () &&
2342
// Don't let transient window open anim be interrupted with a resize notify
2343
!(mCurAnimation->curWindowEvent () == WindowEventOpen &&
2344
(mWindow->wmType () &
2345
(CompWindowTypeDropdownMenuMask |
2346
CompWindowTypePopupMenuMask |
2347
CompWindowTypeMenuMask |
2348
CompWindowTypeTooltipMask |
2349
CompWindowTypeNotificationMask |
2350
CompWindowTypeComboMask |
2351
CompWindowTypeDndMask))) &&
2352
// Ignore resize with dx=0, dy=0, dwidth=0, dheight=0
2353
!(dx == 0 && dy == 0 && dwidth == 0 && dheight == 0) &&
2354
!mCurAnimation->resizeUpdate (dx, dy, dwidth, dheight))
2356
postAnimationCleanUp ();
2357
mPAScreen->updateAnimStillInProgress ();
2360
mWindow->resizeNotify (dx, dy, dwidth, dheight);
2364
PrivateAnimScreen::updateAnimStillInProgress ()
2366
bool animStillInProgress = false;
2367
const CompWindowList &pl = pushLockedPaintList ();
2369
foreach (CompWindow *w, pl)
2371
PrivateAnimWindow *aw = AnimWindow::get (w)->priv;
2372
if (aw->curAnimation () &&
2373
aw->curAnimation ()->inProgress ())
2375
animStillInProgress = true;
2380
aw->notifyAnimation (false);
2384
popLockedPaintList ();
2386
if (!animStillInProgress)
2387
activateEvent (false);
2391
PrivateAnimWindow::moveNotify (int dx,
2395
if (mCurAnimation && mCurAnimation->inProgress () &&
2396
(mGrabbed || !mCurAnimation->moveUpdate (dx, dy)))
2398
// Stop the animation
2399
postAnimationCleanUp ();
2400
mPAScreen->updateAnimStillInProgress ();
2403
mWindow->moveNotify (dx, dy, immediate);
2407
PrivateAnimWindow::grabNotify (int x,
2414
mWindow->grabNotify (x, y, state, mask);
2418
PrivateAnimWindow::ungrabNotify ()
2422
mWindow->ungrabNotify ();
2426
PrivateAnimScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
2427
const GLMatrix &matrix,
2428
const CompRegion ®ion,
2432
assert (mAnimInProgress);
2434
mStartingNewPaintRound = true;
2436
foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
2437
extPlugin->prePaintOutput (output);
2439
mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
2443
return gScreen->glPaintOutput (attrib, matrix, region, output, mask);
2446
AnimEffectInfo::AnimEffectInfo (const char *name,
2447
bool usedO, bool usedC, bool usedM,
2448
bool usedS, bool usedF,
2449
CreateAnimFunc create,
2450
bool isRestackAnim) :
2453
isRestackAnim (isRestackAnim)
2455
usedForEvents[AnimEventOpen] = usedO;
2456
usedForEvents[AnimEventClose] = usedC;
2457
usedForEvents[AnimEventMinimize] = usedM;
2458
usedForEvents[AnimEventShade] = usedS;
2459
usedForEvents[AnimEventFocus] = usedF;
2463
AnimEffectInfo::matchesEffectName (const CompString &animName)
2465
return (0 == strcasecmp (animName.c_str (), name));
2469
AnimEffectInfo::matchesPluginName (const CompString &pluginName)
2471
return (0 == strncmp (pluginName.c_str (), name, pluginName.length ()));
2474
AnimEffect animEffects[NUM_EFFECTS];
2476
ExtensionPluginAnimation animExtensionPluginInfo (CompString ("animation"),
2477
NUM_EFFECTS, animEffects, 0,
2478
NUM_NONEFFECT_OPTIONS);
2479
ExtensionPluginInfo *
2480
Animation::getExtensionPluginInfo ()
2482
return &animExtensionPluginInfo;
2485
AnimEffect AnimEffectNone;
2486
AnimEffect AnimEffectRandom;
2487
AnimEffect AnimEffectCurvedFold;
2488
AnimEffect AnimEffectDodge;
2489
AnimEffect AnimEffectDream;
2490
AnimEffect AnimEffectFade;
2491
AnimEffect AnimEffectFocusFade;
2492
AnimEffect AnimEffectGlide1;
2493
AnimEffect AnimEffectGlide2;
2494
AnimEffect AnimEffectHorizontalFolds;
2495
AnimEffect AnimEffectMagicLamp;
2496
AnimEffect AnimEffectMagicLampWavy;
2497
AnimEffect AnimEffectRollUp;
2498
AnimEffect AnimEffectSidekick;
2499
AnimEffect AnimEffectWave;
2500
AnimEffect AnimEffectZoom;
2502
PrivateAnimScreen::PrivateAnimScreen (CompScreen *s, AnimScreen *as) :
2503
cScreen (CompositeScreen::get (s)),
2504
gScreen (GLScreen::get (s)),
2506
mLastRedrawTimeFresh (false),
2507
mSwitcherPostWait (0),
2508
mStartCountdown (20), // start the countdown
2509
mLastActiveWindow (0),
2510
mAnimInProgress (false),
2511
mStartingNewPaintRound (false),
2512
mPrePaintWindowsBackToFrontEnabled (false),
2514
mLockedPaintList (NULL),
2515
mLockedPaintListCnt (0),
2516
mGetWindowPaintListEnableCnt (0)
2518
for (int i = 0; i < WatchedScreenPluginNum; i++)
2519
mPluginActive[i] = false;
2521
// Never animate screen-dimming layer of logout window and gksu.
2522
mNeverAnimateMatch |= "title=gksu";
2523
mNeverAnimateMatch |= "title=x-session-manager";
2524
mNeverAnimateMatch |= "title=gnome-session";
2525
mNeverAnimateMatch.update ();
2527
// Set-up option notifiers
2529
#define MATCHES_BIND \
2530
boost::bind (&PrivateAnimScreen::eventMatchesChanged, this, _1, _2)
2531
#define OPTIONS_BIND \
2532
boost::bind (&PrivateAnimScreen::eventOptionsChanged, this, _1, _2)
2533
#define EFFECTS_BIND \
2534
boost::bind (&PrivateAnimScreen::eventEffectsChanged, this, _1, _2)
2535
#define RANDOM_EFFECTS_BIND \
2536
boost::bind (&PrivateAnimScreen::eventRandomEffectsChanged, this, _1, _2)
2538
optionSetOpenMatchesNotify (MATCHES_BIND);
2539
optionSetCloseMatchesNotify (MATCHES_BIND);
2540
optionSetMinimizeMatchesNotify (MATCHES_BIND);
2541
optionSetFocusMatchesNotify (MATCHES_BIND);
2542
optionSetShadeMatchesNotify (MATCHES_BIND);
2544
optionSetOpenOptionsNotify (OPTIONS_BIND);
2545
optionSetCloseOptionsNotify (OPTIONS_BIND);
2546
optionSetMinimizeOptionsNotify (OPTIONS_BIND);
2547
optionSetFocusOptionsNotify (OPTIONS_BIND);
2548
optionSetShadeOptionsNotify (OPTIONS_BIND);
2550
optionSetOpenEffectsNotify (EFFECTS_BIND);
2551
optionSetCloseEffectsNotify (EFFECTS_BIND);
2552
optionSetMinimizeEffectsNotify (EFFECTS_BIND);
2553
optionSetFocusEffectsNotify (EFFECTS_BIND);
2554
optionSetShadeEffectsNotify (EFFECTS_BIND);
2556
optionSetOpenRandomEffectsNotify (RANDOM_EFFECTS_BIND);
2557
optionSetCloseRandomEffectsNotify (RANDOM_EFFECTS_BIND);
2558
optionSetMinimizeRandomEffectsNotify (RANDOM_EFFECTS_BIND);
2559
optionSetShadeRandomEffectsNotify (RANDOM_EFFECTS_BIND);
2561
ScreenInterface::setHandler (::screen);
2562
CompositeScreenInterface::setHandler (cScreen, false);
2563
GLScreenInterface::setHandler (gScreen, false);
2566
PrivateAnimScreen::~PrivateAnimScreen ()
2568
if (mAnimInProgress)
2569
activateEvent (false);
2571
for (int i = 0; i < NUM_EFFECTS; i++)
2572
delete animEffects[i];
2576
PrivateAnimScreen::initAnimationList ()
2579
animEffects[i++] = AnimEffectNone =
2580
new AnimEffectInfo ("animation:None",
2581
true, true, true, true, true, 0);
2582
animEffects[i++] = AnimEffectRandom =
2583
new AnimEffectInfo ("animation:Random",
2584
true, true, true, true, false, 0);
2585
animEffects[i++] = AnimEffectCurvedFold =
2586
new AnimEffectInfo ("animation:Curved Fold",
2587
true, true, true, true, false,
2588
&createAnimation<CurvedFoldAnim>);
2589
animEffects[i++] = AnimEffectDodge =
2590
new AnimEffectInfo ("animation:Dodge",
2591
false, false, false, false, true,
2592
&createAnimation<DodgeAnim>,
2594
animEffects[i++] = AnimEffectDream =
2595
new AnimEffectInfo ("animation:Dream",
2596
true, true, true, false, false,
2597
&createAnimation<DreamAnim>);
2598
animEffects[i++] = AnimEffectFade =
2599
new AnimEffectInfo ("animation:Fade",
2600
true, true, true, false, false,
2601
&createAnimation<FadeAnim>);
2602
animEffects[i++] = AnimEffectFocusFade =
2603
new AnimEffectInfo ("animation:Focus Fade",
2604
false, false, false, false, true,
2605
&createAnimation<FocusFadeAnim>,
2607
animEffects[i++] = AnimEffectGlide1 =
2608
new AnimEffectInfo ("animation:Glide 1",
2609
true, true, true, false, false,
2610
&createAnimation<GlideAnim>);
2611
animEffects[i++] = AnimEffectGlide2 =
2612
new AnimEffectInfo ("animation:Glide 2",
2613
true, true, true, false, false,
2614
&createAnimation<Glide2Anim>);
2615
animEffects[i++] = AnimEffectHorizontalFolds =
2616
new AnimEffectInfo ("animation:Horizontal Folds",
2617
true, true, true, true, false,
2618
&createAnimation<HorizontalFoldsAnim>);
2619
animEffects[i++] = AnimEffectMagicLamp =
2620
new AnimEffectInfo ("animation:Magic Lamp",
2621
true, true, true, false, false,
2622
&createAnimation<MagicLampAnim>);
2623
animEffects[i++] = AnimEffectMagicLampWavy =
2624
new AnimEffectInfo ("animation:Magic Lamp Wavy",
2625
true, true, true, false, false,
2626
&createAnimation<MagicLampWavyAnim>);
2627
animEffects[i++] = AnimEffectRollUp =
2628
new AnimEffectInfo ("animation:Roll Up",
2629
false, false, false, true, false,
2630
&createAnimation<RollUpAnim>);
2631
animEffects[i++] = AnimEffectSidekick =
2632
new AnimEffectInfo ("animation:Sidekick",
2633
true, true, true, false, false,
2634
&createAnimation<SidekickAnim>);
2635
animEffects[i++] = AnimEffectWave =
2636
new AnimEffectInfo ("animation:Wave",
2637
true, true, true, false, true,
2638
&createAnimation<WaveAnim>);
2639
animEffects[i++] = AnimEffectZoom =
2640
new AnimEffectInfo ("animation:Zoom",
2641
true, true, true, false, false,
2642
&createAnimation<ZoomAnim>);
2644
animExtensionPluginInfo.effectOptions = &getOptions ();
2646
// Extends itself with the basic set of animation effects.
2647
addExtension (&animExtensionPluginInfo, false);
2649
for (int e = 0; e < AnimEventNum; e++) // for each anim event
2650
updateOptionSets ((AnimEvent)e);
2652
updateAllEventEffects ();
2654
cScreen->preparePaintSetEnabled (this, true);
2657
PrivateAnimWindow::PrivateAnimWindow (CompWindow *w,
2659
gWindow (GLWindow::get (w)),
2662
mPAScreen (AnimScreen::get (::screen)->priv),
2664
mUnshadePending (false),
2665
mEventNotOpenClose (false),
2670
mIgnoreDamage (false),
2671
mFinishingAnim (false),
2672
mCurAnimSelectionRow (-1)
2674
mBB.x1 = mBB.y1 = MAXSHORT;
2675
mBB.x2 = mBB.y2 = MINSHORT;
2677
for (int i = 0; i < WatchedWindowPluginNum; i++)
2678
mPluginActive[i] = false;
2680
if (w->minimized ())
2682
mState = mNewState = IconicState;
2684
else if (w->shaded ())
2686
mState = mNewState = NormalState;
2691
mState = mNewState = getState ();
2694
WindowInterface::setHandler (mWindow, true);
2695
GLWindowInterface::setHandler (gWindow, false);
2698
PrivateAnimWindow::~PrivateAnimWindow ()
2700
notifyAnimation (false);
2701
postAnimationCleanUpCustom (false, true, true);
2705
PrivateAnimWindow::windowNotify (CompWindowNotify n)
2709
case CompWindowNotifyEnterShowDesktopMode:
2710
case CompWindowNotifyMinimize:
2711
mPAScreen->initiateMinimizeAnim (this);
2712
mEventNotOpenClose = true;
2714
case CompWindowNotifyShade:
2715
mPAScreen->initiateShadeAnim (this);
2716
mEventNotOpenClose = true;
2718
case CompWindowNotifyLeaveShowDesktopMode:
2719
case CompWindowNotifyUnminimize:
2720
mPAScreen->initiateUnminimizeAnim (this);
2721
mEventNotOpenClose = true;
2723
case CompWindowNotifyUnshade:
2726
mCurAnimation->curWindowEvent () == WindowEventShade)
2727
mPAScreen->initiateUnshadeAnim (this); // reverse the shade anim
2729
case CompWindowNotifyClose:
2730
if (!(mCurAnimation &&
2731
(mCurAnimation->curWindowEvent () == WindowEventClose ||
2732
mCurAnimation->curWindowEvent () == WindowEventUnminimize)))
2733
mPAScreen->initiateCloseAnim (this);
2735
case CompWindowNotifyShow:
2736
case CompWindowNotifyBeforeMap:
2737
// Prevent dialog disappearing when a dialog is reopened during
2738
// its close animation.
2739
if (mCurAnimation &&
2740
mCurAnimation->curWindowEvent () == WindowEventClose)
2742
mPAScreen->initiateOpenAnim (this);
2743
mEventNotOpenClose = false;
2746
case CompWindowNotifyMap:
2748
mUnshadePending = true;
2749
else if (!mUnshadePending &&
2750
!mEventNotOpenClose &&
2751
!mPAScreen->mStartCountdown &&
2753
(mCurAnimation->curWindowEvent () ==
2754
WindowEventUnminimize ||
2755
mCurAnimation->curWindowEvent () == WindowEventOpen)))
2756
mPAScreen->initiateOpenAnim (this);
2757
mEventNotOpenClose = false;
2759
case CompWindowNotifyBeforeUnmap:
2760
if (mCurAnimation && mCurAnimation->curWindowEvent () == WindowEventMinimize)
2763
mWindow->incrementUnmapReference ();
2766
case CompWindowNotifyBeforeDestroy:
2767
if (!mFinishingAnim)
2771
if (mPAScreen->shouldIgnoreWindowForAnim (mWindow, true))
2774
if (AnimEffectNone ==
2775
mPAScreen->getMatchingAnimSelection (mWindow,
2781
mWindow->incrementDestroyReference ();
2784
case CompWindowNotifyUnreparent:
2785
if (!mFinishingAnim)
2787
if (mPAScreen->shouldIgnoreWindowForAnim (mWindow, false))
2791
case CompWindowNotifyFocusChange:
2792
if (!mPAScreen->mLastActiveWindow ||
2793
mPAScreen->mLastActiveWindow != mWindow->id ())
2795
mPAScreen->mLastActiveWindow = mWindow->id ();
2797
if (mPAScreen->mStartCountdown) // Don't animate at startup
2801
AnimEffect chosenEffect =
2802
mPAScreen->getMatchingAnimSelection (mWindow,
2807
chosenEffect != AnimEffectNone &&
2808
!chosenEffect->isRestackAnim)
2809
mPAScreen->initiateFocusAnim (this);
2813
case CompWindowNotifyRestack:
2815
// Prevent menu disappearing when a menu is reopened during
2816
// its close animation. In that case a restack notify is thrown
2818
if (mCurAnimation &&
2819
mCurAnimation->curWindowEvent () == WindowEventClose)
2821
mPAScreen->initiateOpenAnim (this);
2822
mEventNotOpenClose = false;
2826
// Handle CompWindowNotifyRestack only when necessary.
2827
if (!mPAScreen->isRestackAnimPossible ())
2830
if (mPAScreen->mStartCountdown) // Don't animate at startup
2833
foreach (ExtensionPluginInfo *extPlugin,
2834
mPAScreen->mExtensionPlugins)
2835
extPlugin->handleRestackNotify (mAWindow);
2843
mWindow->windowNotify (n);
2847
AnimWindow::curAnimation ()
2849
return priv->curAnimation ();
2853
AnimScreen::getMatchingAnimSelection (CompWindow *w,
2857
return priv->getMatchingAnimSelection (w, e, duration);
2861
AnimScreen::otherPluginsActive ()
2863
return priv->otherPluginsActive ();
2867
AnimScreen::isAnimEffectPossible (AnimEffect theEffect)
2869
return priv->isAnimEffectPossible (theEffect);
2873
AnimScreen::initiateFocusAnim (AnimWindow *aw)
2875
return priv->initiateFocusAnim (aw->priv);
2878
/// If duration is 0, it should be set to a positive value later.
2880
AnimWindow::createFocusAnimation (AnimEffect effect, int duration)
2882
priv->createFocusAnimation (effect, duration);
2886
AnimWindow::deletePersistentData (const char *name)
2888
PersistentDataMap::iterator itData =
2889
persistentData.find (name);
2890
if (itData != persistentData.end ()) // if found
2892
delete itData->second;
2893
persistentData.erase (itData);
2898
PrivateAnimWindow::createFocusAnimation (AnimEffect effect, int duration)
2901
effect->create (mWindow, WindowEventFocus,
2905
enablePainting (true);
2908
AnimScreen::AnimScreen (CompScreen *s) :
2909
PluginClassHandler<AnimScreen, CompScreen, ANIMATION_ABI> (s),
2910
priv (new PrivateAnimScreen (s, this))
2912
priv->initAnimationList ();
2915
AnimScreen::~AnimScreen ()
2920
AnimWindow::AnimWindow (CompWindow *w) :
2921
PluginClassHandler<AnimWindow, CompWindow, ANIMATION_ABI> (w),
2923
priv (new PrivateAnimWindow (w, this)),
2924
mSavedRectsValid (false)
2926
foreach (ExtensionPluginInfo *extPlugin, priv->mPAScreen->mExtensionPlugins)
2927
extPlugin->initPersistentData (this);
2930
AnimWindow::~AnimWindow ()
2934
// Destroy each persistent data object
2935
PersistentDataMap::iterator itData = persistentData.begin ();
2936
for (; itData != persistentData.end (); itData++)
2937
delete itData->second;
2939
persistentData.clear ();
2943
AnimPluginVTable::init ()
2945
if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) |
2946
!CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) |
2947
!CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
2951
p.uval = ANIMATION_ABI;
2952
::screen->storeValue ("animation_ABI", p);
2958
AnimPluginVTable::fini ()
2960
::screen->eraseValue ("animation_ABI");