.gitignore                                    |   47 
 Makefile.am                                   |   15 
 NEWS                                          |   34 
 configure.ac                                  |    6 
 gtk/gnome/50-compiz-desktop-key.xml.in        |   10 
 gtk/gnome/50-compiz-key.xml.in                |    4 
 include/compiz-core.h                         |   30 
 kde/window-decorator-kde4/Makefile.am         |    3 
 kde/window-decorator-kde4/decorator.cpp       |  169 -
 kde/window-decorator-kde4/decorator.h         |   31 
 kde/window-decorator-kde4/main.cpp            |   82 
 kde/window-decorator-kde4/paintredirector.cpp |  125 +
 kde/window-decorator-kde4/paintredirector.h   |   60 
 kde/window-decorator-kde4/switcher.cpp        |   39 
 kde/window-decorator-kde4/switcher.h          |    2 
 kde/window-decorator-kde4/utils.h             |    6 
 kde/window-decorator-kde4/window.cpp          | 1103 ++-------
 kde/window-decorator-kde4/window.h            |   77 
 metadata/core.xml.in.in                       |    2 
 metadata/gnomecompat.xml.in                   |    2 
 metadata/obs.xml.in                           |   24 
 metadata/place.xml.in                         |   46 
 metadata/screenshot.xml.in                    |    9 
 plugins/annotate.c                            |    4 
 plugins/blur.c                                |    3 
 plugins/clone.c                               |    2 
 plugins/cube.c                                |    2 
 plugins/decoration.c                          |   37 
 plugins/fuse.c                                |    3 
 plugins/glib.c                                |   13 
 plugins/move.c                                |   61 
 plugins/place.c                               |  725 +++++-
 plugins/regex.c                               |   11 
 plugins/resize.c                              |  344 ++
 plugins/rotate.c                              |   31 
 plugins/scale.c                               |   27 
 plugins/screenshot.c                          |  132 +
 plugins/switcher.c                            |  175 -
 plugins/water.c                               |    2 
 plugins/wobbly.c                              |  132 +
 plugins/zoom.c                                |    4 
 po/POTFILES.in                                |    1 
 po/POTFILES.skip                              |    1 
 po/af.po                                      |  112 
 po/ar.po                                      |  127 -
 po/as.po                                      | 2624 ++++++++++++++++++++++
 po/be.po                                      | 2738 +++++++++++++++++++++++
 po/bg.po                                      |  334 +-
 po/bn.po                                      |  133 -
 po/bn_IN.po                                   |  133 -
 po/bs.po                                      |  106 
 po/ca.po                                      |  131 -
 po/cs.po                                      |  141 -
 po/cy.po                                      |  120 -
 po/da.po                                      |  163 -
 po/de.po                                      |  196 -
 po/el.po                                      |  399 +--
 po/en_GB.po                                   |  122 -
 po/es.po                                      |  455 +--
 po/et.po                                      |  122 -
 po/eu.po                                      |  290 --
 po/fa.po                                      | 2634 ++++++++++++++++++++++
 po/fi.po                                      |  264 --
 po/fr.po                                      |  279 +-
 po/gl.po                                      |  617 ++---
 po/gu.po                                      |  131 -
 po/he.po                                      |  302 +-
 po/hi.po                                      |  127 -
 po/hr.po                                      |  128 -
 po/hu.po                                      |  259 --
 po/id.po                                      |  104 
 po/it.po                                      | 1243 +++++-----
 po/ja.po                                      |  694 ++----
 po/ka.po                                      |   96 
 po/km.po                                      |  122 -
 po/ko.po                                      |  437 +--
 po/lo.po                                      |   96 
 po/lt.po                                      |  122 -
 po/mk.po                                      |   97 
 po/ml_IN.po                                   | 3000 ++++++++++++++++++++++++++
 po/nb.po                                      |  139 -
 po/nl.po                                      |  141 -
 po/or.po                                      |  139 -
 po/pa.po                                      |  127 -
 po/pl.po                                      |  474 +---
 po/pt.po                                      |  282 --
 po/pt_BR.po                                   |  139 -
 po/ro.po                                      |  141 -
 po/ru.po                                      |  301 +-
 po/sk.po                                      |  139 -
 po/sl.po                                      |  126 -
 po/sr.po                                      |  132 -
 po/sv.po                                      |  139 -
 po/ta.po                                      |  111 
 po/tr.po                                      |  147 -
 po/uk.po                                      | 1651 +++++---------
 po/vi.po                                      |   96 
 po/xh.po                                      |  112 
 po/zh_CN.po                                   |  413 +--
 po/zh_TW.po                                   | 1279 ++++-------
 po/zu.po                                      |  112 
 src/Makefile.am                               |    2 
 src/display.c                                 |  100 
 src/event.c                                   |   94 
 src/main.c                                    |   17 
 src/plugin.c                                  |    3 
 src/screen.c                                  |  317 +-
 src/texture.c                                 |    4 
 src/window.c                                  |  214 +
 109 files changed, 19836 insertions(+), 10089 deletions(-)

