← Back to team overview

focus-follows-mouse team mailing list archive

[Merge] lp:~focus-follows-mouse/ubuntu/precise/compiz/fix-883383 into lp:ubuntu/compiz

 

James Pharaoh has proposed merging lp:~focus-follows-mouse/ubuntu/precise/compiz/fix-883383 into lp:ubuntu/compiz.

Requested reviews:
  Ubuntu branches (ubuntu-branches)
Related bugs:
  Bug #883383 in compiz (Ubuntu): "Drag title bar should not raise if raise-on-click is disabled"
  https://bugs.launchpad.net/ubuntu/+source/compiz/+bug/883383

For more details, see:
https://code.launchpad.net/~focus-follows-mouse/ubuntu/precise/compiz/fix-883383/+merge/80727
-- 
https://code.launchpad.net/~focus-follows-mouse/ubuntu/precise/compiz/fix-883383/+merge/80727
Your team Focus Follows Mouse is subscribed to branch lp:~focus-follows-mouse/ubuntu/precise/compiz/fix-883383.
=== added file '.pc/.quilt_patches'
--- .pc/.quilt_patches	1970-01-01 00:00:00 +0000
+++ .pc/.quilt_patches	2011-10-29 09:07:25 +0000
@@ -0,0 +1,1 @@
+debian/patches

=== added file '.pc/.quilt_series'
--- .pc/.quilt_series	1970-01-01 00:00:00 +0000
+++ .pc/.quilt_series	2011-10-29 09:07:25 +0000
@@ -0,0 +1,1 @@
+series

=== modified file '.pc/applied-patches'
--- .pc/applied-patches	2011-10-12 10:44:49 +0000
+++ .pc/applied-patches	2011-10-29 09:07:25 +0000
@@ -12,3 +12,5 @@
 fix-832150.patch
 fix-864478.patch
 fix-864330.patch
+fix-881329.patch
+fix-883383.patch

=== added directory '.pc/fix-881329.patch'
=== added file '.pc/fix-881329.patch/.timestamp'
=== added directory '.pc/fix-881329.patch/plugins'
=== added directory '.pc/fix-881329.patch/plugins/move'
=== added directory '.pc/fix-881329.patch/plugins/move/src'
=== added file '.pc/fix-881329.patch/plugins/move/src/move.cpp'
--- .pc/fix-881329.patch/plugins/move/src/move.cpp	1970-01-01 00:00:00 +0000
+++ .pc/fix-881329.patch/plugins/move/src/move.cpp	2011-10-29 09:07:25 +0000
@@ -0,0 +1,756 @@
+/*
+ * Copyright © 2005 Novell, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Novell, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * Novell, Inc. makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: David Reveman <davidr@xxxxxxxxxx>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <X11/cursorfont.h>
+
+#include <core/atoms.h>
+#include "move.h"
+
+COMPIZ_PLUGIN_20090315 (move, MovePluginVTable)
+
+static bool
+moveInitiate (CompAction      *action,
+	      CompAction::State state,
+	      CompOption::Vector &options)
+{
+    CompWindow *w;
+    Window     xid;
+
+    MOVE_SCREEN (screen);
+
+    xid = CompOption::getIntOptionNamed (options, "window");
+
+    w = screen->findWindow (xid);
+    if (w && (w->actions () & CompWindowActionMoveMask))
+    {
+	CompRect     workArea;
+	unsigned int mods;
+	int          x, y, button;
+	bool         sourceExternalApp;
+
+	CompScreen *s = screen;
+
+	mods = CompOption::getIntOptionNamed (options, "modifiers", 0);
+
+	x = CompOption::getIntOptionNamed (options, "x", w->geometry ().x () +
+					   (w->size ().width () / 2));
+	y = CompOption::getIntOptionNamed (options, "y", w->geometry ().y () +
+					   (w->size ().height () / 2));
+
+	button = CompOption::getIntOptionNamed (options, "button", -1);
+
+	if (s->otherGrabExist ("move", NULL))
+	    return false;
+
+	if (ms->w)
+	    return false;
+
+	if (w->type () & (CompWindowTypeDesktopMask |
+		       CompWindowTypeDockMask    |
+		       CompWindowTypeFullscreenMask))
+	    return false;
+
+	if (w->overrideRedirect ())
+	    return false;
+
+	if (state & CompAction::StateInitButton)
+	    action->setState (action->state () | CompAction::StateTermButton);
+
+	if (ms->region)
+	{
+	    XDestroyRegion (ms->region);
+	    ms->region = NULL;
+	}
+
+	ms->status = RectangleOut;
+
+	ms->savedX = w->serverGeometry ().x ();
+	ms->savedY = w->serverGeometry ().y ();
+
+	ms->x = 0;
+	ms->y = 0;
+
+	lastPointerX = x;
+	lastPointerY = y;
+
+	sourceExternalApp =
+	    CompOption::getBoolOptionNamed (options, "external", false);
+	ms->yConstrained = sourceExternalApp && ms->optionGetConstrainY ();
+
+	ms->origState = w->state ();
+
+	workArea = s->getWorkareaForOutput (w->outputDevice ());
+
+	ms->snapBackY = w->serverGeometry ().y () - workArea.y ();
+	ms->snapOffY  = y - workArea.y ();
+
+	if (!ms->grab)
+	    ms->grab = s->pushGrab (ms->moveCursor, "move");
+
+	if (ms->grab)
+	{
+	    unsigned int grabMask = CompWindowGrabMoveMask |
+				    CompWindowGrabButtonMask;
+
+	    if (sourceExternalApp)
+		grabMask |= CompWindowGrabExternalAppMask;
+
+	    ms->w = w;
+
+	    ms->releaseButton = button;
+
+	    w->grabNotify (x, y, mods, grabMask);
+
+	    /* Click raise happens implicitly on buttons 1, 2 and 3 so don't
+	     * restack this window again if the action buttonbinding was from
+	     * one of those buttons */
+	    if (screen->getOption ("raise_on_click")->value ().b () &&
+		button != Button1 && button != Button2 && button != Button3)
+		w->updateAttributes (CompStackingUpdateModeAboveFullscreen);
+
+	    if (state & CompAction::StateInitKey)
+	    {
+		int xRoot, yRoot;
+
+		xRoot = w->geometry ().x () + (w->size ().width () / 2);
+		yRoot = w->geometry ().y () + (w->size ().height () / 2);
+
+		s->warpPointer (xRoot - pointerX, yRoot - pointerY);
+	    }
+
+	    if (ms->moveOpacity != OPAQUE)
+	    {
+		MOVE_WINDOW (w);
+
+		if (mw->cWindow)
+		    mw->cWindow->addDamage ();
+		if (mw->gWindow)
+		mw->gWindow->glPaintSetEnabled (mw, true);
+	    }
+	}
+    }
+
+    return false;
+}
+
+static bool
+moveTerminate (CompAction      *action,
+	       CompAction::State state,
+	       CompOption::Vector &options)
+{
+    MOVE_SCREEN (screen);
+
+    if (ms->w)
+    {
+	if (state & CompAction::StateCancel)
+	    ms->w->move (ms->savedX - ms->w->geometry ().x (),
+			 ms->savedY - ms->w->geometry ().y (), false);
+
+	ms->w->syncPosition ();
+
+	/* update window attributes as window constraints may have
+	   changed - needed e.g. if a maximized window was moved
+	   to another output device */
+	ms->w->updateAttributes (CompStackingUpdateModeNone);
+
+	ms->w->ungrabNotify ();
+
+	if (ms->grab)
+	{
+	    screen->removeGrab (ms->grab, NULL);
+	    ms->grab = NULL;
+	}
+
+	if (ms->moveOpacity != OPAQUE)
+	{
+	    MOVE_WINDOW (ms->w);
+
+	    if (mw->cWindow)
+		mw->cWindow->addDamage ();
+	    if (mw->gWindow)
+		mw->gWindow->glPaintSetEnabled (mw, false);
+	}
+
+	ms->w             = 0;
+	ms->releaseButton = 0;
+    }
+
+    action->setState (action->state () & ~(CompAction::StateTermKey |
+					   CompAction::StateTermButton));
+
+    return false;
+}
+
+/* creates a region containing top and bottom struts. only struts that are
+   outside the screen workarea are considered. */
+static Region
+moveGetYConstrainRegion (CompScreen *s)
+{
+    CompWindow   *w;
+    Region       region;
+    REGION       r;
+    CompRect     workArea;
+    BoxRec       extents;
+    unsigned int i;
+
+    region = XCreateRegion ();
+    if (!region)
+	return NULL;
+
+    r.rects    = &r.extents;
+    r.numRects = r.size = 1;
+
+    r.extents.x1 = MINSHORT;
+    r.extents.y1 = 0;
+    r.extents.x2 = 0;
+    r.extents.y2 = s->height ();
+
+    XUnionRegion (&r, region, region);
+
+    r.extents.x1 = s->width ();
+    r.extents.x2 = MAXSHORT;
+
+    XUnionRegion (&r, region, region);
+
+    for (i = 0; i < s->outputDevs ().size (); i++)
+    {
+	XUnionRegion (s->outputDevs ()[i].region (), region, region);
+
+	workArea = s->getWorkareaForOutput (i);
+	extents = s->outputDevs ()[i].region ()->extents;
+
+	foreach (w, s->windows ())
+	{
+	    if (!w->mapNum ())
+		continue;
+
+	    if (w->struts ())
+	    {
+		r.extents.x1 = w->struts ()->top.x;
+		r.extents.y1 = w->struts ()->top.y;
+		r.extents.x2 = r.extents.x1 + w->struts ()->top.width;
+		r.extents.y2 = r.extents.y1 + w->struts ()->top.height;
+
+		if (r.extents.x1 < extents.x1)
+		    r.extents.x1 = extents.x1;
+		if (r.extents.x2 > extents.x2)
+		    r.extents.x2 = extents.x2;
+		if (r.extents.y1 < extents.y1)
+		    r.extents.y1 = extents.y1;
+		if (r.extents.y2 > extents.y2)
+		    r.extents.y2 = extents.y2;
+
+		if (r.extents.x1 < r.extents.x2 && r.extents.y1 < r.extents.y2)
+		{
+		    if (r.extents.y2 <= workArea.y ())
+			XSubtractRegion (region, &r, region);
+		}
+
+		r.extents.x1 = w->struts ()->bottom.x;
+		r.extents.y1 = w->struts ()->bottom.y;
+		r.extents.x2 = r.extents.x1 + w->struts ()->bottom.width;
+		r.extents.y2 = r.extents.y1 + w->struts ()->bottom.height;
+
+		if (r.extents.x1 < extents.x1)
+		    r.extents.x1 = extents.x1;
+		if (r.extents.x2 > extents.x2)
+		    r.extents.x2 = extents.x2;
+		if (r.extents.y1 < extents.y1)
+		    r.extents.y1 = extents.y1;
+		if (r.extents.y2 > extents.y2)
+		    r.extents.y2 = extents.y2;
+
+		if (r.extents.x1 < r.extents.x2 && r.extents.y1 < r.extents.y2)
+		{
+		    if (r.extents.y1 >= workArea.bottom ())
+			XSubtractRegion (region, &r, region);
+		}
+	    }
+	}
+    }
+
+    return region;
+}
+
+static void
+moveHandleMotionEvent (CompScreen *s,
+		       int	  xRoot,
+		       int	  yRoot)
+{
+    MOVE_SCREEN (s);
+
+    if (ms->grab)
+    {
+	int	     dx, dy;
+	int	     wX, wY;
+	int          wWidth, wHeight;
+	CompWindow   *w;
+
+	w = ms->w;
+
+	wX      = w->geometry ().x ();
+	wY      = w->geometry ().y ();
+	wWidth  = w->geometry ().width () +
+		  w->geometry ().border () * 2;
+	wHeight = w->geometry ().height () +
+		  w->geometry ().border () * 2;
+
+	ms->x += xRoot - lastPointerX;
+	ms->y += yRoot - lastPointerY;
+
+	if (w->type () & CompWindowTypeFullscreenMask)
+	{
+	    dx = dy = 0;
+	}
+	else
+	{
+	    CompRect workArea;
+	    int	     min, max;
+
+	    dx = ms->x;
+	    dy = ms->y;
+
+	    workArea = s->getWorkareaForOutput (w->outputDevice ());
+
+	    if (ms->yConstrained)
+	    {
+		if (!ms->region)
+		    ms->region = moveGetYConstrainRegion (s);
+
+		/* make sure that the top border extents or the top row of
+		   pixels are within what is currently our valid screen
+		   region */
+		if (ms->region)
+		{
+		    int x, y, width, height;
+		    int status;
+
+		    x	   = wX + dx - w->border ().left;
+		    y	   = wY + dy - w->border ().top;
+		    width  = wWidth + w->border ().left + w->border ().right;
+		    height = w->border ().top ? w->border ().top : 1;
+
+		    status = XRectInRegion (ms->region, x, y,
+					    (unsigned int) width,
+					    (unsigned int) height);
+
+		    /* only constrain movement if previous position was valid */
+		    if (ms->status == RectangleIn)
+		    {
+			int xStatus = status;
+
+			while (dx && xStatus != RectangleIn)
+			{
+			    xStatus = XRectInRegion (ms->region,
+						     x, y - dy,
+						     (unsigned int) width,
+						     (unsigned int) height);
+
+			    if (xStatus != RectangleIn)
+				dx += (dx < 0) ? 1 : -1;
+
+			    x = wX + dx - w->border ().left;
+			}
+
+			while (dy && status != RectangleIn)
+			{
+			    status = XRectInRegion (ms->region,
+						    x, y,
+						    (unsigned int) width,
+						    (unsigned int) height);
+
+			    if (status != RectangleIn)
+				dy += (dy < 0) ? 1 : -1;
+
+			    y = wY + dy - w->border ().top;
+			}
+		    }
+		    else
+		    {
+			ms->status = status;
+		    }
+		}
+	    }
+
+	    if (ms->optionGetSnapoffMaximized ())
+	    {
+		if (w->state () & CompWindowStateMaximizedVertMask)
+		{
+		    if (abs (yRoot - workArea.y () - ms->snapOffY) >= SNAP_OFF)
+		    {
+			if (!s->otherGrabExist ("move", NULL))
+			{
+			    int width = w->serverGeometry ().width ();
+
+			    w->saveMask () |= CWX | CWY;
+
+			    if (w->saveMask ()& CWWidth)
+				width = w->saveWc ().width;
+
+			    w->saveWc ().x = xRoot - (width >> 1);
+			    w->saveWc ().y = yRoot + (w->border ().top >> 1);
+
+			    ms->x = ms->y = 0;
+
+			    w->maximize (0);
+
+			    ms->snapOffY = ms->snapBackY;
+
+			    return;
+			}
+		    }
+		}
+		else if (ms->origState & CompWindowStateMaximizedVertMask)
+		{
+		    if (abs (yRoot - workArea.y () - ms->snapBackY) < SNAP_BACK)
+		    {
+			if (!s->otherGrabExist ("move", NULL))
+			{
+			    int wy;
+
+			    /* update server position before maximizing
+			       window again so that it is maximized on
+			       correct output */
+			    w->syncPosition ();
+
+			    w->maximize (ms->origState);
+
+			    wy  = workArea.y () + (w->border ().top >> 1);
+			    wy += w->sizeHints ().height_inc >> 1;
+
+			    s->warpPointer (0, wy - pointerY);
+
+			    return;
+			}
+		    }
+		}
+	    }
+
+	    if (w->state () & CompWindowStateMaximizedVertMask)
+	    {
+		min = workArea.y () + w->border ().top;
+		max = workArea.bottom () - w->border ().bottom - wHeight;
+
+		if (wY + dy < min)
+		    dy = min - wY;
+		else if (wY + dy > max)
+		    dy = max - wY;
+	    }
+
+	    if (w->state () & CompWindowStateMaximizedHorzMask)
+	    {
+		if (wX > (int) s->width () ||
+		    wX + w->size ().width () < 0)
+		    return;
+
+		if (wX + wWidth < 0)
+		    return;
+
+		min = workArea.x () + w->border ().left;
+		max = workArea.right () - w->border ().right - wWidth;
+
+		if (wX + dx < min)
+		    dx = min - wX;
+		else if (wX + dx > max)
+		    dx = max - wX;
+	    }
+	}
+
+	if (dx || dy)
+	{
+	    w->move (wX + dx - w->geometry ().x (),
+		     wY + dy - w->geometry ().y (), false);
+
+	    if (ms->optionGetLazyPositioning () &&
+		ms->hasCompositing &&
+		!MoveWindow::get (ms->w)->mLocked)
+	    {
+		/* FIXME: This form of lazy positioning is broken and should
+		   be replaced asap. Current code exists just to avoid a
+		   major performance regression in the 0.5.2 release. */
+		w->serverGeometry ().setX (w->geometry ().x ());
+		w->serverGeometry ().setY (w->geometry ().y ());
+	    }
+	    else
+	    {
+		w->syncPosition ();
+	    }
+
+	    ms->x -= dx;
+	    ms->y -= dy;
+	}
+    }
+}
+
+/* FIXME: This is a hack to prevent a race condition
+ * when core is processing ConfigureNotify events. It
+ * MUST be removed after 0.9.6 when we can break ABI
+ * and do lazy positioning correctly ! */
+
+void
+MoveScreen::handleCompizEvent (const char *plugin, const char *event, CompOption::Vector &options)
+{
+    if (w)
+    {
+	if (std::string ("core") == std::string (plugin))
+	{
+	    if (std::string ("lock_position") == std::string (event))
+	    {
+		Window xid = CompOption::getIntOptionNamed (options, "window", 0);
+		int    lock = CompOption::getIntOptionNamed (options, "active", 0);
+
+		if (xid == ROOTPARENT (w))
+		    MoveWindow::get (w)->mLocked = lock ? true : false;
+	    }
+	}
+    }
+
+    screen->handleCompizEvent (plugin, event, options);
+}
+
+void
+MoveScreen::handleEvent (XEvent *event)
+{
+    switch (event->type) {
+	case ButtonPress:
+	case ButtonRelease:
+	    if (event->xbutton.root == screen->root ())
+	    {
+		if (grab)
+		{
+		    if (releaseButton == -1 ||
+			releaseButton == (int) event->xbutton.button)
+		    {
+			moveTerminate (&optionGetInitiateButton (),
+				       CompAction::StateTermButton,
+				       noOptions);
+		    }
+		}
+	    }
+	    break;
+	case KeyPress:
+	    if (event->xkey.root == screen->root ())
+	    {
+		if (grab)
+		{
+		    unsigned int i;
+
+		    for (i = 0; i < NUM_KEYS; i++)
+		    {
+			if (event->xkey.keycode == key[i])
+			{
+			    XWarpPointer (screen->dpy (), None, None,
+					  0, 0, 0, 0,
+					  mKeys[i].dx * KEY_MOVE_INC,
+					  mKeys[i].dy * KEY_MOVE_INC);
+			    break;
+			}
+		    }
+		}
+	    }
+	    break;
+	case MotionNotify:
+	    if (event->xmotion.root == screen->root ())
+		moveHandleMotionEvent (screen, pointerX, pointerY);
+	    break;
+	case EnterNotify:
+	case LeaveNotify:
+	    if (event->xcrossing.root == screen->root ())
+		moveHandleMotionEvent (screen, pointerX, pointerY);
+	    break;
+	case ClientMessage:
+	    if (event->xclient.message_type == Atoms::wmMoveResize)
+	    {
+		CompWindow *w;
+		unsigned   long type = (unsigned long) event->xclient.data.l[2];
+
+		MOVE_SCREEN (screen);
+
+		if (type == WmMoveResizeMove ||
+		    type == WmMoveResizeMoveKeyboard)
+		{
+		    w = screen->findWindow (event->xclient.window);
+		    if (w)
+		    {
+			CompOption::Vector o;
+
+			o.push_back (CompOption ("window", CompOption::TypeInt));
+			o[0].value ().set ((int) event->xclient.window);
+
+			o.push_back (CompOption ("external",
+				     CompOption::TypeBool));
+			o[1].value ().set (true);
+
+			if (event->xclient.data.l[2] == WmMoveResizeMoveKeyboard)
+			{
+			    moveInitiate (&optionGetInitiateKey (),
+					  CompAction::StateInitKey, o);
+			}
+			else
+			{
+
+			    /* TODO: not only button 1 */
+			    if (pointerMods & Button1Mask)
+			    {
+				o.push_back (CompOption ("modifiers", CompOption::TypeInt));
+				o[2].value ().set ((int) pointerMods);
+
+				o.push_back (CompOption ("x", CompOption::TypeInt));
+				o[3].value ().set ((int) event->xclient.data.l[0]);
+
+				o.push_back (CompOption ("y", CompOption::TypeInt));
+				o[4].value ().set ((int) event->xclient.data.l[1]);
+
+				o.push_back (CompOption ("button", CompOption::TypeInt));
+				o[5].value ().set ((int) (event->xclient.data.l[3] ?
+					       event->xclient.data.l[3] : -1));
+
+				moveInitiate (&optionGetInitiateButton (),
+					      CompAction::StateInitButton, o);
+
+				moveHandleMotionEvent (screen, pointerX, pointerY);
+			    }
+			}
+		    }
+		}
+		else if (ms->w && type == WmMoveResizeCancel)
+		{
+		    if (ms->w->id () == event->xclient.window)
+		    {
+			moveTerminate (&optionGetInitiateButton (),
+				       CompAction::StateCancel, noOptions);
+			moveTerminate (&optionGetInitiateKey (),
+				       CompAction::StateCancel, noOptions);
+
+		    }
+		}
+	    }
+	    break;
+	case DestroyNotify:
+	    if (w && w->id () == event->xdestroywindow.window)
+	    {
+		moveTerminate (&optionGetInitiateButton (), 0, noOptions);
+		moveTerminate (&optionGetInitiateKey (), 0, noOptions);
+	    }
+	    break;
+	case UnmapNotify:
+	    if (w && w->id () == event->xunmap.window)
+	    {
+		moveTerminate (&optionGetInitiateButton (), 0, noOptions);
+		moveTerminate (&optionGetInitiateKey (), 0, noOptions);
+	    }
+	default:
+	    break;
+    }
+
+    screen->handleEvent (event);
+}
+
+bool
+MoveWindow::glPaint (const GLWindowPaintAttrib &attrib,
+		     const GLMatrix            &transform,
+		     const CompRegion          &region,
+		     unsigned int              mask)
+{
+    GLWindowPaintAttrib sAttrib = attrib;
+    bool                status;
+
+    MOVE_SCREEN (screen);
+
+    if (ms->grab)
+    {
+	if (ms->w == window && ms->moveOpacity != OPAQUE)
+	{
+	    /* modify opacity of windows that are not active */
+	    sAttrib.opacity = (sAttrib.opacity * ms->moveOpacity) >> 16;
+	}
+    }
+
+    status = gWindow->glPaint (sAttrib, transform, region, mask);
+
+    return status;
+}
+
+void
+MoveScreen::updateOpacity ()
+{
+    moveOpacity = (optionGetOpacity () * OPAQUE) / 100;
+}
+
+MoveScreen::MoveScreen (CompScreen *screen) :
+    PluginClassHandler<MoveScreen,CompScreen> (screen),
+    w (0),
+    region (NULL),
+    status (RectangleOut),
+    releaseButton (0),
+    grab (NULL),
+    hasCompositing (false),
+    yConstrained (false)
+{
+
+    updateOpacity ();
+
+    for (unsigned int i = 0; i < NUM_KEYS; i++)
+	key[i] = XKeysymToKeycode (screen->dpy (),
+				   XStringToKeysym (mKeys[i].name));
+
+    moveCursor = XCreateFontCursor (screen->dpy (), XC_fleur);
+    if (CompositeScreen::get (screen))
+	hasCompositing =
+	    CompositeScreen::get (screen)->compositingActive ();
+
+    optionSetOpacityNotify (boost::bind (&MoveScreen::updateOpacity, this));
+
+    optionSetInitiateButtonInitiate (moveInitiate);
+    optionSetInitiateButtonTerminate (moveTerminate);
+
+    optionSetInitiateKeyInitiate (moveInitiate);
+    optionSetInitiateKeyTerminate (moveTerminate);
+
+    ScreenInterface::setHandler (screen);
+}
+
+MoveScreen::~MoveScreen ()
+{
+    if (region)
+	XDestroyRegion (region);
+
+    if (moveCursor)
+	XFreeCursor (screen->dpy (), moveCursor);
+}
+
+bool
+MovePluginVTable::init ()
+{
+    if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
+	 return false;
+
+    return true;
+}
+

