~ubuntu-branches/ubuntu/trusty/compiz/trusty

« back to all changes in this revision

Viewing changes to plugins/freewins/src/paint.cpp

  • Committer: Package Import Robot
  • Author(s): Ubuntu daily release
  • Date: 2013-08-22 06:58:07 UTC
  • mto: This revision was merged to the branch mainline in revision 3352.
  • Revision ID: package-import@ubuntu.com-20130822065807-17nlzez0d30y09so
Tags: upstream-0.9.10+13.10.20130822
ImportĀ upstreamĀ versionĀ 0.9.10+13.10.20130822

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * Compiz Fusion Freewins plugin
 
3
 *
 
4
 * paint.cpp
 
5
 *
 
6
 * Copyright (C) 2007  Rodolfo Granata <warlock.cc@gmail.com>
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or
 
9
 * modify it under the terms of the GNU General Public License
 
10
 * as published by the Free Software Foundation; either version 2
 
11
 * of the License, or (at your option) any later version.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 * GNU General Public License for more details.
 
17
 *
 
18
 * Author(s):
 
19
 * Rodolfo Granata <warlock.cc@gmail.com>
 
20
 * Sam Spilsbury <smspillaz@gmail.com>
 
21
 *
 
22
 * Button binding support and Reset added by:
 
23
 * enigma_0Z <enigma.0ZA@gmail.com>
 
24
 *
 
25
 * Most of the input handling here is based on
 
26
 * the shelf plugin by
 
27
 *        : Kristian LyngstĆøl <kristian@bohemians.org>
 
28
 *        : Danny Baumann <maniac@opencompositing.org>
 
29
 *
 
30
 * Description:
 
31
 *
 
32
 * This plugin allows you to freely transform the texture of a window,
 
33
 * whether that be rotation or scaling to make better use of screen space
 
34
 * or just as a toy.
 
35
 *
 
36
 * Todo:
 
37
 *  - Fully implement an input redirection system by
 
38
 *    finding an inverse matrix, multiplying by it,
 
39
 *    translating to the actual window co-ords and
 
40
 *    XSendEvent() the co-ords to the actual window.
 
41
 *  - Code could be cleaner
 
42
 *  - Add timestep and speed options to animation
 
43
 *  - Add window hover-over info via paintOutput : i.e
 
44
 *    - Resize borders
 
45
 *    - 'Reset' Button
 
46
 *    - 'Scale' Button
 
47
 *    - 'Rotate' Button
 
48
 */
 
49
 
 
50
#include "freewins.h"
 
51
 
 
52
 
 
53
/* ------ Window and Output Painting ------------------------------------*/
 
54
 
 
55
/* Damage util function */
 
56
 
 
57
void
 
58
FWWindow::damageArea ()
 
59
{
 
60
    CompositeScreen::get (screen)->damageRegion (mOutputRect);
 
61
}
 
62
 
 
63
/* Animation Prep */
 
64
void
 
65
FWScreen::preparePaint (int           ms)
 
