[beryl-commits] Animation plugin: Changes to 'master' (ece99e6e122d9d2010d67ef093a32aaa2d3cbf2b)
cornelius at server.beryl-project.org
cornelius at server.beryl-project.org
Fri Jun 22 10:36:31 CEST 2007
New commits:
commit ece99e6e122d9d2010d67ef093a32aaa2d3cbf2b
Merge: 4f493bc05dbd3457bf110692afb7edea7cdf761e 1d600624bf9a0956375a82cfdd1f99da511af55f
Author: Erkin Bahceci <erkinbah at gmail.com>
Date: Fri Jun 22 04:32:40 2007 -0400
Merge branch 'master' of git+ssh://cornelius@git.opencompositing.org/git/compcomm/plugins/animation
commit 4f493bc05dbd3457bf110692afb7edea7cdf761e
Author: Erkin Bahceci <erkinbah at gmail.com>
Date: Fri Jun 22 01:20:28 2007 -0400
Dodge support for apps with open dialog/utility windows (file, find dialogs, gobby, etc.).
commit 3b7f92ab0775f2d5cc3d6fada56183f7a1f67da7
Author: Erkin Bahceci <erkinbah at gmail.com>
Date: Fri Jun 22 01:15:49 2007 -0400
Fix flashing in focus animation with utility windows.
commit e92f99bdc60542bfdd34c4d3e4c5b1304a89e0f1
Author: Erkin Bahceci <erkinbah at gmail.com>
Date: Fri Jun 22 01:14:39 2007 -0400
Allow focus animations on shaded windows.
animation-internal.h | 11 +++-
animation.c | 210 ++++++++++++++++++++++++++++++++++++--------------
dodge.c | 80 ++++++++++++++++++--
3 files changed, 235 insertions(+), 66 deletions(-)
Modified: fusion/plugins/animation/animation-internal.h
===================================================================
--- fusion/plugins/animation/animation-internal.h
+++ fusion/plugins/animation/animation-internal.h
@@ -609,6 +609,8 @@ typedef struct _AnimWindow
CompWindow *dodgeChainStart;// for the subject window
CompWindow *dodgeChainPrev; // for dodging windows
CompWindow *dodgeChainNext; // for dodging windows
+ Bool skipPostPrepareScreen;
+ Bool drawnOnHostSkip;
} AnimWindow;
typedef struct _AnimEffectProperties
@@ -660,12 +662,19 @@ AnimEffectProperties *animEffectPropertiesTmp;
#define sigmoid2(fx, s) (1.0f/(1.0f+exp(-(s)*2*((fx)-0.5))))
// up, down, left, right
-#define DODGE_AMOUNT(dir, w, dw) \
+#define DODGE_AMOUNT(w, dw, dir) \
((dir) == 0 ? WIN_Y(w) - (WIN_Y(dw) + WIN_H(dw)) : \
(dir) == 1 ? (WIN_Y(w) + WIN_H(w)) - WIN_Y(dw) : \
(dir) == 2 ? WIN_X(w) - (WIN_X(dw) + WIN_W(dw)) : \
(WIN_X(w) + WIN_W(w)) - WIN_X(dw))
+// up, down, left, right
+#define DODGE_AMOUNT_BOX(box, dw, dir) \
+ ((dir) == 0 ? (box).y - (WIN_Y(dw) + WIN_H(dw)) : \
+ (dir) == 1 ? ((box).y + (box).height) - WIN_Y(dw) : \
+ (dir) == 2 ? (box).x - (WIN_X(dw) + WIN_W(dw)) : \
+ ((box).x + (box).width) - WIN_X(dw))
+
// spring crossing x (second time it spring movement reaches target)
#define SPRING_CROSSING_X 0.6184f
#define SPRING_PERCEIVED_T 0.5f
Modified: fusion/plugins/animation/animation.c
===================================================================
--- fusion/plugins/animation/animation.c
+++ fusion/plugins/animation/animation.c
@@ -1097,6 +1097,22 @@ static Bool playingPolygonEffect(AnimScreen *as, AnimWindow *aw)
return (thickness > 1e-5); // glide is 3D if thickness > 0
}
+void cleanUpParentChildChainItem(AnimScreen *as, AnimWindow *aw)
+{
+ if (aw->winThisIsPaintedBefore && !aw->winThisIsPaintedBefore->destroyed)
+ {
+ AnimWindow *aw2 =
+ GET_ANIM_WINDOW(aw->winThisIsPaintedBefore, as);
+ if (aw2)
+ aw2->winToBePaintedBeforeThis = NULL;
+ }
+ aw->winThisIsPaintedBefore = NULL;
+ aw->moreToBePaintedPrev = NULL;
+ aw->moreToBePaintedNext = NULL;
+ aw->isDodgeSubject = FALSE;
+ aw->skipPostPrepareScreen = FALSE;
+}
+
void postAnimationCleanup(CompWindow * w, Bool resetAnimation)
{
ANIM_WINDOW(w);
@@ -1115,16 +1131,54 @@ void postAnimationCleanup(CompWindow * w, Bool resetAnimation)
aw->model->magicLampWaves = 0;
}
}
- if (aw->winThisIsPaintedBefore && !aw->winThisIsPaintedBefore->destroyed)
+
+ Bool thereIsUnfinishedChainElem = FALSE;
+
+ // Look for still playing windows in parent-child chain
+ CompWindow *wCur = aw->moreToBePaintedNext;
+ while (wCur)
{
- AnimWindow *aw2 = GET_ANIM_WINDOW(aw->winThisIsPaintedBefore, as);
- if (aw2)
+ AnimWindow *awCur = GET_ANIM_WINDOW(wCur, as);
+
+ if (awCur->animRemainingTime > 0)
{
- aw2->winToBePaintedBeforeThis = NULL;
+ thereIsUnfinishedChainElem = TRUE;
+ break;
+ }
+ wCur = awCur->moreToBePaintedNext;
+ }
+ if (!thereIsUnfinishedChainElem)
+ {
+ wCur = aw->moreToBePaintedPrev;
+ while (wCur)
+ {
+ AnimWindow *awCur = GET_ANIM_WINDOW(wCur, as);
+
+ if (awCur->animRemainingTime > 0)
+ {
+ thereIsUnfinishedChainElem = TRUE;
+ break;
+ }
+ wCur = awCur->moreToBePaintedPrev;
+ }
+ }
+ if (!thereIsUnfinishedChainElem)
+ {
+ // Finish off all windows in parent-child chain
+ CompWindow *wCur = aw->moreToBePaintedNext;
+ while (wCur)
+ {
+ AnimWindow *awCur = GET_ANIM_WINDOW(wCur, as);
+ wCur = awCur->moreToBePaintedNext;
+ cleanUpParentChildChainItem(as, awCur);
+ }
+ wCur = w;
+ while (wCur)
+ {
+ AnimWindow *awCur = GET_ANIM_WINDOW(wCur, as);
+ wCur = awCur->moreToBePaintedPrev;
+ cleanUpParentChildChainItem(as, awCur);
}
- aw->winThisIsPaintedBefore = NULL;
- aw->moreToBePaintedPrev = NULL;
- aw->moreToBePaintedNext = NULL;
}
aw->state = aw->newState;
@@ -1155,7 +1209,12 @@ void postAnimationCleanup(CompWindow * w, Bool resetAnimation)
// Reset dodge parameters
aw->dodgeMaxAmount = 0;
- aw->isDodgeSubject = FALSE;
+ if (!(aw->moreToBePaintedPrev ||
+ aw->moreToBePaintedNext))
+ {
+ aw->isDodgeSubject = FALSE;
+ aw->skipPostPrepareScreen = FALSE;
+ }
if (aw->restackInfo)
{
@@ -1185,6 +1244,17 @@ isWinVisible(CompWindow *w)
(w->attrib.map_state != IsViewable)));
}
+static inline void
+getHostedOnWin (AnimScreen *as,
+ CompWindow *w,
+ CompWindow *wHost)
+{
+ ANIM_WINDOW(w);
+ AnimWindow *awHost = GET_ANIM_WINDOW(wHost, as);
+ awHost->winToBePaintedBeforeThis = w;
+ aw->winThisIsPaintedBefore = wHost;
+}
+
static void
initiateFocusAnimation(CompWindow *w)
{
@@ -1204,21 +1274,6 @@ initiateFocusAnimation(CompWindow *w)
return;
}
- CompWindow *wStart = NULL;
- CompWindow *wEnd = NULL;
- CompWindow *wOldAbove = NULL;
-
- RestackInfo *restackInfo = aw->restackInfo;
- Bool raised = TRUE;
-
- if (restackInfo)
- {
- wStart = restackInfo->wStart;
- wEnd = restackInfo->wEnd;
- wOldAbove = restackInfo->wOldAbove;
- raised = restackInfo->raised;
- }
-
if (matchEval (&as->opt[ANIM_SCREEN_OPTION_FOCUS_MATCH].value.match, w) &&
as->focusEffect &&
// On unminimization, focus event is fired first.
@@ -1228,6 +1283,21 @@ initiateFocusAnimation(CompWindow *w)
aw->curWindowEvent != WindowEventMinimize &&
animEnsureModel(w, WindowEventFocus, as->focusEffect))
{
+ CompWindow *wStart = NULL;
+ CompWindow *wEnd = NULL;
+ CompWindow *wOldAbove = NULL;
+
+ RestackInfo *restackInfo = aw->restackInfo;
+ Bool raised = TRUE;
+
+ if (restackInfo)
+ {
+ wStart = restackInfo->wStart;
+ wEnd = restackInfo->wEnd;
+ wOldAbove = restackInfo->wOldAbove;
+ raised = restackInfo->raised;
+ }
+
if (as->focusEffect == AnimEffectFocusFade ||
as->focusEffect == AnimEffectDodge)
{
@@ -1273,7 +1343,8 @@ initiateFocusAnimation(CompWindow *w)
!XEmptyRegion(thisAndSubjectIntersection))
{
AnimWindow *adw = GET_ANIM_WINDOW(dw, as);
- if (adw->curAnimEffect == AnimEffectNone &&
+ if ((adw->curAnimEffect == AnimEffectNone ||
+ (adw->curAnimEffect == AnimEffectDodge)) &&
dw->id != w->id) // don't let the subject dodge itself
{
// Mark this window for dodge
@@ -1287,6 +1358,15 @@ initiateFocusAnimation(CompWindow *w)
if (XEmptyRegion(fadeRegion))
return; // empty -> won't be drawn
+ if ((as->focusEffect == AnimEffectFocusFade ||
+ as->focusEffect == AnimEffectDodge) && wOldAbove)
+ {
+ // Store this window in the next window
+ // so that this is drawn before that,
+ // i.e. in its old place
+ getHostedOnWin(as, w, wOldAbove);
+ }
+
float dodgeMaxStartProgress =
numDodgingWins *
as->opt[ANIM_SCREEN_OPTION_DODGE_GAP_RATIO].value.f *
@@ -1377,7 +1457,7 @@ initiateFocusAnimation(CompWindow *w)
int i;
for (i = 0; i < 4; i++)
- dodgeAmount[i] = DODGE_AMOUNT(i, w, dw);
+ dodgeAmount[i] = DODGE_AMOUNT(w, dw, i);
int amountMin = abs(dodgeAmount[0]);
int iMin = 0;
@@ -1398,6 +1478,8 @@ initiateFocusAnimation(CompWindow *w)
// Reset back to 0 for the next dodge calculation
adw->dodgeOrder = 0;
}
+ if (aw->isDodgeSubject)
+ aw->dodgeMaxAmount = 0;
// if subject is being lowered,
// point chain-start to the topmost doding window
@@ -1433,22 +1515,6 @@ initiateFocusAnimation(CompWindow *w)
aw->lastKnownCoords.x = w->attrib.x;
aw->lastKnownCoords.y = w->attrib.y;
- if ((as->focusEffect == AnimEffectFocusFade) && wOldAbove)
- {
- // (for focus fade effect)
- // Store this window in the next window
- // so that this is drawn before that,
- // i.e. in its old place
-
- // (for dodge effect)
- // It will again start being drawn in its old place
- // But will gradually move backward/forward
- // to be positioned behind / in front of dodging windows
- AnimWindow *awOldAbove = GET_ANIM_WINDOW(wOldAbove, as);
- awOldAbove->winToBePaintedBeforeThis = w;
- aw->winThisIsPaintedBefore = wOldAbove;
- }
-
damageScreen(w->screen);
}
}
@@ -1457,13 +1523,17 @@ initiateFocusAnimation(CompWindow *w)
static Bool
relevantForFadeFocus(CompWindow *nw)
{
- if (!(nw->type &
- (CompWindowTypeDockMask |
- CompWindowTypeNormalMask |
- CompWindowTypeSplashMask |
- CompWindowTypeDialogMask |
- CompWindowTypeModalDialogMask)))
+ ANIM_SCREEN(nw->screen);
+
+ if (!((nw->type &
+ // these two are to be used as "host" windows
+ // to host the painting of windows being focused
+ // at a stacking order lower than them
+ (CompWindowTypeDockMask | CompWindowTypeSplashMask)) ||
+ matchEval(&as->opt[ANIM_SCREEN_OPTION_FOCUS_MATCH].value.match, nw)))
+ {
return FALSE;
+ }
return isWinVisible(nw);
}
@@ -1508,6 +1578,29 @@ static void animPreparePaintScreen(CompScreen * s, int msSinceLastPaint)
initiateFocusAnimation(w);
}
}
+ if (as->focusEffect == AnimEffectDodge)
+ {
+ for (w = s->reverseWindows; w; w = w->prev)
+ {
+ ANIM_WINDOW(w);
+
+ if (!aw->isDodgeSubject)
+ continue;
+ Bool dodgersAreOnlySubjects = TRUE;
+ CompWindow *dw;
+ AnimWindow *adw;
+ for (dw = aw->dodgeChainStart; dw; dw = adw->dodgeChainNext)
+ {
+ adw = GET_ANIM_WINDOW(dw, as);
+ if (!adw)
+ break;
+ if (!adw->isDodgeSubject)
+ dodgersAreOnlySubjects = FALSE;
+ }
+ if (dodgersAreOnlySubjects)
+ aw->skipPostPrepareScreen = TRUE;
+ }
+ }
}
}
@@ -1601,8 +1694,7 @@ static void animPreparePaintScreen(CompScreen * s, int msSinceLastPaint)
// Call fx step func.
if (animEffectProperties[aw->curAnimEffect].animStepFunc)
{
- animEffectProperties[aw->
- curAnimEffect].
+ animEffectProperties[aw->curAnimEffect].
animStepFunc(s, w, msSinceLastPaint);
}
if (aw->animRemainingTime <= 0)
@@ -2218,8 +2310,6 @@ animDrawWindowTexture(CompWindow * w, CompTexture * texture,
if (aw->animRemainingTime > 0) // if animation in progress, store texture
{
- //printf("%X animDrawWindowTexture, texture: %X\n",
- // (unsigned)w->id, (unsigned)texture);
aw->curTexture = texture;
aw->curPaintAttrib = *attrib;
}
@@ -2302,7 +2392,6 @@ animPaintWindow(CompWindow * w,
if (aw->winToBePaintedBeforeThis)
{
CompWindow *w2 = aw->winToBePaintedBeforeThis;
-
// ========= Paint w2 on host w =========
// Go to the bottommost window in this "focus chain"
@@ -2326,6 +2415,10 @@ animPaintWindow(CompWindow * w,
if (!aw2)
continue;
+ if (aw2->animTotalTime < 1e-4)
+ {
+ aw2->drawnOnHostSkip = TRUE;
+ }
w2->indexCount = 0;
WindowPaintAttrib wAttrib2 = w2->paint;
@@ -2347,7 +2440,11 @@ animPaintWindow(CompWindow * w,
WRAP(as, w2->screen, paintWindow, animPaintWindow);
}
}
-
+ if (aw->drawnOnHostSkip)
+ {
+ aw->drawnOnHostSkip = FALSE;
+ return FALSE;
+ }
if (aw->animRemainingTime > 0)
{
if (aw->curAnimEffect == AnimEffectDodge &&
@@ -3008,11 +3105,6 @@ static void animHandleEvent(CompDisplay * d, XEvent * event)
CompWindowStateSkipTaskbarMask))
continue;
- // skip if shaded
- AnimWindow *awi = GET_ANIM_WINDOW(wi, as);
- if (awi && awi->nowShaded)
- continue;
-
if (clientListStacking[i] !=
as->lastClientListStacking[i])
{
@@ -3902,7 +3994,7 @@ static Bool animInit(CompPlugin * p)
animScreenOptionInfo,
ANIM_SCREEN_OPTION_NUM))
return FALSE;
-
+
displayPrivateIndex = allocateDisplayPrivateIndex();
if (displayPrivateIndex < 0)
{
Modified: fusion/plugins/animation/dodge.c
===================================================================
--- fusion/plugins/animation/dodge.c
+++ fusion/plugins/animation/dodge.c
@@ -3,6 +3,63 @@
// ===================== Effect: Dodge =========================
void
+fxDodgeProcessSubject (CompWindow *wCur, Region wRegion, Region dodgeRegion)
+{
+ XRectangle rect;
+ rect.x = WIN_X(wCur);
+ rect.y = WIN_Y(wCur);
+ rect.width = WIN_W(wCur);
+ rect.height = WIN_H(wCur);
+ Region wCurRegion = XCreateRegion();
+ Region intersectionRegion = XCreateRegion();
+ XUnionRectWithRegion(&rect, &emptyRegion, wCurRegion);
+ XIntersectRegion(wRegion, wCurRegion,
+ intersectionRegion);
+ if (!XEmptyRegion(intersectionRegion))
+ XUnionRegion(dodgeRegion, wCurRegion, dodgeRegion);
+}
+
+void
+fxDodgeFindDodgeBox (CompWindow *w, XRectangle *dodgeBox)
+{
+ ANIM_SCREEN(w->screen);
+ ANIM_WINDOW(w);
+
+ // Find the box to be dodged, it can contain multiple windows
+ // when there are dialog/utility windows of subject windows
+ // (stacked in the moreToBePaintedNext chain)
+ // Then this would be a bounding box of the subject windows
+ // intersecting with dodger.
+ Region wRegion = XCreateRegion();
+ Region dodgeRegion = XCreateRegion();
+
+ XRectangle rect;
+ rect.x = WIN_X(w);
+ rect.y = WIN_Y(w);
+ rect.width = WIN_W(w);
+ rect.height = WIN_H(w);
+ XUnionRectWithRegion(&rect, &emptyRegion, wRegion);
+
+ AnimWindow *awCur;
+ CompWindow *wCur = aw->dodgeSubjectWin;
+ for (; wCur; wCur = awCur->moreToBePaintedNext)
+ {
+ fxDodgeProcessSubject(wCur, wRegion, dodgeRegion);
+ awCur = GET_ANIM_WINDOW(wCur, as);
+ }
+
+ AnimWindow *awSubj = GET_ANIM_WINDOW(aw->dodgeSubjectWin, as);
+ wCur = awSubj->moreToBePaintedPrev;
+ for (; wCur; wCur = awCur->moreToBePaintedPrev)
+ {
+ fxDodgeProcessSubject(wCur, wRegion, dodgeRegion);
+ awCur = GET_ANIM_WINDOW(wCur, as);
+ }
+
+ XClipBox(dodgeRegion, dodgeBox);
+}
+
+void
fxDodgeAnimStep (CompScreen * s, CompWindow * w, float time)
{
defaultAnimStep(s, w, time);
@@ -20,9 +77,12 @@ fxDodgeAnimStep (CompScreen * s, CompWindow * w, float time)
if (!aw->isDodgeSubject)
{
+ XRectangle dodgeBox;
+ fxDodgeFindDodgeBox (w, &dodgeBox);
+
// Update dodge amount if subject window is moved during dodge
int newDodgeAmount =
- DODGE_AMOUNT(aw->dodgeDirection, aw->dodgeSubjectWin, w);
+ DODGE_AMOUNT_BOX(dodgeBox, w, aw->dodgeDirection);
// Only update if amount got larger
if (abs(newDodgeAmount) > abs(aw->dodgeMaxAmount))
@@ -36,6 +96,8 @@ fxDodgeUpdateWindowTransform
{
ANIM_WINDOW(w);
+ if (aw->isDodgeSubject)
+ return;
float amount = sin(M_PI * aw->transformProgress) * aw->dodgeMaxAmount;
if (aw->dodgeDirection > 1) // if x axis
@@ -57,6 +119,9 @@ fxDodgePostPreparePaintScreen(CompScreen *s, CompWindow *w)
if (!aw->restackInfo)
return;
+ if (aw->skipPostPrepareScreen)
+ return;
+
// Dodgy window
CompWindow *dw;
AnimWindow *adw = NULL;
@@ -65,7 +130,6 @@ fxDodgePostPreparePaintScreen(CompScreen *s, CompWindow *w)
adw = GET_ANIM_WINDOW(dw, as);
if (!adw)
break;
-
// find the first dodging window that hasn't yet
// reached 50% progress yet. The subject window should be
// painted right behind that one (or right in front of it if
@@ -80,9 +144,8 @@ fxDodgePostPreparePaintScreen(CompScreen *s, CompWindow *w)
{
if (aw->winThisIsPaintedBefore)
{
- awOldHost = GET_ANIM_WINDOW(aw->winThisIsPaintedBefore, as);
-
// Clear old host
+ awOldHost = GET_ANIM_WINDOW(aw->winThisIsPaintedBefore, as);
awOldHost->winToBePaintedBeforeThis = NULL;
}
if (dw) // if a dodgy win. is still at <0.5 progress
@@ -92,7 +155,13 @@ fxDodgePostPreparePaintScreen(CompScreen *s, CompWindow *w)
}
// otherwise all dodgy win.s have passed 0.5 progress
- aw->winThisIsPaintedBefore = dw; // dw can be null, which is ok
+ CompWindow *wCur = w;
+ while (wCur)
+ {
+ AnimWindow *awCur = GET_ANIM_WINDOW(wCur, as);
+ awCur->winThisIsPaintedBefore = dw; // dw can be null, which is ok
+ wCur = awCur->moreToBePaintedNext;
+ }
}
else if (!aw->restackInfo->raised)
{
@@ -136,4 +205,3 @@ fxDodgePostPreparePaintScreen(CompScreen *s, CompWindow *w)
}
}
-
More information about the commits
mailing list