=== added file '.pc/fix-881329.patch/plugins/move/src/move.h'
--- .pc/fix-881329.patch/plugins/move/src/move.h	1970-01-01 00:00:00 +0000
+++ .pc/fix-881329.patch/plugins/move/src/move.h	2011-10-29 09:07:25 +0000
@@ -0,0 +1,135 @@
+/*
+ * Copyright © 2005 Novell, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Novell, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * Novell, Inc. makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: David Reveman <davidr@xxxxxxxxxx>
+ */
+
+#include <core/core.h>
+#include <core/pluginclasshandler.h>
+
+#include <composite/composite.h>
+#include <opengl/opengl.h>
+
+#include "move_options.h"
+
+#define NUM_KEYS (sizeof (mKeys) / sizeof (mKeys[0]))
+
+#define KEY_MOVE_INC 24
+
+#define SNAP_BACK 20
+#define SNAP_OFF  100
+
+struct _MoveKeys {
+    const char *name;
+    int        dx;
+    int        dy;
+} mKeys[] = {
+    { "Left",  -1,  0 },
+    { "Right",  1,  0 },
+    { "Up",     0, -1 },
+    { "Down",   0,  1 }
+};
+
+class MoveScreen :
+    public ScreenInterface,
+    public PluginClassHandler<MoveScreen,CompScreen>,
+    public MoveOptions
+{
+    public:
+	MoveScreen (CompScreen *screen);
+	~MoveScreen ();
+
+	void updateOpacity ();
+
+	void handleEvent (XEvent *);
+	void handleCompizEvent (const char *plugin,
+				const char *event,
+				CompOption::Vector &options);
+
+	CompWindow *w;
+	int        savedX;
+	int        savedY;
+	int        x;
+	int        y;
+	Region     region;
+	int        status;
+	KeyCode    key[NUM_KEYS];
+
+	int releaseButton;
+
+	GLushort moveOpacity;
+
+	CompScreen::GrabHandle grab;
+
+	Cursor moveCursor;
+
+	unsigned int origState;
+
+	int	snapOffY;
+	int	snapBackY;
+
+	bool hasCompositing;
+
+	bool yConstrained;
+};
+
+class MoveWindow :
+    public GLWindowInterface,
+    public PluginClassHandler<MoveWindow,CompWindow>
+{
+    public:
+	MoveWindow (CompWindow *window) :
+	    PluginClassHandler<MoveWindow,CompWindow> (window),
+	    window (window),
+	    gWindow (GLWindow::get (window)),
+	    cWindow (CompositeWindow::get (window)),
+	    mLocked (false)
+	{
+	    if (gWindow)
+		GLWindowInterface::setHandler (gWindow, false);
+	};
+
+	bool glPaint (const GLWindowPaintAttrib &, const GLMatrix &,
+		      const CompRegion &, unsigned int);
+
+	CompWindow      *window;
+	GLWindow        *gWindow;
+	CompositeWindow *cWindow;
+
+	bool            mLocked;
+};
+
+#define MOVE_SCREEN(s) \
+    MoveScreen *ms = MoveScreen::get (s)
+
+#define MOVE_WINDOW(w) \
+    MoveWindow *mw = MoveWindow::get (w)
+
+
+class MovePluginVTable :
+    public CompPlugin::VTableForScreenAndWindow<MoveScreen, MoveWindow>
+{
+    public:
+
+	bool init ();
+};
+

