summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles Bos2015-06-09 12:49:56 +0100
committerCharles Bos2015-06-09 12:49:56 +0100
commita716d0e8ede8a5a9bd946a245eb3b4f74cdc6f96 (patch)
treee89d61d8842d7ac7c946c71b1a12bd392a7dc23e
downloadaur-a716d0e8ede8a5a9bd946a245eb3b4f74cdc6f96.tar.gz
Initial commit
-rw-r--r--.SRCINFO52
-rw-r--r--PKGBUILD107
-rw-r--r--compiz-bzr.install29
-rw-r--r--focus-prevention-disable.patch12
-rw-r--r--metacity-3_16.patch5387
-rw-r--r--set-gwd-default.patch12
6 files changed, 5599 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
new file mode 100644
index 000000000000..e459864e872f
--- /dev/null
+++ b/.SRCINFO
@@ -0,0 +1,52 @@
+# Generated by makepkg 4.2.1
+# Thu May 14 10:47:18 UTC 2015
+pkgbase = compiz-bzr
+ pkgdesc = Composite manager for Aiglx and Xgl, with plugins and CCSM (development version)
+ pkgver = 3953
+ pkgrel = 1
+ url = https://launchpad.net/compiz
+ install = compiz-bzr.install
+ arch = i686
+ arch = x86_64
+ license = GPL
+ license = LGPL
+ license = MIT
+ makedepends = cmake
+ makedepends = bzr
+ makedepends = intltool
+ depends = boost
+ depends = xorg-server
+ depends = libxcomposite
+ depends = startup-notification
+ depends = librsvg
+ depends = dbus
+ depends = mesa
+ depends = libxslt
+ depends = fuse
+ depends = glibmm
+ depends = libxrender
+ depends = libwnck3
+ depends = pygtk
+ depends = desktop-file-utils
+ depends = pyrex
+ depends = protobuf
+ depends = metacity>=3.16.0
+ depends = glu
+ depends = libsm
+ depends = dconf
+ optdepends = xorg-xprop: grab various window properties for use in window matching rules
+ provides = compiz=0.9.12
+ conflicts = compiz-core
+ conflicts = compiz
+ replaces = compiz-core-bzr
+ source = compiz::bzr+http://bazaar.launchpad.net/~compiz-team/compiz/0.9.12/
+ source = set-gwd-default.patch
+ source = focus-prevention-disable.patch
+ source = metacity-3_16.patch
+ sha256sums = SKIP
+ sha256sums = 3aa6cb70f357b3d34d51735f4b5bcb0479086d7c7336de4bd8157569d6c52c08
+ sha256sums = f4897590b0f677ba34767a29822f8f922a750daf66e8adf47be89f7c2550cf4b
+ sha256sums = 97d4f62ec373ec80a8eff151a497005912050898be447b204846ce90c368fa61
+
+pkgname = compiz-bzr
+
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 000000000000..40e99c29e223
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,107 @@
+# Maintainer: Charles Bos <charlesbos1 AT gmail>
+# Contributor: Rob McCathie <archaur at rmcc dot com dot au
+# Contributor: Iven Hsu <ivenvd AT gmail>
+
+pkgname=compiz-bzr
+pkgver=3953
+pkgrel=1
+_bzrname=compiz
+_bzrbranch=0.9.12
+pkgdesc="Composite manager for Aiglx and Xgl, with plugins and CCSM (development version)"
+arch=('i686' 'x86_64')
+url="https://launchpad.net/compiz"
+license=('GPL' 'LGPL' 'MIT')
+depends=('boost' 'xorg-server' 'libxcomposite' 'startup-notification' 'librsvg' 'dbus' 'mesa' 'libxslt' 'fuse' 'glibmm' 'libxrender' 'libwnck3' 'pygtk' 'desktop-file-utils' 'pyrex' 'protobuf' 'metacity>=3.16.0' 'glu' 'libsm' 'dconf')
+makedepends=('cmake' 'bzr' 'intltool')
+optdepends=(
+ 'xorg-xprop: grab various window properties for use in window matching rules'
+)
+conflicts=('compiz-core' 'compiz')
+provides=("compiz=$_bzrbranch")
+replaces=('compiz-core-bzr')
+source=("$_bzrname::bzr+http://bazaar.launchpad.net/~compiz-team/$_bzrname/$_bzrbranch/"
+ "set-gwd-default.patch"
+ "focus-prevention-disable.patch"
+ "metacity-3_16.patch")
+sha256sums=('SKIP'
+ '3aa6cb70f357b3d34d51735f4b5bcb0479086d7c7336de4bd8157569d6c52c08'
+ 'f4897590b0f677ba34767a29822f8f922a750daf66e8adf47be89f7c2550cf4b'
+ '97d4f62ec373ec80a8eff151a497005912050898be447b204846ce90c368fa61')
+install='compiz-bzr.install'
+
+pkgver() {
+ cd $_bzrname
+ bzr revno
+}
+
+prepare() {
+ cd $_bzrname
+
+ # Set gtk-window-decorator as default in the Window Decoration plugin
+ patch -Np1 -i "${srcdir}/set-gwd-default.patch"
+
+ # Set focus prevention level to off which means that new windows will always get focus
+ patch -Np1 -i "${srcdir}/focus-prevention-disable.patch"
+
+ find -type f \( -name 'CMakeLists.txt' -or -name '*.cmake' \) -exec sed -e 's/COMMAND python/COMMAND python2/g' -i {} \;
+ find compizconfig/ccsm -type f -exec sed -e 's|^#!.*python|#!/usr/bin/env python2|g' -i {} \;
+
+ # Fix Python build directory with CMake 3.2
+ sed -i 's/${PY_BUILD_DIR}/lib/g' compizconfig/ccsm/CMakeLists.txt
+
+ # Metacity 3.16 compatibility
+ patch -Np1 -i "${srcdir}/metacity-3_16.patch"
+}
+
+build() {
+ cd $_bzrname
+
+ export PYTHON="/usr/bin/python2"
+
+ mkdir build; cd build
+
+ cmake .. \
+ -DCMAKE_INSTALL_PREFIX="/usr" \
+ -DCMAKE_INSTALL_LIBDIR="/usr/lib" \
+ -DPYTHON_INCLUDE_DIR=/usr/include/python2.7 \
+ -DPYTHON_LIBRARY=/usr/lib/libpython2.7.so \
+ -DQT_QMAKE_EXECUTABLE=qmake-qt4 \
+ -DCOMPIZ_DISABLE_SCHEMAS_INSTALL=On \
+ -DCOMPIZ_BUILD_WITH_RPATH=Off \
+ -DCOMPIZ_PACKAGING_ENABLED=On \
+ -DBUILD_GTK=On \
+ -DBUILD_METACITY=On \
+ -DBUILD_KDE4=Off \
+ -DUSE_GCONF=Off \
+ -DUSE_GSETTINGS=On \
+ -DCOMPIZ_BUILD_TESTING=Off \
+ -DCOMPIZ_WERROR=Off \
+ -DCOMPIZ_DEFAULT_PLUGINS="composite,opengl,decor,resize,place,move,ccp"
+
+ make
+}
+
+package() {
+ cd $_bzrname/build
+ make DESTDIR="${pkgdir}" install
+
+ # findcompiz_install needs COMPIZ_DESTDIR and install needs DESTDIR
+ # make findcompiz_install
+ CMAKE_DIR=$(cmake --system-information | grep '^CMAKE_ROOT' | awk -F\" '{print $2}')
+ install -dm755 "${pkgdir}${CMAKE_DIR}/Modules/"
+ install -m644 ../cmake/FindCompiz.cmake "${pkgdir}${CMAKE_DIR}/Modules/"
+
+ # Add documentation
+ install -dm755 "${pkgdir}/usr/share/doc/compiz/"
+ install ../{AUTHORS,NEWS,README} "${pkgdir}/usr/share/doc/compiz/"
+
+ # Add gsettings schema files
+ if ls generated/glib-2.0/schemas/ | grep -qm1 .gschema.xml; then
+ install -dm755 "${pkgdir}/usr/share/glib-2.0/schemas/"
+ install -m644 generated/glib-2.0/schemas/*.gschema.xml "${pkgdir}/usr/share/glib-2.0/schemas/"
+ fi
+
+ # Remove GConf schemas
+ rm -rv "${pkgdir}/usr/share/gconf/"
+}
+
diff --git a/compiz-bzr.install b/compiz-bzr.install
new file mode 100644
index 000000000000..08879b2fa042
--- /dev/null
+++ b/compiz-bzr.install
@@ -0,0 +1,29 @@
+post_install() {
+ echo " -> Updating icon cache..."
+ gtk-update-icon-cache -q -f -t /usr/share/icons/hicolor
+ echo " -> Updating XDG menu database..."
+ update-desktop-database -q
+
+ ls usr/share/glib-2.0/schemas 2>/dev/null | grep -qm1 org.compiz
+ if [ $? -eq 0 ]; then
+ echo " -> Recompiling the GSettings database... "
+ glib-compile-schemas usr/share/glib-2.0/schemas
+ fi
+}
+
+post_upgrade() {
+ post_install $1
+}
+
+post_remove() {
+ echo " -> Updating icon cache..."
+ gtk-update-icon-cache -q -f -t /usr/share/icons/hicolor
+ echo " -> Updating XDG menu database..."
+ update-desktop-database -q
+
+ if [ -d /usr/share/glib-2.0/schemas ]; then
+ echo " -> Recompiling the GSettings database... "
+ glib-compile-schemas usr/share/glib-2.0/schemas
+ fi
+}
+
diff --git a/focus-prevention-disable.patch b/focus-prevention-disable.patch
new file mode 100644
index 000000000000..df2fcef106db
--- /dev/null
+++ b/focus-prevention-disable.patch
@@ -0,0 +1,12 @@
+diff -Naur original/metadata/core.xml.in modified/metadata/core.xml.in
+--- original/metadata/core.xml.in 2013-07-23 20:58:03.000000000 +0100
++++ modified/metadata/core.xml.in 2014-06-11 09:06:53.839302487 +0100
+@@ -114,7 +114,7 @@
+ <_long>Level of focus stealing prevention</_long>
+ <min>0</min>
+ <max>4</max>
+- <default>1</default>
++ <default>0</default>
+ <desc>
+ <value>0</value>
+ <_name>Off</_name>
diff --git a/metacity-3_16.patch b/metacity-3_16.patch
new file mode 100644
index 000000000000..7efa9df9df4a
--- /dev/null
+++ b/metacity-3_16.patch
@@ -0,0 +1,5387 @@
+diff -Nur original/gtk/CMakeLists.txt modified/gtk/CMakeLists.txt
+--- original/gtk/CMakeLists.txt 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/CMakeLists.txt 2015-05-14 11:13:01.077589155 +0100
+@@ -28,6 +28,7 @@
+ pkg_check_modules (METACITY libmetacity-private>=3.12.0)
+ if (METACITY_FOUND)
+ compiz_pkg_check_modules (HAVE_METACITY_3_14_0 libmetacity-private>=3.14.0)
++ compiz_pkg_check_modules (HAVE_METACITY_3_16_0 libmetacity-private>=3.16.0)
+ else (METACITY_FOUND)
+ compiz_set (USE_METACITY 0)
+ endif (METACITY_FOUND)
+diff -Nur original/gtk/config.h.gtk.in modified/gtk/config.h.gtk.in
+--- original/gtk/config.h.gtk.in 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/config.h.gtk.in 2015-05-14 11:13:01.077589155 +0100
+@@ -4,4 +4,7 @@
+ /* Define to 1 if metacity version >= 3.14.0 */
+ #cmakedefine HAVE_METACITY_3_14_0 1
+
++/* Define to 1 if metacity version >= 3.16.0 */
++#cmakedefine HAVE_METACITY_3_16_0 1
++
+ #define GETTEXT_PACKAGE "${GETTEXT_PACKAGE}"
+diff -Nur original/gtk/window-decorator/cairo.c modified/gtk/window-decorator/cairo.c
+--- original/gtk/window-decorator/cairo.c 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/window-decorator/cairo.c 2015-05-14 11:12:47.794256180 +0100
+@@ -26,6 +26,8 @@
+ #include "gtk-window-decorator.h"
+ #include "gwd-cairo-window-decoration-util.h"
+
++#define STROKE_ALPHA 0.6f
++
+ void
+ rounded_rectangle (cairo_t *cr,
+ double x,
+diff -Nur original/gtk/window-decorator/CMakeLists.txt modified/gtk/window-decorator/CMakeLists.txt
+--- original/gtk/window-decorator/CMakeLists.txt 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/window-decorator/CMakeLists.txt 2015-05-14 11:13:01.080922489 +0100
+@@ -99,6 +99,7 @@
+ gdk.c
+ switcher.c
+ metacity.c
++ metacity-3-16.c
+ events.c
+ forcequit.c
+ tooltip.c
+@@ -138,6 +139,3 @@
+ endif (COMPIZ_BUILD_TESTING)
+
+ endif (USE_GTK)
+-
+-
+-
+diff -Nur original/gtk/window-decorator/decorator.c modified/gtk/window-decorator/decorator.c
+--- original/gtk/window-decorator/decorator.c 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/window-decorator/decorator.c 2015-05-14 11:12:47.804256179 +0100
+@@ -25,83 +25,12 @@
+
+ #include "gtk-window-decorator.h"
+
+-decor_frame_t *
+-create_normal_frame (const gchar *type)
+-{
+- decor_frame_t *frame = decor_frame_new (type);
+-
+- decor_context_t _window_context = {
+- { 0, 0, 0, 0 },
+- 6, 6, 4, 6,
+- 0, 0, 0, 0
+- };
+-
+- decor_context_t _max_window_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_extents_t _win_extents = { 6, 6, 6, 6 };
+- decor_extents_t _max_win_extents = { 6, 6, 4, 6 };
+-
+- frame->win_extents = _win_extents;
+- frame->max_win_extents = _max_win_extents;
+- frame->update_shadow = decor_frame_update_shadow;
+- frame->window_context_active = _window_context;
+- frame->window_context_inactive = _window_context;
+- frame->window_context_no_shadow = _window_context_no_shadow;
+- frame->max_window_context_active = _max_window_context;
+- frame->max_window_context_inactive = _max_window_context;
+- frame->max_window_context_no_shadow = _max_window_context_no_shadow;
+-
+- return frame;
+-}
+-
+ void
+ destroy_normal_frame (decor_frame_t *frame)
+ {
+ decor_frame_destroy (frame);
+ }
+
+-decor_frame_t *
+-create_bare_frame (const gchar *type)
+-{
+- decor_frame_t *frame = decor_frame_new (type);
+- decor_context_t _shadow_context = {
+- { 0, 0, 0, 0 },
+- 0, 0, 0, 0,
+- 0, 0, 0, 0,
+- };
+-
+- decor_extents_t _shadow_extents = { 0, 0, 0, 0 };
+-
+- frame->win_extents = _shadow_extents;
+- frame->max_win_extents = _shadow_extents;
+- frame->win_extents = _shadow_extents;
+- frame->window_context_active = _shadow_context;
+- frame->window_context_inactive = _shadow_context;
+- frame->window_context_no_shadow = _shadow_context;
+- frame->max_window_context_active = _shadow_context;
+- frame->max_window_context_inactive = _shadow_context;
+- frame->max_window_context_no_shadow = _shadow_context;
+- frame->update_shadow = bare_frame_update_shadow;
+-
+- return frame;
+-}
+-
+ void
+ destroy_bare_frame (decor_frame_t *frame)
+ {
+@@ -411,7 +340,7 @@
+ * the window name using pango (with 6px padding)
+ * Returns zero if window has no name.
+ */
+-gint
++static gint
+ max_window_name_width (WnckWindow *win)
+ {
+ decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+@@ -453,7 +382,7 @@
+ * wnck. Also checks to see if the name has a length (slight optimization)
+ * and re-creates the pango context to re-render the name
+ */
+-void
++static void
+ update_window_decoration_name (WnckWindow *win)
+ {
+ decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+@@ -823,7 +752,7 @@
+ *
+ * We do something similar for the maximimzed mode as well
+ */
+-void
++static void
+ bare_frame_update_shadow (Display *xdisplay,
+ Screen *screen,
+ decor_frame_t *frame,
+@@ -894,7 +823,7 @@
+ NULL);
+ }
+
+-void
++static void
+ decor_frame_update_shadow (Display *xdisplay,
+ Screen *screen,
+ decor_frame_t *frame,
+@@ -1507,3 +1436,74 @@
+ cairo_set_source_surface (d->cr, d->buffer_surface, 0, 0);
+ cairo_paint (d->cr);
+ }
++
++decor_frame_t *
++create_bare_frame (const gchar *type)
++{
++ decor_frame_t *frame = decor_frame_new (type);
++ decor_context_t _shadow_context = {
++ { 0, 0, 0, 0 },
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ };
++
++ decor_extents_t _shadow_extents = { 0, 0, 0, 0 };
++
++ frame->win_extents = _shadow_extents;
++ frame->max_win_extents = _shadow_extents;
++ frame->win_extents = _shadow_extents;
++ frame->window_context_active = _shadow_context;
++ frame->window_context_inactive = _shadow_context;
++ frame->window_context_no_shadow = _shadow_context;
++ frame->max_window_context_active = _shadow_context;
++ frame->max_window_context_inactive = _shadow_context;
++ frame->max_window_context_no_shadow = _shadow_context;
++ frame->update_shadow = bare_frame_update_shadow;
++
++ return frame;
++}
++
++decor_frame_t *
++create_normal_frame (const gchar *type)
++{
++ decor_frame_t *frame = decor_frame_new (type);
++
++ decor_context_t _window_context = {
++ { 0, 0, 0, 0 },
++ 6, 6, 4, 6,
++ 0, 0, 0, 0
++ };
++
++ decor_context_t _max_window_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_extents_t _win_extents = { 6, 6, 6, 6 };
++ decor_extents_t _max_win_extents = { 6, 6, 4, 6 };
++
++ frame->win_extents = _win_extents;
++ frame->max_win_extents = _max_win_extents;
++ frame->update_shadow = decor_frame_update_shadow;
++ frame->window_context_active = _window_context;
++ frame->window_context_inactive = _window_context;
++ frame->window_context_no_shadow = _window_context_no_shadow;
++ frame->max_window_context_active = _max_window_context;
++ frame->max_window_context_inactive = _max_window_context;
++ frame->max_window_context_no_shadow = _max_window_context_no_shadow;
++
++ return frame;
++}
+diff -Nur original/gtk/window-decorator/events.c modified/gtk/window-decorator/events.c
+--- original/gtk/window-decorator/events.c 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/window-decorator/events.c 2015-05-14 11:12:47.804256179 +0100
+@@ -26,7 +26,34 @@
+ #include "gtk-window-decorator.h"
+ #include "gwd-settings-interface.h"
+
+-void
++#define DOUBLE_CLICK_DISTANCE 8.0f
++
++#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
++
++static double
++square (double x)
++{
++ return x * x;
++}
++
++static double
++dist (double x1, double y1,
++ double x2, double y2)
++{
++ return sqrt (square (x1 - x2) + square (y1 - y2));
++}
++
++static void
+ move_resize_window (WnckWindow *win,
+ int direction,
+ decor_event *gtkwd_event)
+@@ -74,7 +101,7 @@
+ XSync (xdisplay, FALSE);
+ }
+
+-void
++static void
+ common_button_event (WnckWindow *win,
+ decor_event *gtkwd_event,
+ decor_event_type gtkwd_type,
+@@ -392,7 +419,7 @@
+ }
+ }
+
+-void
++static void
+ handle_title_button_event (WnckWindow *win,
+ int action,
+ decor_event *gtkwd_event)
+@@ -426,7 +453,7 @@
+ }
+ }
+
+-void
++static void
+ handle_mouse_wheel_title_event (WnckWindow *win,
+ unsigned int button)
+ {
+@@ -526,7 +553,7 @@
+ }
+ }
+
+-void
++static void
+ frame_common_event (WnckWindow *win,
+ int direction,
+ decor_event *gtkwd_event,
+@@ -684,7 +711,7 @@
+ }
+ }
+
+-event_callback
++static event_callback
+ find_event_callback_for_point (decor_t *d,
+ int x,
+ int y,
+@@ -739,7 +766,7 @@
+ return NULL;
+ }
+
+-event_callback
++static event_callback
+ find_leave_event_callback (decor_t *d)
+ {
+ int i, j;
+diff -Nur original/gtk/window-decorator/frames.c modified/gtk/window-decorator/frames.c
+--- original/gtk/window-decorator/frames.c 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/window-decorator/frames.c 2015-05-14 11:12:47.804256179 +0100
+@@ -31,6 +31,192 @@
+ GHashTable *frame_info_table;
+ GHashTable *frames_table;
+
++/* from clearlooks theme */
++static void
++rgb_to_hls (gdouble *r,
++ gdouble *g,
++ gdouble *b)
++{
++ gdouble min;
++ gdouble max;
++ gdouble red;
++ gdouble green;
++ gdouble blue;
++ gdouble h, l, s;
++ gdouble delta;
++
++ red = *r;
++ green = *g;
++ blue = *b;
++
++ if (red > green)
++ {
++ if (red > blue)
++ max = red;
++ else
++ max = blue;
++
++ if (green < blue)
++ min = green;
++ else
++ min = blue;
++ }
++ else
++ {
++ if (green > blue)
++ max = green;
++ else
++ max = blue;
++
++ if (red < blue)
++ min = red;
++ else
++ min = blue;
++ }
++
++ l = (max + min) / 2;
++ s = 0;
++ h = 0;
++
++ if (max != min)
++ {
++ if (l <= 0.5)
++ s = (max - min) / (max + min);
++ else
++ s = (max - min) / (2 - max - min);
++
++ delta = max -min;
++ if (red == max)
++ h = (green - blue) / delta;
++ else if (green == max)
++ h = 2 + (blue - red) / delta;
++ else if (blue == max)
++ h = 4 + (red - green) / delta;
++
++ h *= 60;
++ if (h < 0.0)
++ h += 360;
++ }
++
++ *r = h;
++ *g = l;
++ *b = s;
++}
++
++static void
++hls_to_rgb (gdouble *h,
++ gdouble *l,
++ gdouble *s)
++{
++ gdouble hue;
++ gdouble lightness;
++ gdouble saturation;
++ gdouble m1, m2;
++ gdouble r, g, b;
++
++ lightness = *l;
++ saturation = *s;
++
++ if (lightness <= 0.5)
++ m2 = lightness * (1 + saturation);
++ else
++ m2 = lightness + saturation - lightness * saturation;
++
++ m1 = 2 * lightness - m2;
++
++ if (saturation == 0)
++ {
++ *h = lightness;
++ *l = lightness;
++ *s = lightness;
++ }
++ else
++ {
++ hue = *h + 120;
++ while (hue > 360)
++ hue -= 360;
++ while (hue < 0)
++ hue += 360;
++
++ if (hue < 60)
++ r = m1 + (m2 - m1) * hue / 60;
++ else if (hue < 180)
++ r = m2;
++ else if (hue < 240)
++ r = m1 + (m2 - m1) * (240 - hue) / 60;
++ else
++ r = m1;
++
++ hue = *h;
++ while (hue > 360)
++ hue -= 360;
++ while (hue < 0)
++ hue += 360;
++
++ if (hue < 60)
++ g = m1 + (m2 - m1) * hue / 60;
++ else if (hue < 180)
++ g = m2;
++ else if (hue < 240)
++ g = m1 + (m2 - m1) * (240 - hue) / 60;
++ else
++ g = m1;
++
++ hue = *h - 120;
++ while (hue > 360)
++ hue -= 360;
++ while (hue < 0)
++ hue += 360;
++
++ if (hue < 60)
++ b = m1 + (m2 - m1) * hue / 60;
++ else if (hue < 180)
++ b = m2;
++ else if (hue < 240)
++ b = m1 + (m2 - m1) * (240 - hue) / 60;
++ else
++ b = m1;
++
++ *h = r;
++ *l = g;
++ *s = b;
++ }
++}
++
++static void
++shade (const decor_color_t *a,
++ decor_color_t *b,
++ float k)
++{
++ double red;
++ double green;
++ double blue;
++
++ red = a->r;
++ green = a->g;
++ blue = a->b;
++
++ rgb_to_hls (&red, &green, &blue);
++
++ green *= k;
++ if (green > 1.0)
++ green = 1.0;
++ else if (green < 0.0)
++ green = 0.0;
++
++ blue *= k;
++ if (blue > 1.0)
++ blue = 1.0;
++ else if (blue < 0.0)
++ blue = 0.0;
++
++ hls_to_rgb (&red, &green, &blue);
++
++ b->r = red;
++ b->g = green;
++ b->b = blue;
++}
++
+ static void
+ update_style (GtkWidget *widget)
+ {
+diff -Nur original/gtk/window-decorator/gtk-window-decorator.c modified/gtk/window-decorator/gtk-window-decorator.c
+--- original/gtk/window-decorator/gtk-window-decorator.c 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/window-decorator/gtk-window-decorator.c 2015-05-14 11:12:47.804256179 +0100
+@@ -36,29 +36,13 @@
+
+ gdouble decoration_alpha = 0.5;
+ #ifdef USE_METACITY
+-MetaButtonLayout meta_button_layout;
+ gboolean meta_button_layout_set = FALSE;
+ #endif
+
+ gboolean minimal = FALSE;
+
+-#define SWITCHER_SPACE 40
+-
+-const float STROKE_ALPHA = 0.6f;
+-
+ const unsigned short ICON_SPACE = 20;
+
+-const float DOUBLE_CLICK_DISTANCE = 8.0f;
+-
+-const float SHADOW_RADIUS = 8.0f;
+-const float SHADOW_OPACITY = 0.5f;
+-const unsigned short SHADOW_OFFSET_X = 1;
+-const unsigned short SHADOW_OFFSET_Y = 1;
+-
+-const float META_OPACITY = 0.75f;
+-
+-const float META_ACTIVE_OPACITY = 1.0f;
+-
+ guint cmdline_options = 0;
+
+ Atom frame_input_window_atom;
+diff -Nur original/gtk/window-decorator/gtk-window-decorator.h modified/gtk/window-decorator/gtk-window-decorator.h
+--- original/gtk/window-decorator/gtk-window-decorator.h 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/window-decorator/gtk-window-decorator.h 2015-05-14 11:12:47.807589513 +0100
+@@ -78,52 +78,11 @@
+
+ #include <gwd-fwd.h>
+
+-#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"
+-
+-extern const float STROKE_ALPHA;
+-
+ extern const unsigned short ICON_SPACE;
+
+-extern const float DOUBLE_CLICK_DISTANCE;
+-
+-#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
+-
+-extern const float SHADOW_RADIUS;
+-extern const float SHADOW_OPACITY;
+-extern const unsigned short SHADOW_OFFSET_X;
+-extern const unsigned short SHADOW_OFFSET_Y;
+-#define SHADOW_COLOR_RED 0x0000
+-#define SHADOW_COLOR_GREEN 0x0000
+-#define SHADOW_COLOR_BLUE 0x0000
+-
+-extern const float META_OPACITY;
+-#define META_SHADE_OPACITY TRUE;
+-extern const float META_ACTIVE_OPACITY;
+-#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)
+@@ -144,16 +103,13 @@
+
+ extern gboolean minimal;
+
+-#define SWITCHER_SPACE 40
+-
+ extern GWDSettingsNotified *notified;
+-extern GWDSettings *settings;
++extern GWDSettings *settings;
+ extern GWDSettingsWritable *writable;
+
+ extern gdouble decoration_alpha;
+ #ifdef USE_METACITY
+-extern MetaButtonLayout meta_button_layout;
+-extern gboolean meta_button_layout_set;
++extern gboolean meta_button_layout_set;
+ #endif
+
+ extern Atom frame_input_window_atom;
+@@ -406,22 +362,11 @@
+ extern XRenderPictFormat *xformat_rgba;
+ extern XRenderPictFormat *xformat_rgb;
+
+-/* gtk-window-decorator.c */
+-
+-double
+-dist (double x1, double y1,
+- double x2, double y2);
+-
+ /* frames.c */
+
+ void
+ initialize_decorations ();
+
+-void
+-update_frames_border_extents (gpointer key,
+- gpointer value,
+- gpointer user_data);
+-
+ decor_frame_t *
+ gwd_get_decor_frame (const gchar *);
+
+@@ -458,30 +403,6 @@
+ void
+ frame_update_titlebar_font (decor_frame_t *frame);
+
+-void
+-bare_frame_update_shadow (Display *xdisplay,
+- Screen *screen,
+- decor_frame_t *frame,
+- decor_shadow_t **shadow_normal,
+- decor_context_t *context_normal,
+- decor_shadow_t **shadow_max,
+- decor_context_t *context_max,
+- decor_shadow_info_t *info,
+- decor_shadow_options_t *opt_shadow,
+- decor_shadow_options_t *opt_no_shadow);
+-
+-void
+-decor_frame_update_shadow (Display *xdisplay,
+- Screen *screen,
+- decor_frame_t *frame,
+- decor_shadow_t **shadow_normal,
+- decor_context_t *context_normal,
+- decor_shadow_t **shadow_max,
+- decor_context_t *context_max,
+- decor_shadow_info_t *info,
+- decor_shadow_options_t *opt_shadow,
+- decor_shadow_options_t *opt_no_shadow);
+-
+ decor_frame_t *
+ create_normal_frame (const gchar *type);
+
+@@ -501,12 +422,6 @@
+ gboolean
+ request_update_window_decoration_size (WnckWindow *win);
+
+-void
+-update_window_decoration_name (WnckWindow *win);
+-
+-gint
+-max_window_name_width (WnckWindow *win);
+-
+ unsigned int
+ populate_frame_type (decor_t *d);
+
+@@ -538,9 +453,6 @@
+ update_titlebar_font ();
+
+ void
+-update_window_decoration_name (WnckWindow *win);
+-
+-void
+ update_window_decoration (WnckWindow *win);
+
+ void
+@@ -561,10 +473,6 @@
+ connect_screen (WnckScreen *screen);
+
+ void
+-window_opened (WnckScreen *screen,
+- WnckWindow *window);
+-
+-void
+ window_closed (WnckScreen *screen,
+ WnckWindow *window);
+
+@@ -580,10 +488,6 @@
+ restack_window (WnckWindow *win,
+ int stack_mode);
+
+-void
+-connect_window (WnckWindow *win);
+-
+-
+ /* blur.c */
+
+ void
+@@ -711,6 +615,7 @@
+ surface_new_from_pixbuf (GdkPixbuf *pixbuf, GtkWidget *parent);
+
+ /* metacity.c */
++
+ #ifdef USE_METACITY
+
+ MetaFrameType
+@@ -719,18 +624,6 @@
+ 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,
+- MetaFrameType frame_type,
+- GdkRectangle *clip);
+-
+-void
+-meta_calc_button_size (decor_t *d);
+-
+ gboolean
+ meta_calc_decoration_size (decor_t *d,
+ gint w,
+@@ -749,10 +642,6 @@
+ gint *w,
+ gint *h);
+
+-gboolean
+-meta_button_present (MetaButtonLayout *button_layout,
+- MetaButtonFunction function);
+-
+ void
+ meta_get_event_window_position (decor_t *d,
+ gint i,
+@@ -777,6 +666,7 @@
+ meta_get_shadow (decor_frame_t *, decor_shadow_options_t *opts, gboolean active);
+
+ #endif
++
+ /* switcher.c */
+
+ #define SWITCHER_ALPHA 0xa0a0
+@@ -799,35 +689,13 @@
+ void
+ destroy_switcher_frame ();
+
+-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,
+- char *tooltip);
+-
+-void
+ close_button_event (WnckWindow *win,
+ decor_event *gtkwd_event,
+ decor_event_type gtkwd_type);
+@@ -877,26 +745,11 @@
+ 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);
+@@ -938,17 +791,6 @@
+ 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,
+@@ -1004,18 +846,6 @@
+
+ /* 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,
+diff -Nur original/gtk/window-decorator/gwd-settings-storage-gsettings.c modified/gtk/window-decorator/gwd-settings-storage-gsettings.c
+--- original/gtk/window-decorator/gwd-settings-storage-gsettings.c 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/window-decorator/gwd-settings-storage-gsettings.c 2015-05-14 11:13:01.080922489 +0100
+@@ -17,6 +17,9 @@
+ *
+ * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
+ */
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
+ #include <glib-object.h>
+
+ #include <gio/gio.h>
+@@ -28,6 +31,7 @@
+ #include "gwd-settings-storage-gsettings.h"
+
+ const gchar * ORG_COMPIZ_GWD = "org.compiz.gwd";
++const gchar * ORG_GNOME_METACITY = "org.gnome.metacity";
+ const gchar * ORG_GNOME_MUTTER = "org.gnome.mutter";
+ const gchar * ORG_GNOME_DESKTOP_WM_PREFERENCES = "org.gnome.desktop.wm.preferences";
+
+@@ -39,6 +43,8 @@
+ const gchar * ORG_COMPIZ_GWD_KEY_METACITY_THEME_INACTIVE_SHADE_OPACITY = "metacity-theme-inactive-shade-opacity";
+ const gchar * ORG_COMPIZ_GWD_KEY_USE_METACITY_THEME = "use-metacity-theme";
+ const gchar * ORG_COMPIZ_GWD_KEY_MOUSE_WHEEL_ACTION = "mouse-wheel-action";
++const gchar * ORG_GNOME_METACITY_THEME = "theme";
++const gchar * ORG_GNOME_MUTTER_DRAGGABLE_BORDER_WIDTH = "draggable-border-width";
+ const gchar * ORG_GNOME_DESKTOP_WM_PREFERENCES_ACTION_DOUBLE_CLICK_TITLEBAR = "action-double-click-titlebar";
+ const gchar * ORG_GNOME_DESKTOP_WM_PREFERENCES_ACTION_MIDDLE_CLICK_TITLEBAR = "action-middle-click-titlebar";
+ const gchar * ORG_GNOME_DESKTOP_WM_PREFERENCES_ACTION_RIGHT_CLICK_TITLEBAR = "action-right-click-titlebar";
+@@ -46,7 +52,6 @@
+ const gchar * ORG_GNOME_DESKTOP_WM_PREFERENCES_TITLEBAR_USES_SYSTEM_FONT = "titlebar-uses-system-font";
+ const gchar * ORG_GNOME_DESKTOP_WM_PREFERENCES_TITLEBAR_FONT = "titlebar-font";
+ const gchar * ORG_GNOME_DESKTOP_WM_PREFERENCES_BUTTON_LAYOUT = "button-layout";
+-const gchar * ORG_GNOME_MUTTER_DRAGGABLE_BORDER_WIDTH = "draggable-border-width";
+
+ #define GWD_SETTINGS_STORAGE_GSETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GWD_TYPE_SETTINGS_STORAGE_GSETTINGS, GWDSettingsStorageGSettings));
+ #define GWD_SETTINGS_STORAGE_GSETTINGS_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), GWD_TYPE_SETTINGS_STORAGE_GSETTINGS, GWDSettingsStorageGSettingsClass));
+@@ -74,17 +79,17 @@
+
+ enum
+ {
+- GWD_SETTINGS_STORAGE_GSETTINGS_PROPERTY_DESKTOP_GSETTINGS = 1,
+- GWD_SETTINGS_STORAGE_GSETTINGS_PROPERTY_MUTTER_GSETTINGS = 2,
+- GWD_SETTINGS_STORAGE_GSETTINGS_PROPERTY_GWD_GSETTINGS = 3,
+- GWD_SETTINGS_STORAGE_GSETTINGS_PROPERTY_WRITABLE_SETTINGS = 4
++ GWD_SETTINGS_STORAGE_GSETTINGS_PROPERTY_DESKTOP_GSETTINGS = 1,
++ GWD_SETTINGS_STORAGE_GSETTINGS_PROPERTY_METACITY_GSETTINGS = 2,
++ GWD_SETTINGS_STORAGE_GSETTINGS_PROPERTY_MUTTER_GSETTINGS = 3,
++ GWD_SETTINGS_STORAGE_GSETTINGS_PROPERTY_GWD_GSETTINGS = 4,
++ GWD_SETTINGS_STORAGE_GSETTINGS_PROPERTY_WRITABLE_SETTINGS = 5
+ };
+
+-const guint GWD_SETTINGS_STORAGE_GSETTINGS_N_CONSTRUCTION_PARAMS = 4;
+-
+ typedef struct _GWDSettingsStorageGSettingsPrivate
+ {
+ GSettings *desktop;
++ GSettings *metacity;
+ GSettings *mutter;
+ GSettings *gwd;
+ GWDSettingsWritable *writable;
+@@ -135,20 +140,34 @@
+ static gboolean
+ gwd_settings_storage_gsettings_update_metacity_theme (GWDSettingsStorage *settings)
+ {
+- GWDSettingsStorageGSettings *storage = GWD_SETTINGS_STORAGE_GSETTINGS (settings);
+- GWDSettingsStorageGSettingsPrivate *priv = GET_PRIVATE (storage);
++ GWDSettingsStorageGSettings *storage;
++ GWDSettingsStorageGSettingsPrivate *priv;
++ gboolean use_metacity_theme;
++ gchar *theme;
++
++ storage = GWD_SETTINGS_STORAGE_GSETTINGS (settings);
++ priv = GET_PRIVATE (storage);
+
+ if (!priv->gwd)
+- return FALSE;
++ return FALSE;
++
++ use_metacity_theme = g_settings_get_boolean (priv->gwd, ORG_COMPIZ_GWD_KEY_USE_METACITY_THEME);
+
++#ifdef HAVE_METACITY_3_16_0
++ if (!priv->metacity)
++ return FALSE;
++
++ theme = g_settings_get_string (priv->metacity, ORG_GNOME_METACITY_THEME);
++#else
+ if (!priv->desktop)
+- return FALSE;
++ return FALSE;
++
++ theme = g_settings_get_string (priv->desktop, ORG_GNOME_DESKTOP_WM_PREFERENCES_THEME);
++#endif
+
+ return gwd_settings_writable_metacity_theme_changed (priv->writable,
+- g_settings_get_boolean (priv->gwd,
+- ORG_COMPIZ_GWD_KEY_USE_METACITY_THEME),
+- g_settings_get_string (priv->desktop,
+- ORG_GNOME_DESKTOP_WM_PREFERENCES_THEME));
++ use_metacity_theme,
++ theme);
+ }
+
+ static gboolean
+@@ -284,6 +303,12 @@
+
+ priv->desktop = g_value_dup_object (value);
+ break;
++ case GWD_SETTINGS_STORAGE_GSETTINGS_PROPERTY_METACITY_GSETTINGS:
++ if (priv->metacity)
++ g_object_unref (priv->metacity);
++
++ priv->metacity = g_value_dup_object (value);
++ break;
+ case GWD_SETTINGS_STORAGE_GSETTINGS_PROPERTY_MUTTER_GSETTINGS:
+ if (priv->mutter)
+ g_object_unref (priv->mutter);
+@@ -314,6 +339,9 @@
+ if (priv->desktop)
+ g_object_unref (priv->desktop);
+
++ if (priv->metacity)
++ g_object_unref (priv->metacity);
++
+ if (priv->mutter)
+ g_object_unref (priv->mutter);
+
+@@ -339,6 +367,11 @@
+ "GSettings Object for org.gnome.desktop.wm.preferences",
+ G_TYPE_SETTINGS,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY),
++ g_param_spec_object ("metacity-gsettings",
++ ORG_GNOME_METACITY,
++ "GSettings Object for org.gnome.metacity",
++ G_TYPE_SETTINGS,
++ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY),
+ g_param_spec_object ("mutter-gsettings",
+ ORG_GNOME_MUTTER,
+ "GSettings Object for org.gnome.mutter",
+@@ -372,14 +405,16 @@
+
+ GWDSettingsStorage *
+ gwd_settings_storage_gsettings_new (GSettings *desktop,
++ GSettings *metacity,
+ GSettings *mutter,
+ GSettings *gwd,
+ GWDSettingsWritable *writable)
+ {
+- static const guint gwd_settings_storage_gsettings_n_construction_params = 4;
++ static const guint gwd_settings_storage_gsettings_n_construction_params = 5;
+ GParameter param[gwd_settings_storage_gsettings_n_construction_params];
+
+ GValue desktop_value = G_VALUE_INIT;
++ GValue metacity_value = G_VALUE_INIT;
+ GValue mutter_value = G_VALUE_INIT;
+ GValue gwd_value = G_VALUE_INIT;
+ GValue writable_value = G_VALUE_INIT;
+@@ -389,29 +424,34 @@
+ g_return_val_if_fail (writable != NULL, NULL);
+
+ g_value_init (&desktop_value, G_TYPE_OBJECT);
++ g_value_init (&metacity_value, G_TYPE_OBJECT);
+ g_value_init (&mutter_value, G_TYPE_OBJECT);
+ g_value_init (&gwd_value, G_TYPE_OBJECT);
+ g_value_init (&writable_value, G_TYPE_POINTER);
+
+ g_value_take_object (&desktop_value, desktop);
++ g_value_take_object (&metacity_value, metacity);
+ g_value_take_object (&mutter_value, mutter);
+ g_value_take_object (&gwd_value, gwd);
+ g_value_set_pointer (&writable_value, writable);
+
+ param[0].name = "desktop-gsettings";
+ param[0].value = desktop_value;
+- param[1].name = "mutter-gsettings";
+- param[1].value = mutter_value;
+- param[2].name = "gwd-gsettings";
+- param[2].value = gwd_value;
+- param[3].name = "writable-settings";
+- param[3].value = writable_value;
++ param[1].name = "metacity-gsettings";
++ param[1].value = metacity_value;
++ param[2].name = "mutter-gsettings";
++ param[2].value = mutter_value;
++ param[3].name = "gwd-gsettings";
++ param[3].value = gwd_value;
++ param[4].name = "writable-settings";
++ param[4].value = writable_value;
+
+ storage = GWD_SETTINGS_STORAGE_INTERFACE (g_object_newv (GWD_TYPE_SETTINGS_STORAGE_GSETTINGS,
+ gwd_settings_storage_gsettings_n_construction_params,
+ param));
+
+ g_value_unset (&desktop_value);
++ g_value_unset (&metacity_value);
+ g_value_unset (&mutter_value);
+ g_value_unset (&gwd_value);
+ g_value_unset (&writable_value);
+@@ -472,6 +512,35 @@
+ }
+
+ static void
++org_gnome_metacity_settings_changed (GSettings *settings,
++ const gchar *key,
++ gpointer user_data)
++{
++ GWDSettingsStorage *storage;
++
++ storage = GWD_SETTINGS_STORAGE_INTERFACE (user_data);
++
++ if (strcmp (key, ORG_GNOME_METACITY_THEME) == 0)
++ gwd_settings_storage_update_metacity_theme (storage);
++}
++
++void
++gwd_connect_org_gnome_metacity_settings (GSettings *settings,
++ GWDSettingsStorage *storage)
++{
++ if (!settings)
++ return;
++
++ g_signal_connect (settings, "changed", (GCallback) org_gnome_metacity_settings_changed, storage);
++}
++
++GSettings *
++gwd_get_org_gnome_metacity_settings ()
++{
++ return get_settings_no_abort (ORG_GNOME_METACITY);
++}
++
++static void
+ org_gnome_mutter_settings_changed (GSettings *settings,
+ const gchar *key,
+ gpointer user_data)
+diff -Nur original/gtk/window-decorator/gwd-settings-storage-gsettings.h modified/gtk/window-decorator/gwd-settings-storage-gsettings.h
+--- original/gtk/window-decorator/gwd-settings-storage-gsettings.h 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/window-decorator/gwd-settings-storage-gsettings.h 2015-05-14 11:13:01.080922489 +0100
+@@ -30,6 +30,7 @@
+
+ GWDSettingsStorage *
+ gwd_settings_storage_gsettings_new (GSettings *orgGNOMEDesktopSettings,
++ GSettings *metacitySettings,
+ GSettings *mutterSettings,
+ GSettings *gwdSettings,
+ GWDSettingsWritable *writableSettings);
+@@ -42,6 +43,13 @@
+ gwd_get_org_compiz_gwd_settings ();
+
+ void
++gwd_connect_org_gnome_metacity_settings (GSettings *settings,
++ GWDSettingsStorage *storage);
++
++GSettings *
++gwd_get_org_gnome_metacity_settings ();
++
++void
+ gwd_connect_org_gnome_mutter_settings (GSettings *settings,
+ GWDSettingsStorage *storage);
+
+@@ -56,6 +64,7 @@
+ gwd_get_org_gnome_desktop_wm_preferences_settings ();
+
+ extern const gchar * ORG_COMPIZ_GWD;
++extern const gchar * ORG_GNOME_METACITY;
+ extern const gchar * ORG_GNOME_MUTTER;
+ extern const gchar * ORG_GNOME_DESKTOP_WM_PREFERENCES;
+
+@@ -67,6 +76,8 @@
+ extern const gchar * ORG_COMPIZ_GWD_KEY_METACITY_THEME_INACTIVE_SHADE_OPACITY;
+ extern const gchar * ORG_COMPIZ_GWD_KEY_USE_METACITY_THEME;
+ extern const gchar * ORG_COMPIZ_GWD_KEY_MOUSE_WHEEL_ACTION;
++extern const gchar * ORG_GNOME_METACITY_THEME;
++extern const gchar * ORG_GNOME_MUTTER_DRAGGABLE_BORDER_WIDTH;
+ extern const gchar * ORG_GNOME_DESKTOP_WM_PREFERENCES_ACTION_DOUBLE_CLICK_TITLEBAR;
+ extern const gchar * ORG_GNOME_DESKTOP_WM_PREFERENCES_ACTION_MIDDLE_CLICK_TITLEBAR;
+ extern const gchar * ORG_GNOME_DESKTOP_WM_PREFERENCES_ACTION_RIGHT_CLICK_TITLEBAR;
+@@ -74,7 +85,6 @@
+ extern const gchar * ORG_GNOME_DESKTOP_WM_PREFERENCES_TITLEBAR_USES_SYSTEM_FONT;
+ extern const gchar * ORG_GNOME_DESKTOP_WM_PREFERENCES_TITLEBAR_FONT;
+ extern const gchar * ORG_GNOME_DESKTOP_WM_PREFERENCES_BUTTON_LAYOUT;
+-extern const gchar * ORG_GNOME_MUTTER_DRAGGABLE_BORDER_WIDTH;
+
+ G_END_DECLS
+
+diff -Nur original/gtk/window-decorator/metacity-3-16.c modified/gtk/window-decorator/metacity-3-16.c
+--- original/gtk/window-decorator/metacity-3-16.c 1970-01-01 01:00:00.000000000 +0100
++++ modified/gtk/window-decorator/metacity-3-16.c 2015-05-14 11:13:01.100922489 +0100
+@@ -0,0 +1,1555 @@
++/*
++ * 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@novell.com>
++ *
++ * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com>
++ * Frames Management: Copright © 2011 Canonical Ltd.
++ * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
++ */
++
++#include "gtk-window-decorator.h"
++
++#ifdef USE_METACITY
++#ifdef HAVE_METACITY_3_16_0
++
++MetaButtonLayout meta_button_layout;
++
++static gboolean
++meta_button_present (MetaButtonLayout *button_layout,
++ MetaButtonFunction function)
++{
++ int i;
++
++ for (i = 0; i < MAX_BUTTONS_PER_CORNER; ++i)
++ if (button_layout->left_buttons[i] == function)
++ return TRUE;
++
++ for (i = 0; i < MAX_BUTTONS_PER_CORNER; ++i)
++ if (button_layout->right_buttons[i] == function)
++ return TRUE;
++
++ return FALSE;
++}
++
++static void
++decor_update_meta_window_property (decor_t *d,
++ MetaTheme *theme,
++ MetaFrameFlags flags,
++ MetaFrameType type,
++ Region top,
++ Region bottom,
++ Region left,
++ Region right)
++{
++ long *data;
++ GdkDisplay *display;
++ Display *xdisplay;
++ gint nQuad;
++ decor_extents_t win_extents;
++ decor_extents_t frame_win_extents;
++ decor_extents_t max_win_extents;
++ decor_extents_t frame_max_win_extents;
++ decor_quad_t quads[N_QUADS_MAX];
++ unsigned int nOffset;
++ unsigned int frame_type;
++ unsigned int frame_state;
++ unsigned int frame_actions;
++ gint w;
++ gint lh;
++ gint rh;
++ gint top_stretch_offset;
++ gint bottom_stretch_offset;
++ gint left_stretch_offset;
++ gint right_stretch_offset;
++
++ display = gdk_display_get_default ();
++ xdisplay = gdk_x11_display_get_xdisplay (display);
++
++ nOffset = 1;
++
++ frame_type = populate_frame_type (d);
++ frame_state = populate_frame_state (d);
++ frame_actions = populate_frame_actions (d);
++
++ win_extents = frame_win_extents = d->frame->win_extents;
++ max_win_extents = frame_max_win_extents = d->frame->max_win_extents;
++
++ /* Add the invisible grab area padding, but only for
++ * pixmap type decorations */
++ if (!d->frame_window)
++ {
++ GdkScreen *screen;
++ MetaStyleInfo *style_info;
++ MetaFrameBorders borders;
++
++ screen = gtk_widget_get_screen (d->frame->style_window_rgba);
++ style_info = meta_theme_create_style_info (screen, NULL);
++
++ meta_theme_get_frame_borders (theme, style_info, type,
++ d->frame->text_height,
++ flags, &borders);
++
++ if (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE)
++ {
++ frame_win_extents.left += borders.invisible.left;
++ frame_win_extents.right += borders.invisible.right;
++ frame_max_win_extents.left += borders.invisible.left;
++ frame_max_win_extents.right += borders.invisible.right;
++ }
++
++ if (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE)
++ {
++ frame_win_extents.bottom += borders.invisible.bottom;
++ frame_win_extents.top += borders.invisible.top;
++ frame_max_win_extents.bottom += borders.invisible.bottom;
++ frame_max_win_extents.top += borders.invisible.top;
++ }
++
++ meta_style_info_unref (style_info);
++ }
++
++ w = d->border_layout.top.x2 - d->border_layout.top.x1 -
++ d->context->left_space - d->context->right_space;
++
++ if (d->border_layout.rotation)
++ lh = d->border_layout.left.x2 - d->border_layout.left.x1;
++ else
++ lh = d->border_layout.left.y2 - d->border_layout.left.y1;
++
++ if (d->border_layout.rotation)
++ rh = d->border_layout.right.x2 - d->border_layout.right.x1;
++ else
++ rh = d->border_layout.right.y2 - d->border_layout.right.y1;
++
++ left_stretch_offset = lh / 2;
++ right_stretch_offset = rh / 2;
++ top_stretch_offset = w - d->button_width - 1;
++ bottom_stretch_offset = (d->border_layout.bottom.x2 - d->border_layout.bottom.x1 -
++ d->context->left_space - d->context->right_space) / 2;
++
++ nQuad = decor_set_lXrXtXbX_window_quads (quads, d->context, &d->border_layout,
++ left_stretch_offset, right_stretch_offset,
++ top_stretch_offset, bottom_stretch_offset);
++
++ win_extents.top += d->frame->titlebar_height;
++ frame_win_extents.top += d->frame->titlebar_height;
++ max_win_extents.top += d->frame->max_titlebar_height;
++ frame_max_win_extents.top += d->frame->max_titlebar_height;
++
++ if (d->frame_window)
++ {
++ data = decor_alloc_property (nOffset, WINDOW_DECORATION_TYPE_WINDOW);
++ decor_gen_window_property (data, nOffset - 1, &win_extents, &max_win_extents,
++ 20, 20, frame_type, frame_state, frame_actions);
++ }
++ else
++ {
++ data = decor_alloc_property (nOffset, WINDOW_DECORATION_TYPE_PIXMAP);
++ decor_quads_to_property (data, nOffset - 1, cairo_xlib_surface_get_drawable (d->surface),
++ &frame_win_extents, &win_extents,
++ &frame_max_win_extents, &max_win_extents,
++ ICON_SPACE + d->button_width,
++ 0, quads, nQuad, frame_type, frame_state, frame_actions);
++ }
++
++ gdk_error_trap_push ();
++
++ XChangeProperty (xdisplay, d->prop_xid, win_decor_atom, XA_INTEGER,
++ 32, PropModeReplace, (guchar *) data,
++ PROP_HEADER_SIZE + BASE_PROP_SIZE + QUAD_PROP_SIZE * N_QUADS_MAX);
++ gdk_display_sync (display);
++
++ gdk_error_trap_pop_ignored ();
++
++ free (data);
++
++ decor_update_blur_property (d, w, lh,
++ top, top_stretch_offset,
++ bottom, bottom_stretch_offset,
++ left, left_stretch_offset,
++ right, right_stretch_offset);
++}
++
++static void
++meta_get_corner_radius (const MetaFrameGeometry *fgeom,
++ int *top_left_radius,
++ int *top_right_radius,
++ int *bottom_left_radius,
++ int *bottom_right_radius)
++{
++ *top_left_radius = fgeom->top_left_corner_rounded_radius;
++ *top_right_radius = fgeom->top_right_corner_rounded_radius;
++ *bottom_left_radius = fgeom->bottom_left_corner_rounded_radius;
++ *bottom_right_radius = fgeom->bottom_right_corner_rounded_radius;
++}
++
++static int
++radius_to_width (int radius,
++ int i)
++{
++ float r1 = sqrt (radius) + radius;
++ float r2 = r1 * r1 - (r1 - (i + 0.5)) * (r1 - (i + 0.5));
++
++ return floor (0.5f + r1 - sqrt (r2));
++}
++
++static Region
++meta_get_top_border_region (const MetaFrameGeometry *fgeom,
++ int width)
++{
++ Region corners_xregion;
++ Region border_xregion;
++ XRectangle xrect;
++ int top_left_radius;
++ int top_right_radius;
++ int bottom_left_radius;
++ int bottom_right_radius;
++ int w;
++ int i;
++ int height;
++
++ corners_xregion = XCreateRegion ();
++
++ meta_get_corner_radius (fgeom, &top_left_radius, &top_right_radius,
++ &bottom_left_radius, &bottom_right_radius);
++
++ width = width - fgeom->borders.invisible.left - fgeom->borders.invisible.right;
++ height = fgeom->borders.visible.top;
++
++ if (top_left_radius)
++ {
++ for (i = 0; i < top_left_radius; ++i)
++ {
++ w = radius_to_width (top_left_radius, i);
++
++ xrect.x = 0;
++ xrect.y = i;
++ xrect.width = w;
++ xrect.height = 1;
++
++ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
++ }
++ }
++
++ if (top_right_radius)
++ {
++ for (i = 0; i < top_right_radius; ++i)
++ {
++ w = radius_to_width (top_right_radius, i);
++
++ xrect.x = width - w;
++ xrect.y = i;
++ xrect.width = w;
++ xrect.height = 1;
++
++ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
++ }
++ }
++
++ border_xregion = XCreateRegion ();
++
++ xrect.x = 0;
++ xrect.y = 0;
++ xrect.width = width;
++ xrect.height = height;
++
++ XUnionRectWithRegion (&xrect, border_xregion, border_xregion);
++
++ XSubtractRegion (border_xregion, corners_xregion, border_xregion);
++
++ XDestroyRegion (corners_xregion);
++
++ return border_xregion;
++}
++
++static Region
++meta_get_bottom_border_region (const MetaFrameGeometry *fgeom,
++ int width)
++{
++ Region corners_xregion;
++ Region border_xregion;
++ XRectangle xrect;
++ int top_left_radius;
++ int top_right_radius;
++ int bottom_left_radius;
++ int bottom_right_radius;
++ int w;
++ int i;
++ int height;
++
++ corners_xregion = XCreateRegion ();
++
++ meta_get_corner_radius (fgeom, &top_left_radius, &top_right_radius,
++ &bottom_left_radius, &bottom_right_radius);
++
++ width = width - fgeom->borders.invisible.left - fgeom->borders.invisible.right;
++ height = fgeom->borders.visible.bottom;
++
++ if (bottom_left_radius)
++ {
++ for (i = 0; i < bottom_left_radius; ++i)
++ {
++ w = radius_to_width (bottom_left_radius, i);
++
++ xrect.x = 0;
++ xrect.y = height - i - 1;
++ xrect.width = w;
++ xrect.height = 1;
++
++ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
++ }
++ }
++
++ if (bottom_right_radius)
++ {
++ for (i = 0; i < bottom_right_radius; ++i)
++ {
++ w = radius_to_width (bottom_right_radius, i);
++
++ xrect.x = width - w;
++ xrect.y = height - i - 1;
++ xrect.width = w;
++ xrect.height = 1;
++
++ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
++ }
++ }
++
++ border_xregion = XCreateRegion ();
++
++ xrect.x = 0;
++ xrect.y = 0;
++ xrect.width = width;
++ xrect.height = height;
++
++ XUnionRectWithRegion (&xrect, border_xregion, border_xregion);
++
++ XSubtractRegion (border_xregion, corners_xregion, border_xregion);
++
++ XDestroyRegion (corners_xregion);
++
++ return border_xregion;
++}
++
++static Region
++meta_get_left_border_region (const MetaFrameGeometry *fgeom,
++ int height)
++{
++ Region border_xregion;
++ XRectangle xrect;
++
++ border_xregion = XCreateRegion ();
++
++ xrect.x = 0;
++ xrect.y = 0;
++ xrect.width = fgeom->borders.visible.left;
++ xrect.height = height - fgeom->borders.total.top - fgeom->borders.total.bottom;
++
++ XUnionRectWithRegion (&xrect, border_xregion, border_xregion);
++
++ return border_xregion;
++}
++
++static Region
++meta_get_right_border_region (const MetaFrameGeometry *fgeom,
++ int height)
++{
++ Region border_xregion;
++ XRectangle xrect;
++
++ border_xregion = XCreateRegion ();
++
++ xrect.x = 0;
++ xrect.y = 0;
++ xrect.width = fgeom->borders.visible.right;
++ xrect.height = height - fgeom->borders.total.top - fgeom->borders.total.bottom;
++
++ XUnionRectWithRegion (&xrect, border_xregion, border_xregion);
++
++ return border_xregion;
++}
++
++static MetaButtonState
++meta_button_state (int state)
++{
++ if (state & IN_EVENT_WINDOW)
++ {
++ if (state & PRESSED_EVENT_WINDOW)
++ return META_BUTTON_STATE_PRESSED;
++
++ return META_BUTTON_STATE_PRELIGHT;
++ }
++
++ return META_BUTTON_STATE_NORMAL;
++}
++
++static MetaButtonType
++meta_function_to_type (MetaButtonFunction function)
++{
++ switch (function)
++ {
++ case META_BUTTON_FUNCTION_MENU:
++ return META_BUTTON_TYPE_MENU;
++ case META_BUTTON_FUNCTION_MINIMIZE:
++ return META_BUTTON_TYPE_MINIMIZE;
++ case META_BUTTON_FUNCTION_MAXIMIZE:
++ return META_BUTTON_TYPE_MAXIMIZE;
++ case META_BUTTON_FUNCTION_CLOSE:
++ return META_BUTTON_TYPE_CLOSE;
++ case META_BUTTON_FUNCTION_SHADE:
++ return META_BUTTON_TYPE_SHADE;
++ case META_BUTTON_FUNCTION_ABOVE:
++ return META_BUTTON_TYPE_ABOVE;
++ case META_BUTTON_FUNCTION_STICK:
++ return META_BUTTON_TYPE_STICK;
++ case META_BUTTON_FUNCTION_UNSHADE:
++ return META_BUTTON_TYPE_UNSHADE;
++ case META_BUTTON_FUNCTION_UNABOVE:
++ return META_BUTTON_TYPE_UNABOVE;
++ case META_BUTTON_FUNCTION_UNSTICK:
++ return META_BUTTON_TYPE_UNSTICK;
++ default:
++ break;
++ }
++
++ return META_BUTTON_TYPE_LAST;
++}
++
++static MetaButtonState
++meta_button_state_for_button_type (decor_t *d,
++ MetaButtonType type)
++{
++ switch (type)
++ {
++ case META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND:
++ type = meta_function_to_type (meta_button_layout.left_buttons[0]);
++ break;
++ case META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND:
++ type = meta_function_to_type (meta_button_layout.left_buttons[1]);
++ break;
++ case META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND:
++ type = meta_function_to_type (meta_button_layout.left_buttons[2]);
++ break;
++ case META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND:
++ type = meta_function_to_type (meta_button_layout.right_buttons[0]);
++ break;
++ case META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND:
++ type = meta_function_to_type (meta_button_layout.right_buttons[1]);
++ break;
++ case META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND:
++ type = meta_function_to_type (meta_button_layout.right_buttons[2]);
++ default:
++ break;
++ }
++
++ switch (type)
++ {
++ case META_BUTTON_TYPE_CLOSE:
++ return meta_button_state (d->button_states[BUTTON_CLOSE]);
++ case META_BUTTON_TYPE_MAXIMIZE:
++ return meta_button_state (d->button_states[BUTTON_MAX]);
++ case META_BUTTON_TYPE_MINIMIZE:
++ return meta_button_state (d->button_states[BUTTON_MIN]);
++ case META_BUTTON_TYPE_MENU:
++ return meta_button_state (d->button_states[BUTTON_MENU]);
++ case META_BUTTON_TYPE_SHADE:
++ return meta_button_state (d->button_states[BUTTON_SHADE]);
++ case META_BUTTON_TYPE_ABOVE:
++ return meta_button_state (d->button_states[BUTTON_ABOVE]);
++ case META_BUTTON_TYPE_STICK:
++ return meta_button_state (d->button_states[BUTTON_STICK]);
++ case META_BUTTON_TYPE_UNSHADE:
++ return meta_button_state (d->button_states[BUTTON_UNSHADE]);
++ case META_BUTTON_TYPE_UNABOVE:
++ return meta_button_state (d->button_states[BUTTON_UNABOVE]);
++ case META_BUTTON_TYPE_UNSTICK:
++ return meta_button_state (d->button_states[BUTTON_UNSTICK]);
++ default:
++ break;
++ }
++
++ return META_BUTTON_STATE_NORMAL;
++}
++
++static void
++meta_get_decoration_geometry (decor_t *d,
++ MetaTheme *theme,
++ MetaFrameFlags *flags,
++ MetaFrameGeometry *fgeom,
++ MetaButtonLayout *button_layout,
++ MetaFrameType frame_type)
++{
++ GdkScreen *screen;
++ MetaStyleInfo *style_info;
++ gint client_width;
++ gint client_height;
++
++ if (!(frame_type < META_FRAME_TYPE_LAST))
++ frame_type = META_FRAME_TYPE_NORMAL;
++
++ if (meta_button_layout_set)
++ {
++ *button_layout = meta_button_layout;
++ }
++ else
++ {
++ gint i;
++
++ button_layout->left_buttons[0] = META_BUTTON_FUNCTION_MENU;
++
++ for (i = 1; i < MAX_BUTTONS_PER_CORNER; ++i)
++ button_layout->left_buttons[i] = META_BUTTON_FUNCTION_LAST;
++
++ button_layout->right_buttons[0] = META_BUTTON_FUNCTION_MINIMIZE;
++ button_layout->right_buttons[1] = META_BUTTON_FUNCTION_MAXIMIZE;
++ button_layout->right_buttons[2] = META_BUTTON_FUNCTION_CLOSE;
++
++ for (i = 3; i < MAX_BUTTONS_PER_CORNER; ++i)
++ button_layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST;
++ }
++
++ *flags = 0;
++
++ if (d->actions & WNCK_WINDOW_ACTION_CLOSE)
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_DELETE;
++
++ if (d->actions & WNCK_WINDOW_ACTION_MINIMIZE)
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MINIMIZE;
++
++ if (d->actions & WNCK_WINDOW_ACTION_MAXIMIZE)
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MAXIMIZE;
++
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MENU;
++
++ if (d->actions & WNCK_WINDOW_ACTION_RESIZE)
++ {
++ if (!(d->state & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY))
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_VERTICAL_RESIZE;
++ if (!(d->state & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY))
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_HORIZONTAL_RESIZE;
++ }
++
++ if (d->actions & WNCK_WINDOW_ACTION_MOVE)
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MOVE;
++
++ if (d->actions & WNCK_WINDOW_ACTION_MAXIMIZE)
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MAXIMIZE;
++
++ if (d->actions & WNCK_WINDOW_ACTION_SHADE)
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_SHADE;
++
++ if (d->active)
++ *flags |= (MetaFrameFlags ) META_FRAME_HAS_FOCUS;
++
++ if ((d->state & META_MAXIMIZED) == META_MAXIMIZED)
++ *flags |= (MetaFrameFlags ) META_FRAME_MAXIMIZED;
++
++ if (d->state & WNCK_WINDOW_STATE_STICKY)
++ *flags |= (MetaFrameFlags ) META_FRAME_STUCK;
++
++ if (d->state & WNCK_WINDOW_STATE_FULLSCREEN)
++ *flags |= (MetaFrameFlags ) META_FRAME_FULLSCREEN;
++
++ if (d->state & WNCK_WINDOW_STATE_SHADED)
++ *flags |= (MetaFrameFlags ) META_FRAME_SHADED;
++
++ if (d->state & WNCK_WINDOW_STATE_ABOVE)
++ *flags |= (MetaFrameFlags ) META_FRAME_ABOVE;
++
++ client_width = d->border_layout.top.x2 - d->border_layout.top.x1;
++ client_width -= d->context->right_space + d->context->left_space;
++
++ if (d->border_layout.rotation)
++ client_height = d->border_layout.left.x2 - d->border_layout.left.x1;
++ else
++ client_height = d->border_layout.left.y2 - d->border_layout.left.y1;
++
++ screen = gtk_widget_get_screen (d->frame->style_window_rgba);
++ style_info = meta_theme_create_style_info (screen, NULL);
++
++ meta_theme_calc_geometry (theme, style_info, frame_type, d->frame->text_height,
++ *flags, client_width, client_height,
++ button_layout, fgeom);
++
++ meta_style_info_unref (style_info);
++}
++
++void
++meta_draw_window_decoration (decor_t *d)
++{
++ GdkDisplay *display;
++ GdkScreen *screen;
++ Display *xdisplay;
++ cairo_surface_t *surface;
++ Picture src;
++ MetaButtonState button_states [META_BUTTON_TYPE_LAST];
++ MetaButtonLayout button_layout;
++ MetaFrameGeometry fgeom;
++ MetaFrameFlags flags;
++ MetaFrameType frame_type;
++ MetaTheme *theme;
++ MetaStyleInfo *style_info;
++ GtkStyleContext *context;
++ cairo_t *cr;
++ gint i;
++ Region top_region;
++ Region bottom_region;
++ Region left_region;
++ Region right_region;
++ gdouble meta_active_opacity;
++ gdouble meta_inactive_opacity;
++ gboolean meta_active_shade_opacity;
++ gboolean meta_inactive_shade_opacity;
++ double alpha;
++ gboolean shade_alpha;
++ MetaFrameStyle *frame_style;
++ GtkWidget *style_window;
++ GdkRGBA bg_rgba;
++
++ if (!d->surface || !d->picture)
++ return;
++
++ display = gdk_display_get_default ();
++ xdisplay = gdk_x11_display_get_xdisplay (display);
++
++ top_region = NULL;
++ bottom_region = NULL;
++ left_region = NULL;
++ right_region = NULL;
++
++ g_object_get (settings, "metacity-active-opacity", &meta_active_opacity, NULL);
++ g_object_get (settings, "metacity-inactive-opacity", &meta_inactive_opacity, NULL);
++ g_object_get (settings, "metacity-active-shade-opacity", &meta_active_shade_opacity, NULL);
++ g_object_get (settings, "metacity-inactive-shade-opacity", &meta_inactive_shade_opacity, NULL);
++
++ alpha = (d->active) ? meta_active_opacity : meta_inactive_opacity;
++ shade_alpha = (d->active) ? meta_active_shade_opacity : meta_inactive_shade_opacity;
++
++ if (decoration_alpha == 1.0)
++ alpha = 1.0;
++
++ if (cairo_xlib_surface_get_depth (d->surface) == 32)
++ style_window = d->frame->style_window_rgba;
++ else
++ style_window = d->frame->style_window_rgb;
++
++ context = gtk_widget_get_style_context (style_window);
++
++ cr = cairo_create (d->buffer_surface ? d->buffer_surface : d->surface);
++
++ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
++
++ theme = meta_theme_get_current ();
++
++ frame_type = meta_frame_type_from_string (d->frame->type);
++
++ if (frame_type == META_FRAME_TYPE_LAST)
++ frame_type = META_FRAME_TYPE_NORMAL;
++
++ meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
++ frame_type);
++
++ if ((d->prop_xid || !d->buffer_surface) && !d->frame_window)
++ draw_shadow_background (d, cr, d->shadow, d->context);
++
++ for (i = 0; i < META_BUTTON_TYPE_LAST; ++i)
++ button_states[i] = meta_button_state_for_button_type (d, i);
++
++ frame_style = meta_theme_get_frame_style (theme, frame_type, flags);
++
++ gtk_style_context_get_background_color (context, GTK_STATE_FLAG_NORMAL, &bg_rgba);
++ bg_rgba.alpha = 1.0;
++
++ if (frame_style->window_background_color)
++ {
++ meta_color_spec_render (frame_style->window_background_color,
++ context, &bg_rgba);
++
++ bg_rgba.alpha = frame_style->window_background_alpha / 255.0;
++ }
++
++ /* Draw something that will be almost invisible to user. This is hacky way
++ * to fix invisible decorations. */
++ cairo_set_source_rgba (cr, 0, 0, 0, 0.01);
++ cairo_rectangle (cr, 0, 0, 1, 1);
++ cairo_fill (cr);
++ /* ------------ a/*/
++
++ cairo_destroy (cr);
++
++ if (d->frame_window)
++ surface = create_surface (fgeom.width, fgeom.height, d->frame->style_window_rgb);
++ else
++ surface = create_surface (fgeom.width, fgeom.height, d->frame->style_window_rgba);
++
++ cr = cairo_create (surface);
++ gdk_cairo_set_source_rgba (cr, &bg_rgba);
++ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
++
++ src = XRenderCreatePicture (xdisplay, cairo_xlib_surface_get_drawable (surface),
++ get_format_for_surface (d, surface), 0, NULL);
++
++ screen = gtk_widget_get_screen (d->frame->style_window_rgba);
++ style_info = meta_theme_create_style_info (screen, NULL);
++
++ cairo_paint (cr);
++ meta_theme_draw_frame (theme, style_info, cr, frame_type, flags,
++ fgeom.width - fgeom.borders.total.left - fgeom.borders.total.right,
++ fgeom.height - fgeom.borders.total.top - fgeom.borders.total.bottom,
++ d->layout, d->frame->text_height, &button_layout,
++ button_states, d->icon_pixbuf, NULL);
++
++ meta_style_info_unref (style_info);
++
++ if (fgeom.borders.visible.top)
++ {
++ top_region = meta_get_top_border_region (&fgeom, fgeom.width);
++
++ decor_blend_border_picture (xdisplay, d->context, src,
++ fgeom.borders.invisible.left,
++ fgeom.borders.invisible.top,
++ d->picture, &d->border_layout,
++ BORDER_TOP, top_region,
++ alpha * 0xffff, shade_alpha, 0);
++ }
++
++ if (fgeom.borders.visible.bottom)
++ {
++ bottom_region = meta_get_bottom_border_region (&fgeom, fgeom.width);
++
++ decor_blend_border_picture (xdisplay, d->context, src,
++ fgeom.borders.invisible.left,
++ fgeom.height - fgeom.borders.total.bottom,
++ d->picture, &d->border_layout,
++ BORDER_BOTTOM, bottom_region,
++ alpha * 0xffff, shade_alpha, 0);
++ }
++
++ if (fgeom.borders.visible.left)
++ {
++ left_region = meta_get_left_border_region (&fgeom, fgeom.height);
++
++ decor_blend_border_picture (xdisplay, d->context, src,
++ fgeom.borders.invisible.left,
++ fgeom.borders.total.top,
++ d->picture, &d->border_layout,
++ BORDER_LEFT, left_region,
++ alpha * 0xffff, shade_alpha, 0);
++ }
++
++ if (fgeom.borders.visible.right)
++ {
++ right_region = meta_get_right_border_region (&fgeom, fgeom.height);
++
++ decor_blend_border_picture (xdisplay, d->context, src,
++ fgeom.width - fgeom.borders.total.right,
++ fgeom.borders.total.top,
++ d->picture, &d->border_layout,
++ BORDER_RIGHT, right_region,
++ alpha * 0xffff, shade_alpha, 0);
++ }
++
++ cairo_destroy (cr);
++ cairo_surface_destroy (surface);
++ XRenderFreePicture (xdisplay, src);
++
++ copy_to_front_buffer (d);
++
++ if (d->frame_window)
++ {
++ GdkWindow *gdk_frame_window;
++ GdkPixbuf *pixbuf;
++
++ gdk_frame_window = gtk_widget_get_window (d->decor_window);
++
++ pixbuf = gdk_pixbuf_get_from_surface (d->surface, 0, 0, d->width, d->height);
++ gtk_image_set_from_pixbuf (GTK_IMAGE (d->decor_image), pixbuf);
++ g_object_unref (pixbuf);
++
++ gdk_window_move_resize (gdk_frame_window,
++ d->context->left_corner_space - 1,
++ d->context->top_corner_space - 1,
++ d->width,
++ d->height);
++
++ gdk_window_lower (gdk_frame_window);
++ }
++
++ if (d->prop_xid)
++ {
++ /* translate from frame to client window space */
++ if (top_region)
++ XOffsetRegion (top_region, -fgeom.borders.total.left, -fgeom.borders.total.top);
++ if (bottom_region)
++ XOffsetRegion (bottom_region, -fgeom.borders.total.left, 0);
++ if (left_region)
++ XOffsetRegion (left_region, -fgeom.borders.total.left, 0);
++
++ decor_update_meta_window_property (d, theme, flags, frame_type,
++ top_region, bottom_region,
++ left_region, right_region);
++
++ d->prop_xid = 0;
++ }
++
++ if (top_region)
++ XDestroyRegion (top_region);
++ if (bottom_region)
++ XDestroyRegion (bottom_region);
++ if (left_region)
++ XDestroyRegion (left_region);
++ if (right_region)
++ XDestroyRegion (right_region);
++}
++
++static void
++meta_calc_button_size (decor_t *d)
++{
++ MetaTheme *theme;
++ MetaFrameType frame_type;
++ MetaFrameFlags flags;
++ MetaFrameGeometry fgeom;
++ MetaButtonLayout button_layout;
++ gint i, min_x, x, y, w, h, width;
++
++ if (!d->context)
++ {
++ d->button_width = 0;
++ return;
++ }
++
++ theme = meta_theme_get_current ();
++
++ frame_type = meta_frame_type_from_string (d->frame->type);
++ if (!(frame_type < META_FRAME_TYPE_LAST))
++ frame_type = META_FRAME_TYPE_NORMAL;
++
++ meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
++ frame_type);
++
++ width = d->border_layout.top.x2 - d->border_layout.top.x1 -
++ d->context->left_space - d->context->right_space +
++ fgeom.borders.total.left + fgeom.borders.total.right;
++
++ min_x = width;
++
++ for (i = 0; i < 3; ++i)
++ {
++ static guint button_actions[3] = {
++ WNCK_WINDOW_ACTION_CLOSE,
++ WNCK_WINDOW_ACTION_MAXIMIZE,
++ WNCK_WINDOW_ACTION_MINIMIZE
++ };
++
++ if (d->actions & button_actions[i])
++ {
++ if (meta_get_button_position (d, i, width, 256, &x, &y, &w, &h))
++ {
++ if (x > width / 2 && x < min_x)
++ min_x = x;
++ }
++ }
++ }
++
++ d->button_width = width - min_x;
++}
++
++static MetaButtonFunction
++button_to_meta_button_function (gint i)
++{
++ switch (i)
++ {
++ case BUTTON_MENU:
++ return META_BUTTON_FUNCTION_MENU;
++ case BUTTON_MIN:
++ return META_BUTTON_FUNCTION_MINIMIZE;
++ case BUTTON_MAX:
++ return META_BUTTON_FUNCTION_MAXIMIZE;
++ case BUTTON_CLOSE:
++ return META_BUTTON_FUNCTION_CLOSE;
++ case BUTTON_SHADE:
++ return META_BUTTON_FUNCTION_SHADE;
++ case BUTTON_ABOVE:
++ return META_BUTTON_FUNCTION_ABOVE;
++ case BUTTON_STICK:
++ return META_BUTTON_FUNCTION_STICK;
++ case BUTTON_UNSHADE:
++ return META_BUTTON_FUNCTION_UNSHADE;
++ case BUTTON_UNABOVE:
++ return META_BUTTON_FUNCTION_UNABOVE;
++ case BUTTON_UNSTICK:
++ return META_BUTTON_FUNCTION_UNSTICK;
++ default:
++ break;
++ }
++
++ return META_BUTTON_FUNCTION_LAST;
++}
++
++gboolean
++meta_get_button_position (decor_t *d,
++ gint i,
++ gint width,
++ gint height,
++ gint *x,
++ gint *y,
++ gint *w,
++ gint *h)
++{
++ MetaButtonLayout button_layout;
++ MetaFrameGeometry fgeom;
++ MetaFrameType frame_type;
++ MetaFrameFlags flags;
++ MetaTheme *theme;
++ MetaButtonFunction button_function;
++ MetaButtonSpace *space;
++
++ if (!d->context)
++ {
++ /* undecorated windows implicitly have no buttons */
++ return FALSE;
++ }
++
++ theme = meta_theme_get_current ();
++
++ frame_type = meta_frame_type_from_string (d->frame->type);
++ if (!(frame_type < META_FRAME_TYPE_LAST))
++ frame_type = META_FRAME_TYPE_NORMAL;
++
++ meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
++ frame_type);
++
++ button_function = button_to_meta_button_function (i);
++ if (!meta_button_present (&button_layout, button_function))
++ return FALSE;
++
++ switch (i)
++ {
++ case BUTTON_MENU:
++ space = &fgeom.menu_rect;
++ break;
++ case BUTTON_MIN:
++ space = &fgeom.min_rect;
++ break;
++ case BUTTON_MAX:
++ space = &fgeom.max_rect;
++ break;
++ case BUTTON_CLOSE:
++ space = &fgeom.close_rect;
++ break;
++ case BUTTON_SHADE:
++ space = &fgeom.shade_rect;
++ break;
++ case BUTTON_ABOVE:
++ space = &fgeom.above_rect;
++ break;
++ case BUTTON_STICK:
++ space = &fgeom.stick_rect;
++ break;
++ case BUTTON_UNSHADE:
++ space = &fgeom.unshade_rect;
++ break;
++ case BUTTON_UNABOVE:
++ space = &fgeom.unabove_rect;
++ break;
++ case BUTTON_UNSTICK:
++ space = &fgeom.unstick_rect;
++ break;
++ default:
++ return FALSE;
++ }
++
++ if (!space->clickable.width && !space->clickable.height)
++ return FALSE;
++
++ *x = space->clickable.x;
++ *y = space->clickable.y;
++ *w = space->clickable.width;
++ *h = space->clickable.height;
++
++ if (d->frame_window)
++ {
++ *x += d->frame->win_extents.left + 4;
++ *y += d->frame->win_extents.top + 2;
++ }
++
++ return TRUE;
++}
++
++gfloat
++meta_get_title_scale (decor_frame_t *frame)
++{
++ MetaTheme *theme;
++ MetaFrameType type;
++ MetaFrameFlags flags;
++
++ theme = meta_theme_get_current ();
++ type = meta_frame_type_from_string (frame->type);
++ flags = 0xc33; /* fixme */
++
++ if (type == META_FRAME_TYPE_LAST)
++ return 1.0f;
++
++ gfloat scale = meta_theme_get_title_scale (theme, type, flags);
++
++ return scale;
++}
++
++gboolean
++meta_calc_decoration_size (decor_t *d,
++ gint w,
++ gint h,
++ gint name_width,
++ gint *width,
++ gint *height)
++{
++ decor_layout_t layout;
++ decor_context_t *context;
++ decor_shadow_t *shadow;
++
++ if (!d->decorated)
++ return FALSE;
++
++ if ((d->state & META_MAXIMIZED) == META_MAXIMIZED)
++ {
++ if (!d->frame_window)
++ {
++ if (d->active)
++ {
++ context = &d->frame->max_window_context_active;
++ shadow = d->frame->max_border_shadow_active;
++ }
++ else
++ {
++ context = &d->frame->max_window_context_inactive;
++ shadow = d->frame->max_border_shadow_inactive;
++ }
++ }
++ else
++ {
++ context = &d->frame->max_window_context_no_shadow;
++ shadow = d->frame->max_border_no_shadow;
++ }
++ }
++ else
++ {
++ if (!d->frame_window)
++ {
++ if (d->active)
++ {
++ context = &d->frame->window_context_active;
++ shadow = d->frame->border_shadow_active;
++ }
++ else
++ {
++ context = &d->frame->window_context_inactive;
++ shadow = d->frame->border_shadow_inactive;
++ }
++ }
++ else
++ {
++ context = &d->frame->window_context_no_shadow;
++ shadow = d->frame->border_no_shadow;
++ }
++ }
++
++ if (!d->frame_window)
++ {
++ decor_get_best_layout (context, w, h, &layout);
++
++ if (context != d->context || memcmp (&layout, &d->border_layout, sizeof (layout)))
++ {
++ *width = layout.width;
++ *height = layout.height;
++
++ d->border_layout = layout;
++ d->context = context;
++ d->shadow = shadow;
++
++ meta_calc_button_size (d);
++
++ return TRUE;
++ }
++ }
++ else
++ {
++ if ((d->state & META_MAXIMIZED) == META_MAXIMIZED)
++ decor_get_default_layout (context, d->client_width,
++ d->client_height - d->frame->titlebar_height,
++ &layout);
++ else
++ decor_get_default_layout (context, d->client_width,
++ d->client_height, &layout);
++
++ *width = layout.width;
++ *height = layout.height;
++
++ d->border_layout = layout;
++ d->shadow = shadow;
++ d->context = context;
++
++ meta_calc_button_size (d);
++
++ return TRUE;
++ }
++
++ return FALSE;
++}
++
++#define TOP_RESIZE_HEIGHT 2
++#define RESIZE_EXTENDS 15
++
++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)
++{
++ MetaButtonLayout button_layout;
++ MetaFrameGeometry fgeom;
++ MetaFrameFlags flags;
++ MetaTheme *theme;
++
++ theme = meta_theme_get_current ();
++
++ meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
++ meta_frame_type_from_string (d->frame->type));
++
++ width += fgeom.borders.total.right + fgeom.borders.total.left;
++ height += fgeom.borders.total.top + fgeom.borders.total.bottom;
++
++ switch (i)
++ {
++ case 2: /* bottom */
++ switch (j)
++ {
++ case 2: /* bottom right */
++ *x = width - fgeom.borders.total.right - RESIZE_EXTENDS;
++ *y = height - fgeom.borders.total.bottom - RESIZE_EXTENDS;
++
++ if (d->frame_window)
++ {
++ *x += d->frame->win_extents.left + 2;
++ *y += d->frame->win_extents.top + 2;
++ }
++
++ *w = fgeom.borders.total.right + RESIZE_EXTENDS;
++ *h = fgeom.borders.total.bottom + RESIZE_EXTENDS;
++ break;
++ case 1: /* bottom */
++ *x = fgeom.borders.total.left + RESIZE_EXTENDS;
++ *y = height - fgeom.borders.total.bottom;
++
++ if (d->frame_window)
++ *y += d->frame->win_extents.top + 2;
++
++ *w = width - fgeom.borders.total.left - fgeom.borders.total.right - (2 * RESIZE_EXTENDS);
++ *h = fgeom.borders.total.bottom;
++ break;
++ case 0: /* bottom left */
++ default:
++ *x = 0;
++ *y = height - fgeom.borders.total.bottom - RESIZE_EXTENDS;
++
++ if (d->frame_window)
++ {
++ *x += d->frame->win_extents.left + 4;
++ *y += d->frame->win_extents.bottom + 2;
++ }
++
++ *w = fgeom.borders.total.left + RESIZE_EXTENDS;
++ *h = fgeom.borders.total.bottom + RESIZE_EXTENDS;
++ break;
++ }
++ break;
++ case 1: /* middle */
++ switch (j)
++ {
++ case 2: /* right */
++ *x = width - fgeom.borders.total.right;
++ *y = fgeom.borders.total.top + RESIZE_EXTENDS;
++
++ if (d->frame_window)
++ *x += d->frame->win_extents.left + 2;
++
++ *w = fgeom.borders.total.right;
++ *h = height - fgeom.borders.total.top - fgeom.borders.total.bottom - (2 * RESIZE_EXTENDS);
++ break;
++ case 1: /* middle */
++ *x = fgeom.borders.total.left;
++ *y = fgeom.title_rect.y + TOP_RESIZE_HEIGHT;
++ *w = width - fgeom.borders.total.left - fgeom.borders.total.right;
++ *h = height - fgeom.top_titlebar_edge - fgeom.borders.total.bottom;
++ break;
++ case 0: /* left */
++ default:
++ *x = 0;
++ *y = fgeom.borders.total.top + RESIZE_EXTENDS;
++
++ if (d->frame_window)
++ *x += d->frame->win_extents.left + 4;
++
++ *w = fgeom.borders.total.left;
++ *h = height - fgeom.borders.total.top - fgeom.borders.total.bottom - (2 * RESIZE_EXTENDS);
++ break;
++ }
++ break;
++ case 0: /* top */
++ default:
++ switch (j)
++ {
++ case 2: /* top right */
++ *x = width - fgeom.borders.total.right - RESIZE_EXTENDS;
++ *y = 0;
++
++ if (d->frame_window)
++ {
++ *x += d->frame->win_extents.left + 2;
++ *y += d->frame->win_extents.top + 2 - fgeom.title_rect.height;
++ }
++
++ *w = fgeom.borders.total.right + RESIZE_EXTENDS;
++ *h = fgeom.borders.total.top + RESIZE_EXTENDS;
++ break;
++ case 1: /* top */
++ *x = fgeom.borders.total.left + RESIZE_EXTENDS;
++ *y = 0;
++
++ if (d->frame_window)
++ *y += d->frame->win_extents.top + 2;
++
++ *w = width - fgeom.borders.total.left - fgeom.borders.total.right - (2 * RESIZE_EXTENDS);
++ *h = fgeom.borders.total.top - fgeom.title_rect.height;
++ break;
++ case 0: /* top left */
++ default:
++ *x = 0;
++ *y = 0;
++
++ if (d->frame_window)
++ {
++ *x += d->frame->win_extents.left + 4;
++ *y += d->frame->win_extents.top + 2 - fgeom.title_rect.height;
++ }
++
++ *w = fgeom.borders.total.left + RESIZE_EXTENDS;
++ *h = fgeom.borders.total.top + RESIZE_EXTENDS;
++ break;
++ }
++ break;
++ }
++
++ if (!(flags & META_FRAME_ALLOWS_VERTICAL_RESIZE))
++ {
++ /* turn off top and bottom event windows */
++ if (i == 0 || i == 2)
++ *w = *h = 0;
++ }
++
++ if (!(flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE))
++ {
++ /* turn off left and right event windows */
++ if (j == 0 || j == 2)
++ *w = *h = 0;
++ }
++}
++
++static MetaButtonFunction
++meta_button_function_from_string (const char *str)
++{
++ if (strcmp (str, "menu") == 0)
++ return META_BUTTON_FUNCTION_MENU;
++ else if (strcmp (str, "appmenu") == 0)
++ return META_BUTTON_FUNCTION_APPMENU;
++ else if (strcmp (str, "minimize") == 0)
++ return META_BUTTON_FUNCTION_MINIMIZE;
++ else if (strcmp (str, "maximize") == 0)
++ return META_BUTTON_FUNCTION_MAXIMIZE;
++ else if (strcmp (str, "close") == 0)
++ return META_BUTTON_FUNCTION_CLOSE;
++ else if (strcmp (str, "shade") == 0)
++ return META_BUTTON_FUNCTION_SHADE;
++ else if (strcmp (str, "above") == 0)
++ return META_BUTTON_FUNCTION_ABOVE;
++ else if (strcmp (str, "stick") == 0)
++ return META_BUTTON_FUNCTION_STICK;
++ else if (strcmp (str, "unshade") == 0)
++ return META_BUTTON_FUNCTION_UNSHADE;
++ else if (strcmp (str, "unabove") == 0)
++ return META_BUTTON_FUNCTION_UNABOVE;
++ else if (strcmp (str, "unstick") == 0)
++ return META_BUTTON_FUNCTION_UNSTICK;
++ else
++ return META_BUTTON_FUNCTION_LAST;
++}
++
++static MetaButtonFunction
++meta_button_opposite_function (MetaButtonFunction ofwhat)
++{
++ switch (ofwhat)
++ {
++ case META_BUTTON_FUNCTION_SHADE:
++ return META_BUTTON_FUNCTION_UNSHADE;
++ case META_BUTTON_FUNCTION_UNSHADE:
++ return META_BUTTON_FUNCTION_SHADE;
++
++ case META_BUTTON_FUNCTION_ABOVE:
++ return META_BUTTON_FUNCTION_UNABOVE;
++ case META_BUTTON_FUNCTION_UNABOVE:
++ return META_BUTTON_FUNCTION_ABOVE;
++
++ case META_BUTTON_FUNCTION_STICK:
++ return META_BUTTON_FUNCTION_UNSTICK;
++ case META_BUTTON_FUNCTION_UNSTICK:
++ return META_BUTTON_FUNCTION_STICK;
++
++ default:
++ return META_BUTTON_FUNCTION_LAST;
++ }
++}
++
++static void
++meta_initialize_button_layout (MetaButtonLayout *layout)
++{
++ int i;
++
++ for (i = 0; i < MAX_BUTTONS_PER_CORNER; ++i)
++ {
++ layout->left_buttons[i] = META_BUTTON_FUNCTION_LAST;
++ layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST;
++ layout->left_buttons_has_spacer[i] = FALSE;
++ layout->right_buttons_has_spacer[i] = FALSE;
++ }
++}
++
++void
++meta_update_button_layout (const char *value)
++{
++ MetaButtonLayout new_layout;
++ MetaButtonFunction f;
++ char **sides;
++ int i;
++
++ meta_initialize_button_layout (&new_layout);
++
++ sides = g_strsplit (value, ":", 2);
++
++ if (sides[0] != NULL)
++ {
++ char **buttons;
++ int b;
++ gboolean used[META_BUTTON_FUNCTION_LAST];
++
++ for (i = 0; i < META_BUTTON_FUNCTION_LAST; ++i)
++ used[i] = FALSE;
++
++ buttons = g_strsplit (sides[0], ",", -1);
++
++ i = b = 0;
++ while (buttons[b] != NULL)
++ {
++ f = meta_button_function_from_string (buttons[b]);
++ if (i > 0 && strcmp ("spacer", buttons[b]) == 0)
++ {
++ new_layout.left_buttons_has_spacer[i - 1] = TRUE;
++ f = meta_button_opposite_function (f);
++
++ if (f != META_BUTTON_FUNCTION_LAST)
++ new_layout.left_buttons_has_spacer[i - 2] = TRUE;
++ }
++ else
++ {
++ if (f != META_BUTTON_FUNCTION_LAST && !used[f])
++ {
++ used[f] = TRUE;
++ new_layout.left_buttons[i++] = f;
++
++ f = meta_button_opposite_function (f);
++
++ if (f != META_BUTTON_FUNCTION_LAST)
++ new_layout.left_buttons[i++] = f;
++
++ }
++ else
++ {
++ fprintf (stderr, "%s: Ignoring unknown or already-used "
++ "button name \"%s\"\n", program_name, buttons[b]);
++ }
++ }
++ ++b;
++ }
++
++ new_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
++
++ g_strfreev (buttons);
++
++ if (sides[1] != NULL)
++ {
++ for (i = 0; i < META_BUTTON_FUNCTION_LAST; ++i)
++ used[i] = FALSE;
++
++ buttons = g_strsplit (sides[1], ",", -1);
++
++ i = b = 0;
++ while (buttons[b] != NULL)
++ {
++ f = meta_button_function_from_string (buttons[b]);
++ if (i > 0 && strcmp ("spacer", buttons[b]) == 0)
++ {
++ new_layout.right_buttons_has_spacer[i - 1] = TRUE;
++ f = meta_button_opposite_function (f);
++ if (f != META_BUTTON_FUNCTION_LAST)
++ new_layout.right_buttons_has_spacer[i - 2] = TRUE;
++ }
++ else
++ {
++ if (f != META_BUTTON_FUNCTION_LAST && !used[f])
++ {
++ used[f] = TRUE;
++ new_layout.right_buttons[i++] = f;
++
++ f = meta_button_opposite_function (f);
++
++ if (f != META_BUTTON_FUNCTION_LAST)
++ new_layout.right_buttons[i++] = f;
++ }
++ else
++ {
++ fprintf (stderr, "%s: Ignoring unknown or "
++ "already-used button name \"%s\"\n",
++ program_name, buttons[b]);
++ }
++ }
++ ++b;
++ }
++
++ new_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
++
++ g_strfreev (buttons);
++ }
++ }
++
++ g_strfreev (sides);
++
++ /* Invert the button layout for RTL languages */
++ if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
++ {
++ MetaButtonLayout rtl_layout;
++ int j;
++
++ meta_initialize_button_layout (&rtl_layout);
++
++ i = 0;
++ while (new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST)
++ ++i;
++
++ for (j = 0; j < i; ++j)
++ {
++ rtl_layout.right_buttons[j] = new_layout.left_buttons[i - j - 1];
++ if (j == 0)
++ rtl_layout.right_buttons_has_spacer[i - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
++ else
++ rtl_layout.right_buttons_has_spacer[j - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
++ }
++
++ i = 0;
++ while (new_layout.right_buttons[i] != META_BUTTON_FUNCTION_LAST)
++ ++i;
++
++ for (j = 0; j < i; ++j)
++ {
++ rtl_layout.left_buttons[j] = new_layout.right_buttons[i - j - 1];
++ if (j == 0)
++ rtl_layout.left_buttons_has_spacer[i - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
++ else
++ rtl_layout.left_buttons_has_spacer[j - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
++ }
++
++ new_layout = rtl_layout;
++ }
++
++ meta_button_layout = new_layout;
++}
++
++void
++meta_update_border_extents (decor_frame_t *frame)
++{
++ MetaTheme *theme;
++ GdkScreen *screen;
++ MetaStyleInfo *style_info;
++ MetaFrameBorders borders;
++ MetaFrameType frame_type;
++ gint top_height;
++ gint bottom_height;
++ gint left_width;
++ gint right_width;
++
++ gwd_decor_frame_ref (frame);
++
++ frame_type = meta_frame_type_from_string (frame->type);
++ if (!(frame_type < META_FRAME_TYPE_LAST))
++ frame_type = META_FRAME_TYPE_NORMAL;
++
++ theme = meta_theme_get_current ();
++
++ screen = gtk_widget_get_screen (frame->style_window_rgba);
++ style_info = meta_theme_create_style_info (screen, NULL);
++
++ meta_theme_get_frame_borders (theme, style_info, frame_type, frame->text_height,
++ 0, &borders);
++
++ top_height = borders.visible.top;
++ bottom_height = borders.visible.bottom;
++ left_width = borders.visible.left;
++ right_width = borders.visible.right;
++
++ frame->win_extents.top = frame->win_extents.top;
++ frame->win_extents.bottom = bottom_height;
++ frame->win_extents.left = left_width;
++ frame->win_extents.right = right_width;
++
++ frame->titlebar_height = top_height - frame->win_extents.top;
++
++ meta_theme_get_frame_borders (theme, style_info, frame_type, frame->text_height,
++ META_FRAME_MAXIMIZED, &borders);
++
++ top_height = borders.visible.top;
++ bottom_height = borders.visible.bottom;
++ left_width = borders.visible.left;
++ right_width = borders.visible.right;
++
++ frame->max_win_extents.top = frame->win_extents.top;
++ frame->max_win_extents.bottom = bottom_height;
++ frame->max_win_extents.left = left_width;
++ frame->max_win_extents.right = right_width;
++
++ frame->max_titlebar_height = top_height - frame->max_win_extents.top;
++
++ meta_style_info_unref (style_info);
++
++ gwd_decor_frame_unref (frame);
++}
++
++#endif /* HAVE_METACITY_3_16_0 */
++#endif /* USE_METACITY */
+diff -Nur original/gtk/window-decorator/metacity.c modified/gtk/window-decorator/metacity.c
+--- original/gtk/window-decorator/metacity.c 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/window-decorator/metacity.c 2015-05-14 11:13:01.100922489 +0100
+@@ -26,87 +26,118 @@
+ #include "gtk-window-decorator.h"
+
+ #ifdef USE_METACITY
++#ifndef HAVE_METACITY_3_16_0
++
++MetaButtonLayout meta_button_layout;
++
++static gboolean
++meta_button_present (MetaButtonLayout *button_layout,
++ MetaButtonFunction function)
++{
++ int i;
++
++ for (i = 0; i < MAX_BUTTONS_PER_CORNER; ++i)
++ if (button_layout->left_buttons[i] == function)
++ return TRUE;
++
++ for (i = 0; i < MAX_BUTTONS_PER_CORNER; ++i)
++ if (button_layout->right_buttons[i] == function)
++ return TRUE;
++
++ return FALSE;
++}
+
+ static void
+-decor_update_meta_window_property (decor_t *d,
+- MetaTheme *theme,
+- MetaFrameFlags flags,
+- Region top,
+- Region bottom,
+- Region left,
+- Region right)
+-{
+- long *data;
+- Display *xdisplay =
+- GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+- gint nQuad;
+- decor_extents_t win_extents, frame_win_extents;
+- decor_extents_t max_win_extents, frame_max_win_extents;
+- decor_quad_t quads[N_QUADS_MAX];
+- unsigned int nOffset = 1;
+- unsigned int frame_type = populate_frame_type (d);
+- unsigned int frame_state = populate_frame_state (d);
+- unsigned int frame_actions = populate_frame_actions (d);
+- gint w, lh, rh;
+- gint top_stretch_offset;
+- gint bottom_stretch_offset;
+- gint left_stretch_offset;
+- gint right_stretch_offset;
+- gint mutter_draggable_border_width = 0;
++decor_update_meta_window_property (decor_t *d,
++ MetaTheme *theme,
++ MetaFrameFlags flags,
++ Region top,
++ Region bottom,
++ Region left,
++ Region right)
++{
++ long *data;
++ GdkDisplay *display;
++ Display *xdisplay;
++ gint nQuad;
++ decor_extents_t win_extents;
++ decor_extents_t frame_win_extents;
++ decor_extents_t max_win_extents;
++ decor_extents_t frame_max_win_extents;
++ decor_quad_t quads[N_QUADS_MAX];
++ unsigned int nOffset;
++ unsigned int frame_type;
++ unsigned int frame_state;
++ unsigned int frame_actions;
++ gint w;
++ gint lh;
++ gint rh;
++ gint top_stretch_offset;
++ gint bottom_stretch_offset;
++ gint left_stretch_offset;
++ gint right_stretch_offset;
++ gint mutter_draggable_border_width;
++
++ display = gdk_display_get_default ();
++ xdisplay = gdk_x11_display_get_xdisplay (display);
++
++ nOffset = 1;
++
++ frame_type = populate_frame_type (d);
++ frame_state = populate_frame_state (d);
++ frame_actions = populate_frame_actions (d);
+
+ win_extents = frame_win_extents = d->frame->win_extents;
+ max_win_extents = frame_max_win_extents = d->frame->max_win_extents;
+
+- g_object_get (settings, "draggable-border-width", &mutter_draggable_border_width, NULL);
++ mutter_draggable_border_width = 0;
++
++ g_object_get (settings, "draggable-border-width",
++ &mutter_draggable_border_width, NULL);
+
+ /* Add the invisible grab area padding, but only for
+ * pixmap type decorations */
+ if (!d->frame_window)
+ {
+- if (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE)
+- {
+- frame_win_extents.left += mutter_draggable_border_width;
+- frame_win_extents.right += mutter_draggable_border_width;
+- frame_max_win_extents.left += mutter_draggable_border_width;
+- frame_max_win_extents.right += mutter_draggable_border_width;
+- }
+-
+- if (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE)
+- {
+- frame_win_extents.bottom += mutter_draggable_border_width;
+- frame_win_extents.top += mutter_draggable_border_width;
+- frame_max_win_extents.bottom += mutter_draggable_border_width;
+- frame_max_win_extents.top += mutter_draggable_border_width;
+- }
++ if (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE)
++ {
++ frame_win_extents.left += mutter_draggable_border_width;
++ frame_win_extents.right += mutter_draggable_border_width;
++ frame_max_win_extents.left += mutter_draggable_border_width;
++ frame_max_win_extents.right += mutter_draggable_border_width;
++ }
++
++ if (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE)
++ {
++ frame_win_extents.bottom += mutter_draggable_border_width;
++ frame_win_extents.top += mutter_draggable_border_width;
++ frame_max_win_extents.bottom += mutter_draggable_border_width;
++ frame_max_win_extents.top += mutter_draggable_border_width;
++ }
+ }
+
+ w = d->border_layout.top.x2 - d->border_layout.top.x1 -
+- d->context->left_space - d->context->right_space;
++ d->context->left_space - d->context->right_space;
+
+ if (d->border_layout.rotation)
+- lh = d->border_layout.left.x2 - d->border_layout.left.x1;
++ lh = d->border_layout.left.x2 - d->border_layout.left.x1;
+ else
+- lh = d->border_layout.left.y2 - d->border_layout.left.y1;
++ lh = d->border_layout.left.y2 - d->border_layout.left.y1;
+
+ if (d->border_layout.rotation)
+- rh = d->border_layout.right.x2 - d->border_layout.right.x1;
++ rh = d->border_layout.right.x2 - d->border_layout.right.x1;
+ else
+- rh = d->border_layout.right.y2 - d->border_layout.right.y1;
++ rh = d->border_layout.right.y2 - d->border_layout.right.y1;
+
+- left_stretch_offset = lh / 2;
+- right_stretch_offset = rh / 2;
+- top_stretch_offset = w - d->button_width - 1;
+- bottom_stretch_offset = (d->border_layout.bottom.x2 -
+- d->border_layout.bottom.x1 -
+- d->context->left_space -
+- d->context->right_space) / 2;
+-
+- nQuad = decor_set_lXrXtXbX_window_quads (quads, d->context,
+- &d->border_layout,
+- left_stretch_offset,
+- right_stretch_offset,
+- top_stretch_offset,
+- bottom_stretch_offset);
++ left_stretch_offset = lh / 2;
++ right_stretch_offset = rh / 2;
++ top_stretch_offset = w - d->button_width - 1;
++ bottom_stretch_offset = (d->border_layout.bottom.x2 - d->border_layout.bottom.x1 -
++ d->context->left_space - d->context->right_space) / 2;
++
++ nQuad = decor_set_lXrXtXbX_window_quads (quads, d->context, &d->border_layout,
++ left_stretch_offset, right_stretch_offset,
++ top_stretch_offset, bottom_stretch_offset);
+
+ win_extents.top += d->frame->titlebar_height;
+ frame_win_extents.top += d->frame->titlebar_height;
+@@ -115,47 +146,44 @@
+
+ if (d->frame_window)
+ {
+- data = decor_alloc_property (nOffset, WINDOW_DECORATION_TYPE_WINDOW);
+- decor_gen_window_property (data, nOffset - 1, &win_extents, &max_win_extents, 20, 20,
+- frame_type, frame_state, frame_actions);
++ data = decor_alloc_property (nOffset, WINDOW_DECORATION_TYPE_WINDOW);
++ decor_gen_window_property (data, nOffset - 1, &win_extents, &max_win_extents,
++ 20, 20, frame_type, frame_state, frame_actions);
+ }
+ else
+ {
+- data = decor_alloc_property (nOffset, WINDOW_DECORATION_TYPE_PIXMAP);
+- decor_quads_to_property (data, nOffset - 1, cairo_xlib_surface_get_drawable (d->surface),
+- &frame_win_extents, &win_extents,
+- &frame_max_win_extents, &max_win_extents,
+- ICON_SPACE + d->button_width,
+- 0,
+- quads, nQuad, frame_type, frame_state, frame_actions);
++ data = decor_alloc_property (nOffset, WINDOW_DECORATION_TYPE_PIXMAP);
++ decor_quads_to_property (data, nOffset - 1, cairo_xlib_surface_get_drawable (d->surface),
++ &frame_win_extents, &win_extents,
++ &frame_max_win_extents, &max_win_extents,
++ ICON_SPACE + d->button_width,
++ 0, quads, nQuad, frame_type, frame_state, frame_actions);
+ }
+
+ gdk_error_trap_push ();
+
+- XChangeProperty (xdisplay, d->prop_xid,
+- win_decor_atom,
+- XA_INTEGER,
+- 32, PropModeReplace, (guchar *) data,
+- PROP_HEADER_SIZE + BASE_PROP_SIZE + QUAD_PROP_SIZE * N_QUADS_MAX);
+- gdk_display_sync (gdk_display_get_default ());
++ XChangeProperty (xdisplay, d->prop_xid, win_decor_atom, XA_INTEGER,
++ 32, PropModeReplace, (guchar *) data,
++ PROP_HEADER_SIZE + BASE_PROP_SIZE + QUAD_PROP_SIZE * N_QUADS_MAX);
++ gdk_display_sync (display);
++
+ gdk_error_trap_pop_ignored ();
+
+ free (data);
+
+- decor_update_blur_property (d,
+- w, lh,
+- top, top_stretch_offset,
+- bottom, bottom_stretch_offset,
+- left, left_stretch_offset,
+- right, right_stretch_offset);
++ decor_update_blur_property (d, w, lh,
++ top, top_stretch_offset,
++ bottom, bottom_stretch_offset,
++ left, left_stretch_offset,
++ right, right_stretch_offset);
+ }
+
+ static void
+ meta_get_corner_radius (const MetaFrameGeometry *fgeom,
+- int *top_left_radius,
+- int *top_right_radius,
+- int *bottom_left_radius,
+- int *bottom_right_radius)
++ int *top_left_radius,
++ int *top_right_radius,
++ int *bottom_left_radius,
++ int *bottom_right_radius)
+ {
+ *top_left_radius = fgeom->top_left_corner_rounded_radius;
+ *top_right_radius = fgeom->top_right_corner_rounded_radius;
+@@ -165,7 +193,7 @@
+
+ static int
+ radius_to_width (int radius,
+- int i)
++ int i)
+ {
+ float r1 = sqrt (radius) + radius;
+ float r2 = r1 * r1 - (r1 - (i + 0.5)) * (r1 - (i + 0.5));
+@@ -175,52 +203,51 @@
+
+ static Region
+ meta_get_top_border_region (const MetaFrameGeometry *fgeom,
+- int width)
++ int width)
+ {
+- Region corners_xregion, border_xregion;
++ Region corners_xregion;
++ Region border_xregion;
+ XRectangle xrect;
+- int top_left_radius;
+- int top_right_radius;
+- int bottom_left_radius;
+- int bottom_right_radius;
+- int w, i;
++ int top_left_radius;
++ int top_right_radius;
++ int bottom_left_radius;
++ int bottom_right_radius;
++ int w;
++ int i;
+
+ corners_xregion = XCreateRegion ();
+
+- meta_get_corner_radius (fgeom,
+- &top_left_radius,
+- &top_right_radius,
+- &bottom_left_radius,
+- &bottom_right_radius);
++ meta_get_corner_radius (fgeom, &top_left_radius, &top_right_radius,
++ &bottom_left_radius, &bottom_right_radius);
+
+ if (top_left_radius)
+ {
+- for (i = 0; i < top_left_radius; ++i)
+- {
+- w = radius_to_width (top_left_radius, i);
++ for (i = 0; i < top_left_radius; ++i)
++ {
++ w = radius_to_width (top_left_radius, i);
++
++ xrect.x = 0;
++ xrect.y = i;
++ xrect.width = w;
++ xrect.height = 1;
+
+- xrect.x = 0;
+- xrect.y = i;
+- xrect.width = w;
+- xrect.height = 1;
+-
+- XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+- }
++ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
++ }
+ }
+
+ if (top_right_radius)
+ {
+- for (i = 0; i < top_right_radius; ++i)
+- {
+- w = radius_to_width (top_right_radius, i);
+-
+- xrect.x = width - w;
+- xrect.y = i;
+- xrect.width = w;
+- xrect.height = 1;
++ for (i = 0; i < top_right_radius; ++i)
++ {
++ w = radius_to_width (top_right_radius, i);
++
++ xrect.x = width - w;
++ xrect.y = i;
++ xrect.width = w;
++ xrect.height = 1;
+
+- XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+- }
++ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
++ }
+ }
+
+ border_xregion = XCreateRegion ();
+@@ -241,52 +268,51 @@
+
+ static Region
+ meta_get_bottom_border_region (const MetaFrameGeometry *fgeom,
+- int width)
++ int width)
+ {
+- Region corners_xregion, border_xregion;
++ Region corners_xregion;
++ Region border_xregion;
+ XRectangle xrect;
+- int top_left_radius;
+- int top_right_radius;
+- int bottom_left_radius;
+- int bottom_right_radius;
+- int w, i;
++ int top_left_radius;
++ int top_right_radius;
++ int bottom_left_radius;
++ int bottom_right_radius;
++ int w;
++ int i;
+
+ corners_xregion = XCreateRegion ();
+
+- meta_get_corner_radius (fgeom,
+- &top_left_radius,
+- &top_right_radius,
+- &bottom_left_radius,
+- &bottom_right_radius);
++ meta_get_corner_radius (fgeom, &top_left_radius, &top_right_radius,
++ &bottom_left_radius, &bottom_right_radius);
+
+ if (bottom_left_radius)
+ {
+- for (i = 0; i < bottom_left_radius; ++i)
+- {
+- w = radius_to_width (bottom_left_radius, i);
+-
+- xrect.x = 0;
+- xrect.y = fgeom->bottom_height - i - 1;
+- xrect.width = w;
+- xrect.height = 1;
++ for (i = 0; i < bottom_left_radius; ++i)
++ {
++ w = radius_to_width (bottom_left_radius, i);
++
++ xrect.x = 0;
++ xrect.y = fgeom->bottom_height - i - 1;
++ xrect.width = w;
++ xrect.height = 1;
+
+- XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+- }
++ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
++ }
+ }
+
+ if (bottom_right_radius)
+ {
+- for (i = 0; i < bottom_right_radius; ++i)
+- {
+- w = radius_to_width (bottom_right_radius, i);
++ for (i = 0; i < bottom_right_radius; ++i)
++ {
++ w = radius_to_width (bottom_right_radius, i);
++
++ xrect.x = width - w;
++ xrect.y = fgeom->bottom_height - i - 1;
++ xrect.width = w;
++ xrect.height = 1;
+
+- xrect.x = width - w;
+- xrect.y = fgeom->bottom_height - i - 1;
+- xrect.width = w;
+- xrect.height = 1;
+-
+- XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+- }
++ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
++ }
+ }
+
+ border_xregion = XCreateRegion ();
+@@ -307,16 +333,16 @@
+
+ static Region
+ meta_get_left_border_region (const MetaFrameGeometry *fgeom,
+- int height)
++ int height)
+ {
+- Region border_xregion;
++ Region border_xregion;
+ XRectangle xrect;
+
+ border_xregion = XCreateRegion ();
+
+- xrect.x = 0;
+- xrect.y = 0;
+- xrect.width = fgeom->left_width;
++ xrect.x = 0;
++ xrect.y = 0;
++ xrect.width = fgeom->left_width;
+ xrect.height = height - fgeom->top_height - fgeom->bottom_height;
+
+ XUnionRectWithRegion (&xrect, border_xregion, border_xregion);
+@@ -326,16 +352,16 @@
+
+ static Region
+ meta_get_right_border_region (const MetaFrameGeometry *fgeom,
+- int height)
++ int height)
+ {
+- Region border_xregion;
++ Region border_xregion;
+ XRectangle xrect;
+
+ border_xregion = XCreateRegion ();
+
+- xrect.x = 0;
+- xrect.y = 0;
+- xrect.width = fgeom->right_width;
++ xrect.x = 0;
++ xrect.y = 0;
++ xrect.width = fgeom->right_width;
+ xrect.height = height - fgeom->top_height - fgeom->bottom_height;
+
+ XUnionRectWithRegion (&xrect, border_xregion, border_xregion);
+@@ -348,10 +374,10 @@
+ {
+ if (state & IN_EVENT_WINDOW)
+ {
+- if (state & PRESSED_EVENT_WINDOW)
+- return META_BUTTON_STATE_PRESSED;
++ if (state & PRESSED_EVENT_WINDOW)
++ return META_BUTTON_STATE_PRESSED;
+
+- return META_BUTTON_STATE_PRELIGHT;
++ return META_BUTTON_STATE_PRELIGHT;
+ }
+
+ return META_BUTTON_STATE_NORMAL;
+@@ -360,271 +386,245 @@
+ static MetaButtonType
+ meta_function_to_type (MetaButtonFunction function)
+ {
+- switch (function) {
++ switch (function)
++ {
+ case META_BUTTON_FUNCTION_MENU:
+- return META_BUTTON_TYPE_MENU;
++ return META_BUTTON_TYPE_MENU;
+ case META_BUTTON_FUNCTION_MINIMIZE:
+- return META_BUTTON_TYPE_MINIMIZE;
++ return META_BUTTON_TYPE_MINIMIZE;
+ case META_BUTTON_FUNCTION_MAXIMIZE:
+- return META_BUTTON_TYPE_MAXIMIZE;
++ return META_BUTTON_TYPE_MAXIMIZE;
+ case META_BUTTON_FUNCTION_CLOSE:
+- return META_BUTTON_TYPE_CLOSE;
++ return META_BUTTON_TYPE_CLOSE;
+ case META_BUTTON_FUNCTION_SHADE:
+- return META_BUTTON_TYPE_SHADE;
++ return META_BUTTON_TYPE_SHADE;
+ case META_BUTTON_FUNCTION_ABOVE:
+- return META_BUTTON_TYPE_ABOVE;
++ return META_BUTTON_TYPE_ABOVE;
+ case META_BUTTON_FUNCTION_STICK:
+- return META_BUTTON_TYPE_STICK;
++ return META_BUTTON_TYPE_STICK;
+ case META_BUTTON_FUNCTION_UNSHADE:
+- return META_BUTTON_TYPE_UNSHADE;
++ return META_BUTTON_TYPE_UNSHADE;
+ case META_BUTTON_FUNCTION_UNABOVE:
+- return META_BUTTON_TYPE_UNABOVE;
++ return META_BUTTON_TYPE_UNABOVE;
+ case META_BUTTON_FUNCTION_UNSTICK:
+- return META_BUTTON_TYPE_UNSTICK;
++ return META_BUTTON_TYPE_UNSTICK;
+ default:
+- break;
++ break;
+ }
+
+ return META_BUTTON_TYPE_LAST;
+ }
+
+ static MetaButtonState
+-meta_button_state_for_button_type (decor_t *d,
+- MetaButtonType type)
++meta_button_state_for_button_type (decor_t *d,
++ MetaButtonType type)
+ {
+- switch (type) {
++ switch (type)
++ {
+ case META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND:
+- type = meta_function_to_type (meta_button_layout.left_buttons[0]);
+- break;
++ type = meta_function_to_type (meta_button_layout.left_buttons[0]);
++ break;
+ case META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND:
+- type = meta_function_to_type (meta_button_layout.left_buttons[1]);
+- break;
++ type = meta_function_to_type (meta_button_layout.left_buttons[1]);
++ break;
+ case META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND:
+- type = meta_function_to_type (meta_button_layout.left_buttons[2]);
+- break;
++ type = meta_function_to_type (meta_button_layout.left_buttons[2]);
++ break;
+ case META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND:
+- type = meta_function_to_type (meta_button_layout.right_buttons[0]);
+- break;
++ type = meta_function_to_type (meta_button_layout.right_buttons[0]);
++ break;
+ case META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND:
+- type = meta_function_to_type (meta_button_layout.right_buttons[1]);
+- break;
++ type = meta_function_to_type (meta_button_layout.right_buttons[1]);
++ break;
+ case META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND:
+- type = meta_function_to_type (meta_button_layout.right_buttons[2]);
++ type = meta_function_to_type (meta_button_layout.right_buttons[2]);
+ default:
+- break;
++ break;
+ }
+
+- switch (type) {
++ switch (type)
++ {
+ case META_BUTTON_TYPE_CLOSE:
+- return meta_button_state (d->button_states[BUTTON_CLOSE]);
++ return meta_button_state (d->button_states[BUTTON_CLOSE]);
+ case META_BUTTON_TYPE_MAXIMIZE:
+- return meta_button_state (d->button_states[BUTTON_MAX]);
++ return meta_button_state (d->button_states[BUTTON_MAX]);
+ case META_BUTTON_TYPE_MINIMIZE:
+- return meta_button_state (d->button_states[BUTTON_MIN]);
++ return meta_button_state (d->button_states[BUTTON_MIN]);
+ case META_BUTTON_TYPE_MENU:
+- return meta_button_state (d->button_states[BUTTON_MENU]);
++ return meta_button_state (d->button_states[BUTTON_MENU]);
+ case META_BUTTON_TYPE_SHADE:
+- return meta_button_state (d->button_states[BUTTON_SHADE]);
++ return meta_button_state (d->button_states[BUTTON_SHADE]);
+ case META_BUTTON_TYPE_ABOVE:
+- return meta_button_state (d->button_states[BUTTON_ABOVE]);
++ return meta_button_state (d->button_states[BUTTON_ABOVE]);
+ case META_BUTTON_TYPE_STICK:
+- return meta_button_state (d->button_states[BUTTON_STICK]);
++ return meta_button_state (d->button_states[BUTTON_STICK]);
+ case META_BUTTON_TYPE_UNSHADE:
+- return meta_button_state (d->button_states[BUTTON_UNSHADE]);
++ return meta_button_state (d->button_states[BUTTON_UNSHADE]);
+ case META_BUTTON_TYPE_UNABOVE:
+- return meta_button_state (d->button_states[BUTTON_UNABOVE]);
++ return meta_button_state (d->button_states[BUTTON_UNABOVE]);
+ case META_BUTTON_TYPE_UNSTICK:
+- return meta_button_state (d->button_states[BUTTON_UNSTICK]);
++ return meta_button_state (d->button_states[BUTTON_UNSTICK]);
+ default:
+- break;
++ break;
+ }
+
+ return META_BUTTON_STATE_NORMAL;
+ }
+
+-void
+-meta_get_decoration_geometry (decor_t *d,
+- MetaTheme *theme,
+- MetaFrameFlags *flags,
+- MetaFrameGeometry *fgeom,
+- MetaButtonLayout *button_layout,
+- MetaFrameType frame_type,
+- GdkRectangle *clip)
++static void
++meta_get_decoration_geometry (decor_t *d,
++ MetaTheme *theme,
++ MetaFrameFlags *flags,
++ MetaFrameGeometry *fgeom,
++ MetaButtonLayout *button_layout,
++ MetaFrameType frame_type)
+ {
+-#ifdef HAVE_METACITY_3_14_0
+- MetaFrameBorders borders;
+-#endif
+- gint left_width, right_width, top_height, bottom_height;
++ gint client_width;
++ gint client_height;
+
+ if (!(frame_type < META_FRAME_TYPE_LAST))
+- frame_type = META_FRAME_TYPE_NORMAL;
++ frame_type = META_FRAME_TYPE_NORMAL;
+
+ if (meta_button_layout_set)
+ {
+- *button_layout = meta_button_layout;
++ *button_layout = meta_button_layout;
+ }
+ else
+ {
+- gint i;
++ gint i;
+
+- button_layout->left_buttons[0] = META_BUTTON_FUNCTION_MENU;
++ button_layout->left_buttons[0] = META_BUTTON_FUNCTION_MENU;
+
+- for (i = 1; i < MAX_BUTTONS_PER_CORNER; ++i)
+- button_layout->left_buttons[i] = META_BUTTON_FUNCTION_LAST;
++ for (i = 1; i < MAX_BUTTONS_PER_CORNER; ++i)
++ button_layout->left_buttons[i] = META_BUTTON_FUNCTION_LAST;
+
+- button_layout->right_buttons[0] = META_BUTTON_FUNCTION_MINIMIZE;
+- button_layout->right_buttons[1] = META_BUTTON_FUNCTION_MAXIMIZE;
+- button_layout->right_buttons[2] = META_BUTTON_FUNCTION_CLOSE;
++ button_layout->right_buttons[0] = META_BUTTON_FUNCTION_MINIMIZE;
++ button_layout->right_buttons[1] = META_BUTTON_FUNCTION_MAXIMIZE;
++ button_layout->right_buttons[2] = META_BUTTON_FUNCTION_CLOSE;
+
+- for (i = 3; i < MAX_BUTTONS_PER_CORNER; ++i)
+- button_layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST;
++ for (i = 3; i < MAX_BUTTONS_PER_CORNER; ++i)
++ button_layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST;
+ }
+
+ *flags = 0;
+
+ if (d->actions & WNCK_WINDOW_ACTION_CLOSE)
+- *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_DELETE;
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_DELETE;
+
+ if (d->actions & WNCK_WINDOW_ACTION_MINIMIZE)
+- *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MINIMIZE;
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MINIMIZE;
+
+ if (d->actions & WNCK_WINDOW_ACTION_MAXIMIZE)
+- *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MAXIMIZE;
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MAXIMIZE;
+
+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MENU;
+
+ if (d->actions & WNCK_WINDOW_ACTION_RESIZE)
+ {
+- if (!(d->state & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY))
+- *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_VERTICAL_RESIZE;
+- if (!(d->state & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY))
+- *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_HORIZONTAL_RESIZE;
++ if (!(d->state & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY))
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_VERTICAL_RESIZE;
++ if (!(d->state & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY))
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_HORIZONTAL_RESIZE;
+ }
+
+ if (d->actions & WNCK_WINDOW_ACTION_MOVE)
+- *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MOVE;
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MOVE;
+
+ if (d->actions & WNCK_WINDOW_ACTION_MAXIMIZE)
+- *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MAXIMIZE;
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MAXIMIZE;
+
+ if (d->actions & WNCK_WINDOW_ACTION_SHADE)
+- *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_SHADE;
++ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_SHADE;
+
+ if (d->active)
+- *flags |= (MetaFrameFlags ) META_FRAME_HAS_FOCUS;
++ *flags |= (MetaFrameFlags ) META_FRAME_HAS_FOCUS;
+
+ if ((d->state & META_MAXIMIZED) == META_MAXIMIZED)
+- *flags |= (MetaFrameFlags ) META_FRAME_MAXIMIZED;
++ *flags |= (MetaFrameFlags ) META_FRAME_MAXIMIZED;
+
+ if (d->state & WNCK_WINDOW_STATE_STICKY)
+- *flags |= (MetaFrameFlags ) META_FRAME_STUCK;
++ *flags |= (MetaFrameFlags ) META_FRAME_STUCK;
+
+ if (d->state & WNCK_WINDOW_STATE_FULLSCREEN)
+- *flags |= (MetaFrameFlags ) META_FRAME_FULLSCREEN;
++ *flags |= (MetaFrameFlags ) META_FRAME_FULLSCREEN;
+
+ if (d->state & WNCK_WINDOW_STATE_SHADED)
+- *flags |= (MetaFrameFlags ) META_FRAME_SHADED;
++ *flags |= (MetaFrameFlags ) META_FRAME_SHADED;
+
+ if (d->state & WNCK_WINDOW_STATE_ABOVE)
+- *flags |= (MetaFrameFlags ) META_FRAME_ABOVE;
+-
+-#ifdef HAVE_METACITY_3_14_0
+- meta_theme_get_frame_borders (theme,
+- frame_type,
+- d->frame->text_height,
+- *flags,
+- &borders);
+- top_height = borders.visible.top;
+- bottom_height = borders.visible.bottom;
+- left_width = borders.visible.left;
+- right_width = borders.visible.right;
+-#else
+- meta_theme_get_frame_borders (theme,
+- frame_type,
+- d->frame->text_height,
+- *flags,
+- &top_height,
+- &bottom_height,
+- &left_width,
+- &right_width);
+-#endif
++ *flags |= (MetaFrameFlags ) META_FRAME_ABOVE;
+
+- clip->x = d->context->left_space - left_width;
+- clip->y = d->context->top_space - top_height;
+-
+- clip->width = d->border_layout.top.x2 - d->border_layout.top.x1;
+- clip->width -= d->context->right_space + d->context->left_space;
++ client_width = d->border_layout.top.x2 - d->border_layout.top.x1;
++ client_width -= d->context->right_space + d->context->left_space;
+
+ if (d->border_layout.rotation)
+- clip->height = d->border_layout.left.x2 - d->border_layout.left.x1;
++ client_height = d->border_layout.left.x2 - d->border_layout.left.x1;
+ else
+- clip->height = d->border_layout.left.y2 - d->border_layout.left.y1;
+-
+- meta_theme_calc_geometry (theme,
+- frame_type,
+- d->frame->text_height,
+- *flags,
+- clip->width,
+- clip->height,
+- button_layout,
+- fgeom);
++ client_height = d->border_layout.left.y2 - d->border_layout.left.y1;
+
+- clip->width += left_width + right_width;
+- clip->height += top_height + bottom_height;
++ meta_theme_calc_geometry (theme, frame_type, d->frame->text_height,
++ *flags, client_width, client_height,
++ button_layout, fgeom);
+ }
+
+ void
+ meta_draw_window_decoration (decor_t *d)
+ {
+- Display *xdisplay =
+- GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
++ GdkDisplay *display;
++ Display *xdisplay;
+ cairo_surface_t *surface;
+- Picture src;
+- MetaButtonState button_states [META_BUTTON_TYPE_LAST];
+- MetaButtonLayout button_layout;
++ Picture src;
++ MetaButtonState button_states [META_BUTTON_TYPE_LAST];
++ MetaButtonLayout button_layout;
+ MetaFrameGeometry fgeom;
+- MetaFrameFlags flags;
+- MetaFrameType frame_type;
+- MetaTheme *theme;
++ MetaFrameFlags flags;
++ MetaFrameType frame_type;
++ MetaTheme *theme;
+ GtkStyleContext *context;
+- cairo_t *cr;
+- gint i;
+- GdkRectangle clip;
+- Region top_region = NULL;
+- Region bottom_region = NULL;
+- Region left_region = NULL;
+- Region right_region = NULL;
+- gdouble meta_active_opacity, meta_inactive_opacity;
+- gboolean meta_active_shade_opacity, meta_inactive_shade_opacity;
++ cairo_t *cr;
++ gint i;
++ Region top_region;
++ Region bottom_region;
++ Region left_region;
++ Region right_region;
++ gdouble meta_active_opacity;
++ gdouble meta_inactive_opacity;
++ gboolean meta_active_shade_opacity;
++ gboolean meta_inactive_shade_opacity;
++ double alpha;
++ gboolean shade_alpha;
++ MetaFrameStyle *frame_style;
++ GtkWidget *style_window;
++ GdkRGBA bg_rgba;
++
++ if (!d->surface || !d->picture)
++ return;
++
++ display = gdk_display_get_default ();
++ xdisplay = gdk_x11_display_get_xdisplay (display);
++
++ top_region = NULL;
++ bottom_region = NULL;
++ left_region = NULL;
++ right_region = NULL;
+
+ g_object_get (settings, "metacity-active-opacity", &meta_active_opacity, NULL);
+ g_object_get (settings, "metacity-inactive-opacity", &meta_inactive_opacity, NULL);
+ g_object_get (settings, "metacity-active-shade-opacity", &meta_active_shade_opacity, NULL);
+ g_object_get (settings, "metacity-inactive-shade-opacity", &meta_inactive_shade_opacity, NULL);
+
+- double alpha = (d->active) ? meta_active_opacity : meta_inactive_opacity;
+- gboolean shade_alpha = (d->active) ? meta_active_shade_opacity :
+- meta_inactive_shade_opacity;
+- MetaFrameStyle *frame_style;
+- GtkWidget *style_window;
+- GdkRGBA bg_rgba;
+-
+- if (!d->surface || !d->picture)
+- return;
++ alpha = (d->active) ? meta_active_opacity : meta_inactive_opacity;
++ shade_alpha = (d->active) ? meta_active_shade_opacity : meta_inactive_shade_opacity;
+
+ if (decoration_alpha == 1.0)
+- alpha = 1.0;
++ alpha = 1.0;
+
+ if (cairo_xlib_surface_get_depth (d->surface) == 32)
+- {
+- context = gtk_widget_get_style_context (d->frame->style_window_rgba);
+- style_window = d->frame->style_window_rgba;
+- }
++ style_window = d->frame->style_window_rgba;
+ else
+- {
+- context = gtk_widget_get_style_context (d->frame->style_window_rgb);
+- style_window = d->frame->style_window_rgb;
+- }
++ style_window = d->frame->style_window_rgb;
++
++ context = gtk_widget_get_style_context (style_window);
+
+ cr = cairo_create (d->buffer_surface ? d->buffer_surface : d->surface);
+
+@@ -635,31 +635,28 @@
+ frame_type = meta_frame_type_from_string (d->frame->type);
+
+ if (frame_type == META_FRAME_TYPE_LAST)
+- frame_type = META_FRAME_TYPE_NORMAL;
++ frame_type = META_FRAME_TYPE_NORMAL;
+
+ meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
+- frame_type, &clip);
++ frame_type);
+
+ if ((d->prop_xid || !d->buffer_surface) && !d->frame_window)
+- draw_shadow_background (d, cr, d->shadow, d->context);
++ draw_shadow_background (d, cr, d->shadow, d->context);
+
+ for (i = 0; i < META_BUTTON_TYPE_LAST; ++i)
+- button_states[i] = meta_button_state_for_button_type (d, i);
++ button_states[i] = meta_button_state_for_button_type (d, i);
+
+- frame_style = meta_theme_get_frame_style (theme,
+- frame_type,
+- flags);
++ frame_style = meta_theme_get_frame_style (theme, frame_type, flags);
+
+ gtk_style_context_get_background_color (context, GTK_STATE_FLAG_NORMAL, &bg_rgba);
+ bg_rgba.alpha = 1.0;
+
+ if (frame_style->window_background_color)
+ {
+- meta_color_spec_render (frame_style->window_background_color,
+- gtk_widget_get_style_context (style_window),
+- &bg_rgba);
++ meta_color_spec_render (frame_style->window_background_color,
++ context, &bg_rgba);
+
+- bg_rgba.alpha = frame_style->window_background_alpha / 255.0;
++ bg_rgba.alpha = frame_style->window_background_alpha / 255.0;
+ }
+
+ /* Draw something that will be almost invisible to user. This is hacky way
+@@ -671,152 +668,123 @@
+
+ cairo_destroy (cr);
+
+- if (d->frame_window)
+- surface = create_surface (clip.width, clip.height, d->frame->style_window_rgb);
+- else
+- surface = create_surface (clip.width, clip.height, d->frame->style_window_rgba);
+-
+- cr = cairo_create (surface);
+- gdk_cairo_set_source_rgba (cr, &bg_rgba);
+- cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
++ if (d->frame_window)
++ surface = create_surface (fgeom.width, fgeom.height, d->frame->style_window_rgb);
++ else
++ surface = create_surface (fgeom.width, fgeom.height, d->frame->style_window_rgba);
++
++ cr = cairo_create (surface);
++ gdk_cairo_set_source_rgba (cr, &bg_rgba);
++ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+- src = XRenderCreatePicture (xdisplay, cairo_xlib_surface_get_drawable (surface),
++ src = XRenderCreatePicture (xdisplay, cairo_xlib_surface_get_drawable (surface),
+ get_format_for_surface (d, surface), 0, NULL);
+
+ cairo_paint (cr);
+- meta_theme_draw_frame (theme,
+- style_window,
+- cr,
+- frame_type,
+- flags,
+- clip.width - fgeom.left_width - fgeom.right_width,
+- clip.height - fgeom.top_height - fgeom.bottom_height,
+- d->layout,
+- d->frame->text_height,
+- &button_layout,
+- button_states,
+- d->icon_pixbuf,
+- NULL);
++ meta_theme_draw_frame (theme, style_window, cr, frame_type, flags,
++ fgeom.width - fgeom.left_width - fgeom.right_width,
++ fgeom.height - fgeom.top_height - fgeom.bottom_height,
++ d->layout, d->frame->text_height, &button_layout,
++ button_states, d->icon_pixbuf, NULL);
+
+ if (fgeom.top_height)
+- {
+- top_region = meta_get_top_border_region (&fgeom, clip.width);
+-
+- decor_blend_border_picture (xdisplay,
+- d->context,
+- src,
+- 0, 0,
+- d->picture,
+- &d->border_layout,
+- BORDER_TOP,
+- top_region,
+- alpha * 0xffff,
+- shade_alpha,
+- 0);
+- }
++ {
++ top_region = meta_get_top_border_region (&fgeom, fgeom.width);
+
+- if (fgeom.bottom_height)
+- {
+- bottom_region = meta_get_bottom_border_region (&fgeom, clip.width);
++ decor_blend_border_picture (xdisplay, d->context, src,
++ 0, 0,
++ d->picture, &d->border_layout,
++ BORDER_TOP, top_region,
++ alpha * 0xffff, shade_alpha, 0);
++ }
+
+- decor_blend_border_picture (xdisplay,
+- d->context,
+- src,
+- 0, clip.height - fgeom.bottom_height,
+- d->picture,
+- &d->border_layout,
+- BORDER_BOTTOM,
+- bottom_region,
+- alpha * 0xffff,
+- shade_alpha,
+- 0);
++ if (fgeom.bottom_height)
++ {
++ bottom_region = meta_get_bottom_border_region (&fgeom, fgeom.width);
+
+- }
++ decor_blend_border_picture (xdisplay, d->context, src,
++ 0, fgeom.height - fgeom.bottom_height,
++ d->picture, &d->border_layout,
++ BORDER_BOTTOM, bottom_region,
++ alpha * 0xffff, shade_alpha, 0);
++ }
+
+- if (fgeom.left_width)
+- {
+- left_region = meta_get_left_border_region (&fgeom, clip.height);
++ if (fgeom.left_width)
++ {
++ left_region = meta_get_left_border_region (&fgeom, fgeom.height);
+
+- decor_blend_border_picture (xdisplay,
+- d->context,
+- src,
+- 0, fgeom.top_height,
+- d->picture,
+- &d->border_layout,
+- BORDER_LEFT,
+- left_region,
+- alpha * 0xffff,
+- shade_alpha,
+- 0);
+- }
++ decor_blend_border_picture (xdisplay, d->context, src,
++ 0, fgeom.top_height,
++ d->picture, &d->border_layout,
++ BORDER_LEFT, left_region,
++ alpha * 0xffff, shade_alpha, 0);
++ }
+
+- if (fgeom.right_width)
+- {
+- right_region = meta_get_right_border_region (&fgeom, clip.height);
++ if (fgeom.right_width)
++ {
++ right_region = meta_get_right_border_region (&fgeom, fgeom.height);
+
+- decor_blend_border_picture (xdisplay,
+- d->context,
+- src,
+- clip.width - fgeom.right_width, fgeom.top_height,
+- d->picture,
+- &d->border_layout,
+- BORDER_RIGHT,
+- right_region,
+- alpha * 0xffff,
+- shade_alpha,
+- 0);
+- }
++ decor_blend_border_picture (xdisplay, d->context, src,
++ fgeom.width - fgeom.right_width, fgeom.top_height,
++ d->picture, &d->border_layout,
++ BORDER_RIGHT, right_region,
++ alpha * 0xffff, shade_alpha, 0);
++ }
+
+- cairo_destroy (cr);
+- cairo_surface_destroy (surface);
+- XRenderFreePicture (xdisplay, src);
++ cairo_destroy (cr);
++ cairo_surface_destroy (surface);
++ XRenderFreePicture (xdisplay, src);
+
+ copy_to_front_buffer (d);
+
+ if (d->frame_window)
+ {
+- GdkWindow *gdk_frame_window = gtk_widget_get_window (d->decor_window);
+- GdkPixbuf *pixbuf = gdk_pixbuf_get_from_surface (d->surface, 0, 0, d->width, d->height);
++ GdkWindow *gdk_frame_window;
++ GdkPixbuf *pixbuf;
+
+- gtk_image_set_from_pixbuf (GTK_IMAGE (d->decor_image), pixbuf);
+- g_object_unref (pixbuf);
++ gdk_frame_window = gtk_widget_get_window (d->decor_window);
+
+- gtk_window_resize (GTK_WINDOW (d->decor_window), d->width, d->height);
+- gdk_window_move (gdk_frame_window,
+- d->context->left_corner_space - 1,
+- d->context->top_corner_space - 1);
+- gdk_window_lower (gdk_frame_window);
++ pixbuf = gdk_pixbuf_get_from_surface (d->surface, 0, 0, d->width, d->height);
++ gtk_image_set_from_pixbuf (GTK_IMAGE (d->decor_image), pixbuf);
++ g_object_unref (pixbuf);
++
++ gdk_window_move_resize (gdk_frame_window,
++ d->context->left_corner_space - 1,
++ d->context->top_corner_space - 1,
++ d->width,
++ d->height);
++
++ gdk_window_lower (gdk_frame_window);
+ }
+
+ if (d->prop_xid)
+ {
+- /* translate from frame to client window space */
+- if (top_region)
+- XOffsetRegion (top_region, -fgeom.left_width, -fgeom.top_height);
+- if (bottom_region)
+- XOffsetRegion (bottom_region, -fgeom.left_width, 0);
+- if (left_region)
+- XOffsetRegion (left_region, -fgeom.left_width, 0);
+-
+- decor_update_meta_window_property (d, theme, flags,
+- top_region,
+- bottom_region,
+- left_region,
+- right_region);
+- d->prop_xid = 0;
++ /* translate from frame to client window space */
++ if (top_region)
++ XOffsetRegion (top_region, -fgeom.left_width, -fgeom.top_height);
++ if (bottom_region)
++ XOffsetRegion (bottom_region, -fgeom.left_width, 0);
++ if (left_region)
++ XOffsetRegion (left_region, -fgeom.left_width, 0);
++
++ decor_update_meta_window_property (d, theme, flags,
++ top_region, bottom_region,
++ left_region, right_region);
++
++ d->prop_xid = 0;
+ }
+
+ if (top_region)
+- XDestroyRegion (top_region);
++ XDestroyRegion (top_region);
+ if (bottom_region)
+- XDestroyRegion (bottom_region);
++ XDestroyRegion (bottom_region);
+ if (left_region)
+- XDestroyRegion (left_region);
++ XDestroyRegion (left_region);
+ if (right_region)
+- XDestroyRegion (right_region);
++ XDestroyRegion (right_region);
+ }
+
+-void
++static void
+ meta_calc_button_size (decor_t *d)
+ {
+ gint i, min_x, x, y, w, h, width;
+@@ -959,19 +927,15 @@
+
+ if (d->frame_window)
+ {
+- *x += d->frame->win_extents.left + 4;
+- *y += d->frame->win_extents.top + 2;
++ *x += d->frame->win_extents.left + 4;
++ *y += d->frame->win_extents.top + 2;
+ }
+
+ if (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE)
+- {
+- *x += mutter_draggable_border_width;
+- }
++ *x += mutter_draggable_border_width;
+
+ if (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE)
+- {
+- *y += mutter_draggable_border_width;
+- }
++ *y += mutter_draggable_border_width;
+
+ return TRUE;
+ }
+@@ -979,14 +943,16 @@
+ gfloat
+ meta_get_title_scale (decor_frame_t *frame)
+ {
+- MetaTheme *theme = meta_theme_get_current ();
+- MetaFrameType type;
+- MetaFrameFlags flags = 0xc33; /* fixme */
++ MetaTheme *theme;
++ MetaFrameType type;
++ MetaFrameFlags flags;
+
++ theme = meta_theme_get_current ();
+ type = meta_frame_type_from_string (frame->type);
++ flags = 0xc33; /* fixme */
+
+ if (type == META_FRAME_TYPE_LAST)
+- return 1.0f;
++ return 1.0f;
+
+ gfloat scale = meta_theme_get_title_scale (theme, type, flags);
+
+@@ -995,381 +961,367 @@
+
+ gboolean
+ meta_calc_decoration_size (decor_t *d,
+- gint w,
+- gint h,
+- gint name_width,
+- gint *width,
+- gint *height)
++ gint w,
++ gint h,
++ gint name_width,
++ gint *width,
++ gint *height)
+ {
+- decor_layout_t layout;
++ decor_layout_t layout;
+ decor_context_t *context;
+- decor_shadow_t *shadow;
++ decor_shadow_t *shadow;
+
+ if (!d->decorated)
+- return FALSE;
++ return FALSE;
+
+ if ((d->state & META_MAXIMIZED) == META_MAXIMIZED)
+ {
+- if (!d->frame_window)
+- {
+- if (d->active)
+- {
+- context = &d->frame->max_window_context_active;
+- shadow = d->frame->max_border_shadow_active;
+- }
+- else
+- {
+- context = &d->frame->max_window_context_inactive;
+- shadow = d->frame->max_border_shadow_inactive;
+- }
+- }
+- else
+- {
+- context = &d->frame->max_window_context_no_shadow;
+- shadow = d->frame->max_border_no_shadow;
+- }
++ if (!d->frame_window)
++ {
++ if (d->active)
++ {
++ context = &d->frame->max_window_context_active;
++ shadow = d->frame->max_border_shadow_active;
++ }
++ else
++ {
++ context = &d->frame->max_window_context_inactive;
++ shadow = d->frame->max_border_shadow_inactive;
++ }
++ }
++ else
++ {
++ context = &d->frame->max_window_context_no_shadow;
++ shadow = d->frame->max_border_no_shadow;
++ }
+ }
+ else
+ {
+- if (!d->frame_window)
+- {
+- if (d->active)
+- {
+- context = &d->frame->window_context_active;
+- shadow = d->frame->border_shadow_active;
+- }
+- else
+- {
+- context = &d->frame->window_context_inactive;
+- shadow = d->frame->border_shadow_inactive;
+- }
+- }
+- else
+- {
+- context = &d->frame->window_context_no_shadow;
+- shadow = d->frame->border_no_shadow;
+- }
++ if (!d->frame_window)
++ {
++ if (d->active)
++ {
++ context = &d->frame->window_context_active;
++ shadow = d->frame->border_shadow_active;
++ }
++ else
++ {
++ context = &d->frame->window_context_inactive;
++ shadow = d->frame->border_shadow_inactive;
++ }
++ }
++ else
++ {
++ context = &d->frame->window_context_no_shadow;
++ shadow = d->frame->border_no_shadow;
++ }
+ }
+
+ if (!d->frame_window)
+ {
+- decor_get_best_layout (context, w, h, &layout);
++ decor_get_best_layout (context, w, h, &layout);
+
+- if (context != d->context ||
+- memcmp (&layout, &d->border_layout, sizeof (layout)))
+- {
+- *width = layout.width;
+- *height = layout.height;
++ if (context != d->context || memcmp (&layout, &d->border_layout, sizeof (layout)))
++ {
++ *width = layout.width;
++ *height = layout.height;
+
+- d->border_layout = layout;
+- d->context = context;
+- d->shadow = shadow;
++ d->border_layout = layout;
++ d->context = context;
++ d->shadow = shadow;
+
+- meta_calc_button_size (d);
++ meta_calc_button_size (d);
+
+- return TRUE;
+- }
++ return TRUE;
++ }
+ }
+ else
+ {
+- if ((d->state & META_MAXIMIZED) == META_MAXIMIZED)
+- decor_get_default_layout (context, d->client_width,
+- d->client_height - d->frame->titlebar_height,
+- &layout);
+- else
+- decor_get_default_layout (context, d->client_width,
+- d->client_height, &layout);
+-
+- *width = layout.width;
+- *height = layout.height;
+-
+- d->border_layout = layout;
+- d->shadow = shadow;
+- d->context = context;
++ if ((d->state & META_MAXIMIZED) == META_MAXIMIZED)
++ decor_get_default_layout (context, d->client_width,
++ d->client_height - d->frame->titlebar_height,
++ &layout);
++ else
++ decor_get_default_layout (context, d->client_width,
++ d->client_height, &layout);
++
++ *width = layout.width;
++ *height = layout.height;
++
++ d->border_layout = layout;
++ d->shadow = shadow;
++ d->context = context;
+
+- meta_calc_button_size (d);
++ meta_calc_button_size (d);
+
+- return TRUE;
++ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+-gboolean
+-meta_button_present (MetaButtonLayout *button_layout,
+- MetaButtonFunction function)
+-{
+- int i;
+-
+- for (i = 0; i < MAX_BUTTONS_PER_CORNER; ++i)
+- if (button_layout->left_buttons[i] == function)
+- return TRUE;
+-
+- for (i = 0; i < MAX_BUTTONS_PER_CORNER; ++i)
+- if (button_layout->right_buttons[i] == function)
+- return TRUE;
+-
+- return FALSE;
+-}
+-
+ #define TOP_RESIZE_HEIGHT 2
+ #define RESIZE_EXTENDS 15
+
+ 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)
++ gint i,
++ gint j,
++ gint width,
++ gint height,
++ gint *x,
++ gint *y,
++ gint *w,
++ gint *h)
+ {
+- MetaButtonLayout button_layout;
++ MetaButtonLayout button_layout;
+ MetaFrameGeometry fgeom;
+- MetaFrameFlags flags;
+- MetaTheme *theme;
+- GdkRectangle clip;
+-
+- gint mutter_draggable_border_width = 0;
++ MetaFrameFlags flags;
++ MetaTheme *theme;
++ gint mutter_draggable_border_width;
+
++ mutter_draggable_border_width = 0;
+ g_object_get (settings, "draggable-border-width", &mutter_draggable_border_width, NULL);
+
+ theme = meta_theme_get_current ();
+
+ meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
+- meta_frame_type_from_string (d->frame->type),
+- &clip);
++ meta_frame_type_from_string (d->frame->type));
+
+- width += fgeom.right_width + fgeom.left_width;
+- height += fgeom.top_height + fgeom.bottom_height;
++ width += fgeom.right_width + fgeom.left_width;
++ height += fgeom.top_height + fgeom.bottom_height;
+
+- switch (i) {
++ switch (i)
++ {
+ case 2: /* bottom */
+- switch (j) {
+- case 2: /* bottom right */
+- if (d->frame_window)
+- {
+- *x = width - fgeom.right_width - RESIZE_EXTENDS +
+- d->frame->win_extents.left + 2;
+- *y = height - fgeom.bottom_height - RESIZE_EXTENDS +
+- d->frame->win_extents.top + 2;
+- }
+- else
+- {
+- *x = width - fgeom.right_width - RESIZE_EXTENDS;
+- *y = height - fgeom.bottom_height - RESIZE_EXTENDS;
+- }
+- *w = fgeom.right_width + RESIZE_EXTENDS;
+- *h = fgeom.bottom_height + RESIZE_EXTENDS;
++ switch (j)
++ {
++ case 2: /* bottom right */
++ if (d->frame_window)
++ {
++ *x = width - fgeom.right_width - RESIZE_EXTENDS +
++ d->frame->win_extents.left + 2;
++ *y = height - fgeom.bottom_height - RESIZE_EXTENDS +
++ d->frame->win_extents.top + 2;
++ }
++ else
++ {
++ *x = width - fgeom.right_width - RESIZE_EXTENDS;
++ *y = height - fgeom.bottom_height - RESIZE_EXTENDS;
++ }
+
+- if (!d->frame_window)
+- {
+- *x += mutter_draggable_border_width;
+- *y += mutter_draggable_border_width;
+- *w += mutter_draggable_border_width;
+- *h += mutter_draggable_border_width;
+- }
++ *w = fgeom.right_width + RESIZE_EXTENDS;
++ *h = fgeom.bottom_height + RESIZE_EXTENDS;
+
+- break;
+- case 1: /* bottom */
+- *x = fgeom.left_width + RESIZE_EXTENDS;
+- *y = height - fgeom.bottom_height;
+- if (d->frame_window)
+- *y += d->frame->win_extents.top + 2;
+- *w = width - fgeom.left_width - fgeom.right_width -
+- (2 * RESIZE_EXTENDS);
+- *h = fgeom.bottom_height;
++ if (!d->frame_window)
++ {
++ *x += mutter_draggable_border_width;
++ *y += mutter_draggable_border_width;
++ *w += mutter_draggable_border_width;
++ *h += mutter_draggable_border_width;
++ }
++ break;
++ case 1: /* bottom */
++ *x = fgeom.left_width + RESIZE_EXTENDS;
++ *y = height - fgeom.bottom_height;
+
+- if (!d->frame_window)
+- {
+- *x -= mutter_draggable_border_width;
+- *y += mutter_draggable_border_width;
+- *h += mutter_draggable_border_width;
+- *w += mutter_draggable_border_width * 2;
+- }
++ if (d->frame_window)
++ *y += d->frame->win_extents.top + 2;
+
+- break;
+- case 0: /* bottom left */
+- default:
+- *x = 0;
+- *y = height - fgeom.bottom_height - RESIZE_EXTENDS;
+- if (d->frame_window)
+- {
+- *x += d->frame->win_extents.left + 4;
+- *y += d->frame->win_extents.bottom + 2;
+- }
+- *w = fgeom.left_width + RESIZE_EXTENDS;
+- *h = fgeom.bottom_height + RESIZE_EXTENDS;
++ *w = width - fgeom.left_width - fgeom.right_width - (2 * RESIZE_EXTENDS);
++ *h = fgeom.bottom_height;
+
+- if (!d->frame_window)
+- {
+- *y += mutter_draggable_border_width;
+- *w += mutter_draggable_border_width;
+- *h += mutter_draggable_border_width;
+- }
++ if (!d->frame_window)
++ {
++ *x -= mutter_draggable_border_width;
++ *y += mutter_draggable_border_width;
++ *h += mutter_draggable_border_width;
++ *w += mutter_draggable_border_width * 2;
++ }
++ break;
++ case 0: /* bottom left */
++ default:
++ *x = 0;
++ *y = height - fgeom.bottom_height - RESIZE_EXTENDS;
+
+- break;
+- }
+- break;
++ if (d->frame_window)
++ {
++ *x += d->frame->win_extents.left + 4;
++ *y += d->frame->win_extents.bottom + 2;
++ }
++
++ *w = fgeom.left_width + RESIZE_EXTENDS;
++ *h = fgeom.bottom_height + RESIZE_EXTENDS;
++
++ if (!d->frame_window)
++ {
++ *y += mutter_draggable_border_width;
++ *w += mutter_draggable_border_width;
++ *h += mutter_draggable_border_width;
++ }
++ break;
++ }
++ break;
+ case 1: /* middle */
+- switch (j) {
+- case 2: /* right */
+- *x = width - fgeom.right_width;
+- *y = fgeom.top_height + RESIZE_EXTENDS;
+- if (d->frame_window)
+- *x += d->frame->win_extents.left + 2;
+- *w = fgeom.right_width;
+- *h = height - fgeom.top_height - fgeom.bottom_height -
+- (2 * RESIZE_EXTENDS);
+-
+- if (!d->frame_window)
+- {
+- *x += mutter_draggable_border_width;
+- *y += mutter_draggable_border_width;
+- *w += mutter_draggable_border_width;
+- *h += mutter_draggable_border_width;
+- }
+-
+-
+- break;
+- case 1: /* middle */
+- *x = fgeom.left_width;
+- *y = fgeom.title_rect.y + TOP_RESIZE_HEIGHT;
+- *w = width - fgeom.left_width - fgeom.right_width;
+- *h = height - fgeom.top_titlebar_edge - fgeom.bottom_height;
++ switch (j)
++ {
++ case 2: /* right */
++ *x = width - fgeom.right_width;
++ *y = fgeom.top_height + RESIZE_EXTENDS;
+
+- if (!d->frame_window)
+- {
+- *x += mutter_draggable_border_width;
+- if (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE)
+- *y += mutter_draggable_border_width;
+- }
++ if (d->frame_window)
++ *x += d->frame->win_extents.left + 2;
+
+- break;
+- case 0: /* left */
+- default:
+- *x = 0;
+- if (d->frame_window)
+- *x += d->frame->win_extents.left + 4;
+- *y = fgeom.top_height + RESIZE_EXTENDS;
+- *w = fgeom.left_width;
+- *h = height - fgeom.top_height - fgeom.bottom_height -
+- (2 * RESIZE_EXTENDS);
++ *w = fgeom.right_width;
++ *h = height - fgeom.top_height - fgeom.bottom_height - (2 * RESIZE_EXTENDS);
+
+- if (!d->frame_window)
+- {
+- *y += mutter_draggable_border_width;
+- *h += mutter_draggable_border_width;
+- *w += mutter_draggable_border_width;
+- }
++ if (!d->frame_window)
++ {
++ *x += mutter_draggable_border_width;
++ *y += mutter_draggable_border_width;
++ *w += mutter_draggable_border_width;
++ *h += mutter_draggable_border_width;
++ }
++ break;
++ case 1: /* middle */
++ *x = fgeom.left_width;
++ *y = fgeom.title_rect.y + TOP_RESIZE_HEIGHT;
++ *w = width - fgeom.left_width - fgeom.right_width;
++ *h = height - fgeom.top_titlebar_edge - fgeom.bottom_height;
+
++ if (!d->frame_window)
++ {
++ *x += mutter_draggable_border_width;
+
+- break;
+- }
+- break;
++ if (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE)
++ *y += mutter_draggable_border_width;
++ }
++ break;
++ case 0: /* left */
++ default:
++ *x = 0;
++
++ if (d->frame_window)
++ *x += d->frame->win_extents.left + 4;
++
++ *y = fgeom.top_height + RESIZE_EXTENDS;
++ *w = fgeom.left_width;
++ *h = height - fgeom.top_height - fgeom.bottom_height - (2 * RESIZE_EXTENDS);
++
++ if (!d->frame_window)
++ {
++ *y += mutter_draggable_border_width;
++ *h += mutter_draggable_border_width;
++ *w += mutter_draggable_border_width;
++ }
++ break;
++ }
++ break;
+ case 0: /* top */
+ default:
+- switch (j) {
+- case 2: /* top right */
+- *x = width - fgeom.right_width - RESIZE_EXTENDS;
+- *y = 0;
+- if (d->frame_window)
+- {
+- *x += d->frame->win_extents.left + 2;
+- *y += d->frame->win_extents.top + 2 - fgeom.title_rect.height;
+- }
+- *w = fgeom.right_width + RESIZE_EXTENDS;
+- *h = fgeom.top_height + RESIZE_EXTENDS;
++ switch (j)
++ {
++ case 2: /* top right */
++ *x = width - fgeom.right_width - RESIZE_EXTENDS;
++ *y = 0;
+
+- if (!d->frame_window)
+- {
+- *x += mutter_draggable_border_width;
+- *w += mutter_draggable_border_width;
+- *h += mutter_draggable_border_width;
+- }
+- break;
+- case 1: /* top */
+- *x = fgeom.left_width + RESIZE_EXTENDS;
+- *y = 0;
+- if (d->frame_window)
+- *y += d->frame->win_extents.top + 2;
+- *w = width - fgeom.left_width - fgeom.right_width -
+- (2 * RESIZE_EXTENDS);
+- *h = fgeom.title_rect.y + TOP_RESIZE_HEIGHT;
++ if (d->frame_window)
++ {
++ *x += d->frame->win_extents.left + 2;
++ *y += d->frame->win_extents.top + 2 - fgeom.title_rect.height;
++ }
+
+- if (!d->frame_window)
+- {
+- *x -= mutter_draggable_border_width;
+- *w += mutter_draggable_border_width * 2;
+- *h += mutter_draggable_border_width;
+- }
++ *w = fgeom.right_width + RESIZE_EXTENDS;
++ *h = fgeom.top_height + RESIZE_EXTENDS;
+
+- break;
+- case 0: /* top left */
+- default:
+- *x = 0;
+- *y = 0;
+- if (d->frame_window)
+- {
+- *x += d->frame->win_extents.left + 4;
+- *y += d->frame->win_extents.top + 2 - fgeom.title_rect.height;
+- }
+- *w = fgeom.left_width + RESIZE_EXTENDS;
+- *h = fgeom.top_height + RESIZE_EXTENDS;
++ if (!d->frame_window)
++ {
++ *x += mutter_draggable_border_width;
++ *w += mutter_draggable_border_width;
++ *h += mutter_draggable_border_width;
++ }
++ break;
++ case 1: /* top */
++ *x = fgeom.left_width + RESIZE_EXTENDS;
++ *y = 0;
+
+- if (!d->frame_window)
+- {
+- *w += mutter_draggable_border_width;
+- *h += mutter_draggable_border_width;
+- }
++ if (d->frame_window)
++ *y += d->frame->win_extents.top + 2;
+
+- break;
+- }
++ *w = width - fgeom.left_width - fgeom.right_width - (2 * RESIZE_EXTENDS);
++ *h = fgeom.title_rect.y + TOP_RESIZE_HEIGHT;
++
++ if (!d->frame_window)
++ {
++ *x -= mutter_draggable_border_width;
++ *w += mutter_draggable_border_width * 2;
++ *h += mutter_draggable_border_width;
++ }
++ break;
++ case 0: /* top left */
++ default:
++ *x = 0;
++ *y = 0;
++
++ if (d->frame_window)
++ {
++ *x += d->frame->win_extents.left + 4;
++ *y += d->frame->win_extents.top + 2 - fgeom.title_rect.height;
++ }
++
++ *w = fgeom.left_width + RESIZE_EXTENDS;
++ *h = fgeom.top_height + RESIZE_EXTENDS;
++
++ if (!d->frame_window)
++ {
++ *w += mutter_draggable_border_width;
++ *h += mutter_draggable_border_width;
++ }
++ break;
++ }
++ break;
+ }
+
+ if (!(flags & META_FRAME_ALLOWS_VERTICAL_RESIZE))
+ {
+- /* turn off top and bottom event windows */
+- if (i == 0 || i == 2)
+- *w = *h = 0;
++ /* turn off top and bottom event windows */
++ if (i == 0 || i == 2)
++ *w = *h = 0;
+ }
+
+ if (!(flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE))
+ {
+- /* turn off left and right event windows */
+- if (j == 0 || j == 2)
+- *w = *h = 0;
++ /* turn off left and right event windows */
++ if (j == 0 || j == 2)
++ *w = *h = 0;
+ }
+ }
+
+-
+ static MetaButtonFunction
+ meta_button_function_from_string (const char *str)
+ {
+ if (strcmp (str, "menu") == 0)
+- return META_BUTTON_FUNCTION_MENU;
++ return META_BUTTON_FUNCTION_MENU;
+ else if (strcmp (str, "minimize") == 0)
+- return META_BUTTON_FUNCTION_MINIMIZE;
++ return META_BUTTON_FUNCTION_MINIMIZE;
+ else if (strcmp (str, "maximize") == 0)
+- return META_BUTTON_FUNCTION_MAXIMIZE;
++ return META_BUTTON_FUNCTION_MAXIMIZE;
+ else if (strcmp (str, "close") == 0)
+- return META_BUTTON_FUNCTION_CLOSE;
++ return META_BUTTON_FUNCTION_CLOSE;
+ else if (strcmp (str, "shade") == 0)
+- return META_BUTTON_FUNCTION_SHADE;
++ return META_BUTTON_FUNCTION_SHADE;
+ else if (strcmp (str, "above") == 0)
+- return META_BUTTON_FUNCTION_ABOVE;
++ return META_BUTTON_FUNCTION_ABOVE;
+ else if (strcmp (str, "stick") == 0)
+- return META_BUTTON_FUNCTION_STICK;
++ return META_BUTTON_FUNCTION_STICK;
+ else if (strcmp (str, "unshade") == 0)
+- return META_BUTTON_FUNCTION_UNSHADE;
++ return META_BUTTON_FUNCTION_UNSHADE;
+ else if (strcmp (str, "unabove") == 0)
+- return META_BUTTON_FUNCTION_UNABOVE;
++ return META_BUTTON_FUNCTION_UNABOVE;
+ else if (strcmp (str, "unstick") == 0)
+- return META_BUTTON_FUNCTION_UNSTICK;
++ return META_BUTTON_FUNCTION_UNSTICK;
+ else
+- return META_BUTTON_FUNCTION_LAST;
++ return META_BUTTON_FUNCTION_LAST;
+ }
+
+ static MetaButtonFunction
+@@ -1378,22 +1330,22 @@
+ switch (ofwhat)
+ {
+ case META_BUTTON_FUNCTION_SHADE:
+- return META_BUTTON_FUNCTION_UNSHADE;
++ return META_BUTTON_FUNCTION_UNSHADE;
+ case META_BUTTON_FUNCTION_UNSHADE:
+- return META_BUTTON_FUNCTION_SHADE;
++ return META_BUTTON_FUNCTION_SHADE;
+
+ case META_BUTTON_FUNCTION_ABOVE:
+- return META_BUTTON_FUNCTION_UNABOVE;
++ return META_BUTTON_FUNCTION_UNABOVE;
+ case META_BUTTON_FUNCTION_UNABOVE:
+- return META_BUTTON_FUNCTION_ABOVE;
++ return META_BUTTON_FUNCTION_ABOVE;
+
+ case META_BUTTON_FUNCTION_STICK:
+- return META_BUTTON_FUNCTION_UNSTICK;
++ return META_BUTTON_FUNCTION_UNSTICK;
+ case META_BUTTON_FUNCTION_UNSTICK:
+- return META_BUTTON_FUNCTION_STICK;
++ return META_BUTTON_FUNCTION_STICK;
+
+ default:
+- return META_BUTTON_FUNCTION_LAST;
++ return META_BUTTON_FUNCTION_LAST;
+ }
+ }
+
+@@ -1404,20 +1356,20 @@
+
+ for (i = 0; i < MAX_BUTTONS_PER_CORNER; ++i)
+ {
+- layout->left_buttons[i] = META_BUTTON_FUNCTION_LAST;
+- layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST;
+- layout->left_buttons_has_spacer[i] = FALSE;
+- layout->right_buttons_has_spacer[i] = FALSE;
++ layout->left_buttons[i] = META_BUTTON_FUNCTION_LAST;
++ layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST;
++ layout->left_buttons_has_spacer[i] = FALSE;
++ layout->right_buttons_has_spacer[i] = FALSE;
+ }
+ }
+
+ void
+ meta_update_button_layout (const char *value)
+ {
+- MetaButtonLayout new_layout;
++ MetaButtonLayout new_layout;
+ MetaButtonFunction f;
+- char **sides;
+- int i;
++ char **sides;
++ int i;
+
+ meta_initialize_button_layout (&new_layout);
+
+@@ -1425,96 +1377,97 @@
+
+ if (sides[0] != NULL)
+ {
+- char **buttons;
+- int b;
+- gboolean used[META_BUTTON_FUNCTION_LAST];
+-
+- for (i = 0; i < META_BUTTON_FUNCTION_LAST; ++i)
+- used[i] = FALSE;
+-
+- buttons = g_strsplit (sides[0], ",", -1);
+-
+- i = b = 0;
+- while (buttons[b] != NULL)
+- {
+- f = meta_button_function_from_string (buttons[b]);
+- if (i > 0 && strcmp ("spacer", buttons[b]) == 0)
++ char **buttons;
++ int b;
++ gboolean used[META_BUTTON_FUNCTION_LAST];
++
++ for (i = 0; i < META_BUTTON_FUNCTION_LAST; ++i)
++ used[i] = FALSE;
++
++ buttons = g_strsplit (sides[0], ",", -1);
++
++ i = b = 0;
++ while (buttons[b] != NULL)
++ {
++ f = meta_button_function_from_string (buttons[b]);
++ if (i > 0 && strcmp ("spacer", buttons[b]) == 0)
+ {
+- new_layout.left_buttons_has_spacer[i - 1] = TRUE;
+- f = meta_button_opposite_function (f);
++ new_layout.left_buttons_has_spacer[i - 1] = TRUE;
++ f = meta_button_opposite_function (f);
+
+- if (f != META_BUTTON_FUNCTION_LAST)
+- new_layout.left_buttons_has_spacer[i - 2] = TRUE;
++ if (f != META_BUTTON_FUNCTION_LAST)
++ new_layout.left_buttons_has_spacer[i - 2] = TRUE;
+ }
+- else
+- {
+- if (f != META_BUTTON_FUNCTION_LAST && !used[f])
+- {
+- used[f] = TRUE;
+- new_layout.left_buttons[i++] = f;
+-
+- f = meta_button_opposite_function (f);
+-
+- if (f != META_BUTTON_FUNCTION_LAST)
+- new_layout.left_buttons[i++] = f;
+-
+- }
+- else
+- {
+- fprintf (stderr, "%s: Ignoring unknown or already-used "
+- "button name \"%s\"\n", program_name, buttons[b]);
+- }
+- }
+- ++b;
+- }
++ else
++ {
++ if (f != META_BUTTON_FUNCTION_LAST && !used[f])
++ {
++ used[f] = TRUE;
++ new_layout.left_buttons[i++] = f;
++
++ f = meta_button_opposite_function (f);
++
++ if (f != META_BUTTON_FUNCTION_LAST)
++ new_layout.left_buttons[i++] = f;
++
++ }
++ else
++ {
++ fprintf (stderr, "%s: Ignoring unknown or already-used "
++ "button name \"%s\"\n", program_name, buttons[b]);
++ }
++ }
++ ++b;
++ }
+
+- new_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
++ new_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
+
+- g_strfreev (buttons);
++ g_strfreev (buttons);
+
+- if (sides[1] != NULL)
+- {
+- for (i = 0; i < META_BUTTON_FUNCTION_LAST; ++i)
+- used[i] = FALSE;
++ if (sides[1] != NULL)
++ {
++ for (i = 0; i < META_BUTTON_FUNCTION_LAST; ++i)
++ used[i] = FALSE;
+
+- buttons = g_strsplit (sides[1], ",", -1);
++ buttons = g_strsplit (sides[1], ",", -1);
+
+- i = b = 0;
+- while (buttons[b] != NULL)
+- {
+- f = meta_button_function_from_string (buttons[b]);
+- if (i > 0 && strcmp ("spacer", buttons[b]) == 0)
+- {
+- new_layout.right_buttons_has_spacer[i - 1] = TRUE;
+- f = meta_button_opposite_function (f);
+- if (f != META_BUTTON_FUNCTION_LAST)
+- new_layout.right_buttons_has_spacer[i - 2] = TRUE;
+- }
+- else
+- {
+- if (f != META_BUTTON_FUNCTION_LAST && !used[f])
+- {
+- used[f] = TRUE;
+- new_layout.right_buttons[i++] = f;
+-
+- f = meta_button_opposite_function (f);
+-
+- if (f != META_BUTTON_FUNCTION_LAST)
+- new_layout.right_buttons[i++] = f;
+- }
+- else
+- {
+- fprintf (stderr, "%s: Ignoring unknown or "
+- "already-used button name \"%s\"\n",
+- program_name, buttons[b]);
+- }
+- }
+- ++b;
+- }
+- new_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
++ i = b = 0;
++ while (buttons[b] != NULL)
++ {
++ f = meta_button_function_from_string (buttons[b]);
++ if (i > 0 && strcmp ("spacer", buttons[b]) == 0)
++ {
++ new_layout.right_buttons_has_spacer[i - 1] = TRUE;
++ f = meta_button_opposite_function (f);
++ if (f != META_BUTTON_FUNCTION_LAST)
++ new_layout.right_buttons_has_spacer[i - 2] = TRUE;
++ }
++ else
++ {
++ if (f != META_BUTTON_FUNCTION_LAST && !used[f])
++ {
++ used[f] = TRUE;
++ new_layout.right_buttons[i++] = f;
++
++ f = meta_button_opposite_function (f);
++
++ if (f != META_BUTTON_FUNCTION_LAST)
++ new_layout.right_buttons[i++] = f;
++ }
++ else
++ {
++ fprintf (stderr, "%s: Ignoring unknown or "
++ "already-used button name \"%s\"\n",
++ program_name, buttons[b]);
++ }
++ }
++ ++b;
++ }
+
+- g_strfreev (buttons);
+- }
++ new_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
++
++ g_strfreev (buttons);
++ }
+ }
+
+ g_strfreev (sides);
+@@ -1522,42 +1475,38 @@
+ /* Invert the button layout for RTL languages */
+ if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
+ {
+- MetaButtonLayout rtl_layout;
+- int j;
+-
+- meta_initialize_button_layout (&rtl_layout);
++ MetaButtonLayout rtl_layout;
++ int j;
+
+- i = 0;
+- while (new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST)
+- ++i;
++ meta_initialize_button_layout (&rtl_layout);
+
+- for (j = 0; j < i; ++j)
+- {
+- rtl_layout.right_buttons[j] = new_layout.left_buttons[i - j - 1];
+- if (j == 0)
+- rtl_layout.right_buttons_has_spacer[i - 1] =
+- new_layout.left_buttons_has_spacer[i - j - 1];
+- else
+- rtl_layout.right_buttons_has_spacer[j - 1] =
+- new_layout.left_buttons_has_spacer[i - j - 1];
+- }
++ i = 0;
++ while (new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST)
++ ++i;
++
++ for (j = 0; j < i; ++j)
++ {
++ rtl_layout.right_buttons[j] = new_layout.left_buttons[i - j - 1];
++ if (j == 0)
++ rtl_layout.right_buttons_has_spacer[i - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
++ else
++ rtl_layout.right_buttons_has_spacer[j - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
++ }
++
++ i = 0;
++ while (new_layout.right_buttons[i] != META_BUTTON_FUNCTION_LAST)
++ ++i;
++
++ for (j = 0; j < i; ++j)
++ {
++ rtl_layout.left_buttons[j] = new_layout.right_buttons[i - j - 1];
++ if (j == 0)
++ rtl_layout.left_buttons_has_spacer[i - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
++ else
++ rtl_layout.left_buttons_has_spacer[j - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
++ }
+
+- i = 0;
+- while (new_layout.right_buttons[i] != META_BUTTON_FUNCTION_LAST)
+- ++i;
+-
+- for (j = 0; j < i; ++j)
+- {
+- rtl_layout.left_buttons[j] = new_layout.right_buttons[i - j - 1];
+- if (j == 0)
+- rtl_layout.left_buttons_has_spacer[i - 1] =
+- new_layout.right_buttons_has_spacer[i - j - 1];
+- else
+- rtl_layout.left_buttons_has_spacer[j - 1] =
+- new_layout.right_buttons_has_spacer[i - j - 1];
+- }
+-
+- new_layout = rtl_layout;
++ new_layout = rtl_layout;
+ }
+
+ meta_button_layout = new_layout;
+@@ -1566,37 +1515,36 @@
+ void
+ meta_update_border_extents (decor_frame_t *frame)
+ {
+- MetaTheme *theme = meta_theme_get_current ();
++ MetaTheme *theme;
+ #ifdef HAVE_METACITY_3_14_0
+ MetaFrameBorders borders;
+ #endif
++ MetaFrameType frame_type;
++ gint top_height;
++ gint bottom_height;
++ gint left_width;
++ gint right_width;
+
+ gwd_decor_frame_ref (frame);
+- MetaFrameType frame_type = meta_frame_type_from_string (frame->type);
+- gint top_height, bottom_height, left_width, right_width;
+
++ frame_type = meta_frame_type_from_string (frame->type);
+ if (!(frame_type < META_FRAME_TYPE_LAST))
+- frame_type = META_FRAME_TYPE_NORMAL;
++ frame_type = META_FRAME_TYPE_NORMAL;
++
++ theme = meta_theme_get_current ();
+
+ #ifdef HAVE_METACITY_3_14_0
+- meta_theme_get_frame_borders (theme,
+- frame_type,
+- frame->text_height,
+- 0,
+- &borders);
++ meta_theme_get_frame_borders (theme, frame_type, frame->text_height,
++ 0, &borders);
++
+ top_height = borders.visible.top;
+ bottom_height = borders.visible.bottom;
+ left_width = borders.visible.left;
+ right_width = borders.visible.right;
+ #else
+- meta_theme_get_frame_borders (theme,
+- frame_type,
+- frame->text_height,
+- 0,
+- &top_height,
+- &bottom_height,
+- &left_width,
+- &right_width);
++ meta_theme_get_frame_borders (theme, frame_type, frame->text_height,
++ 0, &top_height, &bottom_height,
++ &left_width, &right_width);
+ #endif
+
+ frame->win_extents.top = frame->win_extents.top;
+@@ -1607,24 +1555,18 @@
+ frame->titlebar_height = top_height - frame->win_extents.top;
+
+ #ifdef HAVE_METACITY_3_14_0
+- meta_theme_get_frame_borders (theme,
+- frame_type,
+- frame->text_height,
+- META_FRAME_MAXIMIZED,
+- &borders);
++ meta_theme_get_frame_borders (theme, frame_type, frame->text_height,
++ META_FRAME_MAXIMIZED, &borders);
++
+ top_height = borders.visible.top;
+ bottom_height = borders.visible.bottom;
+ left_width = borders.visible.left;
+ right_width = borders.visible.right;
+ #else
+- meta_theme_get_frame_borders (theme,
+- frame_type,
+- frame->text_height,
+- META_FRAME_MAXIMIZED,
+- &top_height,
+- &bottom_height,
+- &left_width,
+- &right_width);
++ meta_theme_get_frame_borders (theme, frame_type, frame->text_height,
++ META_FRAME_MAXIMIZED,
++ &top_height, &bottom_height,
++ &left_width, &right_width);
+ #endif
+
+ frame->max_win_extents.top = frame->win_extents.top;
+@@ -1637,4 +1579,5 @@
+ gwd_decor_frame_unref (frame);
+ }
+
+-#endif
++#endif /* HAVE_METACITY_3_16_0 */
++#endif /* USE_METACITY */
+diff -Nur original/gtk/window-decorator/settings.c modified/gtk/window-decorator/settings.c
+--- original/gtk/window-decorator/settings.c 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/window-decorator/settings.c 2015-05-14 11:13:01.100922489 +0100
+@@ -45,11 +45,14 @@
+ #ifdef USE_GSETTINGS
+ #define STORAGE_USED
+ GSettings *compiz = gwd_get_org_compiz_gwd_settings ();
++ GSettings *metacity = gwd_get_org_gnome_metacity_settings ();
+ GSettings *mutter = gwd_get_org_gnome_mutter_settings ();
+ GSettings *gnome = gwd_get_org_gnome_desktop_wm_preferences_settings ();
+- storage = gwd_settings_storage_gsettings_new (gnome, mutter, compiz, writable);
++
++ storage = gwd_settings_storage_gsettings_new (gnome, metacity, mutter, compiz, writable);
+
+ gwd_connect_org_compiz_gwd_settings (compiz, storage);
++ gwd_connect_org_gnome_metacity_settings (metacity, storage);
+ gwd_connect_org_gnome_mutter_settings (mutter, storage);
+ gwd_connect_org_gnome_desktop_wm_preferences_settings (gnome, storage);
+ #endif
+diff -Nur original/gtk/window-decorator/switcher.c modified/gtk/window-decorator/switcher.c
+--- original/gtk/window-decorator/switcher.c 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/window-decorator/switcher.c 2015-05-14 11:12:47.810922845 +0100
+@@ -25,6 +25,8 @@
+
+ #include "gtk-window-decorator.h"
+
++#define SWITCHER_SPACE 40
++
+ decor_frame_t *
+ create_switcher_frame (const gchar *type)
+ {
+@@ -319,7 +321,7 @@
+ copy_to_front_buffer (d);
+ }
+
+-void
++static void
+ draw_switcher_decoration (decor_t *d)
+ {
+ if (d->prop_xid)
+@@ -328,7 +330,8 @@
+ draw_switcher_foreground (d);
+ }
+
+-void
++#if 0
++static void
+ switcher_window_closed ()
+ {
+ decor_t *d = switcher_window;
+@@ -356,10 +359,11 @@
+ g_free (switcher_window);
+ switcher_window = NULL;
+ }
++#endif
+
+ /* Switcher is override-redirect now, we need to track
+ * it separately */
+-decor_t *
++static decor_t *
+ switcher_window_opened (Window popup, Window window)
+ {
+ decor_t *d;
+diff -Nur original/gtk/window-decorator/tests/CMakeLists.txt modified/gtk/window-decorator/tests/CMakeLists.txt
+--- original/gtk/window-decorator/tests/CMakeLists.txt 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/window-decorator/tests/CMakeLists.txt 2015-05-14 11:13:01.100922489 +0100
+@@ -75,6 +75,21 @@
+
+ add_gsettings_schema_to_recompilation_list (compiz_gwd_gsettings_org_gnome_desktop_wm_preferences_schema)
+
++ set (_metacity_gschema_name org.gnome.metacity)
++ set (_metacity_gschema_filename ${_metacity_gschema_name}.gschema.xml)
++ set (_metacity_gschema_filepath ${CMAKE_CURRENT_SOURCE_DIR}/${_metacity_gschema_filename})
++ set (_metacity_gschema_generated_location ${CMAKE_BINARY_DIR}/generated/glib-2.0/schemas/${_metacity_gschema_filename})
++
++ add_custom_command (OUTPUT ${_metacity_gschema_generated_location}
++ COMMAND cp -r ${_metacity_gschema_filepath} ${_metacity_gschema_generated_location}
++ DEPENDS ${_metacity_gschema_filepath}
++ VERBATIM)
++
++ add_custom_target (compiz_gwd_gsettings_org_gnome_metacity_schema ALL
++ DEPENDS ${_metacity_gschema_generated_location})
++
++ add_gsettings_schema_to_recompilation_list (compiz_gwd_gsettings_org_gnome_metacity_schema)
++
+ set (_mutter_gschema_name org.gnome.mutter)
+ set (_mutter_gschema_filename ${_mutter_gschema_name}.gschema.xml)
+ set (_mutter_gschema_filepath ${CMAKE_CURRENT_SOURCE_DIR}/${_mutter_gschema_filename})
+diff -Nur original/gtk/window-decorator/tests/org.gnome.metacity.gschema.xml modified/gtk/window-decorator/tests/org.gnome.metacity.gschema.xml
+--- original/gtk/window-decorator/tests/org.gnome.metacity.gschema.xml 1970-01-01 01:00:00.000000000 +0100
++++ modified/gtk/window-decorator/tests/org.gnome.metacity.gschema.xml 2015-05-14 11:13:01.100922489 +0100
+@@ -0,0 +1,10 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<schemalist>
++ <schema path="/org/gnome/metacity/" id="org.gnome.metacity" gettext-domain="@GETTEXT_DOMAIN">
++ <key type="s" name="theme">
++ <default>'Adwaita'</default>
++ <summary>Current theme</summary>
++ <description>The theme determines the appearance of window borders, titlebar, and so forth.</description>
++ </key>
++ </schema>
++</schemalist>
+diff -Nur original/gtk/window-decorator/tests/test_gwd_settings.cpp modified/gtk/window-decorator/tests/test_gwd_settings.cpp
+--- original/gtk/window-decorator/tests/test_gwd_settings.cpp 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/window-decorator/tests/test_gwd_settings.cpp 2015-05-14 11:13:01.100922489 +0100
+@@ -1481,6 +1481,7 @@
+ boost::bind (gwd_settings_storage_unref, _1));
+
+ gwd_connect_org_compiz_gwd_settings (NULL, mStorage.get ());
++ gwd_connect_org_gnome_metacity_settings (NULL, mStorage.get ());
+ gwd_connect_org_gnome_mutter_settings (NULL, mStorage.get ());
+ gwd_connect_org_gnome_desktop_wm_preferences_settings (NULL, mStorage.get ());
+
+@@ -1500,10 +1501,12 @@
+
+ /* We do not need to keep a reference to these */
+ mGWDSettings = gwd_get_org_compiz_gwd_settings ();
++ mMetacitySettings = gwd_get_org_gnome_mutter_settings ();
+ mMutterSettings = gwd_get_org_gnome_mutter_settings ();
+ mDesktopSettings = gwd_get_org_gnome_desktop_wm_preferences_settings ();
+
+ mStorage.reset (gwd_settings_storage_gsettings_new (mDesktopSettings,
++ mMetacitySettings,
+ mMutterSettings,
+ mGWDSettings,
+ writable),
+@@ -1596,6 +1599,7 @@
+ {
+ mStorage.reset ();
+ mGWDSettings = NULL;
++ mMetacitySettings = NULL;
+ mMutterSettings = NULL;
+ mDesktopSettings = NULL;
+ gsettingsEnv.TearDownEnv ();
+@@ -1605,6 +1609,7 @@
+ private:
+
+ GSettings *mGWDSettings;
++ GSettings *mMetacitySettings;
+ GSettings *mMutterSettings;
+ GSettings *mDesktopSettings;
+ boost::shared_ptr <GWDSettingsStorage> mStorage;
+diff -Nur original/gtk/window-decorator/util.c modified/gtk/window-decorator/util.c
+--- original/gtk/window-decorator/util.c 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/window-decorator/util.c 2015-05-14 11:12:47.810922845 +0100
+@@ -21,19 +21,6 @@
+
+ #include "gtk-window-decorator.h"
+
+-double
+-square (double x)
+-{
+- return x * x;
+-}
+-
+-double
+-dist (double x1, double y1,
+- double x2, double y2)
+-{
+- return sqrt (square (x1 - x2) + square (y1 - y2));
+-}
+-
+ gboolean
+ get_window_prop (Window xwindow,
+ Atom atom,
+@@ -110,190 +97,3 @@
+
+ return decor;
+ }
+-
+-/* from clearlooks theme */
+-static void
+-rgb_to_hls (gdouble *r,
+- gdouble *g,
+- gdouble *b)
+-{
+- gdouble min;
+- gdouble max;
+- gdouble red;
+- gdouble green;
+- gdouble blue;
+- gdouble h, l, s;
+- gdouble delta;
+-
+- red = *r;
+- green = *g;
+- blue = *b;
+-
+- if (red > green)
+- {
+- if (red > blue)
+- max = red;
+- else
+- max = blue;
+-
+- if (green < blue)
+- min = green;
+- else
+- min = blue;
+- }
+- else
+- {
+- if (green > blue)
+- max = green;
+- else
+- max = blue;
+-
+- if (red < blue)
+- min = red;
+- else
+- min = blue;
+- }
+-
+- l = (max + min) / 2;
+- s = 0;
+- h = 0;
+-
+- if (max != min)
+- {
+- if (l <= 0.5)
+- s = (max - min) / (max + min);
+- else
+- s = (max - min) / (2 - max - min);
+-
+- delta = max -min;
+- if (red == max)
+- h = (green - blue) / delta;
+- else if (green == max)
+- h = 2 + (blue - red) / delta;
+- else if (blue == max)
+- h = 4 + (red - green) / delta;
+-
+- h *= 60;
+- if (h < 0.0)
+- h += 360;
+- }
+-
+- *r = h;
+- *g = l;
+- *b = s;
+-}
+-
+-static void
+-hls_to_rgb (gdouble *h,
+- gdouble *l,
+- gdouble *s)
+-{
+- gdouble hue;
+- gdouble lightness;
+- gdouble saturation;
+- gdouble m1, m2;
+- gdouble r, g, b;
+-
+- lightness = *l;
+- saturation = *s;
+-
+- if (lightness <= 0.5)
+- m2 = lightness * (1 + saturation);
+- else
+- m2 = lightness + saturation - lightness * saturation;
+-
+- m1 = 2 * lightness - m2;
+-
+- if (saturation == 0)
+- {
+- *h = lightness;
+- *l = lightness;
+- *s = lightness;
+- }
+- else
+- {
+- hue = *h + 120;
+- while (hue > 360)
+- hue -= 360;
+- while (hue < 0)
+- hue += 360;
+-
+- if (hue < 60)
+- r = m1 + (m2 - m1) * hue / 60;
+- else if (hue < 180)
+- r = m2;
+- else if (hue < 240)
+- r = m1 + (m2 - m1) * (240 - hue) / 60;
+- else
+- r = m1;
+-
+- hue = *h;
+- while (hue > 360)
+- hue -= 360;
+- while (hue < 0)
+- hue += 360;
+-
+- if (hue < 60)
+- g = m1 + (m2 - m1) * hue / 60;
+- else if (hue < 180)
+- g = m2;
+- else if (hue < 240)
+- g = m1 + (m2 - m1) * (240 - hue) / 60;
+- else
+- g = m1;
+-
+- hue = *h - 120;
+- while (hue > 360)
+- hue -= 360;
+- while (hue < 0)
+- hue += 360;
+-
+- if (hue < 60)
+- b = m1 + (m2 - m1) * hue / 60;
+- else if (hue < 180)
+- b = m2;
+- else if (hue < 240)
+- b = m1 + (m2 - m1) * (240 - hue) / 60;
+- else
+- b = m1;
+-
+- *h = r;
+- *l = g;
+- *s = b;
+- }
+-}
+-
+-void
+-shade (const decor_color_t *a,
+- decor_color_t *b,
+- float k)
+-{
+- double red;
+- double green;
+- double blue;
+-
+- red = a->r;
+- green = a->g;
+- blue = a->b;
+-
+- rgb_to_hls (&red, &green, &blue);
+-
+- green *= k;
+- if (green > 1.0)
+- green = 1.0;
+- else if (green < 0.0)
+- green = 0.0;
+-
+- blue *= k;
+- if (blue > 1.0)
+- blue = 1.0;
+- else if (blue < 0.0)
+- blue = 0.0;
+-
+- hls_to_rgb (&red, &green, &blue);
+-
+- b->r = red;
+- b->g = green;
+- b->b = blue;
+-}
+-
+diff -Nur original/gtk/window-decorator/wnck.c modified/gtk/window-decorator/wnck.c
+--- original/gtk/window-decorator/wnck.c 2015-05-14 11:08:08.713570000 +0100
++++ modified/gtk/window-decorator/wnck.c 2015-05-14 11:12:47.810922845 +0100
+@@ -162,7 +162,7 @@
+ }
+ }
+
+-void
++static void
+ update_frames_border_extents (gpointer key,
+ gpointer value,
+ gpointer user_data)
+@@ -590,7 +590,7 @@
+ draw_list = g_slist_remove (draw_list, d);
+ }
+
+-void
++static void
+ connect_window (WnckWindow *win)
+ {
+ g_signal_connect_object (win, "name_changed",
+@@ -762,7 +762,7 @@
+ }
+ }
+
+-void
++static void
+ window_opened (WnckScreen *screen,
+ WnckWindow *win)
+ {
diff --git a/set-gwd-default.patch b/set-gwd-default.patch
new file mode 100644
index 000000000000..624cffbdd5f5
--- /dev/null
+++ b/set-gwd-default.patch
@@ -0,0 +1,12 @@
+diff -Naur original/plugins/decor/decor.xml.in modified/plugins/decor/decor.xml.in
+--- original/plugins/decor/decor.xml.in 2013-07-23 20:58:03.000000000 +0100
++++ modified/plugins/decor/decor.xml.in 2014-06-11 00:01:50.332286339 +0100
+@@ -101,7 +101,7 @@
+ <option name="command" type="string">
+ <_short>Command</_short>
+ <_long>Decorator command line that is executed if no decorator is already running.</_long>
+- <default>exec \"${COMPIZ_BIN_PATH}compiz-decorator\"</default>
++ <default>gtk-window-decorator</default>
+ </option>
+ <option name="mipmap" type="bool">
+ <_short>Mipmap</_short>