66
{
 
67
    /* FIXME: should only loop over all windows if at least one animation is running */
 
68
    foreach (CompWindow *w, screen->windows ())
 
69
    {
 
70
        FREEWINS_WINDOW (w);
 
71
        float speed = optionGetSpeed ();
 
72
        fww->mAnimate.steps = ((float) ms / ((20.1 - speed) * 100));
 
73
 
 
74
        if (fww->mAnimate.steps < 0.005)
 
75
            fww->mAnimate.steps = 0.005;
 
76
 
 
77
        /* Animation. We calculate how much increment
 
78
         * a window must rotate / scale per paint by
 
79
         * using the set destination attributes minus
 
80
         * the old attributes divided by the time
 
81
         * remaining.
 
82
         */
 
83
 
 
84
        /* Don't animate if the window is saved */
 
85
        fww->mTransform.angX += (float) fww->mAnimate.steps * (fww->mAnimate.destAngX - fww->mTransform.angX) * speed;
 
86
        fww->mTransform.angY += (float) fww->mAnimate.steps * (fww->mAnimate.destAngY - fww->mTransform.angY) * speed;
 
87
        fww->mTransform.angZ += (float) fww->mAnimate.steps * (fww->mAnimate.destAngZ - fww->mTransform.angZ) * speed;
 
88
 
 
89
        fww->mTransform.scaleX += (float) fww->mAnimate.steps * (fww->mAnimate.destScaleX - fww->mTransform.scaleX) * speed;
 
90
        fww->mTransform.scaleY += (float) fww->mAnimate.steps * (fww->mAnimate.destScaleY - fww->mTransform.scaleY) * speed;
 
91
 
 
92
        if (((fww->mTransform.angX >= fww->mAnimate.destAngX - 0.05 &&
 
93
              fww->mTransform.angX <= fww->mAnimate.destAngX + 0.05 ) &&
 
94
             (fww->mTransform.angY >= fww->mAnimate.destAngY - 0.05 &&
 
95
              fww->mTransform.angY <= fww->mAnimate.destAngY + 0.05 ) &&
 
96
             (fww->mTransform.angZ >= fww->mAnimate.destAngZ - 0.05 &&
 
97
              fww->mTransform.angZ <= fww->mAnimate.destAngZ + 0.05 ) &&
 
98
             (fww->mTransform.scaleX >= fww->mAnimate.destScaleX - 0.00005 &&
 
99
              fww->mTransform.scaleX <= fww->mAnimate.destScaleX + 0.00005 ) &&
 
100
             (fww->mTransform.scaleY >= fww->mAnimate.destScaleY - 0.00005 &&
 
101
              fww->mTransform.scaleY <= fww->mAnimate.destScaleY + 0.00005 )))
 
102
        {
 
103
            fww->mResetting = FALSE;
 
104
 
 
105
            fww->mTransform.angX = fww->mAnimate.destAngX;
 
106
            fww->mTransform.angY = fww->mAnimate.destAngY;
 
107
            fww->mTransform.angZ = fww->mAnimate.destAngZ;
 
108
            fww->mTransform.scaleX = fww->mAnimate.destScaleX;
 
109
            fww->mTransform.scaleY = fww->mAnimate.destScaleY;
 
110
 
 
111
            fww->mTransform.unsnapAngX = fww->mAnimate.destAngX;
 
112
            fww->mTransform.unsnapAngY = fww->mAnimate.destAngY;
 
113
            fww->mTransform.unsnapAngZ = fww->mAnimate.destAngZ;
 
114
            fww->mTransform.unsnapScaleX = fww->mAnimate.destScaleX;
 
115
            fww->mTransform.unsnapScaleY = fww->mAnimate.destScaleX;
 
116
        }
 
117
        //else
 
118
        //    fww->damageArea ();
 
119
    }
 
120
 
 
121
    cScreen->preparePaint (ms);
 
122
}
 
123
 
 
124
/* Paint the window rotated or scaled */
 
125
bool
 
126
FWWindow::glPaint (const GLWindowPaintAttrib &attrib,
 
127
                   const GLMatrix            &transform,
 
128
                   const CompRegion          &region,
 
129
                   unsigned int              mask)
 