=== added directory '.pc/fix-883383.patch'
=== added file '.pc/fix-883383.patch/.timestamp'
=== added directory '.pc/fix-883383.patch/unity'
=== added directory '.pc/fix-883383.patch/unity/unity_window_decorator'
=== added directory '.pc/fix-883383.patch/unity/unity_window_decorator/src'
=== added file '.pc/fix-883383.patch/unity/unity_window_decorator/src/events.c'
--- .pc/fix-883383.patch/unity/unity_window_decorator/src/events.c	1970-01-01 00:00:00 +0000
+++ .pc/fix-883383.patch/unity/unity_window_decorator/src/events.c	2011-10-29 09:07:25 +0000
@@ -0,0 +1,1146 @@
+#include "gtk-window-decorator.h"
+
+void
+move_resize_window (WnckWindow *win,
+		    int	       direction,
+		    decor_event *gtkwd_event)
+{
+    Display    *xdisplay;
+    GdkDisplay *gdkdisplay;
+    GdkScreen  *screen;
+    Window     xroot;
+    XEvent     ev;
+
+    gdkdisplay = gdk_display_get_default ();
+    xdisplay   = GDK_DISPLAY_XDISPLAY (gdkdisplay);
+    screen     = gdk_display_get_default_screen (gdkdisplay);
+    xroot      = RootWindowOfScreen (gdk_x11_screen_get_xscreen (screen));
+
+    if (action_menu_mapped)
+    {
+	gtk_object_destroy (GTK_OBJECT (action_menu));
+	action_menu_mapped = FALSE;
+	action_menu = NULL;
+	return;
+    }
+
+    ev.xclient.type    = ClientMessage;
+    ev.xclient.display = xdisplay;
+
+    ev.xclient.serial	  = 0;
+    ev.xclient.send_event = TRUE;
+
+    ev.xclient.window	    = wnck_window_get_xid (win);
+    ev.xclient.message_type = wm_move_resize_atom;
+    ev.xclient.format	    = 32;
+
+    ev.xclient.data.l[0] = gtkwd_event->x_root;
+    ev.xclient.data.l[1] = gtkwd_event->y_root;
+    ev.xclient.data.l[2] = direction;
+    ev.xclient.data.l[3] = gtkwd_event->button;
+    ev.xclient.data.l[4] = 1;
+
+    XUngrabPointer (xdisplay, gtkwd_event->time);
+    XUngrabKeyboard (xdisplay, gtkwd_event->time);
+
+    XSendEvent (xdisplay, xroot, FALSE,
+		SubstructureRedirectMask | SubstructureNotifyMask,
+		&ev);
+
+    XSync (xdisplay, FALSE);
+}
+
+void
+common_button_event (WnckWindow *win,
+		     decor_event *gtkwd_event,
+		     decor_event_type gtkwd_type,
+		     int	button,
+		     int	max)
+{
+    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+    guint   state = d->button_states[button];
+
+    if (d->frame_window && gtkwd_type == GEnterNotify)
+    {
+	GdkCursor* cursor;
+	cursor = gdk_cursor_new (GDK_LEFT_PTR);
+	gdk_window_set_cursor (d->frame_window, cursor);
+	gdk_cursor_unref (cursor);
+    }
+
+    switch (gtkwd_type) {
+    case GButtonPress:
+	if (gtkwd_event->button <= max)
+	    d->button_states[button] |= PRESSED_EVENT_WINDOW;
+	break;
+    case GButtonRelease:
+	if (gtkwd_event->button <= max)
+	    d->button_states[button] &= ~PRESSED_EVENT_WINDOW;
+	break;
+    case GEnterNotify:
+	d->button_states[button] |= IN_EVENT_WINDOW;
+	break;
+    case GLeaveNotify:
+	d->button_states[button] &= ~IN_EVENT_WINDOW;
+	break;
+    default:
+	break;
+    }
+
+    if (state != d->button_states[button])
+	queue_decor_draw (d);
+}
+
+#define BUTTON_EVENT_ACTION_STATE (PRESSED_EVENT_WINDOW | IN_EVENT_WINDOW)
+
+void
+close_button_event (WnckWindow *win,
+		    decor_event *gtkwd_event,
+		    decor_event_type gtkwd_type)
+{
+    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+    guint   state = d->button_states[BUTTON_CLOSE];
+
+    common_button_event (win, gtkwd_event, gtkwd_type,
+			 BUTTON_CLOSE, 1);
+
+    switch (gtkwd_type) {
+    case GButtonRelease:
+	if (gtkwd_event->button == 1)
+	    if (state == BUTTON_EVENT_ACTION_STATE)
+		wnck_window_close (win, gtkwd_event->time);
+	break;
+    default:
+	break;
+    }
+}
+
+void
+max_button_event (WnckWindow *win,
+		  decor_event *gtkwd_event,
+		  decor_event_type gtkwd_type)
+{
+    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+    guint   state = d->button_states[BUTTON_MAX];
+
+    if (wnck_window_is_maximized (win))
+	common_button_event (win, gtkwd_event, gtkwd_type, BUTTON_MAX,
+			     3);
+    else
+	common_button_event (win, gtkwd_event, gtkwd_type, BUTTON_MAX,
+			     3);
+
+    switch (gtkwd_type) {
+    case GButtonRelease:
+	if (gtkwd_event->button <= 3)
+	{
+	    if (state == BUTTON_EVENT_ACTION_STATE)
+	    {
+		if (gtkwd_event->button == 2)
+		{
+		    if (wnck_window_is_maximized_vertically (win))
+			wnck_window_unmaximize_vertically (win);
+		    else
+			wnck_window_maximize_vertically (win);
+		}
+		else if (gtkwd_event->button == 3)
+		{
+		    if (wnck_window_is_maximized_horizontally (win))
+			wnck_window_unmaximize_horizontally (win);
+		    else
+			wnck_window_maximize_horizontally (win);
+		}
+		else
+		{
+		    if (wnck_window_is_maximized (win))
+			wnck_window_unmaximize (win);
+		    else
+			wnck_window_maximize (win);
+		}
+	    }
+	}
+	break;
+    default:
+	break;
+    }
+}
+
+void
+min_button_event (WnckWindow *win,
+		  decor_event *gtkwd_event,
+		  decor_event_type gtkwd_type)
+{
+    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+    guint   state = d->button_states[BUTTON_MIN];
+
+    common_button_event (win, gtkwd_event, gtkwd_type,
+			 BUTTON_MIN, 1);
+
+    switch (gtkwd_type) {
+    case GButtonRelease:
+	if (gtkwd_event->button == 1)
+	    if (state == BUTTON_EVENT_ACTION_STATE)
+		wnck_window_minimize (win);
+	break;
+    default:
+	break;
+    }
+}
+
+void
+menu_button_event (WnckWindow *win,
+		   decor_event *gtkwd_event,
+		   decor_event_type gtkwd_type)
+{
+
+    common_button_event (win, gtkwd_event, gtkwd_type,
+			 BUTTON_MENU, 1);
+
+    switch (gtkwd_type) {
+    case GButtonPress:
+	if (gtkwd_event->button == 1)
+	    action_menu_map (win,
+			     gtkwd_event->button,
+			     gtkwd_event->time);
+	break;
+    default:
+	break;
+    }
+}
+
+void
+shade_button_event (WnckWindow *win,
+		    decor_event *gtkwd_event,
+		    decor_event_type gtkwd_type)
+{
+    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+    guint   state = d->button_states[BUTTON_SHADE];
+
+    common_button_event (win, gtkwd_event, gtkwd_type,
+			 BUTTON_SHADE, 1);
+
+    switch (gtkwd_type) {
+    case GButtonRelease:
+	if (gtkwd_event->button == 1)
+	{
+	    if (state == BUTTON_EVENT_ACTION_STATE)
+		wnck_window_shade (win);
+	}
+	break;
+    default:
+	break;
+    }
+}
+
+void
+above_button_event (WnckWindow *win,
+		    decor_event *gtkwd_event,
+		    decor_event_type gtkwd_type)
+{
+    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+    guint   state = d->button_states[BUTTON_ABOVE];
+
+    common_button_event (win, gtkwd_event, gtkwd_type,
+			 BUTTON_ABOVE, 1);
+
+    switch (gtkwd_type) {
+    case GButtonRelease:
+	if (gtkwd_event->button == 1)
+	    if (state == BUTTON_EVENT_ACTION_STATE)
+#ifdef HAVE_LIBWNCK_2_18_1
+		wnck_window_make_above (win);
+#endif
+	break;
+    default:
+	break;
+    }
+}
+
+void
+stick_button_event (WnckWindow *win,
+		    decor_event *gtkwd_event,
+		    decor_event_type gtkwd_type)
+{
+    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+    guint   state = d->button_states[BUTTON_STICK];
+
+    common_button_event (win, gtkwd_event, gtkwd_type,
+			 BUTTON_STICK, 1);
+
+    switch (gtkwd_type) {
+    case GButtonRelease:
+	if (gtkwd_event->button == 1)
+	    if (state == BUTTON_EVENT_ACTION_STATE)
+		wnck_window_stick (win);
+	break;
+    default:
+	break;
+    }
+}
+
+void
+unshade_button_event (WnckWindow *win,
+		      decor_event *gtkwd_event,
+		      decor_event_type gtkwd_type)
+{
+    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+    guint   state = d->button_states[BUTTON_UNSHADE];
+
+    common_button_event (win, gtkwd_event, gtkwd_type,
+			 BUTTON_UNSHADE, 1);
+
+    switch (gtkwd_type) {
+    case GButtonRelease:
+	if (gtkwd_event->button == 1)
+	    if (state == BUTTON_EVENT_ACTION_STATE)
+		wnck_window_unshade (win);
+	break;
+    default:
+	break;
+    }
+}
+
+void
+unabove_button_event (WnckWindow *win,
+		      decor_event *gtkwd_event,
+		      decor_event_type gtkwd_type)
+{
+    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+    guint   state = d->button_states[BUTTON_UNABOVE];
+
+    common_button_event (win, gtkwd_event, gtkwd_type,
+			 BUTTON_UNABOVE, 1);
+
+    switch (gtkwd_type) {
+    case GButtonRelease:
+	if (gtkwd_event->button == 1)
+	    if (state == BUTTON_EVENT_ACTION_STATE)
+#ifdef HAVE_LIBWNCK_2_18_1
+		wnck_window_unmake_above (win);
+#endif
+	break;
+    default:
+	break;
+    }
+}
+
+void
+unstick_button_event (WnckWindow *win,
+		      decor_event *gtkwd_event,
+		      decor_event_type gtkwd_type)
+{
+    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+    guint   state = d->button_states[BUTTON_UNSTICK];
+
+    common_button_event (win, gtkwd_event, gtkwd_type,
+			 BUTTON_UNSTICK, 1);
+
+    switch (gtkwd_type) {
+    case GButtonRelease:
+	if (gtkwd_event->button == 1)
+	    if (state == BUTTON_EVENT_ACTION_STATE)
+		wnck_window_unstick (win);
+	break;
+    default:
+	break;
+    }
+}
+
+void
+handle_title_button_event (WnckWindow   *win,
+			   int          action,
+			   decor_event *gtkwd_event)
+{
+    switch (action) {
+    case CLICK_ACTION_SHADE:
+	if (wnck_window_is_shaded (win))
+	    wnck_window_unshade (win);
+	else
+	    wnck_window_shade (win);
+	break;
+    case CLICK_ACTION_MAXIMIZE:
+	if (wnck_window_is_maximized (win))
+	    wnck_window_unmaximize (win);
+	else
+	    wnck_window_maximize (win);
+	break;
+    case CLICK_ACTION_MINIMIZE:
+	if (!wnck_window_is_minimized (win))
+	    wnck_window_minimize (win);
+	break;
+    case CLICK_ACTION_RAISE:
+	restack_window (win, Above);
+	break;
+    case CLICK_ACTION_LOWER:
+	restack_window (win, Below);
+	break;
+    case CLICK_ACTION_MENU:
+	action_menu_map (win, gtkwd_event->button, gtkwd_event->time);
+	break;
+    }
+}
+
+void
+handle_mouse_wheel_title_event (WnckWindow   *win,
+				unsigned int button)
+{
+    switch (wheel_action) {
+    case WHEEL_ACTION_SHADE:
+	if (button == 4)
+	{
+	    if (!wnck_window_is_shaded (win))
+		wnck_window_shade (win);
+	}
+	else if (button == 5)
+	{
+	    if (wnck_window_is_shaded (win))
+		wnck_window_unshade (win);
+	}
+	break;
+    default:
+	break;
+    }
+}
+
+void
+title_event (WnckWindow       *win,
+	     decor_event      *gtkwd_event,
+	     decor_event_type gtkwd_type)
+{
+    static int	  last_button_num = 0;
+    static Window last_button_xwindow = None;
+    static Time	  last_button_time = 0;
+    static int	  last_button_x = 0;
+    static int	  last_button_y = 0;
+
+    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+
+    if (d->frame_window && gtkwd_type == GEnterNotify)
+    {
+	GdkCursor* cursor = gdk_cursor_new (GDK_LEFT_PTR);
+	gdk_window_set_cursor (d->frame_window, cursor);
+	gdk_cursor_unref (cursor);
+    }
+
+    if (gtkwd_type != GButtonPress)
+	return;
+
+    if (gtkwd_event->button == 1)
+    {
+	if (gtkwd_event->button == last_button_num		        &&
+	    gtkwd_event->window == last_button_xwindow		        &&
+	    gtkwd_event->time < last_button_time + double_click_timeout &&
+	    dist (gtkwd_event->x, gtkwd_event->y,
+		  last_button_x, last_button_y) < DOUBLE_CLICK_DISTANCE)
+	{
+	    handle_title_button_event (win, double_click_action,
+				       gtkwd_event);
+
+	    last_button_num	= 0;
+	    last_button_xwindow = None;
+	    last_button_time	= 0;
+	    last_button_x	= 0;
+	    last_button_y	= 0;
+	}
+	else
+	{
+	    last_button_num	= gtkwd_event->button;
+	    last_button_xwindow = gtkwd_event->window;
+	    last_button_time	= gtkwd_event->time;
+	    last_button_x	= gtkwd_event->x;
+	    last_button_y	= gtkwd_event->y;
+
+	    restack_window (win, Above);
+
+	    move_resize_window (win, WM_MOVERESIZE_MOVE, gtkwd_event);
+	}
+    }
+    else if (gtkwd_event->button == 2)
+    {
+	handle_title_button_event (win, middle_click_action,
+				   gtkwd_event);
+    }
+    else if (gtkwd_event->button == 3)
+    {
+	handle_title_button_event (win, right_click_action,
+				   gtkwd_event);
+    }
+    else if (gtkwd_event->button == 4 ||
+	     gtkwd_event->button == 5)
+    {
+	handle_mouse_wheel_title_event (win, gtkwd_event->button);
+    }
+}
+
+void
+frame_common_event (WnckWindow       *win,
+		    int              direction,
+		    decor_event      *gtkwd_event,
+		    decor_event_type gtkwd_type)
+{
+
+    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+
+    if (d->frame_window && gtkwd_type == GEnterNotify)
+    {
+	GdkCursor *cursor = NULL;
+
+	switch (direction)
+	{
+	    case WM_MOVERESIZE_SIZE_TOPLEFT:
+		cursor = gdk_cursor_new (GDK_TOP_LEFT_CORNER);
+		break;
+	    case WM_MOVERESIZE_SIZE_LEFT:
+		cursor = gdk_cursor_new (GDK_LEFT_SIDE);
+		break;
+	    case WM_MOVERESIZE_SIZE_BOTTOMLEFT:
+		cursor = gdk_cursor_new (GDK_BOTTOM_LEFT_CORNER);
+		break;
+	    case WM_MOVERESIZE_SIZE_BOTTOM:
+		cursor = gdk_cursor_new (GDK_BOTTOM_SIDE);
+	        break;
+	    case WM_MOVERESIZE_SIZE_BOTTOMRIGHT:
+		cursor = gdk_cursor_new (GDK_BOTTOM_RIGHT_CORNER);
+		break;
+	    case WM_MOVERESIZE_SIZE_RIGHT:
+		cursor = gdk_cursor_new (GDK_RIGHT_SIDE);
+		break;
+	    case WM_MOVERESIZE_SIZE_TOPRIGHT:
+		cursor = gdk_cursor_new (GDK_TOP_RIGHT_CORNER);
+		break;
+	    case WM_MOVERESIZE_SIZE_TOP:
+		cursor = gdk_cursor_new (GDK_TOP_SIDE);
+		break;
+	    default:
+		break;
+	}
+
+	if (cursor)
+	{
+	    gdk_window_set_cursor (d->frame_window, cursor);
+	    gdk_cursor_unref (cursor);
+	}
+    }
+
+    if (gtkwd_type != GButtonPress)
+	return;
+
+    switch (gtkwd_event->button) {
+    case 1:
+	move_resize_window (win, direction, gtkwd_event);
+	restack_window (win, Above);
+	break;
+    case 2:
+	handle_title_button_event (win, middle_click_action,
+				   gtkwd_event);
+	break;
+    case 3:
+	handle_title_button_event (win, right_click_action,
+				   gtkwd_event);
+	break;
+    }
+}
+
+void
+top_left_event (WnckWindow       *win,
+		decor_event      *gtkwd_event,
+		decor_event_type gtkwd_type)
+{
+    frame_common_event (win, WM_MOVERESIZE_SIZE_TOPLEFT,
+		        gtkwd_event, gtkwd_type);
+}
+
+void
+top_event (WnckWindow       *win,
+	   decor_event      *gtkwd_event,
+	   decor_event_type gtkwd_type)
+{
+    frame_common_event (win, WM_MOVERESIZE_SIZE_TOP,
+			gtkwd_event, gtkwd_type);
+}
+
+void
+top_right_event (WnckWindow       *win,
+		 decor_event      *gtkwd_event,
+		 decor_event_type gtkwd_type)
+{
+    frame_common_event (win, WM_MOVERESIZE_SIZE_TOPRIGHT,
+			gtkwd_event, gtkwd_type);
+}
+
+void
+left_event (WnckWindow       *win,
+	    decor_event      *gtkwd_event,
+	    decor_event_type gtkwd_type)
+{
+    frame_common_event (win, WM_MOVERESIZE_SIZE_LEFT,
+			gtkwd_event, gtkwd_type);
+}
+
+void
+right_event (WnckWindow       *win,
+	     decor_event      *gtkwd_event,
+	     decor_event_type gtkwd_type)
+{
+    frame_common_event (win, WM_MOVERESIZE_SIZE_RIGHT,
+			gtkwd_event, gtkwd_type);
+}
+
+void
+bottom_left_event (WnckWindow *win,
+		   decor_event *gtkwd_event,
+		   decor_event_type gtkwd_type)
+{
+    frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOMLEFT,
+			gtkwd_event, gtkwd_type);
+}
+
+void
+bottom_event (WnckWindow *win,
+	      decor_event *gtkwd_event,
+	      decor_event_type gtkwd_type)
+{
+    frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOM,
+			gtkwd_event, gtkwd_type);
+}
+
+void
+bottom_right_event (WnckWindow *win,
+		    decor_event *gtkwd_event,
+		    decor_event_type gtkwd_type)
+{
+    frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOMRIGHT,
+			gtkwd_event, gtkwd_type);
+}
+
+void
+frame_window_realized (GtkWidget *widget,
+		       gpointer  data)
+{
+    decor_t *d = (decor_t *) data;
+
+    if (d)
+    {
+	GdkWindow *gdk_frame_window = gtk_widget_get_window (d->decor_window);
+	gdk_window_reparent (gdk_frame_window, d->frame_window, 0, 0);
+	gdk_window_lower (gdk_frame_window);
+
+    }
+}
+
+event_callback
+find_event_callback_for_point (decor_t *d,
+			       int     x,
+			       int     y,
+			       Bool    *enter,
+			       Bool    *leave,
+			       BoxPtr  *entered_box)
+{
+    int    i, j;
+    BoxPtr box;
+
+    for (i = 0; i < BUTTON_NUM; i++)
+    {
+	box = &d->button_windows[i].pos;
+	if (x >= box->x1 && x <= box->x2 &&
+	    y >= box->y1 && y <= box->y2)
+	{
+	    if (d->last_pos_entered != box)
+	    {
+		if (enter)
+		    *enter = TRUE;
+		if (leave && d->last_pos_entered)
+		    *leave = TRUE;
+		if (entered_box)
+		    *entered_box = box;
+	    }
+	    return d->button_windows[i].callback;
+	}
+    }
+
+    for (i = 0; i < 3; i++)
+    {
+	for (j = 0; j < 3; j++)
+	{
+	    box = &d->event_windows[i][j].pos;
+	    if (x >= box->x1 && x <= box->x2 &&
+		y >= box->y1 && y <= box->y2)
+	    {
+		if (d->last_pos_entered != box)
+		{
+		    if (enter)
+			*enter = TRUE;
+		    if (leave && d->last_pos_entered)
+			*leave = TRUE;
+		    if (entered_box)
+			*entered_box = box;
+		}
+		return d->event_windows[i][j].callback;
+	    }
+	}
+    }
+
+    return NULL;
+}
+
+event_callback
+find_leave_event_callback (decor_t *d)
+{
+    int i, j;
+
+    for (i = 0; i < BUTTON_NUM; i++)
+    {
+	if (d->last_pos_entered == &d->button_windows[i].pos)
+	    return d->button_windows[i].callback;
+    }
+
+    for (i = 0; i < 3; i++)
+    {
+	for (j = 0; j < 3; j++)
+	{
+	    if (d->last_pos_entered == &d->event_windows[i][j].pos)
+		return d->event_windows[i][j].callback;
+	}
+    }
+
+    return NULL;
+}
+
+void
+frame_handle_button_press (GtkWidget      *widget,
+			   GdkEventButton *event,
+			   gpointer       user_data)
+{
+    decor_t *d = (decor_t *) user_data;
+
+    if (d)
+    {
+	/* Check to see where the event happened and fill out an appropriate
+	 * struct
+	 */
+	event_callback cb;
+
+	cb = find_event_callback_for_point (d, event->x, event->y,
+					    NULL, NULL, NULL);
+
+	if (cb && d->decorated)
+	{
+	    decor_event gtkwd_event;
+
+	    gtkwd_event.window = GDK_WINDOW_XID (d->frame_window);
+	    gtkwd_event.button = event->button;
+	    gtkwd_event.x      = event->x;
+	    gtkwd_event.y      = event->y;
+	    gtkwd_event.x_root = event->x_root;
+	    gtkwd_event.y_root = event->y_root;
+	    gtkwd_event.time   = event->time;
+
+	    (*cb) (d->win, &gtkwd_event, GButtonPress);
+	}
+    }
+}
+
+void
+frame_handle_button_release (GtkWidget      *widget,
+			     GdkEventButton *event,
+			     gpointer       user_data)
+{
+    decor_t *d = (decor_t *) user_data;
+
+    if (d)
+    {
+	event_callback cb;
+
+	cb = find_event_callback_for_point (d, event->x, event->y,
+					    NULL, NULL, NULL);
+
+	if (cb && d->decorated)
+	{
+	    decor_event gtkwd_event;
+
+	    gtkwd_event.window = GDK_WINDOW_XID (d->frame_window);
+	    gtkwd_event.button = event->button;
+	    gtkwd_event.x      = event->x;
+	    gtkwd_event.y      = event->y;
+	    gtkwd_event.x_root = event->x_root;
+	    gtkwd_event.y_root = event->y_root;
+	    gtkwd_event.time   = event->time;
+
+	    (*cb) (d->win, &gtkwd_event, GButtonRelease);
+	}
+    }
+}
+
+void
+frame_handle_motion (GtkWidget      *widget,
+		     GdkEventMotion *event,
+		     gpointer       user_data)
+{
+    decor_t *d = (decor_t *) user_data;
+
+    if (d)
+    {
+	event_callback cb = NULL;
+	Bool           send_enter = FALSE;
+	Bool           send_leave = FALSE;
+	BoxPtr         entered_box;
+
+	cb = find_event_callback_for_point (d, event->x, event->y,
+					    &send_enter, &send_leave,
+					    &entered_box);
+
+	if (cb && d->decorated)
+	{
+	    decor_event gtkwd_event;
+
+	    gtkwd_event.window = GDK_WINDOW_XID (d->frame_window);
+	    gtkwd_event.x      = event->x;
+	    gtkwd_event.y      = event->y;
+	    gtkwd_event.x_root = event->x_root;
+	    gtkwd_event.y_root = event->y_root;
+	    gtkwd_event.time   = event->time;
+
+	    if (send_enter)
+		(*cb) (d->win, &gtkwd_event, GEnterNotify);
+
+	    if (send_leave)
+	    {
+		event_callback leave_cb;
+
+		leave_cb = find_leave_event_callback (d);
+
+		if (leave_cb)
+		    (*leave_cb) (d->win, &gtkwd_event, GLeaveNotify);
+
+	    }
+
+	    if (send_enter)
+		d->last_pos_entered = entered_box;
+	}
+	else if (d->last_pos_entered && d->decorated)
+	{
+	    /* We are not in an event / button window but last_pos_entered
+	     * is still set, so send a GLeaveNotify to last_pos_entered
+	     * and set it to NULL
+	     */
+
+	    event_callback leave_cb;
+
+	    leave_cb = find_leave_event_callback (d);
+
+	    if (leave_cb)
+	    {
+		decor_event    gtkwd_event;
+
+		gtkwd_event.window = GDK_WINDOW_XID (d->frame_window);
+		gtkwd_event.x      = event->x;
+		gtkwd_event.y      = event->y;
+		gtkwd_event.x_root = event->x_root;
+		gtkwd_event.y_root = event->y_root;
+		gtkwd_event.time   = event->time;
+
+		(*leave_cb) (d->win, &gtkwd_event, GLeaveNotify);
+	    }
+
+	    d->last_pos_entered = NULL;
+	}
+    }
+}
+
+GdkFilterReturn
+event_filter_func (GdkXEvent *gdkxevent,
+		   GdkEvent  *event,
+		   gpointer  data)
+{
+    Display    *xdisplay;
+    GdkDisplay *gdkdisplay;
+    XEvent     *xevent = gdkxevent;
+    gulong     xid = 0;
+    Window     select = 0;
+
+    gdkdisplay = gdk_display_get_default ();
+    xdisplay   = GDK_DISPLAY_XDISPLAY (gdkdisplay);
+
+    switch (xevent->type) {
+    case CreateNotify:
+	{
+	    if (!wnck_window_get (xevent->xcreatewindow.window))
+	    {
+		GdkWindow *toplevel = create_foreign_window (xevent->xcreatewindow.window);
+
+		if (toplevel)
+		{
+		    gdk_window_set_events (toplevel,
+					   gdk_window_get_events (toplevel) |
+					   GDK_PROPERTY_CHANGE_MASK);
+
+		    /* check if the window is a switcher and update accordingly */
+
+		    if (get_window_prop (xevent->xcreatewindow.window, select_window_atom, &select))
+			update_switcher_window (xevent->xcreatewindow.window, select);
+		}
+	    }
+	}
+	break;
+    case ButtonPress:
+    case ButtonRelease:
+	xid = (gulong)
+	    g_hash_table_lookup (frame_table,
+				 GINT_TO_POINTER (xevent->xbutton.window));
+	break;
+    case EnterNotify:
+    case LeaveNotify:
+	xid = (gulong)
+	    g_hash_table_lookup (frame_table,
+				 GINT_TO_POINTER (xevent->xcrossing.window));
+	break;
+    case MotionNotify:
+	xid = (gulong)
+	    g_hash_table_lookup (frame_table,
+				 GINT_TO_POINTER (xevent->xmotion.window));
+	break;
+    case PropertyNotify:
+	if (xevent->xproperty.atom == frame_input_window_atom)
+	{
+	    WnckWindow *win;
+
+	    xid = xevent->xproperty.window;
+
+	    win = wnck_window_get (xid);
+	    if (win)
+	    {
+		Window frame;
+
+		if (!get_window_prop (xid, select_window_atom, &select))
+		{
+		    if (get_window_prop (xid, frame_input_window_atom, &frame))
+			add_frame_window (win, frame, FALSE);
+		    else
+			remove_frame_window (win);
+		}
+	    }
+	}
+	if (xevent->xproperty.atom == frame_output_window_atom)
+	{
+	    WnckWindow *win;
+
+	    xid = xevent->xproperty.window;
+
+	    win = wnck_window_get (xid);
+	    if (win)
+	    {
+		Window frame;
+
+		if (!get_window_prop (xid, select_window_atom, &select))
+		{
+		    if (get_window_prop (xid, frame_output_window_atom, &frame))
+			add_frame_window (win, frame, TRUE);
+		    else
+			remove_frame_window (win);
+		}
+	    }
+	}
+	else if (xevent->xproperty.atom == compiz_shadow_info_atom ||
+		 xevent->xproperty.atom == compiz_shadow_color_atom)
+	{
+	    GdkScreen  *g_screen = gdk_display_get_default_screen (gdkdisplay);
+	    Window     root = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (g_screen));
+	    WnckScreen *screen;
+
+	    screen = wnck_screen_get_for_root (root);
+
+	    if (screen)
+	    {
+		shadow_property_changed (screen);
+	    }
+	}
+	else if (xevent->xproperty.atom == mwm_hints_atom)
+	{
+	    WnckWindow *win;
+
+	    xid = xevent->xproperty.window;
+
+	    win = wnck_window_get (xid);
+	    if (win)
+	    {
+		decor_t  *d = g_object_get_data (G_OBJECT (win), "decor");
+		gboolean decorated = FALSE;
+
+		if (get_mwm_prop (xid) & (MWM_DECOR_ALL | MWM_DECOR_TITLE))
+		    decorated = TRUE;
+
+		if (decorated != d->decorated)
+		{
+		    d->decorated = decorated;
+		    if (decorated)
+		    {
+			d->context = NULL;
+			d->width = d->height = 0;
+
+			update_window_decoration_size (win);
+			update_event_windows (win);
+		    }
+		    else
+		    {
+			gdk_error_trap_push ();
+			XDeleteProperty (xdisplay, xid, win_decor_atom);
+			gdk_display_sync (gdk_display_get_default ());
+			gdk_error_trap_pop ();
+		    }
+		}
+	    }
+	}
+	else if (xevent->xproperty.atom == select_window_atom)
+	{
+	    Window select;
+
+	    if (get_window_prop (xevent->xproperty.window, select_window_atom, &select))
+		update_switcher_window (xevent->xproperty.window, select);
+	}
+	break;
+    case DestroyNotify:
+    {
+	g_hash_table_remove (frame_table,
+			     GINT_TO_POINTER (xevent->xproperty.window));
+
+	break;
+    }
+    case ClientMessage:
+	if (xevent->xclient.message_type == toolkit_action_atom)
+	{
+	    long action;
+
+	    action = xevent->xclient.data.l[0];
+	    if (action == toolkit_action_window_menu_atom)
+	    {
+		WnckWindow *win;
+
+		win = wnck_window_get (xevent->xclient.window);
+		if (win)
+		{
+		    action_menu_map (win,
+				     xevent->xclient.data.l[2],
+				     xevent->xclient.data.l[1]);
+		}
+	    }
+	    else if (action == toolkit_action_force_quit_dialog_atom)
+	    {
+		WnckWindow *win;
+
+		win = wnck_window_get (xevent->xclient.window);
+		if (win)
+		{
+		    if (xevent->xclient.data.l[2])
+			show_force_quit_dialog (win,
+						xevent->xclient.data.l[1]);
+		    else
+			hide_force_quit_dialog (win);
+		}
+	    }
+	}
+    default:
+	break;
+    }
+
+    if (xid)
+    {
+	WnckWindow *win;
+
+	win = wnck_window_get (xid);
+	if (win)
+	{
+	    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+
+	    if (d->decorated)
+	    {
+		gint             i, j;
+		event_callback   cb = NULL;
+		Window           w = xevent->xany.window;
+
+		for (i = 0; i < 3; i++)
+		    for (j = 0; j < 3; j++)
+			if (d->event_windows[i][j].window == w)
+			    cb = d->event_windows[i][j].callback;
+
+		if (!cb)
+		{
+		    for (i = 0; i < BUTTON_NUM; i++)
+			if (d->button_windows[i].window == w)
+			    cb = d->button_windows[i].callback;
+		}
+
+		if (cb)
+		{
+		    decor_event      gtkwd_event;
+		    decor_event_type gtkwd_type;
+
+		    gtkwd_event.window = w;
+
+		    switch (xevent->type)
+		    {
+			case ButtonPress:
+			case ButtonRelease:
+			    if (xevent->type == ButtonPress)
+				gtkwd_type = GButtonPress;
+			    else
+				gtkwd_type = GButtonRelease;
+			    gtkwd_event.button = xevent->xbutton.button;
+			    gtkwd_event.x = xevent->xbutton.x;
+			    gtkwd_event.y = xevent->xbutton.y;
+			    gtkwd_event.x_root = xevent->xbutton.x_root;
+			    gtkwd_event.y_root = xevent->xbutton.y_root;
+			    gtkwd_event.time = xevent->xbutton.time;
+			    break;
+			case EnterNotify:
+			case LeaveNotify:
+			    if (xevent->type == EnterNotify)
+				gtkwd_type = GEnterNotify;
+			    else
+				gtkwd_type = GLeaveNotify;
+			    gtkwd_event.x = xevent->xcrossing.x;
+			    gtkwd_event.y = xevent->xcrossing.y;
+			    gtkwd_event.x_root = xevent->xcrossing.x_root;
+			    gtkwd_event.y_root = xevent->xcrossing.y_root;
+			    gtkwd_event.time = xevent->xcrossing.time;
+			    break;
+			default:
+			    cb = NULL;
+			    break;
+		    }
+		    if (cb)
+			(*cb) (win, &gtkwd_event, gtkwd_type);
+		}
+	    }
+	}
+    }
+
+    return GDK_FILTER_CONTINUE;
+}
+
+GdkFilterReturn
+selection_event_filter_func (GdkXEvent *gdkxevent,
+			     GdkEvent  *event,
+			     gpointer  data)
+{
+    Display    *xdisplay;
+    GdkDisplay *gdkdisplay;
+    XEvent     *xevent = gdkxevent;
+    int	       status;
+
+    gdkdisplay = gdk_display_get_default ();
+    xdisplay   = GDK_DISPLAY_XDISPLAY (gdkdisplay);
+
+    switch (xevent->type) {
+    case SelectionRequest:
+	decor_handle_selection_request (xdisplay, xevent, dm_sn_timestamp);
+	break;
+    case SelectionClear:
+	status = decor_handle_selection_clear (xdisplay, xevent, 0);
+	if (status == DECOR_SELECTION_GIVE_UP)
+	    exit (0);
+    default:
+	break;
+    }
+
+    return GDK_FILTER_CONTINUE;
+}

