summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob McCathie2015-07-26 16:43:01 +1000
committerRob McCathie2015-07-26 16:43:01 +1000
commit198f19297a4cd81d44e2988452b1b44409a626ca (patch)
treeadf42db9569dd64de87c65646f8951a0245694bb
downloadaur-198f19297a4cd81d44e2988452b1b44409a626ca.tar.gz
initial aur4 commit. includes update to start xfwm4 post uninstallation on Xfce
-rw-r--r--.SRCINFO94
-rw-r--r--PKGBUILD160
-rwxr-xr-xcompiz-gtk-decorator-theme-selector44
-rw-r--r--compiz-gtk-decorator-theme.desktop11
-rwxr-xr-xcompiz-manjaro-decoratortheme11
-rw-r--r--compiz-manjaro-decoratortheme.desktop11
-rw-r--r--compiz-manjaro-defaults.patch253
-rwxr-xr-xcompiz-manjaro-mate-decoratortheme7
-rw-r--r--compiz-manjaro-mate-decoratortheme.desktop11
-rw-r--r--compiz-manjaro.gschema.override9
-rw-r--r--compiz-manjaro.install81
-rwxr-xr-xcompiz-xfce-autostart25
-rw-r--r--compiz-xfce-autostart.desktop11
-rw-r--r--compiz-xfce-uninstall-helper7
-rw-r--r--compiz-xfce-uninstall-helper.desktop11
-rw-r--r--focus-prevention-disable.patch12
-rw-r--r--metacity-3_16.patch6172
-rw-r--r--set-gwd-default.patch12
18 files changed, 6942 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
new file mode 100644
index 000000000000..03ca8698de49
--- /dev/null
+++ b/.SRCINFO
@@ -0,0 +1,94 @@
+# Generated by makepkg 4.2.1
+# Sun Jul 26 06:42:34 UTC 2015
+pkgbase = compiz-manjaro
+ pkgdesc = OpenGL compositing window manager. Includes friendly defaults, GWD theme selector and autostart for Xfce & MATE.
+ pkgver = 0.9.12.1
+ pkgrel = 5
+ url = https://launchpad.net/compiz
+ install = compiz-manjaro.install
+ arch = i686
+ arch = x86_64
+ license = GPL
+ license = LGPL
+ license = MIT
+ makedepends = cmake
+ 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
+ provides = compiz=0.9.12.1
+ provides = compiz-core-devel=0.9.12.1
+ conflicts = compiz
+ conflicts = compiz09-manjaro-test
+ conflicts = compiz-core-bzr
+ conflicts = compiz-core-devel
+ conflicts = compiz-core
+ conflicts = compiz-gtk-standalone
+ conflicts = compiz-xfce
+ conflicts = compiz-mate
+ conflicts = compiz-core-mate
+ conflicts = compiz-fusion-plugins-main
+ conflicts = compiz-fusion-plugins-extra
+ conflicts = compiz-fusion-plugins-unsupported
+ conflicts = compiz-decorator-gtk
+ conflicts = compiz-decorator-kde
+ conflicts = libcompizconfig
+ conflicts = compizconfig-python
+ conflicts = compizconfig-backend-gconf
+ conflicts = compiz-bcop
+ conflicts = ccsm
+ replaces = compiz09-manjaro-test
+ source = https://launchpad.net/compiz/0.9.12/0.9.12.1/+download/compiz-0.9.12.1.tar.bz2
+ source = set-gwd-default.patch
+ source = focus-prevention-disable.patch
+ source = compiz-manjaro-defaults.patch
+ source = compiz-manjaro.gschema.override
+ source = compiz-gtk-decorator-theme-selector
+ source = compiz-gtk-decorator-theme.desktop
+ source = compiz-xfce-autostart
+ source = compiz-xfce-autostart.desktop
+ source = compiz-xfce-uninstall-helper
+ source = compiz-xfce-uninstall-helper.desktop
+ source = compiz-manjaro-decoratortheme
+ source = compiz-manjaro-decoratortheme.desktop
+ source = compiz-manjaro-mate-decoratortheme
+ source = compiz-manjaro-mate-decoratortheme.desktop
+ source = greybird-1.5.3.tar.gz::https://github.com/shimmerproject/Greybird/archive/v1.5.3.tar.gz
+ source = metacity-3_16.patch
+ sha1sums = 4ccbc1fc3728ded896f14e11db121bf771cec59f
+ sha1sums = be585a68eacf93a1064ea914a927623c3e774b95
+ sha1sums = b74ab025a89419c23d6f01c41e414281e1a2382f
+ sha1sums = 1996419be45490410887385975cbbebfa15a539a
+ sha1sums = e54a97ebda168c507457feee5e5085bd2ae98546
+ sha1sums = 45b98fd5e238a595e3a60741106193321bebdf64
+ sha1sums = f7e1544f8e6987f86c1b2c3e69b70d2accf95bc9
+ sha1sums = b428f171ab8b34b236aed9954867102bdd33f9da
+ sha1sums = a790b6556695b06af4eff910e7dc409aab85f9a8
+ sha1sums = 4b4fa287ea72f8b8eccdf4254dfe2174d9b41b2a
+ sha1sums = 847d498050e96fbb1a43c29a0f98b70a74319203
+ sha1sums = 36b8c620e00cfd7d9099c02589cab6906f483e53
+ sha1sums = 56146a4fc169f46504eaa86ca240de34c4bb1fd8
+ sha1sums = 8eff3fedffb543960ebfc19b15e95d7f7a90ee50
+ sha1sums = 890b02696130b8275104aaea110b9beb3a162dce
+ sha1sums = ebc447a9c13b6c8563fec789d290354b3d7c8230
+ sha1sums = 699ca81225749cc9a1b8906f5c5d30fdb649b5ef
+
+pkgname = compiz-manjaro
+
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 000000000000..db284f3413c4
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,160 @@
+# Maintainer : Rob McCathie <korrode AT gmail>
+# Contributor: Charles Bos <charlesbos1 AT gmail>
+# Contributor: Iven Hsu <ivenvd AT gmail>
+
+_name=compiz
+pkgname=compiz-manjaro
+_series=0.9.12
+pkgver=${_series}.1
+pkgrel=5
+_greybirdver=1.5.3
+pkgdesc="OpenGL compositing window manager. Includes friendly defaults, GWD theme selector and autostart for Xfce & MATE."
+arch=('i686' 'x86_64')
+url="https://launchpad.net/${_name}"
+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' 'intltool')
+#optdepends=()
+conflicts=('compiz' 'compiz09-manjaro-test' 'compiz-core-bzr' 'compiz-core-devel' 'compiz-core' 'compiz-gtk-standalone' 'compiz-xfce' 'compiz-mate'
+ 'compiz-core-mate' 'compiz-fusion-plugins-main' 'compiz-fusion-plugins-extra' 'compiz-fusion-plugins-unsupported' 'compiz-decorator-gtk'
+ 'compiz-decorator-kde' 'libcompizconfig' 'compizconfig-python' 'compizconfig-backend-gconf' 'compiz-bcop' 'ccsm')
+replaces=('compiz09-manjaro-test')
+provides=("${_name}=${pkgver}" "${_name}-core-devel=${pkgver}")
+source=("${url}/${_series}/${pkgver}/+download/${_name}-${pkgver}.tar.bz2"
+ "set-gwd-default.patch"
+ "focus-prevention-disable.patch"
+ "${pkgname}-defaults.patch"
+ "${pkgname}.gschema.override"
+ "compiz-gtk-decorator-theme-selector"
+ "compiz-gtk-decorator-theme.desktop"
+ "compiz-xfce-autostart"
+ "compiz-xfce-autostart.desktop"
+ "compiz-xfce-uninstall-helper"
+ "compiz-xfce-uninstall-helper.desktop"
+ "${pkgname}-decoratortheme"
+ "${pkgname}-decoratortheme.desktop"
+ "${pkgname}-mate-decoratortheme"
+ "${pkgname}-mate-decoratortheme.desktop"
+ "greybird-${_greybirdver}.tar.gz::https://github.com/shimmerproject/Greybird/archive/v${_greybirdver}.tar.gz"
+ "metacity-3_16.patch")
+sha1sums=('4ccbc1fc3728ded896f14e11db121bf771cec59f'
+ 'be585a68eacf93a1064ea914a927623c3e774b95'
+ 'b74ab025a89419c23d6f01c41e414281e1a2382f'
+ '1996419be45490410887385975cbbebfa15a539a'
+ 'e54a97ebda168c507457feee5e5085bd2ae98546'
+ '45b98fd5e238a595e3a60741106193321bebdf64'
+ 'f7e1544f8e6987f86c1b2c3e69b70d2accf95bc9'
+ 'b428f171ab8b34b236aed9954867102bdd33f9da'
+ 'a790b6556695b06af4eff910e7dc409aab85f9a8'
+ '4b4fa287ea72f8b8eccdf4254dfe2174d9b41b2a'
+ '847d498050e96fbb1a43c29a0f98b70a74319203'
+ '36b8c620e00cfd7d9099c02589cab6906f483e53'
+ '56146a4fc169f46504eaa86ca240de34c4bb1fd8'
+ '8eff3fedffb543960ebfc19b15e95d7f7a90ee50'
+ '890b02696130b8275104aaea110b9beb3a162dce'
+ 'ebc447a9c13b6c8563fec789d290354b3d7c8230'
+ '699ca81225749cc9a1b8906f5c5d30fdb649b5ef')
+install="${pkgname}.install"
+
+prepare() {
+ cd "${_name}-${pkgver}"
+
+ # Set gtk-window-decorator as default in the Window Decoration plugin
+ patch -p1 -i "${srcdir}/set-gwd-default.patch"
+
+ # Set focus prevention level to off which means that new windows will always get focus
+ patch -p1 -i "${srcdir}/focus-prevention-disable.patch"
+
+ # Manjaro defaults
+ patch -p1 -i "${srcdir}/${pkgname}-defaults.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 "${_name}-${pkgver}"
+
+ export PYTHON="/usr/bin/python2"
+
+ mkdir build; cd build
+
+ cmake .. \
+ -DCMAKE_BUILD_TYPE="Release" \
+ -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,compiztoolbox,staticswitcher,expo,grid,regex,animation,ccp"
+
+ make
+}
+
+package() {
+ cd "${_name}-${pkgver}/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 the gsettings schema files manually
+ 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/"
+
+ ## Manjaro stuff
+ # Add Manjaro dconf/gsettings schema override file
+ install -Dm644 "${srcdir}/${pkgname}.gschema.override" "${pkgdir}/usr/share/glib-2.0/schemas/${pkgname}.gschema.override"
+ # Make ccsm icon appear in Xfce settings manager
+ sed -i 's|Categories=Settings;DesktopSettings;|Categories=Settings;DesktopSettings;X-XFCE-SettingsDialog;X-XFCE-OtherSettings;|' "${pkgdir}/usr/share/applications/ccsm.desktop"
+ # Install GWD theme selector app
+ install -Dm755 "${srcdir}/compiz-gtk-decorator-theme-selector" "${pkgdir}/usr/bin/compiz-gtk-decorator-theme-selector"
+ install -Dm644 "${srcdir}/compiz-gtk-decorator-theme.desktop" "${pkgdir}/usr/share/applications/compiz-gtk-decorator-theme.desktop"
+ # Place autostart/theme scripts/enablers
+ install -Dm755 "${srcdir}/compiz-xfce-autostart" "${pkgdir}/usr/bin/compiz-xfce-autostart"
+ install -Dm644 "${srcdir}/compiz-xfce-autostart.desktop" "${pkgdir}/etc/xdg/autostart/compiz-xfce-autostart.desktop"
+ install -Dm755 "${srcdir}/compiz-xfce-uninstall-helper" "${pkgdir}/usr/share/compiz-xfce/compiz-xfce-uninstall-helper"
+ install -Dm644 "${srcdir}/compiz-xfce-uninstall-helper.desktop" "${pkgdir}/usr/share/compiz-xfce/compiz-xfce-uninstall-helper.desktop"
+ install -Dm755 "${srcdir}/${pkgname}-decoratortheme" "${pkgdir}/usr/bin/${pkgname}-decoratortheme"
+ install -Dm644 "${srcdir}/${pkgname}-decoratortheme.desktop" "${pkgdir}/etc/xdg/autostart/${pkgname}-decoratortheme.desktop"
+ install -Dm755 "${srcdir}/${pkgname}-mate-decoratortheme" "${pkgdir}/usr/bin/${pkgname}-mate-decoratortheme"
+ install -Dm644 "${srcdir}/${pkgname}-mate-decoratortheme.desktop" "${pkgdir}/etc/xdg/autostart/${pkgname}-mate-decoratortheme.desktop"
+
+ # greybird window decorations
+ cd "${srcdir}/Greybird-${_greybirdver}"
+ mkdir -p "${pkgdir}/usr/share/themes/compiz-xfce-greybird"
+ cp LICENSE* "${pkgdir}/usr/share/themes/compiz-xfce-greybird"
+ cp -r metacity-1/ "${pkgdir}/usr/share/themes/compiz-xfce-greybird"
+ rm "${pkgdir}/usr/share/themes/compiz-xfce-greybird/metacity-1/metacity-theme-2.xml"
+ sed -i 's|Greybird|compiz-xfce-greybird|' "${pkgdir}/usr/share/themes/compiz-xfce-greybird/metacity-1/metacity-theme-3.xml"
+}
+
diff --git a/compiz-gtk-decorator-theme-selector b/compiz-gtk-decorator-theme-selector
new file mode 100755
index 000000000000..bca2a8da5642
--- /dev/null
+++ b/compiz-gtk-decorator-theme-selector
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+SAVEIFS=$IFS
+IFS=$(echo -en "\n\b")
+
+if [ ! -f /usr/bin/metacity ]; then
+ zenity --warning --text="<b>You do not appear to have Metacity installed.</b>\n\nThe Compiz GTK window decorator uses Metacity libraries to operate. The Metacity theme is what this tool adjusts.\n\nInstall the metacity package if you would like to use the Compiz GTK window decorator."
+fi
+
+if [ -f ~/.config/compiz-manjaro-gtk-decorator-theme.cfg ]; then
+ rm ~/.config/compiz-manjaro-gtk-decorator-theme.cfg
+ gsettings reset org.gnome.desktop.wm.preferences titlebar-uses-system-font
+fi
+
+main_window() {
+ selection=$(
+ zenity --height 450 --width 300 --list --ok-label="Apply" --cancel-label="Close" --title="Compiz GTK decorator theme" \
+ --column="Installed Metacity themes:" "Compiz GWD default" \
+ $(
+ for i in /usr/share/themes/*; do
+ if [ -f "$i"/metacity-1/metacity-theme-3.xml ]; then
+ cat "$i"/metacity-1/metacity-theme-3.xml | grep "</name>" | sed 's/^.*<name>//' | sed 's|</name>||' | sed 's/ /-/'
+ fi
+ if [ -f "$i"/metacity-1/metacity-theme-2.xml ] && [ ! -f "$i"/metacity-1/metacity-theme-3.xml ]; then
+ cat "$i"/metacity-1/metacity-theme-2.xml | grep "</name>" | sed 's/^.*<name>//' | sed 's|</name>||' | sed 's/ /-/'
+ fi
+ if [ -f "$i"/metacity-1/metacity-theme-1.xml ] && [ ! -f "$i"/metacity-1/metacity-theme-2.xml ] && [ ! -f "$i"/metacity-1/metacity-theme-3.xml ]; then
+ cat "$i"/metacity-1/metacity-theme-1.xml | grep "</name>" | sed 's/^.*<name>//' | sed 's|</name>||' | sed 's/ /-/'
+ fi
+ done
+ )
+ )
+}
+
+while [ $? = 0 ]; do
+if [ "$selection" == "Compiz GWD default" ]; then
+ gsettings set org.gnome.metacity theme ""
+elif [ "$selection" != "" ]; then
+ gsettings set org.gnome.metacity theme "$selection"
+fi
+main_window
+done
+
+IFS=$SAVEIFS
diff --git a/compiz-gtk-decorator-theme.desktop b/compiz-gtk-decorator-theme.desktop
new file mode 100644
index 000000000000..d044c784d805
--- /dev/null
+++ b/compiz-gtk-decorator-theme.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Name=Compiz GTK decorator theme
+Comment=Set the theme for the Compiz GTK window decorator
+Icon=ccsm
+Exec=compiz-gtk-decorator-theme-selector
+Terminal=false
+Type=Application
+Categories=Compiz;Settings;DesktopSettings;X-XFCE-SettingsDialog;X-XFCE-OtherSettings;
+NotShowIn=MATE;
+StartupNotify=true
diff --git a/compiz-manjaro-decoratortheme b/compiz-manjaro-decoratortheme
new file mode 100755
index 000000000000..4ab78267bc70
--- /dev/null
+++ b/compiz-manjaro-decoratortheme
@@ -0,0 +1,11 @@
+#!/bin/bash
+gsettings reset org.gnome.desktop.wm.preferences theme
+
+if [ -f /usr/bin/xfconf-query ] && [ "$(xfconf-query -c xsettings -p /Net/ThemeName)" == "Menda" ]; then
+ gsettings set org.gnome.desktop.wm.preferences theme "Menda"
+fi
+
+mkdir -p ~/.config/autostart
+rm ~/.config/autostart/compiz-manjaro-decoratortheme.desktop
+cp /etc/xdg/autostart/compiz-manjaro-decoratortheme.desktop ~/.config/autostart/
+sed -i 's|Hidden=false|Hidden=true|' ~/.config/autostart/compiz-manjaro-decoratortheme.desktop
diff --git a/compiz-manjaro-decoratortheme.desktop b/compiz-manjaro-decoratortheme.desktop
new file mode 100644
index 000000000000..76eb7ecb3aa5
--- /dev/null
+++ b/compiz-manjaro-decoratortheme.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=0.9.4
+Type=Application
+Name=Compiz-Manjaro decorator theme enabler
+Comment=
+Exec=compiz-manjaro-decoratortheme
+OnlyShowIn=XFCE;
+StartupNotify=false
+Terminal=false
+Hidden=false
diff --git a/compiz-manjaro-defaults.patch b/compiz-manjaro-defaults.patch
new file mode 100644
index 000000000000..71bf48fa5275
--- /dev/null
+++ b/compiz-manjaro-defaults.patch
@@ -0,0 +1,253 @@
+diff -Naur a/metadata/core.xml.in b/metadata/core.xml.in
+--- a/metadata/core.xml.in 2014-11-07 00:07:52.000000000 +1100
++++ b/metadata/core.xml.in 2014-12-18 02:58:05.830223000 +1100
+@@ -215,7 +215,7 @@
+ <option name="window_menu_button" type="button">
+ <_short>Window Menu</_short>
+ <_long>Window menu button binding</_long>
+- <default>&lt;Alt&gt;Button3</default>
++ <default>&lt;Alt&gt;Button2</default>
+ </option>
+ <option name="show_desktop_key" type="key">
+ <_short>Show Desktop</_short>
+@@ -254,14 +254,14 @@
+ <option name="hsize" type="int">
+ <_short>Horizontal Virtual Size</_short>
+ <_long>Screen size multiplier for horizontal virtual size</_long>
+- <default>4</default>
++ <default>2</default>
+ <min>1</min>
+ <max>32</max>
+ </option>
+ <option name="vsize" type="int">
+ <_short>Vertical Virtual Size</_short>
+ <_long>Screen size multiplier for vertical virtual size</_long>
+- <default>1</default>
++ <default>2</default>
+ <min>1</min>
+ <max>32</max>
+ </option>
+diff -Naur a/plugins/animation/animation.xml.in b/plugins/animation/animation.xml.in
+--- a/plugins/animation/animation.xml.in 2014-11-07 00:07:52.000000000 +1100
++++ b/plugins/animation/animation.xml.in 2014-12-18 02:58:05.830223000 +1100
+@@ -58,8 +58,8 @@
+ <_long>The windows that will be animated.</_long>
+ <type>match</type>
+ <default>
+- <value>(type=Normal | Dialog | ModalDialog | Unknown) &amp; !(name=gnome-screensaver)</value>
+- <value>(type=Menu | PopupMenu | DropdownMenu | Combo)</value>
++ <value>(type=Normal) &amp; !(name=gnome-screensaver)</value>
++ <value>(type=Menu | PopupMenu | DropdownMenu | Combo | Dialog | ModalDialog | Unknown)</value>
+ <value>(type=Tooltip | Notification | Utility) &amp; !(name=compiz) &amp; !(title=notify-osd)</value>
+ </default>
+ </option>
+@@ -124,8 +124,8 @@
+ <_long>The windows that will be animated.</_long>
+ <type>match</type>
+ <default>
+- <value>(type=Normal | Dialog | ModalDialog | Unknown) &amp; !(name=gnome-screensaver)</value>
+- <value>(type=Menu | PopupMenu | DropdownMenu | Combo)</value>
++ <value>(type=Normal) &amp; !(name=gnome-screensaver)</value>
++ <value>(type=Menu | PopupMenu | DropdownMenu | Combo | Dialog | ModalDialog | Unknown)</value>
+ <value>(type=Tooltip | Notification | Utility) &amp; !(name=compiz) &amp; !(title=notify-osd)</value>
+ </default>
+ </option>
+@@ -168,7 +168,7 @@
+ <extensible/>
+ <sort start="2"/>
+ <default>
+- <value>animation:Magic Lamp</value>
++ <value>animation:Zoom</value>
+ </default>
+ </option>
+ <option name="minimize_durations" type="list">
+@@ -178,7 +178,7 @@
+ <min>50</min>
+ <max>4000</max>
+ <default>
+- <value>300</value>
++ <value>250</value>
+ </default>
+ </option>
+ <option name="minimize_matches" type="list">
+@@ -226,7 +226,7 @@
+ <extensible/>
+ <sort start="2"/>
+ <default>
+- <value>animation:Magic Lamp</value>
++ <value>animation:Zoom</value>
+ </default>
+ </option>
+ <option name="unminimize_durations" type="list">
+@@ -236,7 +236,7 @@
+ <min>50</min>
+ <max>4000</max>
+ <default>
+- <value>300</value>
++ <value>250</value>
+ </default>
+ </option>
+ <option name="unminimize_matches" type="list">
+diff -Naur a/plugins/composite/composite.xml.in b/plugins/composite/composite.xml.in
+--- a/plugins/composite/composite.xml.in 2014-11-07 00:07:52.000000000 +1100
++++ b/plugins/composite/composite.xml.in 2014-12-18 02:58:05.830223000 +1100
+@@ -24,7 +24,7 @@
+ <option name="unredirect_fullscreen_windows" type="bool">
+ <_short>Unredirect Fullscreen Windows</_short>
+ <_long>Allow drawing of fullscreen windows to not be redirected to offscreen pixmaps</_long>
+- <default>true</default>
++ <default>false</default>
+ </option>
+ <option name="unredirect_match" type="match">
+ <_short>Unredirect Match</_short>
+diff -Naur a/plugins/expo/expo.xml.in b/plugins/expo/expo.xml.in
+--- a/plugins/expo/expo.xml.in 2014-11-07 00:07:52.000000000 +1100
++++ b/plugins/expo/expo.xml.in 2014-12-18 02:58:05.830223000 +1100
+@@ -25,7 +25,7 @@
+ <option name="expo_key" type="key">
+ <_short>Expo Key</_short>
+ <_long>Initiate or terminate Expo mode with this keyboard shortcut.</_long>
+- <default>&lt;Super&gt;e</default>
++ <default></default>
+ </option>
+ <option name="expo_button" type="button">
+ <_short>Expo Button</_short>
+@@ -80,7 +80,7 @@
+ <option name="zoom_time" type="float">
+ <_short>Animation Duration</_short>
+ <_long>Duration of the selected animation (in seconds).</_long>
+- <default>0.5</default>
++ <default>0.25</default>
+ <min>0.1</min>
+ <max>5.0</max>
+ <precision>0.1</precision>
+@@ -232,7 +232,7 @@
+ <option name="reflection" type="bool">
+ <_short>Reflection</_short>
+ <_long>Render a realtime reflection of the viewports on the ground.</_long>
+- <default>true</default>
++ <default>false</default>
+ </option>
+ <option name="ground_color1" type="color">
+ <_short>Ground Color (near)</_short>
+diff -Naur a/plugins/grid/grid.xml.in b/plugins/grid/grid.xml.in
+--- a/plugins/grid/grid.xml.in 2014-11-07 00:07:52.000000000 +1100
++++ b/plugins/grid/grid.xml.in 2014-12-18 02:58:05.830223000 +1100
+@@ -566,16 +566,16 @@
+ <option name="animation_duration" type="int">
+ <_short>Preview Animation Duration</_short>
+ <_long>Preview animation duration (in ms).</_long>
+- <default>350</default>
++ <default>250</default>
+ <min>0</min>
+ </option>
+ <option name="outline_color" type="color">
+ <_short>Preview Outline Color</_short>
+ <_long>Color and opacity of the resize indicator preview outline.</_long>
+ <default>
+- <red>0xfbfb</red>
+- <green>0x8b8b</green>
+- <blue>0x0</blue>
++ <red>0x8c8c</red>
++ <green>0xbcbc</green>
++ <blue>0x6565</blue>
+ <alpha>0x9f9f</alpha>
+ </default>
+ </option>
+@@ -583,9 +583,9 @@
+ <_short>Preview Fill Color</_short>
+ <_long>Fill color and opacity of the resize indicator preview.</_long>
+ <default>
+- <red>0xfbfb</red>
+- <green>0x8b8b</green>
+- <blue>0x0</blue>
++ <red>0x8c8c</red>
++ <green>0xbcbc</green>
++ <blue>0x6565</blue>
+ <alpha>0x4f4f</alpha>
+ </default>
+ </option>
+diff -Naur a/plugins/place/place.xml.in b/plugins/place/place.xml.in
+--- a/plugins/place/place.xml.in 2014-11-07 00:07:52.000000000 +1100
++++ b/plugins/place/place.xml.in 2014-12-18 03:54:37.601201910 +1100
+@@ -84,21 +84,33 @@
+ <_short>Positioned windows</_short>
+ <_long>Windows that should be positioned by default</_long>
+ <type>match</type>
++ <default>
++ <value>title=Whisker Menu</value>
++ </default>
+ </option>
+ <option name="position_x_values" type="list">
+ <_short>X Positions</_short>
+ <_long>X position values</_long>
+ <type>int</type>
++ <default>
++ <value>-1</value>
++ </default>
+ </option>
+ <option name="position_y_values" type="list">
+ <_short>Y Positions</_short>
+ <_long>Y position values</_long>
+ <type>int</type>
++ <default>
++ <value>-1</value>
++ </default>
+ </option>
+ <option name="position_constrain_workarea" type="list">
+ <_short>Keep In Workarea</_short>
+ <_long>Keep placed window in work area, even if that means that the position might differ from the specified position</_long>
+ <type>bool</type>
++ <default>
++ <value>false</value>
++ </default>
+ </option>
+ </subgroup>
+ <subgroup>
+diff -Naur a/plugins/resize/resize.xml.in b/plugins/resize/resize.xml.in
+--- a/plugins/resize/resize.xml.in 2014-11-07 00:07:52.000000000 +1100
++++ b/plugins/resize/resize.xml.in 2014-12-18 02:58:05.830223000 +1100
+@@ -17,7 +17,7 @@
+ <option name="initiate_button" type="button">
+ <_short>Initiate Window Resize</_short>
+ <_long>Start resizing window</_long>
+- <default>&lt;Alt&gt;Button2</default>
++ <default>&lt;Alt&gt;Button3</default>
+ </option>
+ <option name="initiate_key" type="key">
+ <_short>Initiate Window Resize</_short>
+@@ -28,7 +28,7 @@
+ <option name="mode" type="int">
+ <_short>Default Resize Mode</_short>
+ <_long>Default mode used for window resizing</_long>
+- <default>0</default>
++ <default>2</default>
+ <min>0</min>
+ <max>3</max>
+ <desc>
+@@ -62,9 +62,9 @@
+ <_short>Border Color</_short>
+ <_long>Border color used for outline and rectangle resize modes</_long>
+ <default>
+- <red>0x2f2f</red>
+- <green>0x2f2f</green>
+- <blue>0x4f4f</blue>
++ <red>0x5f5f</red>
++ <green>0x8080</green>
++ <blue>0x4444</blue>
+ <alpha>0x9f9f</alpha>
+ </default>
+ </option>
+@@ -72,9 +72,9 @@
+ <_short>Fill Color</_short>
+ <_long>Fill color used for rectangle resize mode</_long>
+ <default>
+- <red>0x2f2f</red>
+- <green>0x2f2f</green>
+- <blue>0x4f4f</blue>
++ <red>0x3939</red>
++ <green>0x4c4c</green>
++ <blue>0x2929</blue>
+ <alpha>0x4f4f</alpha>
+ </default>
+ </option>
diff --git a/compiz-manjaro-mate-decoratortheme b/compiz-manjaro-mate-decoratortheme
new file mode 100755
index 000000000000..b555cb83bf98
--- /dev/null
+++ b/compiz-manjaro-mate-decoratortheme
@@ -0,0 +1,7 @@
+#!/bin/bash
+gsettings set org.gnome.desktop.wm.preferences theme $(gsettings get org.mate.interface gtk-theme | sed "s/'//g")
+
+mkdir -p ~/.config/autostart
+rm ~/.config/autostart/compiz-manjaro-mate-decoratortheme.desktop
+cp /etc/xdg/autostart/compiz-manjaro-mate-decoratortheme.desktop ~/.config/autostart/
+sed -i 's|Hidden=false|Hidden=true|' ~/.config/autostart/compiz-manjaro-mate-decoratortheme.desktop
diff --git a/compiz-manjaro-mate-decoratortheme.desktop b/compiz-manjaro-mate-decoratortheme.desktop
new file mode 100644
index 000000000000..fdfb88333bb0
--- /dev/null
+++ b/compiz-manjaro-mate-decoratortheme.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=0.9.4
+Type=Application
+Name=Compiz-Manjaro-MATE decorator theme enabler
+Comment=
+Exec=compiz-manjaro-mate-decoratortheme
+OnlyShowIn=MATE;
+StartupNotify=false
+Terminal=false
+Hidden=false
diff --git a/compiz-manjaro.gschema.override b/compiz-manjaro.gschema.override
new file mode 100644
index 000000000000..e1f6f40def28
--- /dev/null
+++ b/compiz-manjaro.gschema.override
@@ -0,0 +1,9 @@
+[org.gnome.desktop.wm.preferences]
+button-layout=":minimize,maximize,close"
+titlebar-uses-system-font=true
+
+[org.gnome.metacity]
+theme="compiz-xfce-greybird"
+
+[org.mate.session.required-components]
+windowmanager="compiz"
diff --git a/compiz-manjaro.install b/compiz-manjaro.install
new file mode 100644
index 000000000000..91829bac1674
--- /dev/null
+++ b/compiz-manjaro.install
@@ -0,0 +1,81 @@
+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
+
+ # Xfce autostart. This sed command generally won't work on initial installation, but that's ok, it's dealt with elsewhere.
+ sed -i 's|xfwm4|compiz|' /home/*/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml 2>/dev/null
+
+## This shouldn't be needed anymore, but the removal warning is.
+# echo ""
+# echo "** XFCE USERS **"
+# echo "** It's recommended you clear your saved sessions before **"
+# echo "** logging out and back in: **"
+# echo "** **"
+# echo "** Menu -> Settings -> Session and Startup -> Session tab **"
+# echo "** 'Clear saved sessions' button **"
+# echo "** **"
+# echo "** Make sure 'Save session for future logins' is NOT ticked **"
+# echo "** in the log out window. **"
+# echo "** Log out and back in, then Compiz should be active. **"
+# echo ""
+
+ echo ""
+ echo "*** Xfce and MATE users just log out ***"
+ echo "*** and back in, Compiz will autostart ***"
+ echo ""
+}
+
+post_upgrade() {
+ 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_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
+
+ # Xfce autostart removal. The first sed command remains to reverse actions made by earlier revisions of the package.
+ sed -i 's|compiz|xfwm4|' /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml 2>/dev/null
+ sed -i 's|compiz|xfwm4|' /home/*/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml 2>/dev/null
+ rm /home/*/.config/autostart/compiz-xfce-autostart.desktop 2>/dev/null
+ rm /home/*/.config/autostart/compiz-manjaro-decoratortheme.desktop 2>/dev/null
+ # MATE initial decoration fix removal
+ rm /home/*/.config/autostart/compiz-manjaro-mate-decoratortheme.desktop 2>/dev/null
+
+ echo ""
+ echo "** XFCE USERS **"
+ echo "** It's recommended you clear your saved sessions before **"
+ echo "** logging out and back in: **"
+ echo "** **"
+ echo "** Menu -> Settings -> Session and Startup -> Session tab **"
+ echo "** 'Clear saved sessions' button **"
+ echo "** **"
+ echo "** Make sure 'Save session for future logins' is NOT ticked **"
+ echo "** in the log out window. **"
+ echo "** Log out and back in, then Xfwm4 should be restored. **"
+ echo ""
+}
+
diff --git a/compiz-xfce-autostart b/compiz-xfce-autostart
new file mode 100755
index 000000000000..d8f008d0d0ea
--- /dev/null
+++ b/compiz-xfce-autostart
@@ -0,0 +1,25 @@
+#!/bin/bash
+if [ -f ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml ] && [ "$(grep -i 'xfwm4' ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml)" != "" ]; then
+ sed -i 's|xfwm4|compiz|' ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml
+elif [ -f ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml ] && [ "$(grep -i 'compiz' ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml)" == "" ]; then
+ mv ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml.backup
+ cp /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml
+ sed -i 's|xfwm4|compiz|' ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml
+elif [ ! -f ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml ]; then
+ cp /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml
+ sed -i 's|xfwm4|compiz|' ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml
+fi
+
+mkdir -p ~/.config/autostart
+rm ~/.config/autostart/compiz-xfce-autostart.desktop
+cp /etc/xdg/autostart/compiz-xfce-autostart.desktop ~/.config/autostart/
+sed -i 's|Hidden=false|Hidden=true|' ~/.config/autostart/compiz-xfce-autostart.desktop
+
+mkdir -p ~/.local/bin
+rm ~/.local/bin/compiz-xfce-uninstall-helper
+rm ~/.config/autostart/compiz-xfce-uninstall-helper.desktop
+cp /usr/share/compiz-xfce/compiz-xfce-uninstall-helper ~/.local/bin/
+cp /usr/share/compiz-xfce/compiz-xfce-uninstall-helper.desktop ~/.config/autostart/
+
+## This first-time run when it's replacing a running xfwm4, we run it twice cause of bugs
+compiz --replace ; exec compiz --replace
diff --git a/compiz-xfce-autostart.desktop b/compiz-xfce-autostart.desktop
new file mode 100644
index 000000000000..19839dad2006
--- /dev/null
+++ b/compiz-xfce-autostart.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=0.9.4
+Type=Application
+Name=Compiz-Xfce autostart enabler
+Comment=
+Exec=compiz-xfce-autostart
+OnlyShowIn=XFCE;
+StartupNotify=false
+Terminal=false
+Hidden=false
diff --git a/compiz-xfce-uninstall-helper b/compiz-xfce-uninstall-helper
new file mode 100644
index 000000000000..240468eb04f5
--- /dev/null
+++ b/compiz-xfce-uninstall-helper
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+if [ ! -f /usr/bin/compiz ]; then
+ xfwm4 --daemon
+ rm ~/.config/autostart/compiz-xfce-uninstall-helper.desktop
+ rm ~/.local/bin/compiz-xfce-uninstall-helper
+fi
diff --git a/compiz-xfce-uninstall-helper.desktop b/compiz-xfce-uninstall-helper.desktop
new file mode 100644
index 000000000000..731719b2d391
--- /dev/null
+++ b/compiz-xfce-uninstall-helper.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=0.9.4
+Type=Application
+Name=Compiz-Xfce uninstallation helper
+Comment=
+Exec=sh -c ~/.local/bin/compiz-xfce-uninstall-helper
+OnlyShowIn=XFCE;
+StartupNotify=false
+Terminal=false
+Hidden=false
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..150a7362e239
--- /dev/null
+++ b/metacity-3_16.patch
@@ -0,0 +1,6172 @@
+diff -Nur original/gtk/CMakeLists.txt modified/gtk/CMakeLists.txt
+--- original/gtk/CMakeLists.txt 2015-04-11 14:38:52.624406000 +0100
++++ modified/gtk/CMakeLists.txt 2015-04-11 14:34:11.000000000 +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-04-11 14:38:52.624406000 +0100
++++ modified/gtk/config.h.gtk.in 2015-04-11 14:34:11.000000000 +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-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/cairo.c 2015-04-11 14:34:11.000000000 +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-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/CMakeLists.txt 2015-04-11 14:34:11.000000000 +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-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/decorator.c 2015-04-11 14:34:11.000000000 +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-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/events.c 2015-04-11 14:34:11.000000000 +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-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/frames.c 2015-04-11 14:34:11.000000000 +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-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/gtk-window-decorator.c 2015-04-11 14:34:11.000000000 +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-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/gtk-window-decorator.h 2015-04-11 14:34:11.000000000 +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.c modified/gtk/window-decorator/gwd-settings.c
+--- original/gtk/window-decorator/gwd-settings.c 2015-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/gwd-settings.c 2015-04-11 14:34:11.000000000 +0100
+@@ -61,21 +61,20 @@
+ GWD_SETTINGS_IMPL_PROPERTY_INACTIVE_SHADOW = 2,
+ GWD_SETTINGS_IMPL_PROPERTY_USE_TOOLTIPS = 3,
+ GWD_SETTINGS_IMPL_PROPERTY_DRAGGABLE_BORDER_WIDTH = 4,
+- GWD_SETTINGS_IMPL_PROPERTY_ATTACH_MODAL_DIALOGS = 5,
+- GWD_SETTINGS_IMPL_PROPERTY_BLUR_CHANGED = 6,
+- GWD_SETTINGS_IMPL_PROPERTY_METACITY_THEME = 7,
+- GWD_SETTINGS_IMPL_PROPERTY_ACTIVE_OPACITY = 8,
+- GWD_SETTINGS_IMPL_PROPERTY_INACTIVE_OPACITY = 9,
+- GWD_SETTINGS_IMPL_PROPERTY_ACTIVE_SHADE_OPACITY = 10,
+- GWD_SETTINGS_IMPL_PROPERTY_INACTIVE_SHADE_OPACITY = 11,
+- GWD_SETTINGS_IMPL_PROPERTY_BUTTON_LAYOUT = 12,
+- GWD_SETTINGS_IMPL_PROPERTY_TITLEBAR_ACTION_DOUBLE_CLICK = 13,
+- GWD_SETTINGS_IMPL_PROPERTY_TITLEBAR_ACTION_MIDDLE_CLICK = 14,
+- GWD_SETTINGS_IMPL_PROPERTY_TITLEBAR_ACTION_RIGHT_CLICK = 15,
+- GWD_SETTINGS_IMPL_PROPERTY_MOUSE_WHEEL_ACTION = 16,
+- GWD_SETTINGS_IMPL_PROPERTY_TITLEBAR_FONT = 17,
+- GWD_SETTINGS_IMPL_PROPERTY_CMDLINE_OPTIONS = 18,
+- GWD_SETTINGS_IMPL_PROPERTY_SETTINGS_NOTIFIED = 19
++ GWD_SETTINGS_IMPL_PROPERTY_BLUR_CHANGED = 5,
++ GWD_SETTINGS_IMPL_PROPERTY_METACITY_THEME = 6,
++ GWD_SETTINGS_IMPL_PROPERTY_ACTIVE_OPACITY = 7,
++ GWD_SETTINGS_IMPL_PROPERTY_INACTIVE_OPACITY = 8,
++ GWD_SETTINGS_IMPL_PROPERTY_ACTIVE_SHADE_OPACITY = 9,
++ GWD_SETTINGS_IMPL_PROPERTY_INACTIVE_SHADE_OPACITY = 10,
++ GWD_SETTINGS_IMPL_PROPERTY_BUTTON_LAYOUT = 11,
++ GWD_SETTINGS_IMPL_PROPERTY_TITLEBAR_ACTION_DOUBLE_CLICK = 12,
++ GWD_SETTINGS_IMPL_PROPERTY_TITLEBAR_ACTION_MIDDLE_CLICK = 13,
++ GWD_SETTINGS_IMPL_PROPERTY_TITLEBAR_ACTION_RIGHT_CLICK = 14,
++ GWD_SETTINGS_IMPL_PROPERTY_MOUSE_WHEEL_ACTION = 15,
++ GWD_SETTINGS_IMPL_PROPERTY_TITLEBAR_FONT = 16,
++ GWD_SETTINGS_IMPL_PROPERTY_CMDLINE_OPTIONS = 17,
++ GWD_SETTINGS_IMPL_PROPERTY_SETTINGS_NOTIFIED = 18
+ };
+
+ enum
+@@ -92,7 +91,6 @@
+ decor_shadow_options_t inactive_shadow;
+ gboolean use_tooltips;
+ gint draggable_border_width;
+- gboolean attach_modal_dialogs;
+ gint blur_type;
+ gchar *metacity_theme;
+ gdouble metacity_active_opacity;
+@@ -261,24 +259,6 @@
+ }
+
+ static gboolean
+-gwd_settings_attach_modal_dialogs_changed (GWDSettingsWritable *settings,
+- gboolean attach_modal_dialogs)
+-{
+- GWDSettingsImpl *settings_impl = GWD_SETTINGS_IMPL (settings);
+- GWDSettingsImplPrivate *priv = GET_PRIVATE (settings_impl);
+-
+- if (priv->attach_modal_dialogs != attach_modal_dialogs)
+- {
+- priv->attach_modal_dialogs = attach_modal_dialogs;
+- append_to_notify_funcs (settings_impl, gwd_settings_notified_update_decorations);
+- release_notify_funcs (settings_impl);
+- return TRUE;
+- }
+- else
+- return FALSE;
+-}
+-
+-static gboolean
+ gwd_settings_blur_changed (GWDSettingsWritable *settings,
+ const gchar *type)
+
+@@ -554,7 +534,6 @@
+ interface->shadow_property_changed = gwd_settings_shadow_property_changed;
+ interface->use_tooltips_changed = gwd_settings_use_tooltips_changed;
+ interface->draggable_border_width_changed = gwd_settings_draggable_border_width_changed;
+- interface->attach_modal_dialogs_changed = gwd_settings_attach_modal_dialogs_changed;
+ interface->blur_changed = gwd_settings_blur_changed;
+ interface->metacity_theme_changed = gwd_settings_metacity_theme_changed;
+ interface->opacity_changed = gwd_settings_opacity_changed;
+@@ -659,9 +638,6 @@
+ case GWD_SETTINGS_IMPL_PROPERTY_DRAGGABLE_BORDER_WIDTH:
+ g_value_set_int (value, priv->draggable_border_width);
+ break;
+- case GWD_SETTINGS_IMPL_PROPERTY_ATTACH_MODAL_DIALOGS:
+- g_value_set_boolean (value, priv->attach_modal_dialogs);
+- break;
+ case GWD_SETTINGS_IMPL_PROPERTY_BLUR_CHANGED:
+ g_value_set_int (value, priv->blur_type);
+ break;
+@@ -729,9 +705,6 @@
+ GWD_SETTINGS_IMPL_PROPERTY_DRAGGABLE_BORDER_WIDTH,
+ "draggable-border-width");
+ g_object_class_override_property (object_class,
+- GWD_SETTINGS_IMPL_PROPERTY_ATTACH_MODAL_DIALOGS,
+- "attach-modal-dialogs");
+- g_object_class_override_property (object_class,
+ GWD_SETTINGS_IMPL_PROPERTY_BLUR_CHANGED,
+ "blur");
+ g_object_class_override_property (object_class,
+@@ -807,7 +780,6 @@
+ priv->inactive_shadow.shadow_color[1] = 0;
+ priv->inactive_shadow.shadow_color[2] = 0;
+ priv->draggable_border_width = DRAGGABLE_BORDER_WIDTH_DEFAULT;
+- priv->attach_modal_dialogs = ATTACH_MODAL_DIALOGS_DEFAULT;
+ priv->blur_type = BLUR_TYPE_DEFAULT;
+ priv->metacity_theme = g_strdup (METACITY_THEME_DEFAULT);
+ priv->metacity_active_opacity = METACITY_ACTIVE_OPACITY_DEFAULT;
+diff -Nur original/gtk/window-decorator/gwd-settings-interface.c modified/gtk/window-decorator/gwd-settings-interface.c
+--- original/gtk/window-decorator/gwd-settings-interface.c 2015-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/gwd-settings-interface.c 2015-04-11 14:34:11.000000000 +0100
+@@ -34,7 +34,6 @@
+ const gchar *INACTIVE_SHADOW_COLOR_DEFAULT = "#00000000";
+
+ const guint DRAGGABLE_BORDER_WIDTH_DEFAULT = 7;
+-const gboolean ATTACH_MODAL_DIALOGS_DEFAULT = FALSE;
+ const gint BLUR_TYPE_DEFAULT = BLUR_TYPE_NONE;
+
+ const gchar *METACITY_THEME_DEFAULT = "Adwaita";
+@@ -83,12 +82,6 @@
+ DRAGGABLE_BORDER_WIDTH_DEFAULT,
+ G_PARAM_READABLE));
+ g_object_interface_install_property (settings_interface,
+- g_param_spec_boolean ("attach-modal-dialogs",
+- "Attach modal dialogs",
+- "Attach modal dialogs setting",
+- ATTACH_MODAL_DIALOGS_DEFAULT,
+- G_PARAM_READABLE));
+- g_object_interface_install_property (settings_interface,
+ g_param_spec_int ("blur",
+ "Blur Type",
+ "Blur type property",
+diff -Nur original/gtk/window-decorator/gwd-settings-notified.c modified/gtk/window-decorator/gwd-settings-notified.c
+--- original/gtk/window-decorator/gwd-settings-notified.c 2015-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/gwd-settings-notified.c 2015-04-11 14:34:11.000000000 +0100
+@@ -200,17 +200,6 @@
+ interface->update_metacity_theme = gwd_settings_notified_impl_update_metacity_theme;
+ }
+
+-static void gwd_settings_notified_impl_dispose (GObject *object)
+-{
+- GWDSettingsNotifiedImplPrivate *priv = GET_PRIVATE (object);
+-
+- if (priv->screen)
+- {
+- g_object_unref (priv->screen);
+- priv->screen = NULL;
+- }
+-}
+-
+ static void gwd_settings_notified_impl_finalize (GObject *object)
+ {
+ G_OBJECT_CLASS (gwd_settings_notified_impl_parent_class)->finalize (object);
+@@ -240,7 +229,6 @@
+
+ g_type_class_add_private (klass, sizeof (GWDSettingsNotifiedImplPrivate));
+
+- object_class->dispose = gwd_settings_notified_impl_dispose;
+ object_class->finalize = gwd_settings_notified_impl_finalize;
+ object_class->set_property = gwd_settings_notified_impl_set_property;
+
+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-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/gwd-settings-storage-gsettings.c 2015-04-11 14:34:11.000000000 +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,8 +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_ATTACH_MODAL_DIALOGS = "attach-modal-dialogs";
+-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));
+@@ -75,10 +79,11 @@
+
+ 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;
+@@ -86,6 +91,7 @@
+ typedef struct _GWDSettingsStorageGSettingsPrivate
+ {
+ GSettings *desktop;
++ GSettings *metacity;
+ GSettings *mutter;
+ GSettings *gwd;
+ GWDSettingsWritable *writable;
+@@ -120,20 +126,6 @@
+ }
+
+ static gboolean
+-gwd_settings_storage_gsettings_update_attach_modal_dialogs (GWDSettingsStorage *settings)
+-{
+- GWDSettingsStorageGSettings *storage = GWD_SETTINGS_STORAGE_GSETTINGS (settings);
+- GWDSettingsStorageGSettingsPrivate *priv = GET_PRIVATE (storage);
+-
+- if (!priv->mutter)
+- return FALSE;
+-
+- return gwd_settings_writable_attach_modal_dialogs_changed (priv->writable,
+- g_settings_get_boolean (priv->mutter,
+- ORG_GNOME_MUTTER_ATTACH_MODAL_DIALOGS));
+-}
+-
+-static gboolean
+ gwd_settings_storage_gsettings_update_blur (GWDSettingsStorage *settings)
+ {
+ GWDSettingsStorageGSettings *storage = GWD_SETTINGS_STORAGE_GSETTINGS (settings);
+@@ -150,20 +142,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
+@@ -275,7 +281,6 @@
+ {
+ interface->update_use_tooltips = gwd_settings_storage_gsettings_update_use_tooltips;
+ interface->update_draggable_border_width = gwd_settings_storage_gsettings_update_draggable_border_width;
+- interface->update_attach_modal_dialogs = gwd_settings_storage_gsettings_update_attach_modal_dialogs;
+ interface->update_blur = gwd_settings_storage_gsettings_update_blur;
+ interface->update_metacity_theme = gwd_settings_storage_gsettings_update_metacity_theme;
+ interface->update_opacity = gwd_settings_storage_gsettings_update_opacity;
+@@ -300,6 +305,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);
+@@ -330,6 +341,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);
+
+@@ -355,6 +369,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",
+@@ -388,14 +407,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;
+@@ -405,29 +426,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);
+@@ -488,6 +514,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)
+@@ -496,8 +551,6 @@
+
+ if (strcmp (key, ORG_GNOME_MUTTER_DRAGGABLE_BORDER_WIDTH) == 0)
+ gwd_settings_storage_update_draggable_border_width (storage);
+- else if (strcmp (key, ORG_GNOME_MUTTER_ATTACH_MODAL_DIALOGS) == 0)
+- gwd_settings_storage_update_attach_modal_dialogs (storage);
+ }
+
+ void
+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-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/gwd-settings-storage-gsettings.h 2015-04-11 14:34:11.000000000 +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,8 +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_ATTACH_MODAL_DIALOGS;
+-extern const gchar * ORG_GNOME_MUTTER_DRAGGABLE_BORDER_WIDTH;
+
+ G_END_DECLS
+
+diff -Nur original/gtk/window-decorator/gwd-settings-storage-interface.c modified/gtk/window-decorator/gwd-settings-storage-interface.c
+--- original/gtk/window-decorator/gwd-settings-storage-interface.c 2015-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/gwd-settings-storage-interface.c 2015-04-11 14:34:11.000000000 +0100
+@@ -39,12 +39,6 @@
+ return (*interface->update_draggable_border_width) (settings);
+ }
+
+-gboolean gwd_settings_storage_update_attach_modal_dialogs (GWDSettingsStorage *settings)
+-{
+- GWDSettingsStorageInterface *interface = GWD_SETTINGS_STORAGE_GET_INTERFACE (settings);
+- return (*interface->update_attach_modal_dialogs) (settings);
+-}
+-
+ gboolean gwd_settings_storage_update_blur (GWDSettingsStorage *settings)
+ {
+ GWDSettingsStorageInterface *interface = GWD_SETTINGS_STORAGE_GET_INTERFACE (settings);
+diff -Nur original/gtk/window-decorator/gwd-settings-storage-interface.h modified/gtk/window-decorator/gwd-settings-storage-interface.h
+--- original/gtk/window-decorator/gwd-settings-storage-interface.h 2015-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/gwd-settings-storage-interface.h 2015-04-11 14:34:11.000000000 +0100
+@@ -41,7 +41,6 @@
+
+ gboolean (*update_use_tooltips) (GWDSettingsStorage *settings);
+ gboolean (*update_draggable_border_width) (GWDSettingsStorage *settings);
+- gboolean (*update_attach_modal_dialogs) (GWDSettingsStorage *settings);
+ gboolean (*update_blur) (GWDSettingsStorage *settings);
+ gboolean (*update_metacity_theme) (GWDSettingsStorage *settings);
+ gboolean (*update_opacity) (GWDSettingsStorage *settings);
+@@ -52,7 +51,6 @@
+
+ gboolean gwd_settings_storage_update_use_tooltips (GWDSettingsStorage *settings);
+ gboolean gwd_settings_storage_update_draggable_border_width (GWDSettingsStorage *settings);
+-gboolean gwd_settings_storage_update_attach_modal_dialogs (GWDSettingsStorage *settings);
+ gboolean gwd_settings_storage_update_blur (GWDSettingsStorage *settings);
+ gboolean gwd_settings_storage_update_metacity_theme (GWDSettingsStorage *settings);
+ gboolean gwd_settings_storage_update_opacity (GWDSettingsStorage *settings);
+diff -Nur original/gtk/window-decorator/gwd-settings-writable-interface.c modified/gtk/window-decorator/gwd-settings-writable-interface.c
+--- original/gtk/window-decorator/gwd-settings-writable-interface.c 2015-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/gwd-settings-writable-interface.c 2015-04-11 14:34:11.000000000 +0100
+@@ -85,14 +85,6 @@
+ }
+
+ gboolean
+-gwd_settings_writable_attach_modal_dialogs_changed (GWDSettingsWritable *settings,
+- gboolean attach_modal_dialogs)
+-{
+- GWDSettingsWritableInterface *iface = GWD_SETTINGS_WRITABLE_GET_INTERFACE (settings);
+- return (*iface->attach_modal_dialogs_changed) (settings, attach_modal_dialogs);
+-}
+-
+-gboolean
+ gwd_settings_writable_blur_changed (GWDSettingsWritable *settings,
+ const gchar *blur_type)
+ {
+diff -Nur original/gtk/window-decorator/gwd-settings-writable-interface.h modified/gtk/window-decorator/gwd-settings-writable-interface.h
+--- original/gtk/window-decorator/gwd-settings-writable-interface.h 2015-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/gwd-settings-writable-interface.h 2015-04-11 14:34:11.000000000 +0100
+@@ -56,8 +56,6 @@
+ gboolean new_value);
+ gboolean (*draggable_border_width_changed) (GWDSettingsWritable *settings,
+ gint new_value);
+- gboolean (*attach_modal_dialogs_changed) (GWDSettingsWritable *settings,
+- gboolean new_value);
+ gboolean (*blur_changed) (GWDSettingsWritable *settings,
+ const gchar *type);
+ gboolean (*metacity_theme_changed) (GWDSettingsWritable *settings,
+@@ -108,10 +106,6 @@
+ gint draggable_border_width);
+
+ gboolean
+-gwd_settings_writable_attach_modal_dialogs_changed (GWDSettingsWritable *settings,
+- gboolean attach_modal_dialogs);
+-
+-gboolean
+ gwd_settings_writable_blur_changed (GWDSettingsWritable *settings,
+ const gchar *blur_type);
+
+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-04-11 14:34:11.000000000 +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);
++ /* ------------ */
++
++ 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-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/metacity.c 2015-04-11 14:34:11.000000000 +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);
+-
+- xrect.x = 0;
+- xrect.y = i;
+- xrect.width = w;
+- xrect.height = 1;
++ 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);
+- }
++ 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);
+-
+- xrect.x = width - w;
+- xrect.y = fgeom->bottom_height - i - 1;
+- xrect.width = w;
+- xrect.height = 1;
++ 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;
+
+- 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,286 +668,290 @@
+
+ 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);
++ {
++ top_region = meta_get_top_border_region (&fgeom, fgeom.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, 0,
+- d->picture,
+- &d->border_layout,
+- BORDER_TOP,
+- top_region,
+- alpha * 0xffff,
+- shade_alpha,
+- 0);
+- }
+-
+- if (fgeom.bottom_height)
+- {
+- bottom_region = meta_get_bottom_border_region (&fgeom, clip.width);
+-
+- 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.left_width)
+- {
+- left_region = meta_get_left_border_region (&fgeom, clip.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);
+- }
+-
+- if (fgeom.right_width)
+- {
+- right_region = meta_get_right_border_region (&fgeom, clip.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);
+- }
+-
+- cairo_destroy (cr);
+- cairo_surface_destroy (surface);
+- XRenderFreePicture (xdisplay, src);
++ 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, 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);
++ }
++
++ if (fgeom.right_width)
++ {
++ right_region = meta_get_right_border_region (&fgeom, fgeom.height);
++
++ 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);
+
+ 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;
++
++ gdk_frame_window = gtk_widget_get_window (d->decor_window);
+
+- gtk_image_set_from_pixbuf (GTK_IMAGE (d->decor_image), pixbuf);
+- g_object_unref (pixbuf);
++ 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);
+
+- 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);
++ 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)
+ {
++ MetaTheme *theme;
++ MetaFrameType frame_type;
++ MetaFrameFlags flags;
++ MetaFrameGeometry fgeom;
++ MetaButtonLayout button_layout;
++ MetaFrameBorders borders;
++ gint mutter_draggable_border_width;
+ 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);
++ meta_theme_get_frame_borders (theme, frame_type, d->frame->text_height,
++ flags, &borders);
++
++ mutter_draggable_border_width = 0;
++ g_object_get (settings, "draggable-border-width", &mutter_draggable_border_width, NULL);
++
+ width = 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 +
++ borders.visible.left + borders.visible.right;
++
++ if (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE)
++ width += mutter_draggable_border_width;
++
+ 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;
+- }
+- }
++ 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 + 6;
++ d->button_width = width - min_x;
+ }
+
+-gboolean
+-meta_get_button_position (decor_t *d,
+- gint i,
+- gint width,
+- gint height,
+- gint *x,
+- gint *y,
+- gint *w,
+- gint *h)
++static MetaButtonFunction
++button_to_meta_button_function (gint i)
+ {
+- MetaButtonLayout button_layout;
+- MetaFrameGeometry fgeom;
+- MetaFrameFlags flags;
+- MetaTheme *theme;
+-
+- GdkRectangle clip;
++ 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;
++ }
+
+- MetaButtonSpace *space;
++ return META_BUTTON_FUNCTION_LAST;
++}
+
+- gint mutter_draggable_border_width = 0;
++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;
++ MetaFrameFlags flags;
++ MetaTheme *theme;
++ MetaButtonFunction button_function;
++ MetaButtonSpace *space;
++ gint mutter_draggable_border_width;
+
++ mutter_draggable_border_width = 0;
+ g_object_get (settings, "draggable-border-width", &mutter_draggable_border_width, NULL);
+
+ if (!d->context)
+ {
+- /* undecorated windows implicitly have no buttons */
+- return FALSE;
++ /* undecorated windows implicitly have no buttons */
++ return FALSE;
+ }
+
+ 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));
+
+- switch (i) {
+- case BUTTON_MENU:
+- if (!meta_button_present (&button_layout, META_BUTTON_FUNCTION_MENU))
+- return FALSE;
++ button_function = button_to_meta_button_function (i);
++ if (!meta_button_present (&button_layout, button_function))
++ return FALSE;
+
+- space = &fgeom.menu_rect;
+- break;
++ switch (i)
++ {
++ case BUTTON_MENU:
++ space = &fgeom.menu_rect;
++ break;
+ case BUTTON_MIN:
+- if (!meta_button_present (&button_layout,
+- META_BUTTON_FUNCTION_MINIMIZE))
+- return FALSE;
+-
+- space = &fgeom.min_rect;
+- break;
++ space = &fgeom.min_rect;
++ break;
+ case BUTTON_MAX:
+- if (!meta_button_present (&button_layout,
+- META_BUTTON_FUNCTION_MAXIMIZE))
+- return FALSE;
+-
+- space = &fgeom.max_rect;
+- break;
++ space = &fgeom.max_rect;
++ break;
+ case BUTTON_CLOSE:
+- if (!meta_button_present (&button_layout, META_BUTTON_FUNCTION_CLOSE))
+- return FALSE;
+-
+- space = &fgeom.close_rect;
+- break;
++ space = &fgeom.close_rect;
++ break;
+ case BUTTON_SHADE:
+- if (!meta_button_present (&button_layout, META_BUTTON_FUNCTION_SHADE))
+- return FALSE;
+-
+- space = &fgeom.shade_rect;
+- break;
++ space = &fgeom.shade_rect;
++ break;
+ case BUTTON_ABOVE:
+- if (!meta_button_present (&button_layout, META_BUTTON_FUNCTION_ABOVE))
+- return FALSE;
+-
+- space = &fgeom.above_rect;
+- break;
++ space = &fgeom.above_rect;
++ break;
+ case BUTTON_STICK:
+- if (!meta_button_present (&button_layout, META_BUTTON_FUNCTION_STICK))
+- return FALSE;
+-
+- space = &fgeom.stick_rect;
+- break;
++ space = &fgeom.stick_rect;
++ break;
+ case BUTTON_UNSHADE:
+- if (!meta_button_present (&button_layout, META_BUTTON_FUNCTION_UNSHADE))
+- return FALSE;
+-
+- space = &fgeom.unshade_rect;
+- break;
++ space = &fgeom.unshade_rect;
++ break;
+ case BUTTON_UNABOVE:
+- if (!meta_button_present (&button_layout, META_BUTTON_FUNCTION_UNABOVE))
+- return FALSE;
+-
+- space = &fgeom.unabove_rect;
+- break;
++ space = &fgeom.unabove_rect;
++ break;
+ case BUTTON_UNSTICK:
+- if (!meta_button_present (&button_layout, META_BUTTON_FUNCTION_UNSTICK))
+- return FALSE;
+-
+- space = &fgeom.unstick_rect;
+- break;
++ space = &fgeom.unstick_rect;
++ break;
+ default:
+- return FALSE;
++ return FALSE;
+ }
+
+ if (!space->clickable.width && !space->clickable.height)
+- return FALSE;
++ return FALSE;
+
+ *x = space->clickable.x;
+ *y = space->clickable.y;
+@@ -959,19 +960,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 +976,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 +994,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;
+-
+- 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)
+- *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;
+- *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;
+- 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;
++ 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;
++
++ 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)
++ *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;
++ *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;
++
++ 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;
+-
+- if (!d->frame_window)
+- {
+- *x += mutter_draggable_border_width;
+- 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;
++ 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;
++
++ if (!d->frame_window)
++ {
++ *x += mutter_draggable_border_width;
++
++ 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;
+-
+- 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 -= 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;
+- }
++ 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;
++
++ 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 -= 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;
+
+- break;
+- }
++ 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 +1363,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 +1389,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 +1410,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)
+- {
+- 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;
++ 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 (buttons);
++ }
+ }
+
+ g_strfreev (sides);
+@@ -1522,42 +1508,38 @@
+ /* Invert the button layout for RTL languages */
+ if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
+ {
+- MetaButtonLayout rtl_layout;
+- int j;
++ MetaButtonLayout rtl_layout;
++ int j;
+
+- meta_initialize_button_layout (&rtl_layout);
++ 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];
+- }
++ 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;
++ new_layout = rtl_layout;
+ }
+
+ meta_button_layout = new_layout;
+@@ -1566,37 +1548,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 +1588,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 +1612,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-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/settings.c 2015-04-11 14:34:11.000000000 +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
+@@ -70,7 +73,6 @@
+ gwd_settings_storage_update_titlebar_actions (storage);
+ gwd_settings_storage_update_blur (storage);
+ gwd_settings_storage_update_draggable_border_width (storage);
+- gwd_settings_storage_update_attach_modal_dialogs (storage);
+ gwd_settings_storage_update_use_tooltips (storage);
+ gwd_process_decor_shadow_property_update ();
+ #else
+diff -Nur original/gtk/window-decorator/switcher.c modified/gtk/window-decorator/switcher.c
+--- original/gtk/window-decorator/switcher.c 2015-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/switcher.c 2015-04-11 14:34:11.000000000 +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-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/tests/CMakeLists.txt 2015-04-11 14:34:11.000000000 +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/compiz_gwd_mock_settings_storage.cpp modified/gtk/window-decorator/tests/compiz_gwd_mock_settings_storage.cpp
+--- original/gtk/window-decorator/tests/compiz_gwd_mock_settings_storage.cpp 2015-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/tests/compiz_gwd_mock_settings_storage.cpp 2015-04-11 14:34:11.000000000 +0100
+@@ -73,13 +73,6 @@
+ return settingsGMock->updateDraggableBorderWidth ();
+ }
+
+-gboolean gwd_mock_settings_storage_update_attach_modal_dialogs (GWDSettingsStorage *settings)
+-{
+- GWDMockSettingsStorage *settingsStorageMock = GWD_MOCK_SETTINGS_STORAGE (settings)
+- GWDMockSettingsStorageGMockInterface *settingsGMock = GET_PRIVATE (settingsStorageMock)->mock;
+- return settingsGMock->updateAttachModalDialogs ();
+-}
+-
+ gboolean gwd_mock_settings_storage_update_blur (GWDSettingsStorage *settings)
+ {
+ GWDMockSettingsStorage *settingsStorageMock = GWD_MOCK_SETTINGS_STORAGE (settings);
+@@ -126,7 +119,6 @@
+ {
+ interface->update_use_tooltips = gwd_mock_settings_storage_update_use_tooltips;
+ interface->update_draggable_border_width = gwd_mock_settings_storage_update_draggable_border_width;
+- interface->update_attach_modal_dialogs = gwd_mock_settings_storage_update_attach_modal_dialogs;
+ interface->update_blur = gwd_mock_settings_storage_update_blur;
+ interface->update_metacity_theme = gwd_mock_settings_storage_update_metacity_theme;
+ interface->update_opacity = gwd_mock_settings_storage_update_opacity;
+diff -Nur original/gtk/window-decorator/tests/compiz_gwd_mock_settings_writable.cpp modified/gtk/window-decorator/tests/compiz_gwd_mock_settings_writable.cpp
+--- original/gtk/window-decorator/tests/compiz_gwd_mock_settings_writable.cpp 2015-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/tests/compiz_gwd_mock_settings_writable.cpp 2015-04-11 14:34:11.000000000 +0100
+@@ -116,14 +116,6 @@
+ }
+
+ gboolean
+-gwd_mock_settings_writable_attach_modal_dialogs_changed (GWDSettingsWritable *settings,
+- gboolean attach_modal_dialogs)
+-{
+- GWDMockSettingsWritableGMockInterface *gmockSettingsWritable = GET_PRIVATE (settings)->mock;
+- return gmockSettingsWritable->attachModalDialogsChanged (attach_modal_dialogs);
+-}
+-
+-gboolean
+ gwd_mock_settings_writable_blur_changed (GWDSettingsWritable *settings,
+ const gchar *blur_type)
+ {
+@@ -187,7 +179,6 @@
+ interface->shadow_property_changed = gwd_mock_settings_writable_shadow_property_changed;
+ interface->use_tooltips_changed = gwd_mock_settings_writable_use_tooltips_changed;
+ interface->draggable_border_width_changed = gwd_mock_settings_writable_draggable_border_width_changed;
+- interface->attach_modal_dialogs_changed = gwd_mock_settings_writable_attach_modal_dialogs_changed;
+ interface->blur_changed = gwd_mock_settings_writable_blur_changed;
+ interface->metacity_theme_changed = gwd_mock_settings_writable_metacity_theme_changed;
+ interface->opacity_changed = gwd_mock_settings_writable_opacity_changed;
+diff -Nur original/gtk/window-decorator/tests/compiz_gwd_mock_settings_writable.h modified/gtk/window-decorator/tests/compiz_gwd_mock_settings_writable.h
+--- original/gtk/window-decorator/tests/compiz_gwd_mock_settings_writable.h 2015-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/tests/compiz_gwd_mock_settings_writable.h 2015-04-11 14:34:11.000000000 +0100
+@@ -59,7 +59,6 @@
+ const gchar *inactive_shadow_color) = 0;
+ virtual gboolean useTooltipsChanged (gboolean newValue) = 0;
+ virtual gboolean draggableBorderWidthChanged (gint newValue) = 0;
+- virtual gboolean attachModalDialogsChanged (gboolean newValue) = 0;
+ virtual gboolean blurChanged (const gchar *type) = 0;
+ virtual gboolean metacityThemeChanged (gboolean useMetacityTheme, const gchar *metacityTheme) = 0;
+ virtual gboolean opacityChanged (gdouble inactiveOpacity,
+@@ -90,7 +89,6 @@
+ gdouble, gdouble, gdouble, gdouble, const gchar *));
+ MOCK_METHOD1 (useTooltipsChanged, gboolean (gboolean));
+ MOCK_METHOD1 (draggableBorderWidthChanged, gboolean (gint));
+- MOCK_METHOD1 (attachModalDialogsChanged, gboolean (gboolean));
+ MOCK_METHOD1 (blurChanged, gboolean (const gchar *));
+ MOCK_METHOD2 (metacityThemeChanged, gboolean (gboolean, const gchar *));
+ MOCK_METHOD4 (opacityChanged, gboolean (gdouble, gdouble, gboolean, gboolean));
+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-04-11 14:34:11.000000000 +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/org.gnome.mutter.gschema.xml modified/gtk/window-decorator/tests/org.gnome.mutter.gschema.xml
+--- original/gtk/window-decorator/tests/org.gnome.mutter.gschema.xml 2015-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/tests/org.gnome.mutter.gschema.xml 2015-04-11 14:34:11.000000000 +0100
+@@ -1,13 +1,6 @@
+ <?xml version="1.0" encoding="UTF-8"?>
+ <schemalist>
+ <schema path="/org/gnome/mutter/" id="org.gnome.mutter" gettext-domain="@GETTEXT_DOMAIN">
+-
+- <key type="b" name="attach-modal-dialogs">
+- <default>false</default>
+- <summary>Attach modal dialogs</summary>
+- <description>When true, instead of having independent titlebars, modal dialogs appear attached to the titlebar of the parent window and are moved together with the parent window.</description>
+- </key>
+-
+ <key type="i" name="draggable-border-width">
+ <default>10</default>
+ <range min="0" max="64"/>
+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-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/tests/test_gwd_settings.cpp 2015-04-11 14:34:11.000000000 +0100
+@@ -198,7 +198,6 @@
+ const gushort INACTIVE_SHADOW_COLOR_VALUE[] = { 0, 0, 0 };
+ const gboolean USE_TOOLTIPS_VALUE = !USE_TOOLTIPS_DEFAULT;
+ const guint DRAGGABLE_BORDER_WIDTH_VALUE = 1;
+- const gboolean ATTACH_MODAL_DIALOGS_VALUE = TRUE;
+ const std::string BLUR_TYPE_TITLEBAR_VALUE ("titlebar");
+ const gint BLUR_TYPE_TITLEBAR_INT_VALUE = BLUR_TYPE_TITLEBAR;
+ const std::string BLUR_TYPE_ALL_VALUE ("all");
+@@ -330,7 +329,6 @@
+ Eq (testing_values::INACTIVE_SHADOW_COLOR_STR_VALUE))).WillOnce (Return (TRUE));
+ EXPECT_CALL (writableGMock, useTooltipsChanged (testing_values::USE_TOOLTIPS_VALUE)).WillOnce (Return (TRUE));
+ EXPECT_CALL (writableGMock, draggableBorderWidthChanged (testing_values::DRAGGABLE_BORDER_WIDTH_VALUE)).WillOnce (Return (TRUE));
+- EXPECT_CALL (writableGMock, attachModalDialogsChanged (testing_values::ATTACH_MODAL_DIALOGS_VALUE)).WillOnce (Return (TRUE));
+ EXPECT_CALL (writableGMock, blurChanged (Eq (testing_values::BLUR_TYPE_TITLEBAR_VALUE))).WillOnce (Return (TRUE));
+ EXPECT_CALL (writableGMock, metacityThemeChanged (TRUE, Eq (testing_values::METACITY_THEME_VALUE))).WillOnce (Return (TRUE));
+ EXPECT_CALL (writableGMock, opacityChanged (testing_values::ACTIVE_OPACITY_VALUE,
+@@ -364,7 +362,6 @@
+ testing_values::INACTIVE_SHADOW_COLOR_STR_VALUE.c_str ()), IsTrue ());
+ EXPECT_THAT (gwd_settings_writable_use_tooltips_changed (writableMock.get (), testing_values::USE_TOOLTIPS_VALUE), IsTrue ());
+ EXPECT_THAT (gwd_settings_writable_draggable_border_width_changed (writableMock.get (), testing_values::DRAGGABLE_BORDER_WIDTH_VALUE), IsTrue ());
+- EXPECT_THAT (gwd_settings_writable_attach_modal_dialogs_changed (writableMock.get (), testing_values::ATTACH_MODAL_DIALOGS_VALUE), IsTrue ());
+ EXPECT_THAT (gwd_settings_writable_blur_changed (writableMock.get (), testing_values::BLUR_TYPE_TITLEBAR_VALUE.c_str ()), IsTrue ());
+ EXPECT_THAT (gwd_settings_writable_metacity_theme_changed (writableMock.get (),
+ testing_values::USE_METACITY_THEME_VALUE,
+@@ -472,14 +469,6 @@
+ "draggable-border-width",
+ &integerGValue);
+
+- EXPECT_CALL (settingsGMock, getProperty (GWD_MOCK_SETTINGS_PROPERTY_ATTACH_MODAL_DIALOGS,
+- GValueMatch <gboolean> (FALSE, g_value_get_boolean),
+- _));
+-
+- g_object_get_property (G_OBJECT (settingsMock.get ()),
+- "attach-modal-dialogs",
+- &booleanGValue);
+-
+ EXPECT_CALL (settingsGMock, getProperty (GWD_MOCK_SETTINGS_PROPERTY_BLUR_CHANGED,
+ GValueMatch <gint> (0, g_value_get_int),
+ _));
+@@ -783,29 +772,6 @@
+ DRAGGABLE_BORDER_WIDTH_DEFAULT), IsFalse ());
+ }
+
+-TEST_F(GWDSettingsTest, TestAttachModalDialogsChanged)
+-{
+- EXPECT_CALL (*mGMockNotified, updateDecorations ());
+- EXPECT_THAT (gwd_settings_writable_attach_modal_dialogs_changed (GWD_SETTINGS_WRITABLE_INTERFACE (mSettings.get ()),
+- testing_values::ATTACH_MODAL_DIALOGS_VALUE), IsTrue ());
+-
+- AutoUnsetGValue attachModalDialogsValue (G_TYPE_BOOLEAN);
+- GValue &attachModalDialogsGValue = attachModalDialogsValue;
+-
+- g_object_get_property (G_OBJECT (mSettings.get ()),
+- "attach-modal-dialogs",
+- &attachModalDialogsGValue);
+-
+- EXPECT_THAT (&attachModalDialogsGValue, GValueMatch <gboolean> (testing_values::ATTACH_MODAL_DIALOGS_VALUE,
+- g_value_get_boolean));
+-}
+-
+-TEST_F(GWDSettingsTest, TestAttachModalDialogsChangedIsDefault)
+-{
+- EXPECT_THAT (gwd_settings_writable_attach_modal_dialogs_changed (GWD_SETTINGS_WRITABLE_INTERFACE (mSettings.get ()),
+- ATTACH_MODAL_DIALOGS_DEFAULT), IsFalse ());
+-}
+-
+ TEST_F(GWDSettingsTest, TestBlurChangedTitlebar)
+ {
+ EXPECT_CALL (*mGMockNotified, updateDecorations ());
+@@ -1218,7 +1184,6 @@
+ virtual GWDSettingsStorage * GetStorage () = 0;
+ virtual void SetUseTooltips (gboolean useTooltips) = 0;
+ virtual void SetDraggableBorderWidth (gint draggableBorderWidth) = 0;
+- virtual void SetAttachModalDialogs (gboolean attachModalDialogs) = 0;
+ virtual void SetBlur (const std::string &blurType) = 0;
+ virtual void SetOpacity (gdouble activeOpacity,
+ gdouble inactiveOpacity,
+@@ -1292,16 +1257,6 @@
+ gwd_settings_storage_update_draggable_border_width (storage);
+ }
+
+-TEST_P (GWDSettingsTestStorageUpdates, TestSetAttachModalDialogs)
+-{
+- GWDSettingsStorage *storage = GetParam ()->GetStorage ();
+- GetParam ()->SetAttachModalDialogs (testing_values::ATTACH_MODAL_DIALOGS_VALUE);
+-
+- EXPECT_CALL (*mSettingsMock, attachModalDialogsChanged (testing_values::ATTACH_MODAL_DIALOGS_VALUE));
+-
+- gwd_settings_storage_update_attach_modal_dialogs (storage);
+-}
+-
+ TEST_P (GWDSettingsTestStorageUpdates, TestSetBlur)
+ {
+ GWDSettingsStorage *storage = GetParam ()->GetStorage ();
+@@ -1414,15 +1369,6 @@
+ gwd_settings_writable_draggable_border_width_changed, mWritable, draggableBorderWidth)));
+ }
+
+- virtual void SetAttachModalDialogs (gboolean attachModalDialogs)
+- {
+- EXPECT_CALL (*mStorageMock, updateAttachModalDialogs ())
+- .WillOnce (
+- InvokeFunctor (
+- boost::bind (
+- gwd_settings_writable_attach_modal_dialogs_changed, mWritable, attachModalDialogs)));
+- }
+-
+ virtual void SetBlur (const std::string &blurType)
+ {
+ EXPECT_CALL (*mStorageMock, updateBlur ())
+@@ -1535,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 ());
+
+@@ -1554,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),
+@@ -1579,11 +1528,6 @@
+ g_settings_set_int (mMutterSettings, ORG_GNOME_MUTTER_DRAGGABLE_BORDER_WIDTH, draggableBorderWidth);
+ }
+
+- virtual void SetAttachModalDialogs (gboolean attachModalDialogs)
+- {
+- g_settings_set_boolean (mMutterSettings, ORG_GNOME_MUTTER_ATTACH_MODAL_DIALOGS, attachModalDialogs);
+- }
+-
+ virtual void SetBlur (const std::string &blurType)
+ {
+ g_settings_set_string (mGWDSettings, ORG_COMPIZ_GWD_KEY_BLUR_TYPE, blurType.c_str ());
+@@ -1655,6 +1599,7 @@
+ {
+ mStorage.reset ();
+ mGWDSettings = NULL;
++ mMetacitySettings = NULL;
+ mMutterSettings = NULL;
+ mDesktopSettings = NULL;
+ gsettingsEnv.TearDownEnv ();
+@@ -1664,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-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/util.c 2015-04-11 14:34:11.000000000 +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-04-11 14:38:52.624406000 +0100
++++ modified/gtk/window-decorator/wnck.c 2015-04-11 14:34:11.000000000 +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>