New commits:
commit 79a275b240a98d9f64c8dd1e799e5d469ec8f204
Author: Danny Baumann <dannybaum...@web.de>
Date:   Wed Jan 20 15:05:10 2010 +0100

    Fix window region calculation for windows that have border width set.

diff --git a/src/window.c b/src/window.c
index 90922d1..e7bb987 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1701,8 +1701,8 @@ updateWindowRegion (CompWindow *w)
     {
        r.x      = -w->attrib.border_width;
        r.y      = -w->attrib.border_width;
-       r.width  = w->width;
-       r.height = w->height;
+       r.width  = w->attrib.width + w->attrib.border_width;
+       r.height = w->attrib.height + w->attrib.border_width;
 
        rects = &r;
        n = 1;
@@ -1719,8 +1719,10 @@ updateWindowRegion (CompWindow *w)
     {
        rect.extents.x1 = rects[i].x + w->attrib.border_width;
        rect.extents.y1 = rects[i].y + w->attrib.border_width;
-       rect.extents.x2 = rect.extents.x1 + rects[i].width;
-       rect.extents.y2 = rect.extents.y1 + rects[i].height;
+       rect.extents.x2 = rect.extents.x1 + rects[i].width +
+                         w->attrib.border_width;
+       rect.extents.y2 = rect.extents.y1 + rects[i].height +
+                         w->attrib.border_width;
 
        if (rect.extents.x1 < 0)
            rect.extents.x1 = 0;

commit af6a23a1e9e325a2488cfeceb12741bb1ab21e6c
Author: Erkin Bahceci <erkin...@gmail.com>
Date:   Fri Dec 25 14:14:32 2009 -0600

    wobbly: Constrain throwing at the bottom as well.
    
    Backport from 7d75379a834afaed0e8621751c1b217966122765.

diff --git a/plugins/wobbly.c b/plugins/wobbly.c
index 7625c7e..e33e750 100644
--- a/plugins/wobbly.c
+++ b/plugins/wobbly.c
@@ -1709,27 +1709,46 @@ wobblyPreparePaintScreen (CompScreen *s,
 
                        if (!ww->grabbed && ws->grabWindowWorkArea)
                        {
+                           float topmostYPos    = MAXSHORT;
                            float bottommostYPos = MINSHORT;
-                           int   i, decorTop;
+                           int   decorTop;
+                           int   decorTitleBottom;
+                           int   i;
 
-                           /* find the bottommost top-row object */
                            for (i = 0; i < GRID_WIDTH; i++)
                            {
                                int modelY = model->objects[i].position.y;
+
+                               /* find the bottommost top-row object */
                                bottommostYPos = MAX (modelY, bottommostYPos);
+
+                               /* find the topmost top-row object */
+                               topmostYPos = MIN (modelY, topmostYPos);
                            }
 
                            decorTop = bottommostYPos +
                                       w->output.top - w->input.top;
+                           decorTitleBottom = topmostYPos + w->output.top;
 
                            if (ws->grabWindowWorkArea->y > decorTop)
                            {
-                               /* constrain to work area */
+                               /* constrain to work area box top edge */
                                modelMove (model, 0,
                                           ws->grabWindowWorkArea->y -
                                           decorTop);
                                modelCalcBounds (model);
                            }
+                           else if (ws->grabWindowWorkArea->y +
+                                    ws->grabWindowWorkArea->height <
+                                    decorTitleBottom)
+                           {
+                               /* constrain to work area box bottom edge */
+                               modelMove (model, 0,
+                                          ws->grabWindowWorkArea->y +
+                                          ws->grabWindowWorkArea->height -
+                                          decorTitleBottom);
+                               modelCalcBounds (model);
+                           }
                        }
                    }
                    else

commit 275ebddc4af09ccdeefb8ab5a03cb3db24cc5a79
Author: Erkin Bahceci <erkin...@gmail.com>
Date:   Fri Dec 25 14:08:17 2009 -0600

    wobbly: Fix warning.

diff --git a/plugins/wobbly.c b/plugins/wobbly.c
index 4dceb36..7625c7e 100644
--- a/plugins/wobbly.c
+++ b/plugins/wobbly.c
@@ -1699,8 +1699,6 @@ wobblyPreparePaintScreen (CompScreen *s,
 
                    if (ww->wobbly)
                    {
-                       WOBBLY_DISPLAY (s->display);
-
                        /* snapped to more than one edge, we have to reduce
                           edge escape velocity until only one edge is snapped 
*/
                        if (ww->wobbly == WobblyForce && !ww->grabbed)

commit 6d5f911b83b523c7863ee1addbbcee38aec74db9
Author: Erkin Bahceci <erkin...@gmail.com>
Date:   Fri Dec 25 14:05:50 2009 -0600

    wobbly: Fix y constraint on throwing.

diff --git a/plugins/wobbly.c b/plugins/wobbly.c
index 51f733e..4dceb36 100644
--- a/plugins/wobbly.c
+++ b/plugins/wobbly.c
@@ -1786,6 +1786,8 @@ wobblyPreparePaintScreen (CompScreen *s,
                ws->wobblyWindows |= ww->wobbly;
            }
        }
+       if (!ws->wobblyWindows)
+           ws->grabWindowWorkArea = NULL;
     }
 
     UNWRAP (ws, s, preparePaintScreen);
@@ -2638,9 +2640,8 @@ wobblyWindowUngrabNotify (CompWindow *w)
 
     if (w == ws->grabWindow)
     {
-       ws->grabMask           = 0;
-       ws->grabWindow         = NULL;
-       ws->grabWindowWorkArea = NULL;
+       ws->grabMask   = 0;
+       ws->grabWindow = NULL;
     }
 
     if (ww->grabbed)

commit 6c9c0da40c2eb129b80ce6f4f759c889ba4eeaf5
Author: Erkin Bahceci <erkin...@gmail.com>
Date:   Mon Dec 14 11:27:41 2009 -0600

    Complete the work area optimization.

diff --git a/plugins/resize.c b/plugins/resize.c
index 628bd90..06c43bc 100644
--- a/plugins/resize.c
+++ b/plugins/resize.c
@@ -317,7 +317,6 @@ static Region
 resizeGetConstraintRegion (CompScreen *s)
 {
     Region       region;
-    XRectangle   workArea;
     int          i;
 
     region = XCreateRegion ();
@@ -325,10 +324,7 @@ resizeGetConstraintRegion (CompScreen *s)
        return NULL;
 
     for (i = 0; i < s->nOutputDev; i++)
-    {
-       getWorkareaForOutput (s, i, &workArea);
        XUnionRectWithRegion (&s->outputDev[i].workArea, region, region);
-    }
 
     return region;
 }

commit 53976f1916a6659a75e0159a4dfbc1fb2188d34f
Author: Erkin Bahceci <erkin...@gmail.com>
Date:   Mon Dec 14 11:21:27 2009 -0600

    Do the resize output snap only when "outside".

diff --git a/plugins/resize.c b/plugins/resize.c
index 32f3a97..628bd90 100644
--- a/plugins/resize.c
+++ b/plugins/resize.c
@@ -725,7 +725,7 @@ resizeHandleMotionEvent (CompScreen *s,
        int    w, h;                    /* size of window contents */
        int    wX, wY, wWidth, wHeight; /* rect. for window contents+borders */
        int    i;
-       int    workAreaSnapDistance = 10;
+       int    workAreaSnapDistance = 15;
 
        RESIZE_DISPLAY (s->display);
 
@@ -859,23 +859,23 @@ resizeHandleMotionEvent (CompScreen *s,
            {
                if (rd->mask & ResizeLeftMask)
                {
-                   int dw = wX - workArea->x;
+                   int dw = workArea->x - wX;
 
-                   if (abs (dw) < workAreaSnapDistance)
+                   if (0 < dw && dw < workAreaSnapDistance)
                    {
-                       w      += dw;
-                       wWidth += dw;
-                       wX     -= dw;
+                       w      -= dw;
+                       wWidth -= dw;
+                       wX     += dw;
                    }
                }
                else if (rd->mask & ResizeRightMask)
                {
-                   int dw = workArea->x + workArea->width - (wX + wWidth);
+                   int dw = wX + wWidth - (workArea->x + workArea->width);
 
-                   if (abs (dw) < workAreaSnapDistance)
+                   if (0 < dw && dw < workAreaSnapDistance)
                    {
-                       w      += dw;
-                       wWidth += dw;
+                       w      -= dw;
+                       wWidth -= dw;
                    }
                }
            }
@@ -886,23 +886,23 @@ resizeHandleMotionEvent (CompScreen *s,
            {
                if (rd->mask & ResizeUpMask)
                {
-                   int dh = wY - workArea->y;
+                   int dh = workArea->y - wY;
 
-                   if (abs (dh) < workAreaSnapDistance)
+                   if (0 < dh && dh < workAreaSnapDistance)
                    {
-                       h       += dh;
-                       wHeight += dh;
-                       wY      -= dh;
+                       h       -= dh;
+                       wHeight -= dh;
+                       wY      += dh;
                    }
                }
                else if (rd->mask & ResizeDownMask)
                {
-                   int dh = workArea->y + workArea->height - (wY + wHeight);
+                   int dh = wY + wHeight - (workArea->y + workArea->height);
 
-                   if (abs (dh) < workAreaSnapDistance)
+                   if (0 < dh && dh < workAreaSnapDistance)
                    {
-                       h       += dh;
-                       wHeight += dh;
+                       h       -= dh;
+                       wHeight -= dh;
                    }
                }
            }

commit 36d16aeae7f416a8fa42ee30ecf30ae532a4848d
Author: Danny Baumann <dannybaum...@web.de>
Date:   Sun Dec 13 12:50:08 2009 +0100

    Minor whitespace fixes and optimizations.

diff --git a/plugins/resize.c b/plugins/resize.c
index 5aa93b9..32f3a97 100644
--- a/plugins/resize.c
+++ b/plugins/resize.c
@@ -100,7 +100,6 @@ typedef struct _ResizeDisplay {
     int                 pointerDy;
     KeyCode     key[NUM_KEYS];
 
-    Bool         offWorkAreaConstrained;
     Region       constraintRegion;
     int          inRegionStatus;
     int          lastGoodHotSpotY;
@@ -325,12 +324,10 @@ resizeGetConstraintRegion (CompScreen *s)
     if (!region)
        return NULL;
 
-    XUnionRegion (&emptyRegion, &emptyRegion, region);
-
     for (i = 0; i < s->nOutputDev; i++)
     {
        getWorkareaForOutput (s, i, &workArea);
-       XUnionRectWithRegion (&workArea, region, region);
+       XUnionRectWithRegion (&s->outputDev[i].workArea, region, region);
     }
 
     return region;
@@ -518,17 +515,14 @@ resizeInitiate (CompDisplay     *d,
                warpPointer (w->screen, xRoot - pointerX, yRoot - pointerY);
            }
 
-           /* Update offWorkAreaConstrained and workArea at grab time */
-           rd->offWorkAreaConstrained = FALSE;
+           if (rd->constraintRegion)
+               XDestroyRegion (rd->constraintRegion);
+
            if (sourceExternalApp)
            {
                /* Prevent resizing beyond work area edges when resize is
                   initiated externally (e.g. with window frame or menu)
                   and not with a key (e.g. alt+button) */
-               rd->offWorkAreaConstrained = TRUE;
-
-               if (rd->constraintRegion)
-                   XDestroyRegion (rd->constraintRegion);
 
                rd->inRegionStatus   = RectangleOut;
                rd->lastGoodHotSpotY = -1;
@@ -536,6 +530,10 @@ resizeInitiate (CompDisplay     *d,
                rd->lastGoodHeight   = w->serverHeight;
                rd->constraintRegion = resizeGetConstraintRegion (w->screen);
            }
+           else
+           {
+               rd->constraintRegion = NULL;
+           }
        }
     }
 
@@ -840,88 +838,85 @@ resizeHandleMotionEvent (CompScreen *s,
 
        if (rd->mask & ResizeLeftMask)
            wX = rd->savedGeometry.x + rd->savedGeometry.width -
-               (w + rd->w->input.left);
+                (w + rd->w->input.left);
        else
            wX = rd->savedGeometry.x - rd->w->input.left;
 
        if (rd->mask & ResizeUpMask)
            wY = rd->savedGeometry.y + rd->savedGeometry.height -
-               (h + rd->w->input.top);
+                (h + rd->w->input.top);
        else
            wY = rd->savedGeometry.y - rd->w->input.top;
 
        /* Check if resized edge(s) are near a work-area boundary */
        for (i = 0; i < s->nOutputDev; i++)
        {
-           XRectangle workArea;
-
-           getWorkareaForOutput (s, i, &workArea);
+           const XRectangle *workArea = &s->outputDev[i].workArea;
 
-           // if window and work-area intersect in x axis
-           if (wX + wWidth > workArea.x &&
-               wX < workArea.x + workArea.width)
+           /* if window and work-area intersect in x axis */
+           if (wX + wWidth > workArea->x &&
+               wX < workArea->x + workArea->width)
            {
                if (rd->mask & ResizeLeftMask)
                {
-                   int dw = wX - workArea.x;
-    
+                   int dw = wX - workArea->x;
+
                    if (abs (dw) < workAreaSnapDistance)
                    {
-                       w += dw;
+                       w      += dw;
                        wWidth += dw;
-                       wX -= dw;
+                       wX     -= dw;
                    }
                }
                else if (rd->mask & ResizeRightMask)
                {
-                   int dw = workArea.x + workArea.width - (wX + wWidth);
+                   int dw = workArea->x + workArea->width - (wX + wWidth);
 
                    if (abs (dw) < workAreaSnapDistance)
                    {
-                       w += dw;
+                       w      += dw;
                        wWidth += dw;
                    }
                }
            }
 
-           // if window and work-area intersect in y axis
-           if (wY + wHeight > workArea.y &&
-               wY < workArea.y + workArea.height)
+           /* if window and work-area intersect in y axis */
+           if (wY + wHeight > workArea->y &&
+               wY < workArea->y + workArea->height)
            {
                if (rd->mask & ResizeUpMask)
                {
-                   int dh = wY - workArea.y;
-    
+                   int dh = wY - workArea->y;
+
                    if (abs (dh) < workAreaSnapDistance)
                    {
-                       h += dh;
+                       h       += dh;
                        wHeight += dh;
-                       wY -= dh;
+                       wY      -= dh;
                    }
                }
                else if (rd->mask & ResizeDownMask)
                {
-                   int dh = workArea.y + workArea.height - (wY + wHeight);
+                   int dh = workArea->y + workArea->height - (wY + wHeight);
 
                    if (abs (dh) < workAreaSnapDistance)
                    {
-                       h += dh;
+                       h       += dh;
                        wHeight += dh;
                    }
                }
            }
        }
 
-       if (rd->offWorkAreaConstrained &&
-           rd->constraintRegion)
+       if (rd->constraintRegion)
        {
-           int minWidth = 50;
+           int minWidth  = 50;
            int minHeight = 50;
 
            /* rect. for a minimal height window + borders
               (used for the constraining in X axis) */
            int minimalInputHeight = minHeight +
-               rd->w->input.top + rd->w->input.bottom;
+                                    rd->w->input.top + rd->w->input.bottom;
 
            /* small hot-spot square (on window's corner or edge) that is to be
               constrained to the combined output work-area region */
@@ -1000,7 +995,8 @@ resizeHandleMotionEvent (CompScreen *s,
                    while ((nw > minWidth) && xStatus != RectangleIn)
                    {
                        xStatus = XRectInRegion (rd->constraintRegion,
-                                                nx, yForXResize, width, 
height);
+                                                nx, yForXResize,
+                                                width, height);
                        if (xStatus != RectangleIn)
                        {
                            nw--;
@@ -1585,8 +1581,7 @@ resizeInitDisplay (CompPlugin  *p,
        rd->key[i] = XKeysymToKeycode (d->display,
                                       XStringToKeysym (rKeys[i].name));
 
-    rd->offWorkAreaConstrained = TRUE;
-    rd->constraintRegion       = NULL;
+    rd->constraintRegion = NULL;
 
     WRAP (rd, d, handleEvent, resizeHandleEvent);
 

commit 93d8762391d7c2ffedaa31f5fbb03913089e44ac
Author: Erkin Bahceci <erkin...@gmail.com>
Date:   Sat Dec 12 19:39:10 2009 -0600

    Better resize constraint and snap for combined work area.
    
    Allows resizing across monitors while snapping to work area edges.

diff --git a/plugins/resize.c b/plugins/resize.c
index 59bdc36..5aa93b9 100644
--- a/plugins/resize.c
+++ b/plugins/resize.c
@@ -100,7 +100,12 @@ typedef struct _ResizeDisplay {
     int                 pointerDy;
     KeyCode     key[NUM_KEYS];
 
-    Bool offWorkAreaConstrained;
+    Bool         offWorkAreaConstrained;
+    Region       constraintRegion;
+    int          inRegionStatus;
+    int          lastGoodHotSpotY;
+    int          lastGoodWidth;
+    int          lastGoodHeight;
 } ResizeDisplay;
 
 typedef struct _ResizeScreen {
@@ -121,8 +126,6 @@ typedef struct _ResizeScreen {
     Cursor downRightCursor;
     Cursor middleCursor;
     Cursor cursor[NUM_KEYS];
-
-    const XRectangle *grabWindowWorkArea;
 } ResizeScreen;
 
 #define GET_RESIZE_DISPLAY(d)                                      \
@@ -311,6 +314,28 @@ resizeFinishResizing (CompDisplay *d)
     rd->w = NULL;
 }
 
+static Region
+resizeGetConstraintRegion (CompScreen *s)
+{
+    Region       region;
+    XRectangle   workArea;
+    int          i;
+
+    region = XCreateRegion ();
+    if (!region)
+       return NULL;
+
+    XUnionRegion (&emptyRegion, &emptyRegion, region);
+
+    for (i = 0; i < s->nOutputDev; i++)
+    {
+       getWorkareaForOutput (s, i, &workArea);
+       XUnionRectWithRegion (&workArea, region, region);
+    }
+
+    return region;
+}
+
 static Bool
 resizeInitiate (CompDisplay     *d,
                CompAction      *action,
@@ -497,14 +522,19 @@ resizeInitiate (CompDisplay     *d,
            rd->offWorkAreaConstrained = FALSE;
            if (sourceExternalApp)
            {
-               int output = outputDeviceForWindow (w);
-
-               rs->grabWindowWorkArea = &w->screen->outputDev[output].workArea;
-
                /* Prevent resizing beyond work area edges when resize is
                   initiated externally (e.g. with window frame or menu)
                   and not with a key (e.g. alt+button) */
                rd->offWorkAreaConstrained = TRUE;
+
+               if (rd->constraintRegion)
+                   XDestroyRegion (rd->constraintRegion);
+
+               rd->inRegionStatus   = RectangleOut;
+               rd->lastGoodHotSpotY = -1;
+               rd->lastGoodWidth    = w->serverWidth;
+               rd->lastGoodHeight   = w->serverHeight;
+               rd->constraintRegion = resizeGetConstraintRegion (w->screen);
            }
        }
     }
@@ -694,7 +724,10 @@ resizeHandleMotionEvent (CompScreen *s,
     if (rs->grabIndex)
     {
        BoxRec box;
-       int    w, h;
+       int    w, h;                    /* size of window contents */
+       int    wX, wY, wWidth, wHeight; /* rect. for window contents+borders */
+       int    i;
+       int    workAreaSnapDistance = 10;
 
        RESIZE_DISPLAY (s->display);
 
@@ -801,42 +834,237 @@ resizeHandleMotionEvent (CompScreen *s,
 
        constrainNewWindowSize (rd->w, w, h, &w, &h);
 
-       /* constrain to work area */
-       if (rd->offWorkAreaConstrained)
+       /* compute rect. for window + borders */
+       wWidth  = w + rd->w->input.left + rd->w->input.right;
+       wHeight = h + rd->w->input.top + rd->w->input.bottom;
+
+       if (rd->mask & ResizeLeftMask)
+           wX = rd->savedGeometry.x + rd->savedGeometry.width -
+               (w + rd->w->input.left);
+       else
+           wX = rd->savedGeometry.x - rd->w->input.left;
+
+       if (rd->mask & ResizeUpMask)
+           wY = rd->savedGeometry.y + rd->savedGeometry.height -
+               (h + rd->w->input.top);
+       else
+           wY = rd->savedGeometry.y - rd->w->input.top;
+
+       /* Check if resized edge(s) are near a work-area boundary */
+       for (i = 0; i < s->nOutputDev; i++)
        {
-           if (rd->mask & ResizeUpMask)
+           XRectangle workArea;
+
+           getWorkareaForOutput (s, i, &workArea);
+
+           // if window and work-area intersect in x axis
+           if (wX + wWidth > workArea.x &&
+               wX < workArea.x + workArea.width)
            {
-               int decorTop = rd->savedGeometry.y + rd->savedGeometry.height -
-                   (h + rd->w->input.top);
+               if (rd->mask & ResizeLeftMask)
+               {
+                   int dw = wX - workArea.x;
+    
+                   if (abs (dw) < workAreaSnapDistance)
+                   {
+                       w += dw;
+                       wWidth += dw;
+                       wX -= dw;
+                   }
+               }
+               else if (rd->mask & ResizeRightMask)
+               {
+                   int dw = workArea.x + workArea.width - (wX + wWidth);
 
-               if (rs->grabWindowWorkArea->y > decorTop)
-                   h -= rs->grabWindowWorkArea->y - decorTop;
+                   if (abs (dw) < workAreaSnapDistance)
+                   {
+                       w += dw;
+                       wWidth += dw;
+                   }
+               }
            }
-           if (rd->mask & ResizeDownMask)
+
+           // if window and work-area intersect in y axis
+           if (wY + wHeight > workArea.y &&
+               wY < workArea.y + workArea.height)
            {
-               int decorBottom = rd->savedGeometry.y + h + rd->w->input.bottom;
+               if (rd->mask & ResizeUpMask)
+               {
+                   int dh = wY - workArea.y;
+    
+                   if (abs (dh) < workAreaSnapDistance)
+                   {
+                       h += dh;
+                       wHeight += dh;
+                       wY -= dh;
+                   }
+               }
+               else if (rd->mask & ResizeDownMask)
+               {
+                   int dh = workArea.y + workArea.height - (wY + wHeight);
 
-               if (decorBottom >
-                   rs->grabWindowWorkArea->y + rs->grabWindowWorkArea->height)
-                   h -= decorBottom - (rs->grabWindowWorkArea->y +
-                                       rs->grabWindowWorkArea->height);
+                   if (abs (dh) < workAreaSnapDistance)
+                   {
+                       h += dh;
+                       wHeight += dh;
+                   }
+               }
            }
+       }
+
+       if (rd->offWorkAreaConstrained &&
+           rd->constraintRegion)
+       {
+           int minWidth = 50;
+           int minHeight = 50;
+
+           /* rect. for a minimal height window + borders
+              (used for the constraining in X axis) */
+           int minimalInputHeight = minHeight +
+               rd->w->input.top + rd->w->input.bottom;
+
+           /* small hot-spot square (on window's corner or edge) that is to be
+              constrained to the combined output work-area region */
+           int x, y;
+           int width = rd->w->input.top; /* square size = title bar height */
+           int height = width;
+           int status;
+
+           /* compute x & y for constrained hot-spot rect */
            if (rd->mask & ResizeLeftMask)
+               x = wX;
+           else if (rd->mask & ResizeRightMask)
+               x = wX + wWidth - width;
+           else
+               x = MIN (MAX (xRoot, wX), wX + wWidth - width);
+
+           if (rd->mask & ResizeUpMask)
+               y = wY;
+           else if (rd->mask & ResizeDownMask)
+               y = wY + wHeight - height;
+           else
+               y = MIN (MAX (yRoot, wY), wY + wHeight - height);
+
+           status = XRectInRegion (rd->constraintRegion,
+                                   x, y, width, height);
+
+           /* only constrain movement if previous position was valid */
+           if (rd->inRegionStatus == RectangleIn)
            {
-               int decorLeft = rd->savedGeometry.x + rd->savedGeometry.width -
-                   (w + rd->w->input.left);
+               int xStatus, yForXResize;
+               int nx = x;
+               int nw = w;
+               int nh = h;
+
+               if (rd->mask & (ResizeLeftMask | ResizeRightMask))
+               {
+                   xStatus = status;
+
+                   if (rd->mask & ResizeUpMask)
+                       yForXResize = wY + wHeight - minimalInputHeight;
+                   else if (rd->mask & ResizeDownMask)
+                       yForXResize = wY + minimalInputHeight - height;
+                   else
+                       yForXResize = y;
+
+                   if (XRectInRegion (rd->constraintRegion,
+                                      x, yForXResize,
+                                      width, height) != RectangleIn)
+                   {
+                       if (rd->lastGoodHotSpotY >= 0)
+                           yForXResize = rd->lastGoodHotSpotY;
+                       else
+                           yForXResize = y;
+                   }
+               }
+               if (rd->mask & ResizeLeftMask)
+               {
+                   while ((nw > minWidth) && xStatus != RectangleIn)
+                   {
+                       xStatus = XRectInRegion (rd->constraintRegion,
+                                                nx, yForXResize, width, 
height);
+                       if (xStatus != RectangleIn)
+                       {
+                           nw--;
+                           nx++;
+                       }
+                   }
+                   if (nw > minWidth)
+                   {
+                       x = nx;
+                       w = nw;
+                   }
+               }
+               else if (rd->mask & ResizeRightMask)
+               {
+                   while ((nw > minWidth) && xStatus != RectangleIn)
+                   {
+                       xStatus = XRectInRegion (rd->constraintRegion,
+                                                nx, yForXResize, width, 
height);
+                       if (xStatus != RectangleIn)
+                       {
+                           nw--;
+                           nx--;
+                       }
+                   }
+                   if (nw > minWidth)
+                   {
+                       x = nx;
+                       w = nw;
+                   }
+               }
+
+               if (rd->mask & ResizeUpMask)
+               {
+                   while ((nh > minHeight) && status != RectangleIn)
+                   {
+                       status = XRectInRegion (rd->constraintRegion,
+                                               x, y, width, height);
+                       if (status != RectangleIn)
+                       {
+                           nh--;
+                           y++;
+                       }
+                   }
+                   if (nh > minHeight)
+                       h = nh;
+               }
+               else if (rd->mask & ResizeDownMask)
+               {
+                   while ((nh > minHeight) && status != RectangleIn)
+                   {
+                       status = XRectInRegion (rd->constraintRegion,
+                                               x, y, width, height);
+                       if (status != RectangleIn)
+                       {
+                           nh--;
+                           y--;
+                       }
+                   }
+                   if (nh > minHeight)
+                       h = nh;
+               }
 
-               if (rs->grabWindowWorkArea->x > decorLeft)
-                   w -= rs->grabWindowWorkArea->x - decorLeft;
+               if (((rd->mask & (ResizeLeftMask | ResizeRightMask)) &&
+                    xStatus == RectangleIn) ||
+                   ((rd->mask & (ResizeUpMask | ResizeDownMask)) &&
+                    status == RectangleIn))
+               {
+                   /* hot-spot inside work-area region, store good values */
+                   rd->lastGoodHotSpotY = y;
+                   rd->lastGoodWidth    = w;
+                   rd->lastGoodHeight   = h;
+               }
+               else
+               {
+                   /* failed to find a good hot-spot position, restore size */
+                   w = rd->lastGoodWidth;
+                   h = rd->lastGoodHeight;
+               }
            }
-           if (rd->mask & ResizeRightMask)
+           else
            {
-               int decorRight = rd->savedGeometry.x + w + rd->w->input.right;
-
-               if (decorRight >
-                   rs->grabWindowWorkArea->x + rs->grabWindowWorkArea->width)
-                   w -= decorRight - (rs->grabWindowWorkArea->x +
-                                      rs->grabWindowWorkArea->width);
+               rd->inRegionStatus = status;
            }
        }
 
@@ -1358,6 +1586,7 @@ resizeInitDisplay (CompPlugin  *p,
                                       XStringToKeysym (rKeys[i].name));
 
     rd->offWorkAreaConstrained = TRUE;
+    rd->constraintRegion       = NULL;
 
     WRAP (rd, d, handleEvent, resizeHandleEvent);
 
@@ -1378,6 +1607,9 @@ resizeFiniDisplay (CompPlugin  *p,
 
     compFiniDisplayOptions (d, rd->opt, RESIZE_DISPLAY_OPTION_NUM);
 
+    if (rd->constraintRegion)
+       XDestroyRegion (rd->constraintRegion);
+
     free (rd);
 }
 
@@ -1416,8 +1648,6 @@ resizeInitScreen (CompPlugin *p,
     rs->cursor[2] = rs->upCursor;
     rs->cursor[3] = rs->downCursor;
 
-    rs->grabWindowWorkArea = NULL;
-
     WRAP (rs, s, windowResizeNotify, resizeWindowResizeNotify);
     WRAP (rs, s, paintOutput, resizePaintOutput);
     WRAP (rs, s, paintWindow, resizePaintWindow);

commit 814db40e62bb2240b1708efba1f15ff65b9d2f0e
Author: Danny Baumann <dannybaum...@web.de>
Date:   Mon Dec 14 15:20:29 2009 +0100

    Fix crash.

diff --git a/plugins/switcher.c b/plugins/switcher.c
index 4c0cea5..ff3f3fb 100644
--- a/plugins/switcher.c
+++ b/plugins/switcher.c
@@ -703,10 +703,6 @@ switchInitiate (CompScreen            *s,
                else
                {
                    XMapWindow (s->display->display, ss->popupWindow);
-                   /* we don't get a MapRequest for internal window
-                      creations, so we need to set the managed state
-                      ourselves */
-                   w->managed = TRUE;
                }
            }
 
@@ -1100,7 +1096,11 @@ switchHandleEvent (CompDisplay *d,
 
            if (w->id == ss->popupWindow)
            {
-               w->wmType = getWindowType (d, w->id);
+               /* we don't get a MapRequest for internal window
+                  creations, so we need to update the internals
+                  ourselves */
+               w->wmType  = getWindowType (d, w->id);
+               w->managed = TRUE;
                recalcWindowType (w);
                recalcWindowActions (w);
                updateWindowClassHints (w);


-- 
To UNSUBSCRIBE, email to debian-x-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to