=== added file '.pc/fix-883383.patch/unity/unity_window_decorator/src/gtk-window-decorator.c'
--- .pc/fix-883383.patch/unity/unity_window_decorator/src/gtk-window-decorator.c	1970-01-01 00:00:00 +0000
+++ .pc/fix-883383.patch/unity/unity_window_decorator/src/gtk-window-decorator.c	2011-10-29 09:07:25 +0000
@@ -0,0 +1,443 @@
+/*
+ * Copyright © 2006 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Reveman <davidr@xxxxxxxxxx>
+ */
+
+#include "gtk-window-decorator.h"
+
+gboolean minimal = FALSE;
+
+double decoration_alpha = 0.5;
+
+#define SWITCHER_SPACE 40
+
+decor_extents_t _shadow_extents      = { 0, 0, 0, 0 };
+decor_extents_t _win_extents         = { 6, 6, 6, 6 };
+decor_extents_t _max_win_extents     = { 6, 6, 4, 6 };
+decor_extents_t _default_win_extents = { 6, 6, 6, 6 };
+decor_extents_t _switcher_extents    = { 6, 6, 6, 6 + SWITCHER_SPACE };
+
+int titlebar_height = 17;
+int max_titlebar_height = 17;
+
+decor_context_t window_active_context = {
+    { 0, 0, 0, 0 },
+    6, 6, 4, 6,
+    0, 0, 0, 0
+};
+
+decor_context_t max_window_active_context = {
+    { 0, 0, 0, 0 },
+    6, 6, 4, 6,
+    0, 0, 0, 0
+};
+
+decor_context_t window_inactive_context = {
+    { 0, 0, 0, 0 },
+    6, 6, 4, 6,
+    0, 0, 0, 0
+};
+
+decor_context_t max_window_inactive_context = {
+    { 0, 0, 0, 0 },
+    6, 6, 4, 6,
+    0, 0, 0, 0
+};
+
+decor_context_t window_context_no_shadow = {
+    { 0, 0, 0, 0 },
+    6, 6, 4, 6,
+    0, 0, 0, 0
+};
+
+decor_context_t max_window_context_no_shadow = {
+    { 0, 0, 0, 0 },
+    6, 6, 4, 6,
+    0, 0, 0, 0
+};
+
+decor_context_t switcher_context = {
+    { 0, 0, 0, 0 },
+    6, 6, 6, 6 + SWITCHER_SPACE,
+    0, 0, 0, 0
+};
+
+decor_context_t shadow_context = {
+    { 0, 0, 0, 0 },
+    0, 0, 0, 0,
+    0, 0, 0, 0,
+};
+
+gdouble shadow_radius   = SHADOW_RADIUS;
+gdouble shadow_opacity  = SHADOW_OPACITY;
+gushort shadow_color[3] = {
+  SHADOW_COLOR_RED,
+  SHADOW_COLOR_GREEN,
+  SHADOW_COLOR_BLUE
+};
+gint    shadow_offset_x = SHADOW_OFFSET_X;
+gint    shadow_offset_y = SHADOW_OFFSET_Y;
+
+guint cmdline_options = 0;
+
+decor_shadow_t *no_border_shadow = NULL;
+decor_shadow_t *border_active_shadow = NULL;
+decor_shadow_t *border_inactive_shadow = NULL;
+decor_shadow_t *max_border_active_shadow = NULL;
+decor_shadow_t *max_border_inactive_shadow = NULL;
+decor_shadow_t *border_no_shadow = NULL;
+decor_shadow_t *max_border_no_shadow = NULL;
+decor_shadow_t *switcher_shadow = NULL;
+
+GdkPixmap *decor_normal_pixmap = NULL;
+GdkPixmap *decor_active_pixmap = NULL;
+
+Atom frame_input_window_atom;
+Atom frame_output_window_atom;
+Atom win_decor_atom;
+Atom win_blur_decor_atom;
+Atom wm_move_resize_atom;
+Atom restack_window_atom;
+Atom select_window_atom;
+Atom mwm_hints_atom;
+Atom switcher_fg_atom;
+
+Atom compiz_shadow_info_atom;
+Atom compiz_shadow_color_atom;
+
+Atom toolkit_action_atom;
+Atom toolkit_action_window_menu_atom;
+Atom toolkit_action_force_quit_dialog_atom;
+
+Time dm_sn_timestamp;
+
+struct _cursor cursor[3][3] = {
+    { C (top_left_corner),    C (top_side),    C (top_right_corner)    },
+    { C (left_side),	      C (left_ptr),    C (right_side)	       },
+    { C (bottom_left_corner), C (bottom_side), C (bottom_right_corner) }
+};
+
+struct _pos pos[3][3] = {
+    {
+	{  0,  0, 10, 21,   0, 0, 0, 0, 0, 1 },
+	{ 10,  0, -8,  6,   0, 0, 1, 0, 0, 1 },
+	{  2,  0, 10, 21,   1, 0, 0, 0, 0, 1 }
+    }, {
+	{  0, 10,  6, 11,   0, 0, 0, 1, 1, 0 },
+	{  6,  6,  0, 15,   0, 0, 1, 0, 0, 1 },
+	{  6, 10,  6, 11,   1, 0, 0, 1, 1, 0 }
+    }, {
+	{  0, 17, 10, 10,   0, 1, 0, 0, 1, 0 },
+	{ 10, 21, -8,  6,   0, 1, 1, 0, 1, 0 },
+	{  2, 17, 10, 10,   1, 1, 0, 0, 1, 0 }
+    }
+}, bpos[] = {
+    { 0, 6, 16, 16,   1, 0, 0, 0, 0, 0 },
+    { 0, 6, 16, 16,   1, 0, 0, 0, 0, 0 },
+    { 0, 6, 16, 16,   1, 0, 0, 0, 0, 0 },
+    { 6, 2, 16, 16,   0, 0, 0, 0, 0, 0 }
+};
+
+char *program_name;
+
+GtkWidget     *style_window_rgba;
+GtkWidget     *style_window_rgb;
+GtkWidget     *switcher_label;
+
+GHashTable    *frame_table;
+GtkWidget     *action_menu = NULL;
+gboolean      action_menu_mapped = FALSE;
+decor_color_t _title_color[2];
+PangoContext  *pango_context;
+gint	     double_click_timeout = 250;
+
+GSList *draw_list = NULL;
+guint  draw_idle_id = 0;
+
+PangoFontDescription *titlebar_font = NULL;
+gboolean		    use_system_font = FALSE;
+gint		    text_height;
+
+gint blur_type = BLUR_TYPE_NONE;
+
+GdkPixmap *switcher_pixmap = NULL;
+GdkPixmap *switcher_buffer_pixmap = NULL;
+gint      switcher_width;
+gint      switcher_height;
+Window    switcher_selected_window = None;
+decor_t   *switcher_window = NULL;
+
+XRenderPictFormat *xformat_rgba;
+XRenderPictFormat *xformat_rgb;
+
+int
+main (int argc, char *argv[])
+{
+    GdkDisplay *gdkdisplay;
+    Display    *xdisplay;
+    GdkScreen  *gdkscreen;
+    WnckScreen *screen;
+    gint       i, j, status;
+    unsigned int nchildren;
+    Window     root_ret, parent_ret;
+    Window     *children = NULL;
+    gboolean   replace = FALSE;
+
+#ifdef USE_METACITY
+    char       *meta_theme = NULL;
+#endif
+
+    program_name = argv[0];
+
+    gtk_init (&argc, &argv);
+
+    bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+    bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+    textdomain (GETTEXT_PACKAGE);
+
+    for (i = 0; i < argc; i++)
+    {
+	if (strcmp (argv[i], "--minimal") == 0)
+	{
+	    minimal = TRUE;
+	}
+	else if (strcmp (argv[i], "--replace") == 0)
+	{
+	    replace = TRUE;
+	}
+	else if (strcmp (argv[i], "--blur") == 0)
+	{
+	    if (argc > ++i)
+	    {
+		if (strcmp (argv[i], "titlebar") == 0)
+		    blur_type = BLUR_TYPE_TITLEBAR;
+		else if (strcmp (argv[i], "all") == 0)
+		    blur_type = BLUR_TYPE_ALL;
+	    }
+	    cmdline_options |= CMDLINE_BLUR;
+	}
+
+#ifdef USE_METACITY
+	else if (strcmp (argv[i], "--opacity") == 0)
+	{
+	    if (argc > ++i)
+		meta_opacity = atof (argv[i]);
+	    cmdline_options |= CMDLINE_OPACITY;
+	}
+	else if (strcmp (argv[i], "--no-opacity-shade") == 0)
+	{
+	    meta_shade_opacity = FALSE;
+	    cmdline_options |= CMDLINE_OPACITY_SHADE;
+	}
+	else if (strcmp (argv[i], "--active-opacity") == 0)
+	{
+	    if (argc > ++i)
+		meta_active_opacity = atof (argv[i]);
+	    cmdline_options |= CMDLINE_ACTIVE_OPACITY;
+	}
+	else if (strcmp (argv[i], "--no-active-opacity-shade") == 0)
+	{
+	    meta_active_shade_opacity = FALSE;
+	    cmdline_options |= CMDLINE_ACTIVE_OPACITY_SHADE;
+	}
+	else if (strcmp (argv[i], "--metacity-theme") == 0)
+	{
+	    if (argc > ++i)
+		meta_theme = argv[i];
+	    cmdline_options |= CMDLINE_THEME;
+	}
+#endif
+
+	else if (strcmp (argv[i], "--help") == 0)
+	{
+	    fprintf (stderr, "%s "
+		     "[--minimal] "
+		     "[--replace] "
+		     "[--blur none|titlebar|all] "
+
+#ifdef USE_METACITY
+		     "[--opacity OPACITY] "
+		     "[--no-opacity-shade] "
+		     "[--active-opacity OPACITY] "
+		     "[--no-active-opacity-shade] "
+		     "[--metacity-theme THEME] "
+#endif
+
+		     "[--help]"
+
+		     "\n", program_name);
+	    return 0;
+	}
+    }
+
+    theme_draw_window_decoration    = draw_window_decoration;
+    theme_calc_decoration_size	    = calc_decoration_size;
+    theme_update_border_extents	    = update_border_extents;
+    theme_get_event_window_position = get_event_window_position;
+    theme_get_button_position       = get_button_position;
+    theme_update_shadow		    = cairo_update_shadow;
+    theme_get_shadow		    = get_shadow;
+    theme_get_border_extents	    = get_border_extents;
+
+#ifdef USE_METACITY
+    if (meta_theme)
+    {
+	meta_theme_set_current (meta_theme, TRUE);
+	if (meta_theme_get_current ())
+	{
+	    theme_draw_window_decoration    = meta_draw_window_decoration;
+	    theme_calc_decoration_size	    = meta_calc_decoration_size;
+	    theme_update_border_extents	    = meta_update_border_extents;
+	    theme_get_event_window_position = meta_get_event_window_position;
+	    theme_get_button_position	    = meta_get_button_position;
+	    theme_update_shadow		    = meta_update_shadow;
+	    theme_get_shadow		    = meta_get_shadow;
+	    theme_get_border_extents	    = meta_get_border_extents;
+	}
+    }
+#endif
+
+    gdkdisplay = gdk_display_get_default ();
+    xdisplay   = gdk_x11_display_get_xdisplay (gdkdisplay);
+    gdkscreen  = gdk_display_get_default_screen (gdkdisplay);
+
+    frame_input_window_atom  = XInternAtom (xdisplay,
+					    DECOR_INPUT_FRAME_ATOM_NAME, FALSE);
+    frame_output_window_atom = XInternAtom (xdisplay,
+					    DECOR_OUTPUT_FRAME_ATOM_NAME, FALSE);
+
+    win_decor_atom	= XInternAtom (xdisplay, DECOR_WINDOW_ATOM_NAME, FALSE);
+    win_blur_decor_atom	= XInternAtom (xdisplay, DECOR_BLUR_ATOM_NAME, FALSE);
+    wm_move_resize_atom = XInternAtom (xdisplay, "_NET_WM_MOVERESIZE", FALSE);
+    restack_window_atom = XInternAtom (xdisplay, "_NET_RESTACK_WINDOW", FALSE);
+    select_window_atom	= XInternAtom (xdisplay, DECOR_SWITCH_WINDOW_ATOM_NAME,
+				       FALSE);
+    mwm_hints_atom	= XInternAtom (xdisplay, "_MOTIF_WM_HINTS", FALSE);
+    switcher_fg_atom    = XInternAtom (xdisplay,
+				       DECOR_SWITCH_FOREGROUND_COLOR_ATOM_NAME,
+				       FALSE);
+
+    compiz_shadow_info_atom  = XInternAtom (xdisplay, "_COMPIZ_NET_CM_SHADOW_PROPERTIES", FALSE);
+    compiz_shadow_color_atom = XInternAtom (xdisplay, "_COMPIZ_NET_CM_SHADOW_COLOR", FALSE);
+
+    toolkit_action_atom			  =
+	XInternAtom (xdisplay, "_COMPIZ_TOOLKIT_ACTION", FALSE);
+    toolkit_action_window_menu_atom	  =
+	XInternAtom (xdisplay, "_COMPIZ_TOOLKIT_ACTION_WINDOW_MENU", FALSE);
+    toolkit_action_force_quit_dialog_atom =
+	XInternAtom (xdisplay, "_COMPIZ_TOOLKIT_ACTION_FORCE_QUIT_DIALOG",
+		     FALSE);
+
+    status = decor_acquire_dm_session (xdisplay,
+				       gdk_screen_get_number (gdkscreen),
+				       "gwd", replace, &dm_sn_timestamp);
+    if (status != DECOR_ACQUIRE_STATUS_SUCCESS)
+    {
+	if (status == DECOR_ACQUIRE_STATUS_FAILED)
+	{
+	    fprintf (stderr,
+		     "%s: Could not acquire decoration manager "
+		     "selection on screen %d display \"%s\"\n",
+		     program_name, gdk_screen_get_number (gdkscreen),
+		     DisplayString (xdisplay));
+	}
+	else if (status == DECOR_ACQUIRE_STATUS_OTHER_DM_RUNNING)
+	{
+	    fprintf (stderr,
+		     "%s: Screen %d on display \"%s\" already "
+		     "has a decoration manager; try using the "
+		     "--replace option to replace the current "
+		     "decoration manager.\n",
+		     program_name, gdk_screen_get_number (gdkscreen),
+		     DisplayString (xdisplay));
+	}
+
+	return 1;
+    }
+
+    for (i = 0; i < 3; i++)
+    {
+	for (j = 0; j < 3; j++)
+	{
+	    if (cursor[i][j].shape != XC_left_ptr)
+		cursor[i][j].cursor =
+		    XCreateFontCursor (xdisplay, cursor[i][j].shape);
+	}
+    }
+
+    xformat_rgba = XRenderFindStandardFormat (xdisplay, PictStandardARGB32);
+    xformat_rgb  = XRenderFindStandardFormat (xdisplay, PictStandardRGB24);
+
+    frame_table = g_hash_table_new (NULL, NULL);
+
+    screen = wnck_screen_get_default ();
+    wnck_set_client_type (WNCK_CLIENT_TYPE_PAGER);
+
+    gdk_window_add_filter (NULL,
+			   selection_event_filter_func,
+			   NULL);
+
+    if (!minimal)
+    {
+	GdkWindow *root = create_foreign_window (gdk_x11_get_default_root_xwindow ());
+
+	gdk_window_add_filter (NULL,
+			       event_filter_func,
+			       NULL);
+			       
+	XQueryTree (xdisplay, gdk_x11_get_default_root_xwindow (),
+		    &root_ret, &parent_ret, &children, &nchildren);
+
+	for (i = 0; i < nchildren; i++)
+	{
+	    GdkWindow *toplevel = create_foreign_window (children[i]);
+
+	    /* Need property notify on all windows */
+
+	    gdk_window_set_events (toplevel,
+				   gdk_window_get_events (toplevel) |
+				   GDK_PROPERTY_CHANGE_MASK);
+	}
+
+	/* Need MapNotify on new windows */
+	gdk_window_set_events (root, gdk_window_get_events (root) |
+			       GDK_STRUCTURE_MASK |
+			       GDK_PROPERTY_CHANGE_MASK |
+			       GDK_VISIBILITY_NOTIFY_MASK |
+			       GDK_SUBSTRUCTURE_MASK);
+
+	connect_screen (screen);
+    }
+
+    if (!init_settings (screen))
+    {
+	fprintf (stderr, "%s: Failed to get necessary gtk settings\n", argv[0]);
+	return 1;
+    }
+
+    decor_set_dm_check_hint (xdisplay, gdk_screen_get_number (gdkscreen),
+			     WINDOW_DECORATION_TYPE_PIXMAP |
+			     WINDOW_DECORATION_TYPE_WINDOW);
+
+    update_default_decorations (gdkscreen);
+
+    gtk_main ();
+
+    return 0;
+}