130
{
 
131
 
 
132
    GLMatrix wTransform (transform);
 
133
    int currentCull, invertCull;
 
134
    glGetIntegerv (GL_CULL_FACE_MODE, &currentCull);
 
135
    invertCull = (currentCull == GL_BACK) ? GL_FRONT : GL_BACK;
 
136
 
 
137
    bool status;
 
138
 
 
139
    FREEWINS_SCREEN (screen);
 
140
 
 
141
    /* Has something happened? */
 
142
    
 
143
    /* Check to see if we are painting on a transformed screen */
 
144
    /* Enable this code when we can animate between the two states */
 
145
 
 
146
    if ((mTransform.angX != 0.0 ||
 
147
         mTransform.angY != 0.0 ||
 
148
         mTransform.angZ != 0.0 ||
 
149
         mTransform.scaleX != 1.0 ||
 
150
         mTransform.scaleY != 1.0 ||
 
151
         mOldWinX != WIN_REAL_X (window) ||
 
152
         mOldWinY != WIN_REAL_Y (window)) && fws->optionGetShapeWindowTypes ().evaluate (window))
 
153
    {
 
154
        mOldWinX = WIN_REAL_X (window);
 
155
        mOldWinY = WIN_REAL_Y (window);
 
156
 
 
157
        /* Figure out where our 'origin' is, don't allow the origin to
 
158
         * be where we clicked if the window is not grabbed, etc
 
159
         */
 
160
 
 
161
        /* Here we duplicate some of the work the openGL does
 
162
         * but for different reasons. We have access to the
 
163
         * window's transformation matrix, so we will create
 
164
         * our own matrix and apply the same transformations
 
165
         * to it. From there, we create vectors for each point
 
166
         * that we wish to track and multiply them by this
 
167
         * matrix to give us the rotated / scaled co-ordinates.
 
168
         * From there, we project these co-ordinates onto the flat
 
169
         * screen that we have using the OGL viewport, projection
 
170
         * matrix and model matrix. Projection gives us three
 
171
         * co-ordinates, but we ignore Z and just use X and Y
 
172
         * to store in a surrounding rectangle. We can use this
 
173
         * surrounding rectangle to make things like shaping and
 
174
         * damage a lot more accurate than they used to be.
 
175
         */
 
176
 
 
177
        calculateOutputRect ();
 
178
 
 
179
        /* Prepare for transformation by
 
180
         * doing any necessary adjustments */
 
181
        float autoScaleX = 1.0f;
 
182
        float autoScaleY = 1.0f;
 
183
 
 
184
        if (fws->optionGetAutoZoom ())
 
185
        {
 
186
            float apparantWidth = mOutputRect.width ();
 
187
            float apparantHeight = mOutputRect.height ();
 
188
 
 
189
            autoScaleX = (float) WIN_OUTPUT_W (window) / (float) apparantWidth;
 
190
            autoScaleY = (float) WIN_OUTPUT_H (window) / (float) apparantHeight;
 
191
 
 
192
            if (autoScaleX >= 1.0f)
 
193
                autoScaleX = 1.0f;
 
194
            if (autoScaleY >= 1.0f)
 
195
                autoScaleY = 1.0f;
 
196
 
 
197
            autoScaleX = autoScaleY = (autoScaleX + autoScaleY) / 2;
 
198
 
 
199
            /* Because we modified the scale after calculating
 
200
             * the output rect, we need to recalculate again */
 
201
            calculateOutputRect ();
 
202
 
 
203
        }
 
204
        /*
 
205
        float scaleX = autoScaleX - (1 - mTransform.scaleX);
 
206
        float scaleY = autoScaleY - (1 - mTransform.scaleY);
 
207
        */
 
208
 
 
209
        /* Actually Transform the window */
 
210
        mask |= PAINT_WINDOW_TRANSFORMED_MASK;
 
211
 
 
212
        /* Adjust the window in the matrix to prepare for transformation */
 
213
        if (mGrab != grabRotate && mGrab != grabScale)
 
214
        {
 
215
 
 
216
            calculateInputOrigin (WIN_REAL_X (window) + WIN_REAL_W (window) / 2.0f,
 
217
                                  WIN_REAL_Y (window) + WIN_REAL_H (window) / 2.0f);
 
218
            calculateOutputOrigin (WIN_OUTPUT_X (window) + WIN_OUTPUT_W (window) / 2.0f,
 
219
                                   WIN_OUTPUT_Y (window) + WIN_OUTPUT_H (window) / 2.0f);
 
220
        }
 
221
 
 
222
        float adjustX = 0.0f;
 
223
        float adjustY = 0.0f;
 
224
        fws->modifyMatrix (wTransform,
 
225
                           mTransform.angX,
 
226
                           mTransform.angY,
 
227
                           mTransform.angZ,
 
228
                           mIMidX, mIMidY , 0.0f,
 
229
                           mTransform.scaleX,
 
230
                           mTransform.scaleY,
 
231
                           1.0f, adjustX, adjustY, TRUE);
 
232
 
 
233
        /* Create rects for input after we've dealt with output */
 
234
        calculateInputRect ();
 
235
 
 
236
        /* Determine if the window is inverted */
 
237
        Bool xInvert = FALSE;
 
238
        Bool yInvert = FALSE;
 
239
 
 
240
        Bool needsInvert = FALSE;
 
241
        float renX = fabs (fmodf (mTransform.angX, 360.0f));
 
242
        float renY = fabs (fmodf (mTransform.angY, 360.0f));
 
243
 
 
244
        if (90 < renX && renX < 270)
 
245
            xInvert = TRUE;
 
246
 
 
247
        if (90 < renY && renY < 270)
 
248
            yInvert = TRUE;
 
249
 
 
250
        if ((xInvert || yInvert) && !(xInvert && yInvert))
 
251
            needsInvert = TRUE;
 
252
 
 
253
        if (needsInvert)
 
254
            glCullFace (invertCull);
 
255
 
 
256
        status = gWindow->glPaint (attrib, wTransform, region, mask);
 
257
 
 
258
        if (needsInvert)
 
259
            glCullFace (currentCull);
 
260
 
 
261
    }
 
262
    else
 
263
    {
 
264
        status = gWindow->glPaint (attrib, wTransform, region, mask);
 
265
    }
 
266
 
 
267
    // Check if there are rotated windows
 
268
    if (!((mTransform.angX >= 0.0f - 0.05 &&
 
269
           mTransform.angX <= 0.0f + 0.05 ) &&
 
270
          (mTransform.angY >= 0.0f - 0.05 &&
 
271
           mTransform.angY <= 0.0f + 0.05 ) &&
 
272
          (mTransform.angZ >= 0.0f - 0.05 &&
 
273
           mTransform.angZ <= 0.0f + 0.05 ) &&
 
274
          (mTransform.scaleX >= 1.0f - 0.00005 &&
 
275
           mTransform.scaleX <= 1.0f + 0.00005 ) &&
 
276
          (mTransform.scaleY >= 1.0f - 0.00005 &&
 
277
           mTransform.scaleY <= 1.0f + 0.00005 )) && !mTransformed)
 
278
        mTransformed = TRUE;
 
279
    else if (mTransformed)
 
280
        mTransformed = FALSE;
 
281
 
 
282
    /* There is still animation to be done */
 
283
    if (!(((mTransform.angX >= mAnimate.destAngX - 0.05 &&
 
284
            mTransform.angX <= mAnimate.destAngX + 0.05 ) &&
 
285
           (mTransform.angY >= mAnimate.destAngY - 0.05 &&
 
286
            mTransform.angY <= mAnimate.destAngY + 0.05 ) &&
 
287
           (mTransform.angZ >= mAnimate.destAngZ - 0.05 &&
 
288
            mTransform.angZ <= mAnimate.destAngZ + 0.05 ) &&
 
289
           (mTransform.scaleX >= mAnimate.destScaleX - 0.00005 &&
 
290
            mTransform.scaleX <= mAnimate.destScaleX + 0.00005 ) &&
 
291
           (mTransform.scaleY >= mAnimate.destScaleY - 0.00005 &&
 
292
            mTransform.scaleY <= mAnimate.destScaleY + 0.00005 ))))
 
293
    {
 
294
        damageArea ();
 
295
        mIsAnimating = TRUE;
 
296
    }
 
297
    else if (mIsAnimating) /* We're done animating now, and we were animating */
 
298
    {
 
299
        if (handleWindowInputInfo ())
 
300
            adjustIPW ();
 
301
        mIsAnimating = FALSE;
 
302
    }
 
303
 
 
304
    return status;
 
305
}
 
