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