=== added file '.pc/fix-883383.patch/unity/unity_window_decorator/src/gtk-window-decorator.h'
--- .pc/fix-883383.patch/unity/unity_window_decorator/src/gtk-window-decorator.h	1970-01-01 00:00:00 +0000
+++ .pc/fix-883383.patch/unity/unity_window_decorator/src/gtk-window-decorator.h	2011-10-29 09:07:25 +0000
@@ -0,0 +1,1009 @@
+#ifndef _GTK_WINDOW_DECORATOR_H
+#define _GTK_WINDOW_DECORATOR_H
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <decoration.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/cursorfont.h>
+#include <X11/extensions/Xrender.h>
+#include <X11/Xregion.h>
+
+#ifdef HAVE_GTK_2_24
+
+#ifndef GDK_DISABLE_DEPRECATED
+#define GDK_DISABLE_DEPRECATED
+#endif
+
+#define create_foreign_window(xid)					      \
+    gdk_x11_foreign_new_for_display (gdk_display_get_default (),	      \
+				     xid);
+#else
+
+#define create_foreign_window(xid)					      \
+    gdk_window_foreign_new (xid)
+
+#ifdef GTK_DISABLE_DEPRECATED
+#undef GTK_DISABLE_DEPRECATED
+#endif
+
+#endif
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdk.h>
+
+#ifdef USE_GCONF_UNITY_WINDOW_DECORATOR
+#include <gconf/gconf-client.h>
+#endif
+
+#ifdef USE_DBUS_GLIB
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#endif
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+#include <libwnck/window-action-menu.h>
+
+#ifndef HAVE_LIBWNCK_2_19_4
+#define wnck_window_get_client_window_geometry wnck_window_get_geometry
+#endif
+
+#include <cairo.h>
+#include <cairo-xlib.h>
+
+#if CAIRO_VERSION < CAIRO_VERSION_ENCODE(1, 1, 0)
+#define CAIRO_EXTEND_PAD CAIRO_EXTEND_NONE
+#endif
+
+#include <pango/pango-context.h>
+#include <pango/pangocairo.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <signal.h>
+
+#include <libintl.h>
+#define _(x)  gettext (x)
+#define N_(x) x
+
+#ifdef USE_METACITY
+#include <metacity-private/theme.h>
+#endif
+
+#define METACITY_GCONF_DIR "/apps/metacity/general"
+
+#define COMPIZ_USE_SYSTEM_FONT_KEY		    \
+METACITY_GCONF_DIR "/titlebar_uses_system_font"
+
+#define COMPIZ_TITLEBAR_FONT_KEY	\
+METACITY_GCONF_DIR "/titlebar_font"
+
+#define COMPIZ_DOUBLE_CLICK_TITLEBAR_KEY	       \
+METACITY_GCONF_DIR "/action_double_click_titlebar"
+
+#define COMPIZ_MIDDLE_CLICK_TITLEBAR_KEY	       \
+METACITY_GCONF_DIR "/action_middle_click_titlebar"
+
+#define COMPIZ_RIGHT_CLICK_TITLEBAR_KEY	       \
+METACITY_GCONF_DIR "/action_right_click_titlebar"
+
+#define COMPIZ_GCONF_DIR1 "/apps/compiz/plugins/decoration/allscreens/options"
+
+#define COMPIZ_SHADOW_RADIUS_KEY \
+COMPIZ_GCONF_DIR1 "/shadow_radius"
+
+#define COMPIZ_SHADOW_OPACITY_KEY \
+COMPIZ_GCONF_DIR1 "/shadow_opacity"
+
+#define COMPIZ_SHADOW_COLOR_KEY \
+COMPIZ_GCONF_DIR1 "/shadow_color"
+
+#define COMPIZ_SHADOW_OFFSET_X_KEY \
+COMPIZ_GCONF_DIR1 "/shadow_x_offset"
+
+#define COMPIZ_SHADOW_OFFSET_Y_KEY \
+COMPIZ_GCONF_DIR1 "/shadow_y_offset"
+
+#define META_THEME_KEY		\
+METACITY_GCONF_DIR "/theme"
+
+#define META_BUTTON_LAYOUT_KEY		\
+METACITY_GCONF_DIR "/button_layout"
+
+#define GCONF_DIR "/apps/gwd"
+
+#define USE_META_THEME_KEY	    \
+GCONF_DIR "/use_metacity_theme"
+
+#define META_THEME_OPACITY_KEY	        \
+GCONF_DIR "/metacity_theme_opacity"
+
+#define META_THEME_SHADE_OPACITY_KEY	      \
+GCONF_DIR "/metacity_theme_shade_opacity"
+
+#define META_THEME_ACTIVE_OPACITY_KEY	       \
+GCONF_DIR "/metacity_theme_active_opacity"
+
+#define META_THEME_ACTIVE_SHADE_OPACITY_KEY          \
+GCONF_DIR "/metacity_theme_active_shade_opacity"
+
+#define BLUR_TYPE_KEY	   \
+GCONF_DIR "/blur_type"
+
+#define WHEEL_ACTION_KEY   \
+GCONF_DIR "/mouse_wheel_action"
+
+#define DBUS_DEST       "org.freedesktop.compiz"
+#define DBUS_PATH       "/org/freedesktop/compiz/decor/screen0"
+#define DBUS_INTERFACE  "org.freedesktop.compiz"
+#define DBUS_METHOD_GET "get"
+
+#define STROKE_ALPHA 0.6
+
+#define ICON_SPACE 20
+
+#define DOUBLE_CLICK_DISTANCE 8.0
+
+#define WM_MOVERESIZE_SIZE_TOPLEFT      0
+#define WM_MOVERESIZE_SIZE_TOP          1
+#define WM_MOVERESIZE_SIZE_TOPRIGHT     2
+#define WM_MOVERESIZE_SIZE_RIGHT        3
+#define WM_MOVERESIZE_SIZE_BOTTOMRIGHT  4
+#define WM_MOVERESIZE_SIZE_BOTTOM       5
+#define WM_MOVERESIZE_SIZE_BOTTOMLEFT   6
+#define WM_MOVERESIZE_SIZE_LEFT         7
+#define WM_MOVERESIZE_MOVE              8
+#define WM_MOVERESIZE_SIZE_KEYBOARD     9
+#define WM_MOVERESIZE_MOVE_KEYBOARD    10
+
+#define SHADOW_RADIUS      8.0
+#define SHADOW_OPACITY     0.5
+#define SHADOW_OFFSET_X    1
+#define SHADOW_OFFSET_Y    1
+#define SHADOW_COLOR_RED   0x0000
+#define SHADOW_COLOR_GREEN 0x0000
+#define SHADOW_COLOR_BLUE  0x0000
+
+#define SHADOW_TYPE_ACTIVE_NORMAL 1
+#define SHADOW_TYPE_ACTIVE_MAX    2
+#define SHADOW_TYPE_INACTIVE_NORMAL 3
+#define SHADOW_TYPE_INACTIVE_MAX    4
+
+#define META_OPACITY              0.75
+#define META_SHADE_OPACITY        TRUE
+#define META_ACTIVE_OPACITY       1.0
+#define META_ACTIVE_SHADE_OPACITY TRUE
+
+#define META_MAXIMIZED (WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY | \
+WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
+
+#define CMDLINE_OPACITY              (1 << 0)
+#define CMDLINE_OPACITY_SHADE        (1 << 1)
+#define CMDLINE_ACTIVE_OPACITY       (1 << 2)
+#define CMDLINE_ACTIVE_OPACITY_SHADE (1 << 3)
+#define CMDLINE_BLUR                 (1 << 4)
+#define CMDLINE_THEME                (1 << 5)
+
+#define MWM_HINTS_DECORATIONS (1L << 1)
+
+#define MWM_DECOR_ALL      (1L << 0)
+#define MWM_DECOR_BORDER   (1L << 1)
+#define MWM_DECOR_HANDLE   (1L << 2)
+#define MWM_DECOR_TITLE    (1L << 3)
+#define MWM_DECOR_MENU     (1L << 4)
+#define MWM_DECOR_MINIMIZE (1L << 5)
+#define MWM_DECOR_MAXIMIZE (1L << 6)
+
+#define PROP_MOTIF_WM_HINT_ELEMENTS 3
+
+/* to save some memory, value is specific to current decorations */
+#define TRANSLUCENT_CORNER_SIZE 3
+
+typedef struct {
+unsigned long flags;
+unsigned long functions;
+unsigned long decorations;
+} MwmHints;
+
+enum {
+    CLICK_ACTION_NONE,
+    CLICK_ACTION_SHADE,
+    CLICK_ACTION_MAXIMIZE,
+    CLICK_ACTION_MINIMIZE,
+    CLICK_ACTION_RAISE,
+    CLICK_ACTION_LOWER,
+    CLICK_ACTION_MENU
+};
+
+enum {
+    WHEEL_ACTION_NONE,
+    WHEEL_ACTION_SHADE
+};
+
+#define DOUBLE_CLICK_ACTION_DEFAULT CLICK_ACTION_MAXIMIZE
+#define MIDDLE_CLICK_ACTION_DEFAULT CLICK_ACTION_LOWER
+#define RIGHT_CLICK_ACTION_DEFAULT  CLICK_ACTION_MENU
+#define WHEEL_ACTION_DEFAULT        WHEEL_ACTION_NONE
+
+int double_click_action;
+int middle_click_action;
+int right_click_action;
+int wheel_action;
+
+extern gboolean minimal;
+extern double decoration_alpha;
+
+#define SWITCHER_SPACE 40
+
+extern decor_extents_t _shadow_extents;
+extern decor_extents_t _win_extents;
+extern decor_extents_t _max_win_extents;
+extern decor_extents_t _default_win_extents;
+extern decor_extents_t _switcher_extents;
+
+extern int titlebar_height;
+extern int max_titlebar_height;
+
+extern decor_context_t window_active_context;
+extern decor_context_t window_inactive_context;
+extern decor_context_t window_context_no_shadow;
+extern decor_context_t max_window_active_context;
+extern decor_context_t max_window_inactive_context;
+extern decor_context_t max_window_context_no_shadow;
+extern decor_context_t switcher_context;
+extern decor_context_t shadow_context;
+
+extern gdouble shadow_radius;
+extern gdouble shadow_opacity;
+extern gushort shadow_color[3];
+extern gint    shadow_offset_x;
+extern gint    shadow_offset_y;
+
+#ifdef USE_METACITY
+extern double   meta_opacity;
+extern gboolean meta_shade_opacity;
+extern double   meta_active_opacity;
+extern gboolean meta_active_shade_opacity;
+
+extern gboolean         meta_button_layout_set;
+extern MetaButtonLayout meta_button_layout;
+#endif
+
+extern guint cmdline_options;
+
+extern decor_shadow_t *no_border_shadow;
+extern decor_shadow_t *border_active_shadow;
+extern decor_shadow_t *border_inactive_shadow;
+extern decor_shadow_t *border_no_shadow;
+extern decor_shadow_t *max_border_active_shadow;
+extern decor_shadow_t *max_border_inactive_shadow;
+extern decor_shadow_t *max_border_no_shadow;
+extern decor_shadow_t *switcher_shadow;
+
+extern GdkPixmap *decor_normal_pixmap;
+extern GdkPixmap *decor_active_pixmap;
+
+extern Atom frame_input_window_atom;
+extern Atom frame_output_window_atom;
+extern Atom win_decor_atom;
+extern Atom win_blur_decor_atom;
+extern Atom wm_move_resize_atom;
+extern Atom restack_window_atom;
+extern Atom select_window_atom;
+extern Atom mwm_hints_atom;
+extern Atom switcher_fg_atom;
+
+extern Atom toolkit_action_atom;
+extern Atom toolkit_action_window_menu_atom;
+extern Atom toolkit_action_force_quit_dialog_atom;
+
+extern Time dm_sn_timestamp;
+
+#define C(name) { 0, XC_ ## name }
+
+struct _cursor {
+    Cursor	 cursor;
+    unsigned int shape;
+};
+
+extern struct _cursor cursor[3][3];
+
+#define BUTTON_CLOSE   0
+#define BUTTON_MAX     1
+#define BUTTON_MIN     2
+#define BUTTON_MENU    3
+#define BUTTON_SHADE   4
+#define BUTTON_ABOVE   5
+#define BUTTON_STICK   6
+#define BUTTON_UNSHADE 7
+#define BUTTON_UNABOVE 8
+#define BUTTON_UNSTICK 9
+#define BUTTON_NUM     10
+
+struct _pos {
+    int x, y, w, h;
+    int xw, yh, ww, hh, yth, hth;
+};
+
+extern struct _pos pos[3][3], bpos[];
+
+typedef struct _decor_color {
+    double r;
+    double g;
+    double b;
+} decor_color_t;
+
+
+#define IN_EVENT_WINDOW      (1 << 0)
+#define PRESSED_EVENT_WINDOW (1 << 1)
+
+typedef struct _decor_event {
+    guint time;
+    guint window;
+    guint x;
+    guint y;
+    guint x_root;
+    guint y_root;
+    guint button;
+} decor_event;
+
+typedef enum _decor_event_type {
+    GButtonPress = 1,
+    GButtonRelease,
+    GEnterNotify,
+    GLeaveNotify,
+    GMotionNotify
+} decor_event_type;
+
+typedef void (*event_callback) (WnckWindow       *win,
+				decor_event      *gtkwd_event,
+				decor_event_type gtkwd_type);
+
+typedef struct {
+    Window         window;
+    Box            pos;
+    event_callback callback;
+} event_window;
+
+typedef struct _decor {
+    WnckWindow	      *win;
+    event_window      event_windows[3][3];
+    event_window      button_windows[BUTTON_NUM];
+    Box		      *last_pos_entered;
+    guint	      button_states[BUTTON_NUM];
+    GdkPixmap	      *pixmap;
+    GdkPixmap	      *buffer_pixmap;
+    GdkWindow	      *frame_window;
+    GtkWidget         *decor_window;
+    GtkWidget	      *decor_event_box;
+    GtkWidget         *decor_image;
+    cairo_t	      *cr;
+    decor_layout_t    border_layout;
+    decor_context_t   *context;
+    decor_shadow_t    *shadow;
+    Picture	      picture;
+    gint	      button_width;
+    gint	      width;
+    gint	      height;
+    gint	      client_width;
+    gint	      client_height;
+    gboolean	      decorated;
+    gboolean	      active;
+    PangoLayout	      *layout;
+    gchar	      *name;
+    cairo_pattern_t   *icon;
+    GdkPixmap	      *icon_pixmap;
+    GdkPixbuf	      *icon_pixbuf;
+    WnckWindowState   state;
+    WnckWindowActions actions;
+    XID		      prop_xid;
+    GtkWidget	      *force_quit_dialog;
+    GSList	      *transient_windows;
+    WnckWindow	      *transient_parent;
+    Bool	      created;
+    void	      (*draw) (struct _decor *d);
+} decor_t;
+
+void     (*theme_draw_window_decoration)    (decor_t *d);
+gboolean (*theme_calc_decoration_size)      (decor_t *d,
+					     int     client_width,
+					     int     client_height,
+					     int     text_width,
+					     int     *width,
+					     int     *height);
+void     (*theme_update_border_extents)     (gint    text_height);
+void     (*theme_get_event_window_position) (decor_t *d,
+					     gint    i,
+					     gint    j,
+					     gint    width,
+					     gint    height,
+					     gint    *x,
+					     gint    *y,
+					     gint    *w,
+					     gint    *h);
+gboolean (*theme_get_button_position)       (decor_t *d,
+					     gint    i,
+					     gint    width,
+					     gint    height,
+					     gint    *x,
+					     gint    *y,
+					     gint    *w,
+					     gint    *h);
+
+decor_shadow_t * (*theme_update_shadow) (gint    shadow_type);
+
+void (*theme_get_shadow) (decor_t *d,
+			  gint    shadow_type);
+
+void (*theme_get_border_extents) (decor_extents_t *extents,
+				  decor_extents_t *frame_extents,
+				  decor_extents_t *extents_max,
+				  decor_extents_t *frame_extents_max);
+
+extern char *program_name;
+
+extern GtkWidget     *style_window_rgba;
+extern GtkWidget     *style_window_rgb;
+extern GtkWidget     *switcher_label;
+
+extern GHashTable    *frame_table;
+extern GtkWidget     *action_menu;
+extern gboolean      action_menu_mapped;
+extern decor_color_t _title_color[2];
+extern PangoContext  *pango_context;
+extern gint	     double_click_timeout;
+
+extern GSList *draw_list;
+extern guint  draw_idle_id;
+
+extern PangoFontDescription *titlebar_font;
+extern gboolean		    use_system_font;
+extern gint		    text_height;
+
+#define BLUR_TYPE_NONE     0
+#define BLUR_TYPE_TITLEBAR 1
+#define BLUR_TYPE_ALL      2
+
+extern gint blur_type;
+
+extern GdkPixmap *switcher_pixmap;
+extern GdkPixmap *switcher_buffer_pixmap;
+extern gint      switcher_width;
+extern gint      switcher_height;
+extern Window    switcher_selected_window;
+extern decor_t   *switcher_window;
+
+extern XRenderPictFormat *xformat_rgba;
+extern XRenderPictFormat *xformat_rgb;
+
+extern Atom compiz_shadow_info_atom;
+extern Atom compiz_shadow_color_atom;
+
+/* gtk-window-decorator.c */
+
+double
+dist (double x1, double y1,
+      double x2, double y2);
+
+/* decorator.c */
+
+gboolean
+update_window_decoration_size (WnckWindow *win);
+
+void
+update_window_decoration_name (WnckWindow *win);
+
+gint
+max_window_name_width (WnckWindow *win);
+
+void
+update_default_decorations (GdkScreen *screen);
+
+void
+update_window_decoration_state (WnckWindow *win);
+
+void
+update_window_decoration_actions (WnckWindow *win);
+
+void
+update_window_decoration_icon (WnckWindow *win);
+
+void
+update_event_windows (WnckWindow *win);
+
+int
+update_shadow (void);
+
+void
+shadow_property_changed (WnckScreen *screen);
+
+void
+update_titlebar_font (void);
+
+void
+update_window_decoration_name (WnckWindow *win);
+
+void
+update_window_decoration (WnckWindow *win);
+
+void
+queue_decor_draw (decor_t *d);
+
+void
+copy_to_front_buffer (decor_t *d);
+
+void
+draw_border_shape (Display	   *xdisplay,
+		   Pixmap	   pixmap,
+		   Picture	   picture,
+		   int		   width,
+		   int		   height,
+		   decor_context_t *c,
+		   void		   *closure);
+
+
+/* wnck.c*/
+
+void
+decorations_changed (WnckScreen *screen);
+
+void
+connect_screen (WnckScreen *screen);
+
+void
+add_frame_window (WnckWindow *win,
+		  Window     frame,
+		  Bool	     mode);
+
+void
+remove_frame_window (WnckWindow *win);
+
+void
+restack_window (WnckWindow *win,
+		int	   stack_mode);
+
+void connect_window (WnckWindow *win);
+
+/* blur.c */
+
+void
+decor_update_blur_property (decor_t *d,
+			    int     width,
+			    int     height,
+			    Region  top_region,
+			    int     top_offset,
+			    Region  bottom_region,
+			    int     bottom_offset,
+			    Region  left_region,
+			    int     left_offset,
+			    Region  right_region,
+			    int     right_offset);
+
+/* decorprops.c */
+
+void
+decor_update_window_property (decor_t *d);
+
+void
+decor_update_switcher_property (decor_t *d);
+
+/* cairo.c */
+
+#define CORNER_TOPLEFT     (1 << 0)
+#define CORNER_TOPRIGHT    (1 << 1)
+#define CORNER_BOTTOMRIGHT (1 << 2)
+#define CORNER_BOTTOMLEFT  (1 << 3)
+
+#define SHADE_LEFT   (1 << 0)
+#define SHADE_RIGHT  (1 << 1)
+#define SHADE_TOP    (1 << 2)
+#define SHADE_BOTTOM (1 << 3)
+
+void
+draw_shadow_background (decor_t		*d,
+			cairo_t		*cr,
+			decor_shadow_t  *s,
+			decor_context_t *c);
+
+void
+draw_window_decoration (decor_t *d);
+
+void
+fill_rounded_rectangle (cairo_t       *cr,
+			double        x,
+			double        y,
+			double        w,
+			double        h,
+			double	      radius,
+			int	      corner,
+			decor_color_t *c0,
+			double        alpha0,
+			decor_color_t *c1,
+			double	      alpha1,
+			int	      gravity);
+
+void
+rounded_rectangle (cairo_t *cr,
+		   double  x,
+		   double  y,
+		   double  w,
+		   double  h,
+		   double  radius,
+		   int	   corner);
+
+gboolean
+calc_decoration_size (decor_t *d,
+		      gint    w,
+		      gint    h,
+		      gint    name_width,
+		      gint    *width,
+		      gint    *height);
+
+void
+update_border_extents (gint text_height);
+
+void
+get_border_extents (decor_extents_t *extents,
+		    decor_extents_t *frame_extents,
+		    decor_extents_t *extents_max,
+		    decor_extents_t *frame_extents_max);
+
+gboolean
+get_button_position (decor_t *d,
+		     gint    i,
+		     gint    width,
+		     gint    height,
+		     gint    *x,
+		     gint    *y,
+		     gint    *w,
+		     gint    *h);
+
+void
+get_event_window_position (decor_t *d,
+			   gint    i,
+			   gint    j,
+			   gint    width,
+			   gint    height,
+			   gint    *x,
+			   gint    *y,
+			   gint    *w,
+			   gint    *h);
+
+decor_shadow_t *
+cairo_update_shadow (gint shadow_type);
+
+void
+get_shadow (decor_t *, gint shadow_type);
+
+/* gdk.c */
+
+void
+gdk_cairo_set_source_color_alpha (cairo_t  *cr,
+				  GdkColor *color,
+				  double   alpha);
+
+inline GdkWindow *
+create_gdk_window (Window xframe);
+
+GdkColormap *
+get_colormap_for_drawable (GdkDrawable *d);
+
+XRenderPictFormat *
+get_format_for_drawable (decor_t *d, GdkDrawable *drawable);
+
+GdkPixmap *
+create_pixmap (int w,
+	       int h,
+	       int depth);
+
+GdkPixmap *
+pixmap_new_from_pixbuf (GdkPixbuf *pixbuf, int depth);
+
+/* metacity.c */
+#ifdef USE_METACITY
+void
+meta_draw_window_decoration (decor_t *d);
+
+void
+meta_get_decoration_geometry (decor_t		*d,
+			      MetaTheme	        *theme,
+			      MetaFrameFlags    *flags,
+			      MetaFrameGeometry *fgeom,
+			      MetaButtonLayout  *button_layout,
+			      GdkRectangle      *clip);
+
+void
+meta_calc_button_size (decor_t *d);
+
+gboolean
+meta_calc_decoration_size (decor_t *d,
+			   gint    w,
+			   gint    h,
+			   gint    name_width,
+			   gint    *width,
+			   gint    *height);
+
+gboolean
+meta_get_button_position (decor_t *d,
+			  gint    i,
+			  gint	  width,
+			  gint	  height,
+			  gint    *x,
+			  gint    *y,
+			  gint    *w,
+			  gint    *h);
+
+gboolean
+meta_button_present (MetaButtonLayout   *button_layout,
+		     MetaButtonFunction function);
+
+void
+meta_get_event_window_position (decor_t *d,
+				gint    i,
+				gint    j,
+				gint	width,
+				gint	height,
+				gint    *x,
+				gint    *y,
+				gint    *w,
+				gint    *h);
+void
+meta_update_border_extents (gint text_height);
+
+void
+meta_get_border_extents (decor_extents_t *extents,
+			 decor_extents_t *frame_extents,
+			 decor_extents_t *extents_max,
+			 decor_extents_t *frame_extents_max);
+
+void
+meta_update_button_layout (const char *value);
+
+decor_shadow_t *
+meta_update_shadow (gint shadow_type);
+
+void
+meta_get_shadow (decor_t *, gint shadow_type);
+
+#endif
+/* switcher.c */
+
+#define SWITCHER_ALPHA 0xa0a0
+
+void
+draw_switcher_decoration (decor_t *d);
+
+gboolean
+update_switcher_window (Window 	   popup,
+			Window     selected);
+
+decor_t *
+switcher_window_opened (Window popup, Window selected);
+
+void
+switcher_window_closed ();
+
+/* events.c */
+
+void
+move_resize_window (WnckWindow *win,
+		    int	       direction,
+		    decor_event *gtkwd_event);
+
+void
+common_button_event (WnckWindow *win,
+		     decor_event *gtkwd_event,
+		     decor_event_type gtkwd_type,
+		     int	button,
+		     int	max);
+
+void
+close_button_event (WnckWindow *win,
+		    decor_event *gtkwd_event,
+		    decor_event_type gtkwd_type);
+
+void
+max_button_event (WnckWindow *win,
+		  decor_event *gtkwd_event,
+		  decor_event_type gtkwd_type);
+
+void
+min_button_event (WnckWindow *win,
+		  decor_event *gtkwd_event,
+		  decor_event_type gtkwd_type);
+
+void
+menu_button_event (WnckWindow *win,
+		   decor_event *gtkwd_event,
+		   decor_event_type gtkwd_type);
+
+void
+shade_button_event (WnckWindow *win,
+		    decor_event *gtkwd_event,
+		    decor_event_type gtkwd_type);
+
+void
+above_button_event (WnckWindow *win,
+		    decor_event *gtkwd_event,
+		    decor_event_type gtkwd_type);
+
+void
+stick_button_event (WnckWindow *win,
+		    decor_event *gtkwd_event,
+		    decor_event_type gtkwd_type);
+void
+unshade_button_event (WnckWindow *win,
+		      decor_event *gtkwd_event,
+		      decor_event_type gtkwd_type);
+
+void
+unabove_button_event (WnckWindow *win,
+		      decor_event *gtkwd_event,
+		      decor_event_type gtkwd_type);
+
+void
+unstick_button_event (WnckWindow *win,
+		      decor_event *gtkwd_event,
+		      decor_event_type gtkwd_type);
+
+void
+handle_title_button_event (WnckWindow   *win,
+			   int          action,
+			   decor_event *gtkwd_event);
+
+void
+handle_mouse_wheel_title_event (WnckWindow   *win,
+				unsigned int button);
+
+void
+title_event (WnckWindow       *win,
+	     decor_event      *gtkwd_event,
+	     decor_event_type gtkwd_type);
+
+void
+frame_common_event (WnckWindow       *win,
+		    int              direction,
+		    decor_event      *gtkwd_event,
+		    decor_event_type gtkwd_type);
+
+void
+top_left_event (WnckWindow       *win,
+		decor_event      *gtkwd_event,
+		decor_event_type gtkwd_type);
+
+void
+top_event (WnckWindow       *win,
+	   decor_event      *gtkwd_event,
+	   decor_event_type gtkwd_type);
+
+void
+top_right_event (WnckWindow       *win,
+		 decor_event      *gtkwd_event,
+		 decor_event_type gtkwd_type);
+
+void
+left_event (WnckWindow       *win,
+	    decor_event      *gtkwd_event,
+	    decor_event_type gtkwd_type);
+void
+right_event (WnckWindow       *win,
+	     decor_event      *gtkwd_event,
+	     decor_event_type gtkwd_type);
+
+void
+bottom_left_event (WnckWindow *win,
+		   decor_event *gtkwd_event,
+		   decor_event_type gtkwd_type);
+
+void
+bottom_event (WnckWindow *win,
+	      decor_event *gtkwd_event,
+	      decor_event_type gtkwd_type);
+void
+bottom_right_event (WnckWindow *win,
+		    decor_event *gtkwd_event,
+		    decor_event_type gtkwd_type);
+
+void
+frame_window_realized (GtkWidget *widget,
+		       gpointer  data);
+
+event_callback
+find_event_callback_for_point (decor_t *d,
+			       int     x,
+			       int     y,
+			       Bool    *enter,
+			       Bool    *leave,
+			       BoxPtr  *entered_box);
+
+event_callback
+find_leave_event_callback (decor_t *d);
+
+void
+frame_handle_button_press (GtkWidget      *widget,
+			   GdkEventButton *event,
+			   gpointer       user_data);
+
+void
+frame_handle_button_release (GtkWidget      *widget,
+			     GdkEventButton *event,
+			     gpointer       user_data);
+
+void
+frame_handle_motion (GtkWidget      *widget,
+		     GdkEventMotion *event,
+		     gpointer       user_data);
+
+GdkFilterReturn
+selection_event_filter_func (GdkXEvent *gdkxevent,
+			     GdkEvent  *event,
+			     gpointer  data);
+
+GdkFilterReturn
+event_filter_func (GdkXEvent *gdkxevent,
+		   GdkEvent  *event,
+		   gpointer  data);
+
+/* forcequit.c */
+
+void
+show_force_quit_dialog (WnckWindow *win,
+			Time        timestamp);
+
+void
+hide_force_quit_dialog (WnckWindow *win);
+
+/* actionmenu.c */
+
+void
+action_menu_map (WnckWindow *win,
+		 long	     button,
+		 Time	     time);
+
+/* util.c */
+
+double
+square (double x);
+
+double
+dist (double x1, double y1,
+      double x2, double y2);
+
+void
+shade (const decor_color_t *a,
+       decor_color_t	   *b,
+       float		   k);
+
+gboolean
+get_window_prop (Window xwindow,
+		 Atom   atom,
+		 Window *val);
+
+unsigned int
+get_mwm_prop (Window xwindow);
+
+
+/* style.c */
+
+void
+update_style (GtkWidget *widget);
+
+void
+style_changed (GtkWidget *widget);
+
+/* settings.c */
+
+gboolean
+init_settings (WnckScreen *screen);
+
+#endif