306
 
 
307
/* Paint the window axis help onto the screen */
 
308
bool
 
309
FWScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
 
310
                         const GLMatrix            &transform,
 
311
                         const CompRegion          &region,
 
312
                         CompOutput                *output,
 
313
                         unsigned int              mask)
 
314
{
 
315
    GLMatrix zTransform (transform);
 
316
 
 
317
    if (!mTransformedWindows.empty ())
 
318
        mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
 
319
 
 
320
    bool status = gScreen->glPaintOutput (attrib, transform, region, output, mask);
 
321
 
 
322
    if (mAxisHelp && mHoverWindow)
 
323
    {
 
324
        int j;
 
325
        float x = WIN_REAL_X(mHoverWindow) + WIN_REAL_W(mHoverWindow)/2.0;
 
326
        float y = WIN_REAL_Y(mHoverWindow) + WIN_REAL_H(mHoverWindow)/2.0;
 
327
 
 
328
        FREEWINS_WINDOW (mHoverWindow);
 
329
 
 
330
        float zRad = fww->mRadius * (optionGetTdPercent () / 100);
 
331
 
 
332
        bool wasCulled = glIsEnabled (GL_CULL_FACE);
 
333
 
 
334
        zTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
 
335
 
 
336
        glPushMatrix ();
 
337
        glLoadMatrixf (zTransform.getMatrix ());
 
338
 
 
339
        if (wasCulled)
 
340
            glDisable (GL_CULL_FACE);
 
341
 
 
342
        if (optionGetShowCircle () && optionGetRotationAxis () == RotationAxisAlwaysCentre)
 
343
        {
 
344
            glColor4usv  (optionGetCircleColor ());
 
345
            glEnable (GL_BLEND);
 
346
 
 
347
            glBegin (GL_POLYGON);
 
348
            for (j = 0; j < 360; j += 10)
 
349
                glVertex3f ( x + zRad * cos(D2R(j)), y + zRad * sin(D2R(j)), 0.0 );
 
350
            glEnd ();
 
351
 
 
352
            glDisable (GL_BLEND);
 
353
            glColor4usv  (optionGetLineColor ());
 
354
            glLineWidth (3.0);
 
355
 
 
356
            glBegin (GL_LINE_LOOP);
 
357
            for (j = 360; j >= 0; j -= 10)
 
358
                glVertex3f ( x + zRad * cos(D2R(j)), y + zRad * sin(D2R(j)), 0.0 );
 
359
            glEnd ();
 
360
 
 
361
            glBegin (GL_LINE_LOOP);
 
362
            for (j = 360; j >= 0; j -= 10)
 
363
                glVertex3f( x + fww->mRadius * cos(D2R(j)), y + fww->mRadius * sin(D2R(j)), 0.0 );
 
364
            glEnd ();
 
365
 
 
366
        }
 
367
 
 
368
        /* Draw the 'gizmo' */
 
369
        if (optionGetShowGizmo ())
 
370
        {
 
371
            glPushMatrix ();
 
372
 
 
373
            glTranslatef (x, y, 0.0);
 
374
 
 
375
            glScalef (zRad, zRad, zRad / (float)screen->width ());
 
376
 
 
377
            glRotatef (fww->mTransform.angX, 1.0f, 0.0f, 0.0f);
 
378
            glRotatef (fww->mTransform.angY, 0.0f, 1.0f, 0.0f);
 
379
            glRotatef (fww->mTransform.angZ, 0.0f, 0.0f, 1.0f);
 
380
 
 
381
            glLineWidth (4.0f);
 
382
 
 
383
            for (int i = 0; i < 3; i++)
 
384
            {
 
385
                glPushMatrix ();
 
386
                glColor4f (1.0 * (i==0), 1.0 * (i==1), 1.0 * (i==2), 1.0);
 
387
                glRotatef (90.0, 1.0 * (i==0), 1.0 * (i==1), 1.0 * (i==2));
 
388
 
 
389
                glBegin (GL_LINE_LOOP);
 
390
                for (j=360; j>=0; j -= 10)
 
391
                    glVertex3f ( cos (D2R (j)), sin (D2R (j)), 0.0 );
 
392
                glEnd ();
 
393
                glPopMatrix ();
 
394
            }
 
395
 
 
396
            glPopMatrix ();
 
397
            glColor4usv (defaultColor);
 
398
        }
 
399
 
 
400
        /* Draw the bounding box */
 
401
        if (optionGetShowRegion ())
 
402
        {
 
403
            glDisableClientState (GL_TEXTURE_COORD_ARRAY);
 
404
            glEnable (GL_BLEND);
 
405
            glColor4us (0x2fff, 0x2fff, 0x4fff, 0x4fff);
 
406
            glRecti (fww->mInputRect.x1 (), fww->mInputRect.y1 (), fww->mInputRect.x2 (), fww->mInputRect.y2 ());
 
407
            glColor4us (0x2fff, 0x2fff, 0x4fff, 0x9fff);
 
408
            glBegin (GL_LINE_LOOP);
 
409
            glVertex2i (fww->mInputRect.x1 (), fww->mInputRect.y1 ());
 
410
            glVertex2i (fww->mInputRect.x2 (), fww->mInputRect.y1 ());
 
411
            glVertex2i (fww->mInputRect.x1 (), fww->mInputRect.y2 ());
 
412
            glVertex2i (fww->mInputRect.x2 (), fww->mInputRect.y2 ());
 
413
            glEnd ();
 
414
            glColor4usv (defaultColor);
 
415
            glDisable (GL_BLEND);
 
416
            glEnableClientState (GL_TEXTURE_COORD_ARRAY);
 
417
        }
 
418
 
 
419
        if (optionGetShowCross ())
 
420
        {
 
421
 
 
422
            glColor4usv  (optionGetCrossLineColor ());
 
423
            glBegin(GL_LINES);
 
424
            glVertex3f(x, y - (WIN_REAL_H (mHoverWindow) / 2), 0.0f);
 
425
            glVertex3f(x, y + (WIN_REAL_H (mHoverWindow) / 2), 0.0f);
 
426
            glEnd ();
 
427
 
 
428
            glBegin(GL_LINES);
 
429
            glVertex3f(x - (WIN_REAL_W (mHoverWindow) / 2), y, 0.0f);
 
430
            glVertex3f(x + (WIN_REAL_W (mHoverWindow) / 2), y, 0.0f);
 
431
            glEnd ();
 
432
 
 
433
            /* Move to our first corner (TopLeft)  */
 
434
            if (fww->mInput)
 
435
            {
 
436
                glBegin(GL_LINES);
 
437
                glVertex3f(fww->mOutput.shapex1, fww->mOutput.shapey1, 0.0f);
 
438
                glVertex3f(fww->mOutput.shapex2, fww->mOutput.shapey2, 0.0f);
 
439
                glEnd ();
 
440
 
 
441
                glBegin(GL_LINES);
 
442
                glVertex3f(fww->mOutput.shapex2, fww->mOutput.shapey2, 0.0f);
 
443
                glVertex3f(fww->mOutput.shapex4, fww->mOutput.shapey4, 0.0f);
 
444
                glEnd ();
 
445
 
 
446
                glBegin(GL_LINES);
 
447
                glVertex3f(fww->mOutput.shapex4, fww->mOutput.shapey4, 0.0f);
 
448
                glVertex3f(fww->mOutput.shapex3, fww->mOutput.shapey3, 0.0f);
 
449
                glEnd ();
 
450
 
 
451
                glBegin(GL_LINES);
 
452
                glVertex3f(fww->mOutput.shapex3, fww->mOutput.shapey3, 0.0f);
 
453
                glVertex3f(fww->mOutput.shapex1, fww->mOutput.shapey1, 0.0f);
 
454
                glEnd ();
 
455
            }
 
456
        }
 
457
        if (wasCulled)
 
458
            glEnable(GL_CULL_FACE);
 
459
 
 
460
        glColor4usv(defaultColor);
 
461
        glPopMatrix ();
 
462
    }
 
463
 
 
464
    return status;
 
465
}
 