=== added file '.pc/fix-883383.patch/unity/unity_window_decorator/src/settings.c'
--- .pc/fix-883383.patch/unity/unity_window_decorator/src/settings.c	1970-01-01 00:00:00 +0000
+++ .pc/fix-883383.patch/unity/unity_window_decorator/src/settings.c	2011-10-29 09:07:25 +0000
@@ -0,0 +1,567 @@
+#include "gtk-window-decorator.h"
+
+/* TODO: Trash all of this and use a window property
+ * instead - much much cleaner!
+ */
+
+void
+shadow_property_changed (WnckScreen *s)
+{
+    GdkDisplay *display = gdk_display_get_default ();
+    Display    *xdisplay = GDK_DISPLAY_XDISPLAY (display);
+    GdkScreen  *screen = gdk_display_get_default_screen (display);
+    Window     root = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen));
+    Atom actual;
+    int  result, format;
+    unsigned long n, left;
+    unsigned char *prop_data;
+    gboolean	  changed = FALSE;
+    XTextProperty shadow_color_xtp;
+
+    result = XGetWindowProperty (xdisplay, root, compiz_shadow_info_atom,
+				 0, 32768, 0, XA_INTEGER, &actual,
+				 &format, &n, &left, &prop_data);
+
+    if (result != Success)
+	return;
+
+    if (n == 4)
+    {
+	long *data      = (long *) prop_data;
+	gdouble radius  = data[0];
+	gdouble opacity = data[1];
+	gint x_off      = data[2];
+	gint y_off      = data[3];
+
+	/* Radius and Opacity are multiplied by 1000 to keep precision,
+	 * divide by that much to get our real radius and opacity
+	 */
+	radius /= 1000;
+	opacity /= 1000;
+
+	changed = radius != shadow_radius   ||
+		  opacity != shadow_opacity ||
+		  x_off != shadow_offset_x  ||
+		  y_off != shadow_offset_y;
+
+	shadow_radius = (gdouble) MAX (0.0, MIN (radius, 48.0));
+	shadow_opacity = (gdouble) MAX (0.0, MIN (opacity, 6.0));
+	shadow_offset_x = (gint) MAX (-16, MIN (x_off, 16));
+	shadow_offset_y = (gint) MAX (-16, MIN (y_off, 16));
+    }
+
+    XFree (prop_data);
+
+    result = XGetTextProperty (xdisplay, root, &shadow_color_xtp,
+			       compiz_shadow_color_atom);
+
+    if (shadow_color_xtp.value)
+    {
+	int  ret_count = 0;
+	char **t_data = NULL;
+
+	XTextPropertyToStringList (&shadow_color_xtp, &t_data, &ret_count);
+
+	if (ret_count == 1)
+	{
+	    int c[4];
+
+	    if (sscanf (t_data[0], "#%2x%2x%2x%2x",
+			&c[0], &c[1], &c[2], &c[3]) == 4)
+	    {
+		shadow_color[0] = c[0] << 8 | c[0];
+		shadow_color[1] = c[1] << 8 | c[1];
+		shadow_color[2] = c[2] << 8 | c[2];
+		changed = TRUE;
+	    }
+	}
+
+	XFree (shadow_color_xtp.value);
+	if (t_data)
+	    XFreeStringList (t_data);
+    }
+
+    if (changed)
+	decorations_changed (s);
+}
+
+#ifdef USE_GCONF_UNITY_WINDOW_DECORATOR
+static gboolean
+blur_settings_changed (GConfClient *client)
+{
+    gchar *type;
+    int   new_type = blur_type;
+
+    if (cmdline_options & CMDLINE_BLUR)
+	return FALSE;
+
+    type = gconf_client_get_string (client,
+				    BLUR_TYPE_KEY,
+				    NULL);
+
+    if (type)
+    {
+	if (strcmp (type, "titlebar") == 0)
+	    new_type = BLUR_TYPE_TITLEBAR;
+	else if (strcmp (type, "all") == 0)
+	    new_type = BLUR_TYPE_ALL;
+	else if (strcmp (type, "none") == 0)
+	    new_type = BLUR_TYPE_NONE;
+
+	g_free (type);
+    }
+
+    if (new_type != blur_type)
+    {
+	blur_type = new_type;
+	return TRUE;
+    }
+
+    return FALSE;
+}
+
+static gboolean
+theme_changed (GConfClient *client)
+{
+
+#ifdef USE_METACITY
+    gboolean use_meta_theme;
+
+    if (cmdline_options & CMDLINE_THEME)
+	return FALSE;
+
+    use_meta_theme = gconf_client_get_bool (client,
+					    USE_META_THEME_KEY,
+					    NULL);
+
+    if (use_meta_theme)
+    {
+	gchar *theme;
+
+	theme = gconf_client_get_string (client,
+					 META_THEME_KEY,
+					 NULL);
+
+	if (theme)
+	{
+	    meta_theme_set_current (theme, TRUE);
+	    if (!meta_theme_get_current ())
+		use_meta_theme = FALSE;
+
+	    g_free (theme);
+	}
+	else
+	{
+	    use_meta_theme = FALSE;
+	}
+    }
+
+    if (use_meta_theme)
+    {
+	theme_draw_window_decoration	= meta_draw_window_decoration;
+	theme_calc_decoration_size	= meta_calc_decoration_size;
+	theme_update_border_extents	= meta_update_border_extents;
+	theme_get_event_window_position = meta_get_event_window_position;
+	theme_get_button_position	= meta_get_button_position;
+	theme_update_shadow		= meta_update_shadow;
+	theme_get_shadow		= meta_get_shadow;
+	theme_get_border_extents	= meta_get_border_extents;
+    }
+    else
+    {
+	theme_draw_window_decoration	= draw_window_decoration;
+	theme_calc_decoration_size	= calc_decoration_size;
+	theme_update_border_extents	= update_border_extents;
+	theme_get_event_window_position = get_event_window_position;
+	theme_get_button_position	= get_button_position;
+	theme_update_shadow		= cairo_update_shadow;
+	theme_get_shadow		= get_shadow;
+	theme_get_border_extents	= get_border_extents;
+    }
+
+    return TRUE;
+#else
+    theme_draw_window_decoration    = draw_window_decoration;
+    theme_calc_decoration_size	    = calc_decoration_size;
+    theme_update_border_extents	    = update_border_extents;
+    theme_get_event_window_position = get_event_window_position;
+    theme_get_button_position	    = get_button_position;
+    theme_get_border_extents	    = get_border_extents;
+
+    return FALSE;
+#endif
+
+}
+
+static gboolean
+theme_opacity_changed (GConfClient *client)
+{
+
+#ifdef USE_METACITY
+    gboolean shade_opacity, changed = FALSE;
+    gdouble  opacity;
+
+    opacity = gconf_client_get_float (client,
+				      META_THEME_OPACITY_KEY,
+				      NULL);
+
+    if (!(cmdline_options & CMDLINE_OPACITY) &&
+	opacity != meta_opacity)
+    {
+	meta_opacity = opacity;
+	changed = TRUE;
+    }
+
+    if (opacity < 1.0)
+    {
+	shade_opacity = gconf_client_get_bool (client,
+					       META_THEME_SHADE_OPACITY_KEY,
+					       NULL);
+
+	if (!(cmdline_options & CMDLINE_OPACITY_SHADE) &&
+	    shade_opacity != meta_shade_opacity)
+	{
+	    meta_shade_opacity = shade_opacity;
+	    changed = TRUE;
+	}
+    }
+
+    opacity = gconf_client_get_float (client,
+				      META_THEME_ACTIVE_OPACITY_KEY,
+				      NULL);
+
+    if (!(cmdline_options & CMDLINE_ACTIVE_OPACITY) &&
+	opacity != meta_active_opacity)
+    {
+	meta_active_opacity = opacity;
+	changed = TRUE;
+    }
+
+    if (opacity < 1.0)
+    {
+	shade_opacity =
+	    gconf_client_get_bool (client,
+				   META_THEME_ACTIVE_SHADE_OPACITY_KEY,
+				   NULL);
+
+	if (!(cmdline_options & CMDLINE_ACTIVE_OPACITY_SHADE) &&
+	    shade_opacity != meta_active_shade_opacity)
+	{
+	    meta_active_shade_opacity = shade_opacity;
+	    changed = TRUE;
+	}
+    }
+
+    return changed;
+#else
+    return FALSE;
+#endif
+
+}
+
+static gboolean
+button_layout_changed (GConfClient *client)
+{
+
+#ifdef USE_METACITY
+    gchar *button_layout;
+
+    button_layout = gconf_client_get_string (client,
+					     META_BUTTON_LAYOUT_KEY,
+					     NULL);
+
+    if (button_layout)
+    {
+	meta_update_button_layout (button_layout);
+
+	meta_button_layout_set = TRUE;
+
+	g_free (button_layout);
+
+	return TRUE;
+    }
+
+    if (meta_button_layout_set)
+    {
+	meta_button_layout_set = FALSE;
+	return TRUE;
+    }
+#endif
+
+    return FALSE;
+}
+
+static void
+titlebar_font_changed (GConfClient *client)
+{
+    gchar *str;
+
+    str = gconf_client_get_string (client,
+				   COMPIZ_TITLEBAR_FONT_KEY,
+				   NULL);
+    if (!str)
+	str = g_strdup ("Sans Bold 12");
+
+    if (titlebar_font)
+	pango_font_description_free (titlebar_font);
+
+    titlebar_font = pango_font_description_from_string (str);
+
+    g_free (str);
+}
+
+static void
+titlebar_click_action_changed (GConfClient *client,
+			       const gchar *key,
+			       int         *action_value,
+			       int          default_value)
+{
+    gchar *action;
+
+    *action_value = default_value;
+
+    action = gconf_client_get_string (client, key, NULL);
+    if (action)
+    {
+	if (strcmp (action, "toggle_shade") == 0)
+	    *action_value = CLICK_ACTION_SHADE;
+	else if (strcmp (action, "toggle_maximize") == 0)
+	    *action_value = CLICK_ACTION_MAXIMIZE;
+	else if (strcmp (action, "minimize") == 0)
+	    *action_value = CLICK_ACTION_MINIMIZE;
+	else if (strcmp (action, "raise") == 0)
+	    *action_value = CLICK_ACTION_RAISE;
+	else if (strcmp (action, "lower") == 0)
+	    *action_value = CLICK_ACTION_LOWER;
+	else if (strcmp (action, "menu") == 0)
+	    *action_value = CLICK_ACTION_MENU;
+	else if (strcmp (action, "none") == 0)
+	    *action_value = CLICK_ACTION_NONE;
+
+	g_free (action);
+    }
+}
+
+static void
+wheel_action_changed (GConfClient *client)
+{
+    gchar *action;
+
+    wheel_action = WHEEL_ACTION_DEFAULT;
+
+    action = gconf_client_get_string (client, WHEEL_ACTION_KEY, NULL);
+    if (action)
+    {
+	if (strcmp (action, "shade") == 0)
+	    wheel_action = WHEEL_ACTION_SHADE;
+	else if (strcmp (action, "none") == 0)
+	    wheel_action = WHEEL_ACTION_NONE;
+
+	g_free (action);
+    }
+}
+
+static void
+value_changed (GConfClient *client,
+	       const gchar *key,
+	       GConfValue  *value,
+	       void        *data)
+{
+    gboolean changed = FALSE;
+
+    if (strcmp (key, COMPIZ_USE_SYSTEM_FONT_KEY) == 0)
+    {
+	if (gconf_client_get_bool (client,
+				   COMPIZ_USE_SYSTEM_FONT_KEY,
+				   NULL) != use_system_font)
+	{
+	    use_system_font = !use_system_font;
+	    changed = TRUE;
+	}
+    }
+    else if (strcmp (key, COMPIZ_TITLEBAR_FONT_KEY) == 0)
+    {
+	titlebar_font_changed (client);
+	changed = !use_system_font;
+    }
+    else if (strcmp (key, COMPIZ_DOUBLE_CLICK_TITLEBAR_KEY) == 0)
+    {
+	titlebar_click_action_changed (client, key,
+				       &double_click_action,
+				       DOUBLE_CLICK_ACTION_DEFAULT);
+    }
+    else if (strcmp (key, COMPIZ_MIDDLE_CLICK_TITLEBAR_KEY) == 0)
+    {
+	titlebar_click_action_changed (client, key,
+				       &middle_click_action,
+				       MIDDLE_CLICK_ACTION_DEFAULT);
+    }
+    else if (strcmp (key, COMPIZ_RIGHT_CLICK_TITLEBAR_KEY) == 0)
+    {
+	titlebar_click_action_changed (client, key,
+				       &right_click_action,
+				       RIGHT_CLICK_ACTION_DEFAULT);
+    }
+    else if (strcmp (key, WHEEL_ACTION_KEY) == 0)
+    {
+	wheel_action_changed (client);
+    }
+    else if (strcmp (key, BLUR_TYPE_KEY) == 0)
+    {
+	if (blur_settings_changed (client))
+	    changed = TRUE;
+    }
+    else if (strcmp (key, USE_META_THEME_KEY) == 0 ||
+	     strcmp (key, META_THEME_KEY) == 0)
+    {
+	if (theme_changed (client))
+	    changed = TRUE;
+    }
+    else if (strcmp (key, META_BUTTON_LAYOUT_KEY) == 0)
+    {
+	if (button_layout_changed (client))
+	    changed = TRUE;
+    }
+    else if (strcmp (key, META_THEME_OPACITY_KEY)	       == 0 ||
+	     strcmp (key, META_THEME_SHADE_OPACITY_KEY)	       == 0 ||
+	     strcmp (key, META_THEME_ACTIVE_OPACITY_KEY)       == 0 ||
+	     strcmp (key, META_THEME_ACTIVE_SHADE_OPACITY_KEY) == 0)
+    {
+	if (theme_opacity_changed (client))
+	    changed = TRUE;
+    }
+
+    if (changed)
+	decorations_changed (data);
+}
+#endif
+
+gboolean
+init_settings (WnckScreen *screen)
+{
+    GtkSettings	   *settings;
+    GdkScreen	   *gdkscreen;
+    GdkColormap	   *colormap;
+    AtkObject	   *switcher_label_obj;
+
+#ifdef USE_GCONF_UNITY_WINDOW_DECORATOR
+    GConfClient	   *gconf;
+
+    gconf = gconf_client_get_default ();
+
+    gconf_client_add_dir (gconf,
+			  GCONF_DIR,
+			  GCONF_CLIENT_PRELOAD_ONELEVEL,
+			  NULL);
+
+    gconf_client_add_dir (gconf,
+			  METACITY_GCONF_DIR,
+			  GCONF_CLIENT_PRELOAD_ONELEVEL,
+			  NULL);
+
+    g_signal_connect (G_OBJECT (gconf),
+		      "value_changed",
+		      G_CALLBACK (value_changed),
+		      screen);
+#endif
+
+    style_window_rgba = gtk_window_new (GTK_WINDOW_POPUP);
+
+    gdkscreen = gdk_display_get_default_screen (gdk_display_get_default ());
+    colormap = gdk_screen_get_rgba_colormap (gdkscreen);
+    if (colormap)
+	gtk_widget_set_colormap (style_window_rgba, colormap);
+
+    gtk_widget_realize (style_window_rgba);
+
+    switcher_label = gtk_label_new ("");
+    switcher_label_obj = gtk_widget_get_accessible (switcher_label);
+    atk_object_set_role (switcher_label_obj, ATK_ROLE_STATUSBAR);
+    gtk_container_add (GTK_CONTAINER (style_window_rgba), switcher_label);
+
+    gtk_widget_set_size_request (style_window_rgba, 0, 0);
+    gtk_window_move (GTK_WINDOW (style_window_rgba), -100, -100);
+    gtk_widget_show_all (style_window_rgba);
+
+    g_signal_connect_object (style_window_rgba, "style-set",
+			     G_CALLBACK (style_changed),
+			     0, 0);
+
+    settings = gtk_widget_get_settings (style_window_rgba);
+
+    g_object_get (G_OBJECT (settings), "gtk-double-click-time",
+		  &double_click_timeout, NULL);
+
+    pango_context = gtk_widget_create_pango_context (style_window_rgba);
+
+    style_window_rgb = gtk_window_new (GTK_WINDOW_POPUP);
+
+    gdkscreen = gdk_display_get_default_screen (gdk_display_get_default ());
+    colormap = gdk_screen_get_rgb_colormap (gdkscreen);
+    if (colormap)
+	gtk_widget_set_colormap (style_window_rgb, colormap);
+
+    gtk_widget_realize (style_window_rgb);
+
+    switcher_label = gtk_label_new ("");
+    switcher_label_obj = gtk_widget_get_accessible (switcher_label);
+    atk_object_set_role (switcher_label_obj, ATK_ROLE_STATUSBAR);
+    gtk_container_add (GTK_CONTAINER (style_window_rgb), switcher_label);
+
+    gtk_widget_set_size_request (style_window_rgb, 0, 0);
+    gtk_window_move (GTK_WINDOW (style_window_rgb), -100, -100);
+    gtk_widget_show_all (style_window_rgb);
+
+    g_signal_connect_object (style_window_rgb, "style-set",
+			     G_CALLBACK (style_changed),
+			     0, 0);
+
+    settings = gtk_widget_get_settings (style_window_rgb);
+
+    g_object_get (G_OBJECT (settings), "gtk-double-click-time",
+		  &double_click_timeout, NULL);
+
+    pango_context = gtk_widget_create_pango_context (style_window_rgb);
+
+#ifdef USE_GCONF_UNITY_WINDOW_DECORATOR
+    use_system_font = gconf_client_get_bool (gconf,
+					     COMPIZ_USE_SYSTEM_FONT_KEY,
+					     NULL);
+    theme_changed (gconf);
+    theme_opacity_changed (gconf);
+    button_layout_changed (gconf);
+#endif
+
+    update_style (style_window_rgba);
+    update_style (style_window_rgb);
+#ifdef USE_GCONF_UNITY_WINDOW_DECORATOR
+    titlebar_font_changed (gconf);
+#endif
+
+    update_titlebar_font ();
+
+#ifdef USE_GCONF_UNITY_WINDOW_DECORATOR
+    titlebar_click_action_changed (gconf,
+				   COMPIZ_DOUBLE_CLICK_TITLEBAR_KEY,
+				   &double_click_action,
+				   DOUBLE_CLICK_ACTION_DEFAULT);
+    titlebar_click_action_changed (gconf,
+				   COMPIZ_MIDDLE_CLICK_TITLEBAR_KEY,
+				   &middle_click_action,
+				   MIDDLE_CLICK_ACTION_DEFAULT);
+    titlebar_click_action_changed (gconf,
+				   COMPIZ_RIGHT_CLICK_TITLEBAR_KEY,
+				   &right_click_action,
+				   RIGHT_CLICK_ACTION_DEFAULT);
+    wheel_action_changed (gconf);
+    blur_settings_changed (gconf);
+#endif
+
+    (*theme_update_border_extents) (text_height);
+
+    shadow_property_changed (screen);
+
+    update_shadow ();
+
+    return TRUE;
+}

=== modified file 'debian/changelog'
--- debian/changelog	2011-10-12 10:44:49 +0000
+++ debian/changelog	2011-10-29 09:07:25 +0000
@@ -1,3 +1,12 @@
+compiz (1:0.9.6+bzr20110929-0ubuntu6) precise; urgency=low
+
+  * debian/patches/fix-881329.patch:
+    - Alt+click should raise with raise-on-click disabled (LP: #881329)
+  * debian/patches/fix-883383.patch:
+    - Drag title bar should not raise if raise-on-click is disabled (LP: #883383)
+
+ -- James Pharaoh <james@xxxxxxxxxxx>  Tue, 25 Oct 2011 12:07:03 +0200
+
 compiz (1:0.9.6+bzr20110929-0ubuntu5) oneiric-proposed; urgency=low
 
   * debian/patches/fix-864330.patch:

=== added file 'debian/patches/fix-881329.patch'
--- debian/patches/fix-881329.patch	1970-01-01 00:00:00 +0000
+++ debian/patches/fix-881329.patch	2011-10-29 09:07:25 +0000
@@ -0,0 +1,49 @@
+Index: fix-881329/plugins/move/src/move.cpp
+===================================================================
+--- fix-881329.orig/plugins/move/src/move.cpp	2011-10-25 11:55:52.191836766 +0200
++++ fix-881329/plugins/move/src/move.cpp	2011-10-25 11:56:01.683903132 +0200
+@@ -153,6 +153,8 @@
+ 		if (mw->gWindow)
+ 		mw->gWindow->glPaintSetEnabled (mw, true);
+ 	    }
++
++	    ms->hasMoved = false;
+ 	}
+     }
+ 
+@@ -177,7 +179,12 @@
+ 	/* update window attributes as window constraints may have
+ 	   changed - needed e.g. if a maximized window was moved
+ 	   to another output device */
+-	ms->w->updateAttributes (CompStackingUpdateModeNone);
++	/* also raise on alt-click when raise on click is disabled */
++	bool raiseOnClick = screen->getOption ("raise_on_click")->value ().b ();
++	if (! raiseOnClick && ! ms->hasMoved)
++	    ms->w->updateAttributes (CompStackingUpdateModeAboveFullscreen);
++	else
++	    ms->w->updateAttributes (CompStackingUpdateModeNone);
+ 
+ 	ms->w->ungrabNotify ();
+ 
+@@ -504,6 +511,8 @@
+ 
+ 	    ms->x -= dx;
+ 	    ms->y -= dy;
++
++	    ms->hasMoved = true;
+ 	}
+     }
+ }
+Index: fix-881329/plugins/move/src/move.h
+===================================================================
+--- fix-881329.orig/plugins/move/src/move.h	2011-10-25 11:55:52.215836933 +0200
++++ fix-881329/plugins/move/src/move.h	2011-10-25 11:56:01.683903132 +0200
+@@ -90,6 +90,8 @@
+ 	bool hasCompositing;
+ 
+ 	bool yConstrained;
++
++	bool hasMoved;
+ };
+ 
+ class MoveWindow :