466
 
 
467
void
 
468
FWScreen::donePaint ()
 
469
{
 
470
 
 
471
    if (mAxisHelp && mHoverWindow)
 
472
    {
 
473
        FREEWINS_WINDOW (mHoverWindow);
 
474
 
 
475
        REGION region;
 
476
 
 
477
        region.rects = &region.extents;
 
478
        region.numRects = region.size = 1;
 
479
 
 
480
        region.extents.x1 = MIN (WIN_REAL_X (mHoverWindow),
 
481
                                 WIN_REAL_X (mHoverWindow)
 
482
                                 + WIN_REAL_W (mHoverWindow)
 
483
                                 / 2.0f - fww->mRadius);
 
484
        region.extents.x2 = MAX (WIN_REAL_X (mHoverWindow),
 
485
                                 WIN_REAL_X (mHoverWindow)
 
486
                                 + WIN_REAL_W (mHoverWindow)
 
487
                                 / 2.0f + fww->mRadius);
 
488
 
 
489
        region.extents.y1 = MIN (WIN_REAL_Y (mHoverWindow),
 
490
                                 WIN_REAL_Y (mHoverWindow)
 
491
                                 + WIN_REAL_H (mHoverWindow)
 
492
                                 / 2.0f - fww->mRadius);
 
493
        region.extents.y2 = MAX (WIN_REAL_Y (mHoverWindow),
 
494
                                 WIN_REAL_Y (mHoverWindow)
 
495
                                 + WIN_REAL_H (mHoverWindow)
 
496
                                 / 2.0f + fww->mRadius);
 
497
 
 
498
        CompRegion damageRegion (region.extents.x1, region.extents.y1, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1);
 
499
 
 
500
        cScreen->damageRegion (damageRegion);
 
501
    }
 
502
 
 
503
    cScreen->donePaint ();
 
504
}
 
505
 
 
506
/* Damage the Window Rect */
 
507
bool
 
508
FWWindow::damageRect (bool initial,
 
509
                      const CompRect &rect)
 
510
{
 
511
    FREEWINS_SCREEN(screen);
 
512
 
 
513
    if (mTransformed)
 
514
        damageArea ();
 
515
 
 
516
    /**
 
517
     * Special situations where we must damage the screen
 
518
     * i.e when we are playing with windows and wobbly is
 
519
     * enabled
 
520
     */
 
521
 
 
522
    if ((mGrab == grabMove && !fws->optionGetImmediateMoves ())
 
523
        || (mIsAnimating || window->grabbed ()))
 
524
        fws->cScreen->damageScreen ();
 
525
 
 
526
    return cWindow->damageRect (initial, rect);
 
527
}