=== added file 'debian/patches/fix-883383.patch'
--- debian/patches/fix-883383.patch	1970-01-01 00:00:00 +0000
+++ debian/patches/fix-883383.patch	2011-10-29 09:07:25 +0000
@@ -0,0 +1,77 @@
+Index: fix-883383/unity/unity_window_decorator/src/events.c
+===================================================================
+--- fix-883383.orig/unity/unity_window_decorator/src/events.c	2011-10-29 10:22:29.079644323 +0200
++++ fix-883383/unity/unity_window_decorator/src/events.c	2011-10-29 10:22:31.631675000 +0200
+@@ -450,7 +450,8 @@
+ 	    last_button_x	= gtkwd_event->x;
+ 	    last_button_y	= gtkwd_event->y;
+ 
+-	    restack_window (win, Above);
++	    if (raise_on_click)
++		restack_window (win, Above);
+ 
+ 	    move_resize_window (win, WM_MOVERESIZE_MOVE, gtkwd_event);
+ 	}
+Index: fix-883383/unity/unity_window_decorator/src/gtk-window-decorator.c
+===================================================================
+--- fix-883383.orig/unity/unity_window_decorator/src/gtk-window-decorator.c	2011-10-29 10:22:29.099644474 +0200
++++ fix-883383/unity/unity_window_decorator/src/gtk-window-decorator.c	2011-10-29 10:22:31.631675000 +0200
+@@ -25,6 +25,8 @@
+ 
+ double decoration_alpha = 0.5;
+ 
++gboolean raise_on_click = TRUE;
++
+ #define SWITCHER_SPACE 40
+ 
+ decor_extents_t _shadow_extents      = { 0, 0, 0, 0 };
+Index: fix-883383/unity/unity_window_decorator/src/gtk-window-decorator.h
+===================================================================
+--- fix-883383.orig/unity/unity_window_decorator/src/gtk-window-decorator.h	2011-10-29 10:22:29.123644654 +0200
++++ fix-883383/unity/unity_window_decorator/src/gtk-window-decorator.h	2011-10-29 10:22:31.631675000 +0200
+@@ -97,6 +97,9 @@
+ #define COMPIZ_RIGHT_CLICK_TITLEBAR_KEY	       \
+ METACITY_GCONF_DIR "/action_right_click_titlebar"
+ 
++#define COMPIZ_RAISE_ON_CLICK_KEY \
++METACITY_GCONF_DIR "/raise_on_click"
++
+ #define COMPIZ_GCONF_DIR1 "/apps/compiz/plugins/decoration/allscreens/options"
+ 
+ #define COMPIZ_SHADOW_RADIUS_KEY \
+@@ -243,6 +246,8 @@
+ extern gboolean minimal;
+ extern double decoration_alpha;
+ 
++extern gboolean raise_on_click;
++
+ #define SWITCHER_SPACE 40
+ 
+ extern decor_extents_t _shadow_extents;
+Index: fix-883383/unity/unity_window_decorator/src/settings.c
+===================================================================
+--- fix-883383.orig/unity/unity_window_decorator/src/settings.c	2011-10-29 10:22:29.151644865 +0200
++++ fix-883383/unity/unity_window_decorator/src/settings.c	2011-10-29 10:22:31.631675000 +0200
+@@ -402,6 +402,12 @@
+ 				       &right_click_action,
+ 				       RIGHT_CLICK_ACTION_DEFAULT);
+     }
++    else if (strcmp (key, COMPIZ_RAISE_ON_CLICK_KEY) == 0)
++    {
++	raise_on_click = gconf_client_get_bool (client,
++						COMPIZ_RAISE_ON_CLICK_KEY,
++						NULL);
++    }
+     else if (strcmp (key, WHEEL_ACTION_KEY) == 0)
+     {
+ 	wheel_action_changed (client);
+@@ -555,6 +561,9 @@
+ 				   RIGHT_CLICK_ACTION_DEFAULT);
+     wheel_action_changed (gconf);
+     blur_settings_changed (gconf);
++    raise_on_click = gconf_client_get_bool (gconf,
++					    COMPIZ_RAISE_ON_CLICK_KEY,
++					    NULL);
+ #endif
+ 
+     (*theme_update_border_extents) (text_height);

=== modified file 'debian/patches/series'
--- debian/patches/series	2011-10-12 10:44:49 +0000
+++ debian/patches/series	2011-10-29 09:07:25 +0000
@@ -12,3 +12,5 @@
 fix-832150.patch
 fix-864478.patch
 fix-864330.patch
+fix-881329.patch
+fix-883383.patch

=== modified file 'plugins/move/src/move.cpp'
--- plugins/move/src/move.cpp	2011-10-12 10:44:49 +0000
+++ plugins/move/src/move.cpp	2011-10-29 09:07:25 +0000
@@ -153,6 +153,8 @@
 		if (mw->gWindow)
 		mw->gWindow->glPaintSetEnabled (mw, true);
 	    }
+
+	    ms->hasMoved = false;
 	}
     }
 
@@ -177,7 +179,12 @@
 	/* update window attributes as window constraints may have
 	   changed - needed e.g. if a maximized window was moved
 	   to another output device */
-	ms->w->updateAttributes (CompStackingUpdateModeNone);
+	/* also raise on alt-click when raise on click is disabled */
+	bool raiseOnClick = screen->getOption ("raise_on_click")->value ().b ();
+	if (! raiseOnClick && ! ms->hasMoved)
+	    ms->w->updateAttributes (CompStackingUpdateModeAboveFullscreen);
+	else
+	    ms->w->updateAttributes (CompStackingUpdateModeNone);
 
 	ms->w->ungrabNotify ();
 
@@ -504,6 +511,8 @@
 
 	    ms->x -= dx;
 	    ms->y -= dy;
+
+	    ms->hasMoved = true;
 	}
     }
 }

=== modified file 'plugins/move/src/move.h'
--- plugins/move/src/move.h	2011-09-28 14:15:21 +0000
+++ plugins/move/src/move.h	2011-10-29 09:07:25 +0000
@@ -90,6 +90,8 @@
 	bool hasCompositing;
 
 	bool yConstrained;
+
+	bool hasMoved;
 };
 
 class MoveWindow :

=== modified file 'unity/unity_window_decorator/src/events.c'
--- unity/unity_window_decorator/src/events.c	2011-09-28 14:15:21 +0000
+++ unity/unity_window_decorator/src/events.c	2011-10-29 09:07:25 +0000
@@ -450,7 +450,8 @@
 	    last_button_x	= gtkwd_event->x;
 	    last_button_y	= gtkwd_event->y;
 
-	    restack_window (win, Above);
+	    if (raise_on_click)
+		restack_window (win, Above);
 
 	    move_resize_window (win, WM_MOVERESIZE_MOVE, gtkwd_event);
 	}

=== modified file 'unity/unity_window_decorator/src/gtk-window-decorator.c'
--- unity/unity_window_decorator/src/gtk-window-decorator.c	2011-08-23 18:19:11 +0000
+++ unity/unity_window_decorator/src/gtk-window-decorator.c	2011-10-29 09:07:25 +0000
@@ -25,6 +25,8 @@
 
 double decoration_alpha = 0.5;
 
+gboolean raise_on_click = TRUE;
+
 #define SWITCHER_SPACE 40
 
 decor_extents_t _shadow_extents      = { 0, 0, 0, 0 };

=== modified file 'unity/unity_window_decorator/src/gtk-window-decorator.h'
--- unity/unity_window_decorator/src/gtk-window-decorator.h	2011-08-23 18:19:11 +0000
+++ unity/unity_window_decorator/src/gtk-window-decorator.h	2011-10-29 09:07:25 +0000
@@ -97,6 +97,9 @@
 #define COMPIZ_RIGHT_CLICK_TITLEBAR_KEY	       \
 METACITY_GCONF_DIR "/action_right_click_titlebar"
 
+#define COMPIZ_RAISE_ON_CLICK_KEY \
+METACITY_GCONF_DIR "/raise_on_click"
+
 #define COMPIZ_GCONF_DIR1 "/apps/compiz/plugins/decoration/allscreens/options"
 
 #define COMPIZ_SHADOW_RADIUS_KEY \
@@ -243,6 +246,8 @@
 extern gboolean minimal;
 extern double decoration_alpha;
 
+extern gboolean raise_on_click;
+
 #define SWITCHER_SPACE 40
 
 extern decor_extents_t _shadow_extents;

=== modified file 'unity/unity_window_decorator/src/settings.c'
--- unity/unity_window_decorator/src/settings.c	2011-08-23 18:19:11 +0000
+++ unity/unity_window_decorator/src/settings.c	2011-10-29 09:07:25 +0000
@@ -402,6 +402,12 @@
 				       &right_click_action,
 				       RIGHT_CLICK_ACTION_DEFAULT);
     }
+    else if (strcmp (key, COMPIZ_RAISE_ON_CLICK_KEY) == 0)
+    {
+	raise_on_click = gconf_client_get_bool (client,
+						COMPIZ_RAISE_ON_CLICK_KEY,
+						NULL);
+    }
     else if (strcmp (key, WHEEL_ACTION_KEY) == 0)
     {
 	wheel_action_changed (client);
@@ -555,6 +561,9 @@
 				   RIGHT_CLICK_ACTION_DEFAULT);
     wheel_action_changed (gconf);
     blur_settings_changed (gconf);
+    raise_on_click = gconf_client_get_bool (gconf,
+					    COMPIZ_RAISE_ON_CLICK_KEY,
+					    NULL);
 #endif
 
     (*theme_update_border_extents) (text_height);


Follow ups