code:
From 719cdeb8eceb48be22d8e49d51df4f4fa553a24d Mon Sep 17 00:00:00 2001
From: Mikael Magnusson <mikachu@gmail.com>
Date: Sat, 13 Mar 2010 21:57:58 +0100
Subject: [PATCH] Add Plural-Forms header to fi.po and remove fuzzy mark.

---
 Makefile.am                                       |    8 +
 configure.ac                                      |    6 +-
 data/gnome-session/Makefile                       |    4 +
 data/gnome-session/openbox-gnome-fallback.session |    6 +
 data/gnome-session/openbox-gnome.session          |    9 +
 data/openbox.desktop                              |    4 +
 data/rc.xml                                       |    2 +-
 data/xsession/openbox-gnome-session.in            |   12 +-
 data/xsession/openbox-kde-session.in              |    2 +-
 doc/rc-mouse-focus.xml                            |    2 +-
 obrender/button.c                                 |  117 ++
 obrender/button.h                                 |   11 +
 obrender/color.c                                  |    5 +
 obrender/render.c                                 |    3 +
 obrender/render.h                                 |   53 +-
 obrender/theme.c                                  | 2027 +++++++++++----------
 obrender/theme.h                                  |  100 +-
 obt/keyboard.c                                    |    3 +-
 obt/prop.c                                        |    1 +
 obt/prop.h                                        |    1 +
 openbox/actions/cyclewindows.c                    |    2 +
 openbox/client.c                                  |  115 +-
 openbox/client.h                                  |    2 +
 openbox/client_menu.c                             |   12 +-
 openbox/config.c                                  |   21 +-
 openbox/config.h                                  |    1 +
 openbox/debug.c                                   |   19 +-
 openbox/debug.h                                   |    2 +
 openbox/event.c                                   |   10 +
 openbox/frame.c                                   |    3 +-
 openbox/framerender.c                             |  126 +-
 openbox/keyboard.c                                |    3 +-
 openbox/menu.c                                    |    2 +-
 openbox/mouse.c                                   |   12 +-
 openbox/openbox.c                                 |    6 +-
 openbox/place.c                                   |   86 +-
 openbox/prompt.c                                  |    4 +-
 openbox/screen.c                                  |   13 +-
 po/fi.po                                          |   28 +-
 41 files changed, 1588 insertions(+), 1258 deletions(-)
 create mode 100644 data/gnome-session/Makefile
 create mode 100644 data/gnome-session/openbox-gnome-fallback.session
 create mode 100644 data/gnome-session/openbox-gnome.session
 create mode 100644 obrender/button.c
 create mode 100644 obrender/button.h

diff --git a/Makefile.am b/Makefile.am
index f59d3e7..1f7427c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6,6 +6,7 @@ localedir       = $(datadir)/locale
 configdir       = $(sysconfdir)/xdg
 rcdir           = $(configdir)/openbox
 xsessionsdir    = $(datadir)/xsessions
+gnomesessiondir = $(datadir)/gnome-session/sessions
 gnomewmfilesdir = $(datadir)/gnome/wm-properties
 pkgconfigdir    = $(libdir)/pkgconfig
 obtpubincludedir= $(includedir)/openbox/@OBT_VERSION@/obt
@@ -79,6 +80,7 @@ obrender_libobrender_la_CPPFLAGS = \
 obrender_libobrender_la_LDFLAGS = \
 	-version-info $(RR_CURRENT):$(RR_REVISION):$(RR_AGE)
 obrender_libobrender_la_LIBADD = \
+	obt/libobt.la \
 	$(X_LIBS) \
 	$(PANGO_LIBS) \
 	$(GLIB_LIBS) \
@@ -86,6 +88,8 @@ obrender_libobrender_la_LIBADD = \
 	$(XML_LIBS)
 obrender_libobrender_la_SOURCES = \
 	gettext.h \
+	obrender/button.h \
+	obrender/button.c \
 	obrender/color.h \
 	obrender/color.c \
 	obrender/font.h \
@@ -511,6 +515,10 @@ nodist_xsessions_DATA = \
 	data/xsession/openbox-gnome.desktop \
 	data/xsession/openbox-kde.desktop

+dist_gnomesession_DATA = \
+	data/gnome-session/openbox-gnome.session \
+	data/gnome-session/openbox-gnome-fallback.session
+
 dist_noinst_DATA = \
 	data/rc.xsd \
 	data/menu.xsd \
diff --git a/configure.ac b/configure.ac
index 82c627f..a183309 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,8 +1,10 @@
 AC_PREREQ([2.54])
 AC_INIT([openbox], [3.5.0], [http://bugzilla.icculus.org])
-AM_INIT_AUTOMAKE
 AC_CONFIG_SRCDIR([openbox/openbox.c])

+AM_INIT_AUTOMAKE([foreign])
+AM_SILENT_RULES([yes])
+
 OB_VERSION=$PACKAGE_VERSION
 AC_SUBST(OB_VERSION)

@@ -168,7 +170,7 @@ AC_ARG_ENABLE(imlib2,
     [--disable-imlib2],
     [disable use of Imlib2 image library for loading icons. [default=enabled]]
   ),
-  [enable_imlib2=$enableeval],
+  [enable_imlib2=$enableval],
   [enable_imlib2=yes]
 )

diff --git a/data/gnome-session/Makefile b/data/gnome-session/Makefile
new file mode 100644
index 0000000..b90edac
--- /dev/null
+++ b/data/gnome-session/Makefile
@@ -0,0 +1,4 @@
+all clean install:
+	$(MAKE) -C .. -$(MAKEFLAGS) $@
+
+.PHONY: all clean install
diff --git a/data/gnome-session/openbox-gnome-fallback.session b/data/gnome-session/openbox-gnome-fallback.session
new file mode 100644
index 0000000..156f2c3
--- /dev/null
+++ b/data/gnome-session/openbox-gnome-fallback.session
@@ -0,0 +1,6 @@
+[GNOME Session]
+Name=GNOME/Openbox fallback (Safe Mode)
+RequiredComponents=gnome-settings-daemon;
+RequiredProviders=windowmanager;
+DefaultProvider-windowmanager=openbox
+DesktopName=GNOME
diff --git a/data/gnome-session/openbox-gnome.session b/data/gnome-session/openbox-gnome.session
new file mode 100644
index 0000000..3399c2c
--- /dev/null
+++ b/data/gnome-session/openbox-gnome.session
@@ -0,0 +1,9 @@
+[GNOME Session]
+Name=GNOME/Openbox
+RequiredComponents=gnome-settings-daemon;
+# Try load with the gnome-panel and use the fallback if we can't load a panel
+RequiredProviders=windowmanager;panel
+DefaultProvider-windowmanager=openbox
+DefaultProvider-panel=gnome-panel
+FallbackSession=openbox-gnome-fallback
+DesktopName=GNOME
diff --git a/data/openbox.desktop b/data/openbox.desktop
index 9c19e67..d49ae22 100644
--- a/data/openbox.desktop
+++ b/data/openbox.desktop
@@ -7,6 +7,10 @@ Icon=openbox
 NoDisplay=true
 # name we put on the WM spec check window
 X-GNOME-WMName=Openbox
+# gnome-session autostart
 X-GNOME-Autostart-Phase=WindowManager
 X-GNOME-Provides=windowmanager
+# Ubuntu stuff
+X-Ubuntu-Gettext-Domain=openbox
+# back compat
 X-GNOME-Autostart-Notify=true
diff --git a/data/rc.xml b/data/rc.xml
index 7598a72..209cc2d 100644
--- a/data/rc.xml
+++ b/data/rc.xml
@@ -313,7 +313,7 @@
 <mouse>
   <dragThreshold>1</dragThreshold>
   <!-- number of pixels the mouse must move before a drag begins -->
-  <doubleClickTime>200</doubleClickTime>
+  <doubleClickTime>500</doubleClickTime>
   <!-- in milliseconds (1000 = 1 second) -->
   <screenEdgeWarpTime>400</screenEdgeWarpTime>
   <!-- Time before changing desktops when the pointer touches the edge of the
diff --git a/data/xsession/openbox-gnome-session.in b/data/xsession/openbox-gnome-session.in
index 8dd799c..f31c9ad 100644
--- a/data/xsession/openbox-gnome-session.in
+++ b/data/xsession/openbox-gnome-session.in
@@ -21,11 +21,11 @@ MINOR=$(echo $VER | cut -d . -f 2)
 # run GNOME with Openbox as its window manager

 if test $MAJOR -lt 2 || (test $MAJOR = 2 && test $MINOR -le 22); then
-  # old gnome-session was easy to work with
+  # older gnome-session was easy to work with
   export WINDOW_MANAGER="@bindir@/openbox"
   exec gnome-session --choose-session=openbox-session "$@"
-else
-  # new gnome-session requires openbox to be set in gconf and an
+elif test $MAJOR -lt 3; then
+  # old gnome-session requires openbox to be set in gconf and an
   # openbox.desktop to be installed in the applications directory

   SPATH=/desktop/gnome/session
@@ -54,6 +54,12 @@ else

   # run GNOME/Openbox
   exec gnome-session --default-session-key $SPATH/openbox_session "$@"
+else
+  # new gnome-session requires session file installed in
+  # /usr/share/gnome-session/sessions as well as openbox.desktop to be
+  # installed in the applications directory
+
+  exec gnome-session --session=openbox-gnome
 fi

diff --git a/data/xsession/openbox-kde-session.in b/data/xsession/openbox-kde-session.in
index 14e3504..3572279 100644
--- a/data/xsession/openbox-kde-session.in
+++ b/data/xsession/openbox-kde-session.in
@@ -8,7 +8,7 @@ if test -n "$1"; then
 fi

 # Set the prefix for the menu layout to use
-export XDG_MENU_PREFIX="kde-"
+export XDG_MENU_PREFIX="kde-4-"

 # Clean up after GDM
 xprop -root -remove _NET_NUMBER_OF_DESKTOPS \
diff --git a/doc/rc-mouse-focus.xml b/doc/rc-mouse-focus.xml
index 06c3ce5..dc7f2e9 100644
--- a/doc/rc-mouse-focus.xml
+++ b/doc/rc-mouse-focus.xml
@@ -226,7 +226,7 @@
 <mouse>
   <dragThreshold>8</dragThreshold>
   <!-- number of pixels the mouse must move before a drag begins -->
-  <doubleClickTime>200</doubleClickTime>
+  <doubleClickTime>500</doubleClickTime>
   <!-- in milliseconds (1000 = 1 second) -->

   <context name="Frame">
diff --git a/obrender/button.c b/obrender/button.c
new file mode 100644
index 0000000..14a454d
--- /dev/null
+++ b/obrender/button.c
@@ -0,0 +1,117 @@
+#include "render.h"
+#include "button.h"
+#include "instance.h"
+#include "mask.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <string.h>
+
+RrButton *RrButtonNew (const RrInstance *inst)
+{
+    RrButton *out = NULL;
+
+    out = g_new(RrButton, 1);
+    out->inst = inst;
+
+    /* no need to alloc colors, set them null (for freeing later) */
+    out->focused_unpressed_color = NULL;
+    out->unfocused_unpressed_color = NULL;
+    out->focused_pressed_color = NULL;
+    out->unfocused_pressed_color = NULL;
+    out->disabled_focused_color = NULL;
+    out->disabled_unfocused_color = NULL;
+    out->hover_focused_color = NULL;
+    out->hover_unfocused_color = NULL;
+    out->toggled_hover_focused_color = NULL;
+    out->toggled_hover_unfocused_color = NULL;
+    out->toggled_focused_pressed_color = NULL;
+    out->toggled_unfocused_pressed_color = NULL;
+    out->toggled_focused_unpressed_color = NULL;
+    out->toggled_unfocused_unpressed_color = NULL;
+
+    /* same with masks */
+    out->mask = NULL;
+    out->pressed_mask = NULL;
+    out->disabled_mask = NULL;
+    out->hover_mask = NULL;
+    out->toggled_mask = NULL;
+    out->toggled_hover_mask = NULL;
+    out->toggled_pressed_mask = NULL;
+
+    /* allocate appearances */
+    out->a_focused_unpressed = RrAppearanceNew(inst, 1);
+    out->a_unfocused_unpressed = RrAppearanceNew(inst, 1);
+    out->a_focused_pressed = RrAppearanceNew(inst, 1);
+    out->a_unfocused_pressed = RrAppearanceNew(inst, 1);
+    out->a_disabled_focused = RrAppearanceNew(inst, 1);
+    out->a_disabled_unfocused = RrAppearanceNew(inst, 1);
+    out->a_hover_focused = RrAppearanceNew(inst, 1);
+    out->a_hover_unfocused = RrAppearanceNew(inst, 1);
+    out->a_toggled_focused_unpressed = RrAppearanceNew(inst, 1);
+    out->a_toggled_unfocused_unpressed = RrAppearanceNew(inst, 1);
+    out->a_toggled_focused_pressed = RrAppearanceNew(inst, 1);
+    out->a_toggled_unfocused_pressed = RrAppearanceNew(inst, 1);
+    out->a_toggled_hover_focused = RrAppearanceNew(inst, 1);
+    out->a_toggled_hover_unfocused = RrAppearanceNew(inst, 1);
+
+    return out;
+}
+
+void RrButtonFree(RrButton *b)
+{
+    /* colors */
+    if (b->focused_unpressed_color)
+        RrColorFree(b->focused_unpressed_color);
+    if (b->unfocused_unpressed_color)
+        RrColorFree(b->unfocused_unpressed_color);
+    if (b->focused_pressed_color)
+        RrColorFree(b->focused_pressed_color);
+    if (b->unfocused_pressed_color)
+        RrColorFree(b->unfocused_pressed_color);
+    if (b->disabled_focused_color)
+        RrColorFree(b->disabled_focused_color);
+    if (b->disabled_unfocused_color)
+        RrColorFree(b->disabled_unfocused_color);
+    if (b->hover_focused_color)
+        RrColorFree(b->hover_focused_color);
+    if (b->hover_unfocused_color)
+        RrColorFree(b->hover_unfocused_color);
+    if (b->toggled_hover_focused_color)
+        RrColorFree(b->toggled_hover_focused_color);
+    if (b->toggled_hover_unfocused_color)
+        RrColorFree(b->toggled_hover_unfocused_color);
+    if (b->toggled_focused_pressed_color)
+        RrColorFree(b->toggled_focused_pressed_color);
+    if (b->toggled_unfocused_pressed_color)
+        RrColorFree(b->toggled_unfocused_pressed_color);
+    if (b->toggled_focused_unpressed_color)
+        RrColorFree(b->toggled_focused_unpressed_color);
+    if (b->toggled_unfocused_unpressed_color)
+        RrColorFree(b->toggled_unfocused_unpressed_color);
+
+    /* masks */
+    if (b->mask) RrPixmapMaskFree(b->mask);
+    if (b->pressed_mask) RrPixmapMaskFree(b->pressed_mask);
+    if (b->disabled_mask) RrPixmapMaskFree(b->disabled_mask);
+    if (b->hover_mask) RrPixmapMaskFree(b->hover_mask);
+    if (b->toggled_mask) RrPixmapMaskFree(b->toggled_mask);
+    if (b->toggled_hover_mask) RrPixmapMaskFree(b->toggled_hover_mask);
+    if (b->toggled_pressed_mask) RrPixmapMaskFree(b->toggled_pressed_mask);
+
+    /* appearances */
+    RrAppearanceFree(b->a_focused_unpressed);
+    RrAppearanceFree(b->a_unfocused_unpressed);
+    RrAppearanceFree(b->a_focused_pressed);
+    RrAppearanceFree(b->a_unfocused_pressed);
+    RrAppearanceFree(b->a_disabled_focused);
+    RrAppearanceFree(b->a_disabled_unfocused);
+    RrAppearanceFree(b->a_hover_focused);
+    RrAppearanceFree(b->a_hover_unfocused);
+    RrAppearanceFree(b->a_toggled_focused_unpressed);
+    RrAppearanceFree(b->a_toggled_unfocused_unpressed);
+    RrAppearanceFree(b->a_toggled_focused_pressed);
+    RrAppearanceFree(b->a_toggled_unfocused_pressed);
+    RrAppearanceFree(b->a_toggled_hover_focused);
+    RrAppearanceFree(b->a_toggled_hover_unfocused);
+}
diff --git a/obrender/button.h b/obrender/button.h
new file mode 100644
index 0000000..659c3ea
--- /dev/null
+++ b/obrender/button.h
@@ -0,0 +1,11 @@
+#ifndef __button_h
+#define __button_h
+
+#include "render.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <glib.h>
+
+
+#endif /* __button_h */
diff --git a/obrender/color.c b/obrender/color.c
index dd0551e..221ebc4 100644
--- a/obrender/color.c
+++ b/obrender/color.c
@@ -101,6 +101,11 @@ RrColor *RrColorNew(const RrInstance *inst, gint r, gint g, gint b)
     return out;
 }

+RrColor *RrColorCopy(RrColor* c)
+{
+    return RrColorNew(c->inst, c->r, c->g, c->b);
+}
+
 void RrColorFree(RrColor *c)
 {
     if (c) {
diff --git a/obrender/render.c b/obrender/render.c
index fb59e21..fe9a2a8 100644
--- a/obrender/render.c
+++ b/obrender/render.c
@@ -231,6 +231,8 @@ void RrAppearanceClearTextures(RrAppearance *a)
     memset(a->texture, 0, a->textures * sizeof(RrTexture));
 }

+/* deep copy of orig, means reset ref to 1 on copy
+ * and copy each thing memwise. */
 RrAppearance *RrAppearanceCopy(RrAppearance *orig)
 {
     RrSurface *spo, *spc;
@@ -316,6 +318,7 @@ RrAppearance *RrAppearanceCopy(RrAppearance *orig)
     return copy;
 }

+/* now decrements ref counter, and frees only if ref <= 0 */
 void RrAppearanceFree(RrAppearance *a)
 {
     if (a) {
diff --git a/obrender/render.h b/obrender/render.h
index d7066e2..a5d6500 100644
--- a/obrender/render.h
+++ b/obrender/render.h
@@ -47,6 +47,7 @@ typedef struct _RrImage            RrImage;
 typedef struct _RrImageSet         RrImageSet;
 typedef struct _RrImagePic         RrImagePic;
 typedef struct _RrImageCache       RrImageCache;
+typedef struct _RrButton           RrButton;

 typedef guint32 RrPixel32;  /* RGBA format */
 typedef guint16 RrPixel16;
@@ -221,7 +222,7 @@ struct _RrTexture {

 struct _RrAppearance {
     const RrInstance *inst;
-
+
     RrSurface surface;
     gint textures;
     RrTexture *texture;
@@ -286,6 +287,52 @@ struct _RrImageSet
     gint n_resized;
 };

+struct _RrButton {
+    const RrInstance *inst;
+
+    /* colors */
+    RrColor *focused_unpressed_color;
+    RrColor *unfocused_unpressed_color;
+    RrColor *focused_pressed_color;
+    RrColor *unfocused_pressed_color;
+    RrColor *disabled_focused_color;
+    RrColor *disabled_unfocused_color;
+    RrColor *hover_focused_color;
+    RrColor *hover_unfocused_color;
+    RrColor *toggled_hover_focused_color;
+    RrColor *toggled_hover_unfocused_color;
+    RrColor *toggled_focused_pressed_color;
+    RrColor *toggled_unfocused_pressed_color;
+    RrColor *toggled_focused_unpressed_color;
+    RrColor *toggled_unfocused_unpressed_color;
+
+    /* masks */
+    RrPixmapMask *mask;
+    RrPixmapMask *pressed_mask;
+    RrPixmapMask *disabled_mask;
+    RrPixmapMask *hover_mask;
+    RrPixmapMask *toggled_mask;
+    RrPixmapMask *toggled_hover_mask;
+    RrPixmapMask *toggled_pressed_mask;
+
+    /* textures */
+    RrAppearance *a_focused_unpressed;
+    RrAppearance *a_unfocused_unpressed;
+    RrAppearance *a_focused_pressed;
+    RrAppearance *a_unfocused_pressed;
+    RrAppearance *a_disabled_focused;
+    RrAppearance *a_disabled_unfocused;
+    RrAppearance *a_hover_focused;
+    RrAppearance *a_hover_unfocused;
+    RrAppearance *a_toggled_focused_unpressed;
+    RrAppearance *a_toggled_unfocused_unpressed;
+    RrAppearance *a_toggled_focused_pressed;
+    RrAppearance *a_toggled_unfocused_pressed;
+    RrAppearance *a_toggled_hover_focused;
+    RrAppearance *a_toggled_hover_unfocused;
+
+};
+
 /* these are the same on all endian machines because it seems to be dependant
    on the endianness of the gfx card, not the cpu. */
 #define RrDefaultAlphaOffset 24
@@ -318,6 +365,7 @@ gint     RrGreenMask    (const RrInstance *inst);
 gint     RrBlueMask     (const RrInstance *inst);

 RrColor *RrColorNew   (const RrInstance *inst, gint r, gint g, gint b);
+RrColor *RrColorCopy  (RrColor *c);
 RrColor *RrColorParse (const RrInstance *inst, gchar *colorname);
 void     RrColorFree  (RrColor *in);

@@ -335,6 +383,9 @@ void          RrAppearanceAddTextures(RrAppearance *a, gint numtex);
 /*! Always call this when changing the type of a texture in an appearance */
 void          RrAppearanceClearTextures(RrAppearance *a);

+RrButton *RrButtonNew (const RrInstance *inst);
+void      RrButtonFree(RrButton *b);
+
 RrFont *RrFontOpen          (const RrInstance *inst, const gchar *name,
                              gint size, RrFontWeight weight, RrFontSlant slant);
 RrFont *RrFontOpenDefault   (const RrInstance *inst);
diff --git a/obrender/theme.c b/obrender/theme.c
index 9cc4157..b20182a 100644
--- a/obrender/theme.c
+++ b/obrender/theme.c
@@ -45,6 +45,9 @@ static gboolean read_appearance(XrmDatabase db, const RrInstance *inst,
 static int parse_inline_number(const char *p);
 static RrPixel32* read_c_image(gint width, gint height, const guint8 *data);
 static void set_default_appearance(RrAppearance *a);
+static void read_button_colors(XrmDatabase db, const RrInstance *inst,
+                               const RrTheme *theme, RrButton *btn,
+                               const gchar *btnname);

 static RrFont *get_font(RrFont *target, RrFont **default_font,
                         const RrInstance *inst)
@@ -63,6 +66,46 @@ static RrFont *get_font(RrFont *target, RrFont **default_font,
     }
 }

+#define READ_INT(x_resstr, x_var, x_min, x_max, x_def) \
+    if (!read_int(db, x_resstr, & x_var) || \
+            x_var < x_min || x_var > x_max) \
+        x_var = x_def;
+
+#define READ_COLOR(x_resstr, x_var, x_def) \
+    if (!read_color(db, inst, x_resstr, & x_var)) \
+        x_var = x_def;
+
+#define READ_COLOR_(x_res1, x_res2, x_var, x_def) \
+    if (!read_color(db, inst, x_res1, & x_var) && \
+        !read_color(db, inst, x_res2, & x_var)) \
+        x_var = x_def;
+
+#define READ_MASK_COPY(x_file, x_var, x_copysrc) \
+    if (!read_mask(inst, path, theme, x_file, & x_var)) \
+        x_var = RrPixmapMaskCopy(x_copysrc);
+
+#define READ_APPEARANCE(x_resstr, x_var, x_parrel) \
+    if (!read_appearance(db, inst, x_resstr, x_var, x_parrel)) \
+        set_default_appearance(x_var);
+
+#define READ_APPEARANCE_COPY(x_resstr, x_var, x_parrel, x_defval) \
+    if (!read_appearance(db, inst, x_resstr, x_var, x_parrel)) {\
+        RrAppearanceFree(x_var); \
+        x_var = RrAppearanceCopy(x_defval); }
+
+#define READ_APPEARANCE_COPY_TEXTURES(x_resstr, x_var, x_parrel, x_defval, n_tex) \
+    if (!read_appearance(db, inst, x_resstr, x_var, x_parrel)) {\
+        RrAppearanceFree(x_var); \
+        x_var = RrAppearanceCopy(x_defval); \
+        RrAppearanceRemoveTextures(x_var); \
+        RrAppearanceAddTextures(x_var, 5); }
+
+#define READ_APPEARANCE_(x_res1, x_res2, x_var, x_parrel, x_defval) \
+    if (!read_appearance(db, inst, x_res1, x_var, x_parrel) && \
+        !read_appearance(db, inst, x_res2, x_var, x_parrel)) {\
+        RrAppearanceFree(x_var); \
+        x_var = RrAppearanceCopy(x_defval); }
+
 RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
                     gboolean allow_fallback,
                     RrFont *active_window_font, RrFont *inactive_window_font,
@@ -76,6 +119,21 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
     RrFont *default_font = NULL;
     gchar *path;
     gboolean userdef;
+    gint menu_overlap = 0;
+    RrAppearance *a_disabled_focused_tmp;
+    RrAppearance *a_disabled_unfocused_tmp;
+    RrAppearance *a_hover_focused_tmp;
+    RrAppearance *a_hover_unfocused_tmp;
+    RrAppearance *a_focused_unpressed_tmp;
+    RrAppearance *a_focused_pressed_tmp;
+    RrAppearance *a_unfocused_unpressed_tmp;
+    RrAppearance *a_unfocused_pressed_tmp;
+    RrAppearance *a_toggled_hover_focused_tmp;
+    RrAppearance *a_toggled_hover_unfocused_tmp;
+    RrAppearance *a_toggled_focused_unpressed_tmp;
+    RrAppearance *a_toggled_focused_pressed_tmp;
+    RrAppearance *a_toggled_unfocused_unpressed_tmp;
+    RrAppearance *a_toggled_unfocused_pressed_tmp;

     if (name) {
         db = loaddb(name, &path);
@@ -99,25 +157,36 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
             return NULL;
     }

+    /* initialize temp reading textures */
+    a_disabled_focused_tmp = RrAppearanceNew(inst, 1);
+    a_disabled_unfocused_tmp = RrAppearanceNew(inst, 1);
+    a_hover_focused_tmp = RrAppearanceNew(inst, 1);
+    a_hover_unfocused_tmp = RrAppearanceNew(inst, 1);
+    a_toggled_focused_unpressed_tmp = RrAppearanceNew(inst, 1);
+    a_toggled_unfocused_unpressed_tmp = RrAppearanceNew(inst, 1);
+    a_toggled_hover_focused_tmp = RrAppearanceNew(inst, 1);
+    a_toggled_hover_unfocused_tmp = RrAppearanceNew(inst, 1);
+    a_toggled_focused_pressed_tmp = RrAppearanceNew(inst, 1);
+    a_toggled_unfocused_pressed_tmp = RrAppearanceNew(inst, 1);
+    a_focused_unpressed_tmp = RrAppearanceNew(inst, 1);
+    a_focused_pressed_tmp = RrAppearanceNew(inst, 1);
+    a_unfocused_unpressed_tmp = RrAppearanceNew(inst, 1);
+    a_unfocused_pressed_tmp = RrAppearanceNew(inst, 1);
+
+    /* initialize theme */
     theme = g_slice_new0(RrTheme);

     theme->inst = inst;
     theme->name = g_strdup(name ? name : DEFAULT_THEME);

-    theme->a_disabled_focused_max = RrAppearanceNew(inst, 1);
-    theme->a_disabled_unfocused_max = RrAppearanceNew(inst, 1);
-    theme->a_hover_focused_max = RrAppearanceNew(inst, 1);
-    theme->a_hover_unfocused_max = RrAppearanceNew(inst, 1);
-    theme->a_toggled_focused_unpressed_max = RrAppearanceNew(inst, 1);
-    theme->a_toggled_unfocused_unpressed_max = RrAppearanceNew(inst, 1);
-    theme->a_toggled_hover_focused_max = RrAppearanceNew(inst, 1);
-    theme->a_toggled_hover_unfocused_max = RrAppearanceNew(inst, 1);
-    theme->a_toggled_focused_pressed_max = RrAppearanceNew(inst, 1);
-    theme->a_toggled_unfocused_pressed_max = RrAppearanceNew(inst, 1);
-    theme->a_focused_unpressed_max = RrAppearanceNew(inst, 1);
-    theme->a_focused_pressed_max = RrAppearanceNew(inst, 1);
-    theme->a_unfocused_unpressed_max = RrAppearanceNew(inst, 1);
-    theme->a_unfocused_pressed_max = RrAppearanceNew(inst, 1);
+    /* init buttons */
+    theme->btn_max = RrButtonNew(inst);
+    theme->btn_close = RrButtonNew(inst);
+    theme->btn_desk = RrButtonNew(inst);
+    theme->btn_shade = RrButtonNew(inst);
+    theme->btn_iconify = RrButtonNew(inst);
+
+    /* init appearances */
     theme->a_focused_grip = RrAppearanceNew(inst, 0);
     theme->a_unfocused_grip = RrAppearanceNew(inst, 0);
     theme->a_focused_title = RrAppearanceNew(inst, 0);
@@ -181,427 +250,280 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
     theme->osd_font_unhilite = get_font(inactive_osd_font, &default_font,inst);

     /* load direct dimensions */
-    if ((!read_int(db, "menu.overlap.x", &theme->menu_overlap_x) &&
-         !read_int(db, "menu.overlap", &theme->menu_overlap_x)) ||
-        theme->menu_overlap_x < -100 || theme->menu_overlap_x > 100)
-        theme->menu_overlap_x = 0;
-    if ((!read_int(db, "menu.overlap.y", &theme->menu_overlap_y) &&
-         !read_int(db, "menu.overlap", &theme->menu_overlap_y)) ||
-        theme->menu_overlap_y < -100 || theme->menu_overlap_y > 100)
-        theme->menu_overlap_y = 0;
-    if (!read_int(db, "window.handle.width", &theme->handle_height) ||
-        theme->handle_height < 0 || theme->handle_height > 100)
-        theme->handle_height = 6;
-    if (!read_int(db, "padding.width", &theme->paddingx) ||
-        theme->paddingx < 0 || theme->paddingx > 100)
-        theme->paddingx = 3;
-    if (!read_int(db, "padding.height", &theme->paddingy) ||
-        theme->paddingy < 0 || theme->paddingy > 100)
-        theme->paddingy = theme->paddingx;
-    if (!read_int(db, "border.width", &theme->fbwidth) ||
-        theme->fbwidth < 0 || theme->fbwidth > 100)
-        theme->fbwidth = 1;
-    /* menu border width inherits from the frame border width */
-    if (!read_int(db, "menu.border.width", &theme->mbwidth) ||
-        theme->mbwidth < 0 || theme->mbwidth > 100)
-        theme->mbwidth = theme->fbwidth;
-    /* osd border width inherits from the frame border width */
-    if (!read_int(db, "osd.border.width", &theme->obwidth) ||
-        theme->obwidth < 0 || theme->obwidth > 100)
-        theme->obwidth = theme->fbwidth;
-    if (!read_int(db, "window.client.padding.width", &theme->cbwidthx) ||
-        theme->cbwidthx < 0 || theme->cbwidthx > 100)
-        theme->cbwidthx = theme->paddingx;
-    if (!read_int(db, "window.client.padding.height", &theme->cbwidthy) ||
-        theme->cbwidthy < 0 || theme->cbwidthy > 100)
-        theme->cbwidthy = theme->cbwidthx;
-    if (!read_int(db, "menu.separator.width", &theme->menu_sep_width) ||
-        theme->menu_sep_width < 1 || theme->menu_sep_width > 100)
-        theme->menu_sep_width = 1;
-    if (!read_int(db, "menu.separator.padding.width",
-                  &theme->menu_sep_paddingx) ||
-        theme->menu_sep_paddingx < 0 || theme->menu_sep_paddingx > 100)
-        theme->menu_sep_paddingx = 6;
-    if (!read_int(db, "menu.separator.padding.height",
-                  &theme->menu_sep_paddingy) ||
-        theme->menu_sep_paddingy < 0 || theme->menu_sep_paddingy > 100)
-        theme->menu_sep_paddingy = 3;
+    READ_INT("menu.overlap", menu_overlap, -100, 100, 0);
+    READ_INT("menu.overlap.x", theme->menu_overlap_x, -100, 100, menu_overlap);
+    READ_INT("menu.overlap.y", theme->menu_overlap_y, -100, 100, menu_overlap);
+    READ_INT("window.handle.width", theme->handle_height, 0, 100, 6);
+    READ_INT("padding.width", theme->paddingx, 0, 100, 3);
+    READ_INT("padding.height", theme->paddingy, 0, 100, theme->paddingx);
+    READ_INT("border.width", theme->fbwidth, 0, 100, 1);
+    READ_INT("menu.border.width", theme->mbwidth, 0, 100, theme->fbwidth);
+    READ_INT("osd.border.width", theme->obwidth, 0, 100, theme->fbwidth);
+    READ_INT("undecorated.border.width", theme->ubwidth, 0, 100,
+             theme->fbwidth);
+    READ_INT("menu.separator.width", theme->menu_sep_width, 1, 100, 1);
+    READ_INT("menu.separator.padding.width", theme->menu_sep_paddingx,
+             0, 100, 6);
+    READ_INT("menu.separator.padding.height", theme->menu_sep_paddingy,
+             0, 100, 3);
+    READ_INT("window.client.padding.width", theme->cbwidthx, 0, 100,
+             theme->paddingx);
+    READ_INT("window.client.padding.height", theme->cbwidthy, 0, 100,
+             theme->cbwidthx);

     /* load colors */
-    if (!read_color(db, inst,
-                    "window.active.border.color",
-                    &theme->frame_focused_border_color) &&
-        !read_color(db, inst,
-                    "border.color",
-                    &theme->frame_focused_border_color))
-        theme->frame_focused_border_color = RrColorNew(inst, 0, 0, 0);
+    READ_COLOR_("window.active.border.color", "border.color",
+                theme->frame_focused_border_color, RrColorNew(inst, 0, 0, 0));
+    /* undecorated focused border color inherits from frame focused border
+       color */
+    READ_COLOR("window.undecorated.active.border.color",
+               theme->frame_undecorated_focused_border_color,
+               RrColorCopy(theme->frame_focused_border_color));
     /* title separator focused color inherits from focused border color */
-    if (!read_color(db, inst,
-                    "window.active.title.separator.color",
-                    &theme->title_separator_focused_color))
-        theme->title_separator_focused_color =
-            RrColorNew(inst,
-                       theme->frame_focused_border_color->r,
-                       theme->frame_focused_border_color->g,
-                       theme->frame_focused_border_color->b);
+    READ_COLOR("window.active.title.separator.color",
+               theme->title_separator_focused_color,
+               RrColorCopy(theme->frame_focused_border_color));
+
     /* unfocused border color inherits from frame focused border color */
-    if (!read_color(db, inst,
-                    "window.inactive.border.color",
-                    &theme->frame_unfocused_border_color))
-        theme->frame_unfocused_border_color =
-            RrColorNew(inst, theme->frame_focused_border_color->r,
-                       theme->frame_focused_border_color->g,
-                       theme->frame_focused_border_color->b);
+    READ_COLOR("window.inactive.border.color",
+               theme->frame_unfocused_border_color,
+               RrColorCopy(theme->frame_focused_border_color));
+
+    /* undecorated unfocused border color inherits from frame unfocused border
+       color */
+    READ_COLOR("window.undecorated.inactive.border.color",
+               theme->frame_undecorated_unfocused_border_color,
+               RrColorCopy(theme->frame_unfocused_border_color));
+
     /* title separator unfocused color inherits from unfocused border color */
-    if (!read_color(db, inst,
-                    "window.inactive.title.separator.color",
-                    &theme->title_separator_unfocused_color))
-        theme->title_separator_unfocused_color =
-            RrColorNew(inst,
-                       theme->frame_unfocused_border_color->r,
-                       theme->frame_unfocused_border_color->g,
-                       theme->frame_unfocused_border_color->b);
+    READ_COLOR("window.inactive.title.separator.color",
+               theme->title_separator_unfocused_color,
+               RrColorCopy(theme->frame_unfocused_border_color));

     /* menu border color inherits from frame focused border color */
-    if (!read_color(db, inst, "menu.border.color", &theme->menu_border_color))
-        theme->menu_border_color =
-            RrColorNew(inst,
-                       theme->frame_focused_border_color->r,
-                       theme->frame_focused_border_color->g,
-                       theme->frame_focused_border_color->b);
+    READ_COLOR("menu.border.color", theme->menu_border_color,
+               RrColorCopy(theme->frame_focused_border_color));
+
     /* osd border color inherits from frame focused border color */
-    if (!read_color(db, inst, "osd.border.color", &theme->osd_border_color))
-        theme->osd_border_color =
-            RrColorNew(inst,
-                       theme->frame_focused_border_color->r,
-                       theme->frame_focused_border_color->g,
-                       theme->frame_focused_border_color->b);
-    if (!read_color(db, inst,
-                    "window.active.client.color",
-                    &theme->cb_focused_color))
-        theme->cb_focused_color = RrColorNew(inst, 0xff, 0xff, 0xff);
-    if (!read_color(db, inst,
-                    "window.inactive.client.color",
-                    &theme->cb_unfocused_color))
-        theme->cb_unfocused_color = RrColorNew(inst, 0xff, 0xff, 0xff);
-    if (!read_color(db, inst,
-                    "window.active.label.text.color",
-                    &theme->title_focused_color))
-        theme->title_focused_color = RrColorNew(inst, 0x0, 0x0, 0x0);
-    if (!read_color(db, inst, "osd.active.label.text.color",
-                    &theme->osd_text_active_color) &&
-        !read_color(db, inst, "osd.label.text.color",
-                    &theme->osd_text_active_color))
-        theme->osd_text_active_color =
-            RrColorNew(inst,
-                       theme->title_focused_color->r,
-                       theme->title_focused_color->g,
-                       theme->title_focused_color->b);
-    if (!read_color(db, inst,
-                    "window.inactive.label.text.color",
-                    &theme->title_unfocused_color))
-        theme->title_unfocused_color = RrColorNew(inst, 0xff, 0xff, 0xff);
-    if (!read_color(db, inst, "osd.inactive.label.text.color",
-                    &theme->osd_text_inactive_color))
-        theme->osd_text_inactive_color =
-            RrColorNew(inst,
-                       theme->title_unfocused_color->r,
-                       theme->title_unfocused_color->g,
-                       theme->title_unfocused_color->b);
-    if (!read_color(db, inst,
-                    "window.active.button.unpressed.image.color",
-                    &theme->titlebut_focused_unpressed_color))
-        theme->titlebut_focused_unpressed_color = RrColorNew(inst, 0, 0, 0);
-    if (!read_color(db, inst,
-                    "window.inactive.button.unpressed.image.color",
-                    &theme->titlebut_unfocused_unpressed_color))
-        theme->titlebut_unfocused_unpressed_color =
-            RrColorNew(inst, 0xff, 0xff, 0xff);
-    if (!read_color(db, inst,
-                    "window.active.button.pressed.image.color",
-                    &theme->titlebut_focused_pressed_color))
-        theme->titlebut_focused_pressed_color =
-            RrColorNew(inst,
-                       theme->titlebut_focused_unpressed_color->r,
-                       theme->titlebut_focused_unpressed_color->g,
-                       theme->titlebut_focused_unpressed_color->b);
-    if (!read_color(db, inst,
-                    "window.inactive.button.pressed.image.color",
-                    &theme->titlebut_unfocused_pressed_color))
-        theme->titlebut_unfocused_pressed_color =
-            RrColorNew(inst,
-                       theme->titlebut_unfocused_unpressed_color->r,
-                       theme->titlebut_unfocused_unpressed_color->g,
-                       theme->titlebut_unfocused_unpressed_color->b);
-    if (!read_color(db, inst,
-                    "window.active.button.disabled.image.color",
-                    &theme->titlebut_disabled_focused_color))
-        theme->titlebut_disabled_focused_color =
-            RrColorNew(inst, 0xff, 0xff, 0xff);
-    if (!read_color(db, inst,
-                    "window.inactive.button.disabled.image.color",
-                    &theme->titlebut_disabled_unfocused_color))
-        theme->titlebut_disabled_unfocused_color = RrColorNew(inst, 0, 0, 0);
-    if (!read_color(db, inst,
-                    "window.active.button.hover.image.color",
-                    &theme->titlebut_hover_focused_color))
-        theme->titlebut_hover_focused_color =
-            RrColorNew(inst,
-                       theme->titlebut_focused_unpressed_color->r,
-                       theme->titlebut_focused_unpressed_color->g,
-                       theme->titlebut_focused_unpressed_color->b);
-    if (!read_color(db, inst,
-                    "window.inactive.button.hover.image.color",
-                    &theme->titlebut_hover_unfocused_color))
-        theme->titlebut_hover_unfocused_color =
-            RrColorNew(inst,
-                       theme->titlebut_unfocused_unpressed_color->r,
-                       theme->titlebut_unfocused_unpressed_color->g,
-                       theme->titlebut_unfocused_unpressed_color->b);
-    if (!read_color(db, inst,
-                    "window.active.button.toggled.unpressed.image.color",
-                    &theme->titlebut_toggled_focused_unpressed_color) &&
-        !read_color(db, inst,
-                    "window.active.button.toggled.image.color",
-                    &theme->titlebut_toggled_focused_unpressed_color))
-        theme->titlebut_toggled_focused_unpressed_color =
-            RrColorNew(inst,
-                       theme->titlebut_focused_pressed_color->r,
-                       theme->titlebut_focused_pressed_color->g,
-                       theme->titlebut_focused_pressed_color->b);
-    if (!read_color(db, inst,
-                    "window.inactive.button.toggled.unpressed.image.color",
-                    &theme->titlebut_toggled_unfocused_unpressed_color) &&
-        !read_color(db, inst,
-                    "window.inactive.button.toggled.image.color",
-                    &theme->titlebut_toggled_unfocused_unpressed_color))
-        theme->titlebut_toggled_unfocused_unpressed_color =
-            RrColorNew(inst,
-                       theme->titlebut_unfocused_pressed_color->r,
-                       theme->titlebut_unfocused_pressed_color->g,
-                       theme->titlebut_unfocused_pressed_color->b);
-    if (!read_color(db, inst,
-                    "window.active.button.toggled.hover.image.color",
-                    &theme->titlebut_toggled_hover_focused_color))
-        theme->titlebut_toggled_hover_focused_color =
-            RrColorNew(inst,
-                       theme->titlebut_toggled_focused_unpressed_color->r,
-                       theme->titlebut_toggled_focused_unpressed_color->g,
-                       theme->titlebut_toggled_focused_unpressed_color->b);
-    if (!read_color(db, inst,
-                    "window.inactive.button.toggled.hover.image.color",
-                    &theme->titlebut_toggled_hover_unfocused_color))
-        theme->titlebut_toggled_hover_unfocused_color =
-            RrColorNew(inst,
-                       theme->titlebut_toggled_unfocused_unpressed_color->r,
-                       theme->titlebut_toggled_unfocused_unpressed_color->g,
-                       theme->titlebut_toggled_unfocused_unpressed_color->b);
-    if (!read_color(db, inst,
-                    "window.active.button.toggled.pressed.image.color",
-                    &theme->titlebut_toggled_focused_pressed_color))
-        theme->titlebut_toggled_focused_pressed_color =
-            RrColorNew(inst,
-                       theme->titlebut_focused_pressed_color->r,
-                       theme->titlebut_focused_pressed_color->g,
-                       theme->titlebut_focused_pressed_color->b);
-    if (!read_color(db, inst,
-                    "window.inactive.button.toggled.pressed.image.color",
-                    &theme->titlebut_toggled_unfocused_pressed_color))
-        theme->titlebut_toggled_unfocused_pressed_color =
-            RrColorNew(inst,
-                       theme->titlebut_unfocused_pressed_color->r,
-                       theme->titlebut_unfocused_pressed_color->g,
-                       theme->titlebut_unfocused_pressed_color->b);
-    if (!read_color(db, inst,
-                    "menu.title.text.color", &theme->menu_title_color))
-        theme->menu_title_color = RrColorNew(inst, 0, 0, 0);
-    if (!read_color(db, inst,
-                    "menu.items.text.color", &theme->menu_color))
-        theme->menu_color = RrColorNew(inst, 0xff, 0xff, 0xff);
-    if (!read_color(db, inst,
-                    "menu.items.disabled.text.color",
-                    &theme->menu_disabled_color))
-        theme->menu_disabled_color = RrColorNew(inst, 0, 0, 0);
-    if (!read_color(db, inst,
-                    "menu.items.active.disabled.text.color",
-                    &theme->menu_disabled_selected_color))
-        theme->menu_disabled_selected_color =
-            RrColorNew(inst,
-                       theme->menu_disabled_color->r,
-                       theme->menu_disabled_color->g,
-                       theme->menu_disabled_color->b);
-    if (!read_color(db, inst,
-                    "menu.items.active.text.color",
-                    &theme->menu_selected_color))
-        theme->menu_selected_color = RrColorNew(inst, 0, 0, 0);
-    if (!read_color(db, inst,
-                    "menu.separator.color", &theme->menu_sep_color))
-        theme->menu_sep_color = RrColorNew(inst,
-                                           theme->menu_color->r,
-                                           theme->menu_color->g,
-                                           theme->menu_color->b);
-    if (!read_color(db, inst, "osd.button.unpressed.text.color",
-                    &theme->osd_unpressed_color))
-        theme->osd_unpressed_color =
-            RrColorNew(inst,
-                       theme->osd_text_active_color->r,
-                       theme->osd_text_active_color->g,
-                       theme->osd_text_active_color->b);
-    if (!read_color(db, inst, "osd.button.pressed.text.color",
-                    &theme->osd_pressed_color))
-        theme->osd_pressed_color =
-            RrColorNew(inst,
-                       theme->osd_text_active_color->r,
-                       theme->osd_text_active_color->g,
-                       theme->osd_text_active_color->b);
-    if (!read_color(db, inst, "osd.button.focused.text.color",
-                    &theme->osd_focused_color))
-        theme->osd_focused_color =
-            RrColorNew(inst,
-                       theme->osd_text_active_color->r,
-                       theme->osd_text_active_color->g,
-                       theme->osd_text_active_color->b);
-    if (!read_color(db, inst, "osd.button.pressed.box.color",
-                    &theme->osd_pressed_lineart))
-        theme->osd_pressed_lineart =
-            RrColorNew(inst,
-                       theme->titlebut_focused_pressed_color->r,
-                       theme->titlebut_focused_pressed_color->g,
-                       theme->titlebut_focused_pressed_color->b);
-    if (!read_color(db, inst, "osd.button.focused.box.color",
-                    &theme->osd_focused_lineart))
-        theme->osd_focused_lineart =
-            RrColorNew(inst,
-                       theme->titlebut_hover_focused_color->r,
-                       theme->titlebut_hover_focused_color->g,
-                       theme->titlebut_hover_focused_color->b);
+    READ_COLOR("osd.border.color", theme->osd_border_color,
+               RrColorCopy(theme->frame_focused_border_color));

+    READ_COLOR("window.active.client.color", theme->cb_focused_color,
+               RrColorNew(inst, 0xff, 0xff, 0xff));
+
+    READ_COLOR("window.inactive.client.color", theme->cb_unfocused_color,
+               RrColorNew(inst, 0xff, 0xff, 0xff));
+
+    READ_COLOR("window.active.label.text.color", theme->title_focused_color,
+               RrColorNew(inst, 0x0, 0x0, 0x0));
+
+    READ_COLOR("window.inactive.label.text.color", theme->title_unfocused_color,
+               RrColorCopy(theme->title_unfocused_color));
+
+    READ_COLOR_("osd.active.label.text.color",
+                "osd.label.text.color",
+                theme->osd_text_active_color, RrColorCopy(theme->title_focused_color));
+
+    READ_COLOR("osd.inactive.label.text.color", theme->osd_text_inactive_color,
+               RrColorNew(inst, 0xff, 0xff, 0xff));
+
+    READ_COLOR("window.active.button.unpressed.image.color",
+               theme->titlebut_focused_unpressed_color,
+               RrColorNew(inst, 0, 0, 0));
+
+    READ_COLOR("window.inactive.button.unpressed.image.color",
+               theme->titlebut_unfocused_unpressed_color,
+               RrColorNew(inst, 0xff, 0xff, 0xff));
+
+    READ_COLOR("window.active.button.pressed.image.color",
+               theme->titlebut_focused_pressed_color,
+               RrColorCopy(theme->titlebut_focused_unpressed_color));
+
+    READ_COLOR("window.inactive.button.pressed.image.color",
+               theme->titlebut_unfocused_pressed_color,
+               RrColorCopy(theme->titlebut_unfocused_unpressed_color));
+
+    READ_COLOR("window.active.button.disabled.image.color",
+               theme->titlebut_disabled_focused_color,
+               RrColorNew(inst, 0xff, 0xff, 0xff));
+
+    READ_COLOR("window.inactive.button.disabled.image.color",
+               theme->titlebut_disabled_unfocused_color,
+               RrColorNew(inst, 0, 0, 0));
+
+    READ_COLOR("window.active.button.hover.image.color",
+               theme->titlebut_hover_focused_color,
+               RrColorCopy(theme->titlebut_focused_unpressed_color));
+
+    READ_COLOR("window.inactive.button.hover.image.color",
+               theme->titlebut_hover_unfocused_color,
+               RrColorCopy(theme->titlebut_unfocused_unpressed_color));
+
+    READ_COLOR_("window.active.button.toggled.unpressed.image.color",
+                "window.active.button.toggled.image.color",
+                theme->titlebut_toggled_focused_unpressed_color,
+                RrColorCopy(theme->titlebut_focused_pressed_color));
+
+    READ_COLOR_("window.inactive.button.toggled.unpressed.image.color",
+                "window.inactive.button.toggled.image.color",
+                theme->titlebut_toggled_unfocused_unpressed_color,
+                RrColorCopy(theme->titlebut_unfocused_pressed_color));
+
+    READ_COLOR("window.active.button.toggled.hover.image.color",
+               theme->titlebut_toggled_hover_focused_color,
+               RrColorCopy(theme->titlebut_toggled_focused_unpressed_color));
+
+    READ_COLOR("window.inactive.button.toggled.hover.image.color",
+               theme->titlebut_toggled_hover_unfocused_color,
+               RrColorCopy(theme->titlebut_toggled_unfocused_unpressed_color));
+
+    READ_COLOR("window.active.button.toggled.pressed.image.color",
+               theme->titlebut_toggled_focused_pressed_color,
+               RrColorCopy(theme->titlebut_focused_pressed_color));
+
+    READ_COLOR("window.inactive.button.toggled.pressed.image.color",
+               theme->titlebut_toggled_unfocused_pressed_color,
+               RrColorCopy(theme->titlebut_unfocused_pressed_color));
+
+    READ_COLOR("menu.title.text.color", theme->menu_title_color,
+               RrColorNew(inst, 0, 0, 0));
+
+    READ_COLOR("menu.items.text.color", theme->menu_color,
+               RrColorNew(inst, 0xff, 0xff, 0xff));
+
+    READ_COLOR("menu.bullet.image.color", theme->menu_bullet_color,
+               RrColorCopy(theme->menu_color));
+
+    READ_COLOR("menu.items.disabled.text.color", theme->menu_disabled_color,
+               RrColorNew(inst, 0, 0, 0));
+
+    READ_COLOR("menu.items.active.disabled.text.color",
+               theme->menu_disabled_selected_color,
+               RrColorCopy(theme->menu_disabled_color));
+
+    READ_COLOR("menu.items.active.text.color", theme->menu_selected_color,
+               RrColorNew(inst, 0, 0, 0));
+
+    READ_COLOR("menu.separator.color", theme->menu_sep_color,
+               RrColorCopy(theme->menu_color));
+
+    READ_COLOR("menu.bullet.selected.image.color",
+               theme->menu_bullet_selected_color,
+               RrColorCopy(theme->menu_selected_color));
+
+    READ_COLOR("osd.button.unpressed.text.color", theme->osd_unpressed_color,
+               RrColorCopy(theme->osd_text_active_color));
+    READ_COLOR("osd.button.pressed.text.color", theme->osd_pressed_color,
+               RrColorCopy(theme->osd_text_active_color));
+    READ_COLOR("osd.button.focused.text.color", theme->osd_focused_color,
+               RrColorCopy(theme->osd_text_active_color));
+    READ_COLOR("osd.button.pressed.box.color", theme->osd_pressed_lineart,
+               RrColorCopy(theme->titlebut_focused_pressed_color));
+    READ_COLOR("osd.button.focused.box.color", theme->osd_focused_lineart,
+               RrColorCopy(theme->titlebut_hover_focused_color));
+
     /* load the image masks */

     /* maximize button masks */
     userdef = TRUE;
-    if (!read_mask(inst, path, theme, "max.xbm", &theme->max_mask)) {
+    if (!read_mask(inst, path, theme, "max.xbm", &theme->btn_max->mask)) {
             guchar data[] = { 0x3f, 0x3f, 0x21, 0x21, 0x21, 0x3f };
-            theme->max_mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
+            theme->btn_max->mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
             userdef = FALSE;
     }
     if (!read_mask(inst, path, theme, "max_toggled.xbm",
-                   &theme->max_toggled_mask))
+                   &theme->btn_max->toggled_mask))
     {
         if (userdef)
-            theme->max_toggled_mask = RrPixmapMaskCopy(theme->max_mask);
+            theme->btn_max->toggled_mask = RrPixmapMaskCopy(theme->btn_max->mask);
         else {
             guchar data[] = { 0x3e, 0x22, 0x2f, 0x29, 0x39, 0x0f };
-            theme->max_toggled_mask = RrPixmapMaskNew(inst, 6, 6,(gchar*)data);
+            theme->btn_max->toggled_mask = RrPixmapMaskNew(inst, 6, 6,(gchar*)data);
         }
     }
-    if (!read_mask(inst, path, theme, "max_pressed.xbm",
-                   &theme->max_pressed_mask))
-        theme->max_pressed_mask = RrPixmapMaskCopy(theme->max_mask);
-    if (!read_mask(inst,path,theme,"max_disabled.xbm",
-                   &theme->max_disabled_mask))
-        theme->max_disabled_mask = RrPixmapMaskCopy(theme->max_mask);
-    if (!read_mask(inst, path, theme, "max_hover.xbm", &theme->max_hover_mask))
-        theme->max_hover_mask = RrPixmapMaskCopy(theme->max_mask);
-    if (!read_mask(inst, path, theme, "max_toggled_pressed.xbm",
-                   &theme->max_toggled_pressed_mask))
-        theme->max_toggled_pressed_mask =
-            RrPixmapMaskCopy(theme->max_toggled_mask);
-    if (!read_mask(inst, path, theme, "max_toggled_hover.xbm",
-                   &theme->max_toggled_hover_mask))
-        theme->max_toggled_hover_mask =
-            RrPixmapMaskCopy(theme->max_toggled_mask);
+    READ_MASK_COPY("max_pressed.xbm", theme->btn_max->pressed_mask,
+                   theme->btn_max->mask);
+    READ_MASK_COPY("max_disabled.xbm", theme->btn_max->disabled_mask,
+                   theme->btn_max->mask);
+    READ_MASK_COPY("max_hover.xbm", theme->btn_max->hover_mask,
+                   theme->btn_max->mask);
+    READ_MASK_COPY("max_toggled_pressed.xbm",
+                   theme->btn_max->toggled_pressed_mask,
+                   theme->btn_max->toggled_mask);
+    READ_MASK_COPY("max_toggled_hover.xbm",
+                   theme->btn_max->toggled_hover_mask,
+                   theme->btn_max->toggled_mask);

     /* iconify button masks */
-    if (!read_mask(inst, path, theme, "iconify.xbm", &theme->iconify_mask)) {
+    if (!read_mask(inst, path, theme, "iconify.xbm", &theme->btn_iconify->mask)) {
         guchar data[] = { 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f };
-        theme->iconify_mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
+        theme->btn_iconify->mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
     }
-    if (!read_mask(inst, path, theme, "iconify_pressed.xbm",
-                   &theme->iconify_pressed_mask))
-        theme->iconify_pressed_mask = RrPixmapMaskCopy(theme->iconify_mask);
-    if (!read_mask(inst, path, theme, "iconify_disabled.xbm",
-                   &theme->iconify_disabled_mask))
-        theme->iconify_disabled_mask = RrPixmapMaskCopy(theme->iconify_mask);
-    if (!read_mask(inst, path, theme, "iconify_hover.xbm",
-                   &theme->iconify_hover_mask))
-        theme->iconify_hover_mask = RrPixmapMaskCopy(theme->iconify_mask);
+    READ_MASK_COPY("iconify_pressed.xbm", theme->btn_iconify->pressed_mask,
+                   theme->btn_iconify->mask);
+    READ_MASK_COPY("iconify_disabled.xbm", theme->btn_iconify->disabled_mask,
+                   theme->btn_iconify->mask);
+    READ_MASK_COPY("iconify_hover.xbm", theme->btn_iconify->hover_mask,
+                   theme->btn_iconify->mask);

     /* all desktops button masks */
     userdef = TRUE;
-    if (!read_mask(inst, path, theme, "desk.xbm", &theme->desk_mask)) {
+    if (!read_mask(inst, path, theme, "desk.xbm", &theme->btn_desk->mask)) {
         guchar data[] = { 0x33, 0x33, 0x00, 0x00, 0x33, 0x33 };
-        theme->desk_mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
+        theme->btn_desk->mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
         userdef = FALSE;
     }
     if (!read_mask(inst, path, theme, "desk_toggled.xbm",
-                   &theme->desk_toggled_mask)) {
+                   &theme->btn_desk->toggled_mask)) {
         if (userdef)
-            theme->desk_toggled_mask = RrPixmapMaskCopy(theme->desk_mask);
+            theme->btn_desk->toggled_mask = RrPixmapMaskCopy(theme->btn_desk->mask);
         else {
             guchar data[] = { 0x00, 0x1e, 0x1a, 0x16, 0x1e, 0x00 };
-            theme->desk_toggled_mask =
+            theme->btn_desk->toggled_mask =
                 RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
         }
     }
-    if (!read_mask(inst, path, theme, "desk_pressed.xbm",
-                   &theme->desk_pressed_mask))
-        theme->desk_pressed_mask = RrPixmapMaskCopy(theme->desk_mask);
-    if (!read_mask(inst, path, theme, "desk_disabled.xbm",
-                   &theme->desk_disabled_mask))
-        theme->desk_disabled_mask = RrPixmapMaskCopy(theme->desk_mask);
-    if (!read_mask(inst, path, theme, "desk_hover.xbm",
-                   &theme->desk_hover_mask))
-        theme->desk_hover_mask = RrPixmapMaskCopy(theme->desk_mask);
-    if (!read_mask(inst, path, theme, "desk_toggled_pressed.xbm",
-                   &theme->desk_toggled_pressed_mask))
-        theme->desk_toggled_pressed_mask =
-            RrPixmapMaskCopy(theme->desk_toggled_mask);
-    if (!read_mask(inst, path, theme, "desk_toggled_hover.xbm",
-                   &theme->desk_toggled_hover_mask))
-        theme->desk_toggled_hover_mask =
-            RrPixmapMaskCopy(theme->desk_toggled_mask);
+    READ_MASK_COPY("desk_pressed.xbm", theme->btn_desk->pressed_mask,
+                   theme->btn_desk->mask);
+    READ_MASK_COPY("desk_disabled.xbm", theme->btn_desk->disabled_mask,
+                   theme->btn_desk->mask);
+    READ_MASK_COPY("desk_hover.xbm", theme->btn_desk->hover_mask, theme->btn_desk->mask);
+    READ_MASK_COPY("desk_toggled_pressed.xbm",
+                   theme->btn_desk->toggled_pressed_mask, theme->btn_desk->toggled_mask);
+    READ_MASK_COPY("desk_toggled_hover.xbm", theme->btn_desk->toggled_hover_mask,
+                   theme->btn_desk->toggled_mask);

     /* shade button masks */
-    if (!read_mask(inst, path, theme, "shade.xbm", &theme->shade_mask)) {
+    if (!read_mask(inst, path, theme, "shade.xbm", &theme->btn_shade->mask)) {
         guchar data[] = { 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00 };
-        theme->shade_mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
+        theme->btn_shade->mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
     }
-    if (!read_mask(inst, path, theme, "shade_toggled.xbm",
-                  &theme->shade_toggled_mask))
-        theme->shade_toggled_mask = RrPixmapMaskCopy(theme->shade_mask);
-    if (!read_mask(inst, path, theme, "shade_pressed.xbm",
-                   &theme->shade_pressed_mask))
-        theme->shade_pressed_mask = RrPixmapMaskCopy(theme->shade_mask);
-    if (!read_mask(inst, path, theme, "shade_disabled.xbm",
-                   &theme->shade_disabled_mask))
-        theme->shade_disabled_mask = RrPixmapMaskCopy(theme->shade_mask);
-    if (!read_mask(inst, path, theme, "shade_hover.xbm",
-                   &theme->shade_hover_mask))
-        theme->shade_hover_mask = RrPixmapMaskCopy(theme->shade_mask);
-    if (!read_mask(inst, path, theme, "shade_toggled_pressed.xbm",
-                   &theme->shade_toggled_pressed_mask))
-        theme->shade_toggled_pressed_mask =
-            RrPixmapMaskCopy(theme->shade_toggled_mask);
-    if (!read_mask(inst, path, theme, "shade_toggled_hover.xbm",
-                   &theme->shade_toggled_hover_mask))
-        theme->shade_toggled_hover_mask =
-            RrPixmapMaskCopy(theme->shade_toggled_mask);
+    READ_MASK_COPY("shade_toggled.xbm", theme->btn_shade->toggled_mask,
+                   theme->btn_shade->mask);
+    READ_MASK_COPY("shade_pressed.xbm", theme->btn_shade->pressed_mask,
+                   theme->btn_shade->mask);
+    READ_MASK_COPY("shade_disabled.xbm", theme->btn_shade->disabled_mask,
+                   theme->btn_shade->mask);
+    READ_MASK_COPY("shade_hover.xbm", theme->btn_shade->hover_mask,
+                   theme->btn_shade->mask);
+    READ_MASK_COPY("shade_toggled_pressed.xbm",
+                   theme->btn_shade->toggled_pressed_mask,
+                   theme->btn_shade->toggled_mask);
+    READ_MASK_COPY("shade_toggled_hover.xbm",
+                   theme->btn_shade->toggled_hover_mask,
+                   theme->btn_shade->toggled_mask);

     /* close button masks */
-    if (!read_mask(inst, path, theme, "close.xbm", &theme->close_mask)) {
+    if (!read_mask(inst, path, theme, "close.xbm", &theme->btn_close->mask)) {
         guchar data[] = { 0x33, 0x3f, 0x1e, 0x1e, 0x3f, 0x33 };
-        theme->close_mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
+        theme->btn_close->mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
     }
-    if (!read_mask(inst, path, theme, "close_pressed.xbm",
-                   &theme->close_pressed_mask))
-        theme->close_pressed_mask = RrPixmapMaskCopy(theme->close_mask);
-    if (!read_mask(inst, path, theme, "close_disabled.xbm",
-                   &theme->close_disabled_mask))
-        theme->close_disabled_mask = RrPixmapMaskCopy(theme->close_mask);
-    if (!read_mask(inst, path, theme, "close_hover.xbm",
-                   &theme->close_hover_mask))
-        theme->close_hover_mask = RrPixmapMaskCopy(theme->close_mask);
+    READ_MASK_COPY("close_pressed.xbm", theme->btn_close->pressed_mask,
+                   theme->btn_close->mask);
+    READ_MASK_COPY("close_disabled.xbm", theme->btn_close->disabled_mask,
+                   theme->btn_close->mask);
+    READ_MASK_COPY("close_hover.xbm", theme->btn_close->hover_mask,
+                   theme->btn_close->mask);

     /* submenu bullet mask */
     if (!read_mask(inst, path, theme, "bullet.xbm", &theme->menu_bullet_mask))
@@ -627,51 +549,37 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
     theme->def_win_icon_w = OB_DEFAULT_ICON_WIDTH;
     theme->def_win_icon_h = OB_DEFAULT_ICON_HEIGHT;

+    /* the toggled hover mask = the toggled unpressed mask (i.e. no change) */
+    theme->btn_max->toggled_hover_mask =
+        RrPixmapMaskCopy(theme->btn_max->toggled_mask);
+    theme->btn_desk->toggled_hover_mask =
+        RrPixmapMaskCopy(theme->btn_desk->toggled_mask);
+    theme->btn_shade->toggled_hover_mask =
+        RrPixmapMaskCopy(theme->btn_shade->toggled_mask);
+    /* the toggled pressed mask = the toggled unpressed mask (i.e. no change)*/
+    theme->btn_max->toggled_pressed_mask =
+        RrPixmapMaskCopy(theme->btn_max->toggled_mask);
+    theme->btn_desk->toggled_pressed_mask =
+        RrPixmapMaskCopy(theme->btn_desk->toggled_mask);
+    theme->btn_shade->toggled_pressed_mask =
+        RrPixmapMaskCopy(theme->btn_shade->toggled_mask);
+
     /* read the decoration textures */
-    if (!read_appearance(db, inst,
-                         "window.active.title.bg", theme->a_focused_title,
-                         FALSE))
-        set_default_appearance(theme->a_focused_title);
-    if (!read_appearance(db, inst,
-                         "window.inactive.title.bg", theme->a_unfocused_title,
-                         FALSE))
-        set_default_appearance(theme->a_unfocused_title);
-    if (!read_appearance(db, inst,
-                         "window.active.label.bg", theme->a_focused_label,
-                         TRUE))
-        set_default_appearance(theme->a_focused_label);
-    if (!read_appearance(db, inst,
-                         "window.inactive.label.bg", theme->a_unfocused_label,
-                         TRUE))
-        set_default_appearance(theme->a_unfocused_label);
-    if (!read_appearance(db, inst,
-                         "window.active.handle.bg", theme->a_focused_handle,
-                         FALSE))
-        set_default_appearance(theme->a_focused_handle);
-    if (!read_appearance(db, inst,
-                         "window.inactive.handle.bg",theme->a_unfocused_handle,
-                         FALSE))
-        set_default_appearance(theme->a_unfocused_handle);
-    if (!read_appearance(db, inst,
-                         "window.active.grip.bg", theme->a_focused_grip,
-                         TRUE))
-        set_default_appearance(theme->a_focused_grip);
-    if (!read_appearance(db, inst,
-                         "window.inactive.grip.bg", theme->a_unfocused_grip,
-                         TRUE))
-        set_default_appearance(theme->a_unfocused_grip);
-    if (!read_appearance(db, inst,
-                         "menu.items.bg", theme->a_menu,
-                         FALSE))
-        set_default_appearance(theme->a_menu);
-    if (!read_appearance(db, inst,
-                         "menu.title.bg", theme->a_menu_title,
-                         TRUE))
-        set_default_appearance(theme->a_menu_title);
-    if (!read_appearance(db, inst,
-                         "menu.items.active.bg", theme->a_menu_selected,
-                         TRUE))
-        set_default_appearance(theme->a_menu_selected);
+    READ_APPEARANCE("window.active.title.bg", theme->a_focused_title, FALSE);
+    READ_APPEARANCE("window.inactive.title.bg", theme->a_unfocused_title,
+                    FALSE);
+    READ_APPEARANCE("window.active.label.bg", theme->a_focused_label, TRUE);
+    READ_APPEARANCE("window.inactive.label.bg", theme->a_unfocused_label,
+                    TRUE);
+    READ_APPEARANCE("window.active.handle.bg", theme->a_focused_handle, FALSE);
+    READ_APPEARANCE("window.inactive.handle.bg",theme->a_unfocused_handle,
+                    FALSE);
+    READ_APPEARANCE("window.active.grip.bg", theme->a_focused_grip, TRUE);
+    READ_APPEARANCE("window.inactive.grip.bg", theme->a_unfocused_grip, TRUE);
+    READ_APPEARANCE("menu.items.bg", theme->a_menu, FALSE);
+    READ_APPEARANCE("menu.title.bg", theme->a_menu_title, TRUE);
+    READ_APPEARANCE("menu.items.active.bg", theme->a_menu_selected, TRUE);
+
     theme->a_menu_disabled_selected =
         RrAppearanceCopy(theme->a_menu_selected);

@@ -712,236 +620,289 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
     }

     /* read buttons textures */
-    if (!read_appearance(db, inst,
-                         "window.active.button.disabled.bg",
-                         theme->a_disabled_focused_max,
-                         TRUE))
-        set_default_appearance(theme->a_disabled_focused_max);
-    if (!read_appearance(db, inst,
-                         "window.inactive.button.disabled.bg",
-                         theme->a_disabled_unfocused_max,
-                         TRUE))
-        set_default_appearance(theme->a_disabled_unfocused_max);
-    if (!read_appearance(db, inst,
-                         "window.active.button.pressed.bg",
-                         theme->a_focused_pressed_max,
-                         TRUE))
-        set_default_appearance(theme->a_focused_pressed_max);
-    if (!read_appearance(db, inst,
-                         "window.inactive.button.pressed.bg",
-                         theme->a_unfocused_pressed_max,
-                         TRUE))
-        set_default_appearance(theme->a_unfocused_pressed_max);
-    if (!read_appearance(db, inst,
-                         "window.active.button.toggled.unpressed.bg",
-                         theme->a_toggled_focused_unpressed_max,
-                         TRUE) &&
-        !read_appearance(db, inst,
-                         "window.active.button.toggled.bg",
-                         theme->a_toggled_focused_unpressed_max,
-                         TRUE))
-    {
-        RrAppearanceFree(theme->a_toggled_focused_unpressed_max);
-        theme->a_toggled_focused_unpressed_max =
-            RrAppearanceCopy(theme->a_focused_pressed_max);
-    }
-    if (!read_appearance(db, inst,
-                         "window.inactive.button.toggled.unpressed.bg",
-                         theme->a_toggled_unfocused_unpressed_max,
-                         TRUE) &&
-        !read_appearance(db, inst,
-                         "window.inactive.button.toggled.bg",
-                         theme->a_toggled_unfocused_unpressed_max,
-                         TRUE))
-    {
-        RrAppearanceFree(theme->a_toggled_unfocused_unpressed_max);
-        theme->a_toggled_unfocused_unpressed_max =
-            RrAppearanceCopy(theme->a_unfocused_pressed_max);
-    }
-    if (!read_appearance(db, inst,
-                         "window.active.button.toggled.hover.bg",
-                         theme->a_toggled_hover_focused_max,
-                         TRUE))
-    {
-        RrAppearanceFree(theme->a_toggled_hover_focused_max);
-        theme->a_toggled_hover_focused_max =
-            RrAppearanceCopy(theme->a_toggled_focused_unpressed_max);
-    }
-    if (!read_appearance(db, inst,
-                         "window.inactive.button.toggled.hover.bg",
-                         theme->a_toggled_hover_unfocused_max,
-                         TRUE))
-    {
-        RrAppearanceFree(theme->a_toggled_hover_unfocused_max);
-        theme->a_toggled_hover_unfocused_max =
-            RrAppearanceCopy(theme->a_toggled_unfocused_unpressed_max);
-    }
-    if (!read_appearance(db, inst,
-                         "window.active.button.toggled.pressed.bg",
-                         theme->a_toggled_focused_pressed_max,
-                         TRUE))
-    {
-        RrAppearanceFree(theme->a_toggled_focused_pressed_max);
-        theme->a_toggled_focused_pressed_max =
-            RrAppearanceCopy(theme->a_focused_pressed_max);
-    }
-    if (!read_appearance(db, inst,
-                         "window.inactive.button.toggled.pressed.bg",
-                         theme->a_toggled_unfocused_pressed_max,
-                         TRUE))
-    {
-        RrAppearanceFree(theme->a_toggled_unfocused_pressed_max);
-        theme->a_toggled_unfocused_pressed_max =
-            RrAppearanceCopy(theme->a_unfocused_pressed_max);
-    }
-    if (!read_appearance(db, inst,
-                         "window.active.button.unpressed.bg",
-                         theme->a_focused_unpressed_max,
-                         TRUE))
-        set_default_appearance(theme->a_focused_unpressed_max);
-    if (!read_appearance(db, inst,
-                         "window.inactive.button.unpressed.bg",
-                         theme->a_unfocused_unpressed_max,
-                         TRUE))
-        set_default_appearance(theme->a_unfocused_unpressed_max);
-    if (!read_appearance(db, inst,
-                         "window.active.button.hover.bg",
-                         theme->a_hover_focused_max,
-                         TRUE))
-    {
-        RrAppearanceFree(theme->a_hover_focused_max);
-        theme->a_hover_focused_max =
-            RrAppearanceCopy(theme->a_focused_unpressed_max);
-    }
-    if (!read_appearance(db, inst,
-                         "window.inactive.button.hover.bg",
-                         theme->a_hover_unfocused_max,
-                         TRUE))
-    {
-        RrAppearanceFree(theme->a_hover_unfocused_max);
-        theme->a_hover_unfocused_max =
-            RrAppearanceCopy(theme->a_unfocused_unpressed_max);
-    }
-    if (!read_appearance(db, inst,
-                         "osd.button.unpressed.bg",
-                         theme->osd_unpressed_button,
-                         TRUE))
-    {
-        RrAppearanceFree(theme->osd_unpressed_button);
-        theme->osd_unpressed_button =
-            RrAppearanceCopy(theme->a_focused_unpressed_max);
-    }
-    if (!read_appearance(db, inst,
-                         "osd.button.pressed.bg",
-                         theme->osd_pressed_button,
-                         TRUE))
-    {
-        RrAppearanceFree(theme->osd_pressed_button);
-        theme->osd_pressed_button =
-            RrAppearanceCopy(theme->a_focused_pressed_max);
-        RrAppearanceRemoveTextures(theme->osd_pressed_button);
-        RrAppearanceAddTextures(theme->osd_pressed_button, 5);
-    }
-    if (!read_appearance(db, inst,
-                         "osd.button.focused.bg",
-                         theme->osd_focused_button,
-                         TRUE))
-    {
-        RrAppearanceFree(theme->osd_focused_button);
-        theme->osd_focused_button =
-            RrAppearanceCopy(theme->a_hover_focused_max);
-        RrAppearanceRemoveTextures(theme->osd_focused_button);
-        RrAppearanceAddTextures(theme->osd_focused_button, 5);
-    }

-    theme->a_disabled_focused_close =
-        RrAppearanceCopy(theme->a_disabled_focused_max);
-    theme->a_disabled_unfocused_close =
-        RrAppearanceCopy(theme->a_disabled_unfocused_max);
-    theme->a_hover_focused_close =
-        RrAppearanceCopy(theme->a_hover_focused_max);
-    theme->a_hover_unfocused_close =
-        RrAppearanceCopy(theme->a_hover_unfocused_max);
-    theme->a_unfocused_unpressed_close =
-        RrAppearanceCopy(theme->a_unfocused_unpressed_max);
-    theme->a_unfocused_pressed_close =
-        RrAppearanceCopy(theme->a_unfocused_pressed_max);
-    theme->a_focused_unpressed_close =
-        RrAppearanceCopy(theme->a_focused_unpressed_max);
-    theme->a_focused_pressed_close =
-        RrAppearanceCopy(theme->a_focused_pressed_max);
-    theme->a_disabled_focused_desk =
-        RrAppearanceCopy(theme->a_disabled_focused_max);
-    theme->a_disabled_unfocused_desk =
-        RrAppearanceCopy(theme->a_disabled_unfocused_max);
-    theme->a_hover_focused_desk =
-        RrAppearanceCopy(theme->a_hover_focused_max);
-    theme->a_hover_unfocused_desk =
-        RrAppearanceCopy(theme->a_hover_unfocused_max);
-    theme->a_toggled_hover_focused_desk =
-        RrAppearanceCopy(theme->a_toggled_hover_focused_max);
-    theme->a_toggled_hover_unfocused_desk =
-        RrAppearanceCopy(theme->a_toggled_hover_unfocused_max);
-    theme->a_toggled_focused_unpressed_desk =
-        RrAppearanceCopy(theme->a_toggled_focused_unpressed_max);
-    theme->a_toggled_unfocused_unpressed_desk =
-        RrAppearanceCopy(theme->a_toggled_unfocused_unpressed_max);
-    theme->a_toggled_focused_pressed_desk =
-        RrAppearanceCopy(theme->a_toggled_focused_pressed_max);
-    theme->a_toggled_unfocused_pressed_desk =
-        RrAppearanceCopy(theme->a_toggled_unfocused_pressed_max);
-    theme->a_unfocused_unpressed_desk =
-        RrAppearanceCopy(theme->a_unfocused_unpressed_max);
-    theme->a_unfocused_pressed_desk =
-        RrAppearanceCopy(theme->a_unfocused_pressed_max);
-    theme->a_focused_unpressed_desk =
-        RrAppearanceCopy(theme->a_focused_unpressed_max);
-    theme->a_focused_pressed_desk =
-        RrAppearanceCopy(theme->a_focused_pressed_max);
-    theme->a_disabled_focused_shade =
-        RrAppearanceCopy(theme->a_disabled_focused_max);
-    theme->a_disabled_unfocused_shade =
-        RrAppearanceCopy(theme->a_disabled_unfocused_max);
-    theme->a_hover_focused_shade =
-        RrAppearanceCopy(theme->a_hover_focused_max);
-    theme->a_hover_unfocused_shade =
-        RrAppearanceCopy(theme->a_hover_unfocused_max);
-    theme->a_toggled_hover_focused_shade =
-        RrAppearanceCopy(theme->a_toggled_hover_focused_max);
-    theme->a_toggled_hover_unfocused_shade =
-        RrAppearanceCopy(theme->a_toggled_hover_unfocused_max);
-    theme->a_toggled_focused_unpressed_shade =
-        RrAppearanceCopy(theme->a_toggled_focused_unpressed_max);
-    theme->a_toggled_unfocused_unpressed_shade =
-        RrAppearanceCopy(theme->a_toggled_unfocused_unpressed_max);
-    theme->a_toggled_focused_pressed_shade =
-        RrAppearanceCopy(theme->a_toggled_focused_pressed_max);
-    theme->a_toggled_unfocused_pressed_shade =
-        RrAppearanceCopy(theme->a_toggled_unfocused_pressed_max);
-    theme->a_unfocused_unpressed_shade =
-        RrAppearanceCopy(theme->a_unfocused_unpressed_max);
-    theme->a_unfocused_pressed_shade =
-        RrAppearanceCopy(theme->a_unfocused_pressed_max);
-    theme->a_focused_unpressed_shade =
-        RrAppearanceCopy(theme->a_focused_unpressed_max);
-    theme->a_focused_pressed_shade =
-        RrAppearanceCopy(theme->a_focused_pressed_max);
-    theme->a_disabled_focused_iconify =
-        RrAppearanceCopy(theme->a_disabled_focused_max);
-    theme->a_disabled_unfocused_iconify =
-        RrAppearanceCopy(theme->a_disabled_focused_max);
-    theme->a_hover_focused_iconify =
-        RrAppearanceCopy(theme->a_hover_focused_max);
-    theme->a_hover_unfocused_iconify =
-        RrAppearanceCopy(theme->a_hover_unfocused_max);
-    theme->a_unfocused_unpressed_iconify =
-        RrAppearanceCopy(theme->a_unfocused_unpressed_max);
-    theme->a_unfocused_pressed_iconify =
-        RrAppearanceCopy(theme->a_unfocused_pressed_max);
-    theme->a_focused_unpressed_iconify =
-        RrAppearanceCopy(theme->a_focused_unpressed_max);
-    theme->a_focused_pressed_iconify =
-        RrAppearanceCopy(theme->a_focused_pressed_max);
+    /* bases: unpressed, pressed, disabled */
+    READ_APPEARANCE("window.active.button.unpressed.bg",
+                    a_focused_unpressed_tmp, TRUE);
+    READ_APPEARANCE("window.inactive.button.unpressed.bg",
+                    a_unfocused_unpressed_tmp, TRUE);
+    READ_APPEARANCE("window.active.button.pressed.bg",
+                    a_focused_pressed_tmp, TRUE);
+    READ_APPEARANCE("window.inactive.button.pressed.bg",
+                    a_unfocused_pressed_tmp, TRUE);
+    READ_APPEARANCE("window.active.button.disabled.bg",
+                    a_disabled_focused_tmp, TRUE);
+    READ_APPEARANCE("window.inactive.button.disabled.bg",
+                    a_disabled_unfocused_tmp, TRUE);
+
+    /* hover */
+    READ_APPEARANCE_COPY("window.active.button.hover.bg",
+                         a_hover_focused_tmp, TRUE,
+                         a_focused_unpressed_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.hover.bg",
+                         a_hover_unfocused_tmp, TRUE,
+                         a_unfocused_unpressed_tmp);
+
+    /* toggled unpressed */
+    READ_APPEARANCE_("window.active.button.toggled.unpressed.bg",
+                     "window.active.button.toggled.bg",
+                     a_toggled_focused_unpressed_tmp, TRUE,
+                     a_focused_pressed_tmp);
+    READ_APPEARANCE_("window.inactive.button.toggled.unpressed.bg",
+                     "window.inactive.button.toggled.bg",
+                     a_toggled_unfocused_unpressed_tmp, TRUE,
+                     a_unfocused_pressed_tmp);
+
+    /* toggled pressed */
+    READ_APPEARANCE_COPY("window.active.button.toggled.pressed.bg",
+                         a_toggled_focused_pressed_tmp, TRUE,
+                         a_focused_pressed_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.toggled.pressed.bg",
+                         a_toggled_unfocused_pressed_tmp, TRUE,
+                         a_unfocused_pressed_tmp);
+
+    /* toggled hover */
+    READ_APPEARANCE_COPY("window.active.button.toggled.hover.bg",
+                         a_toggled_hover_focused_tmp, TRUE,
+                         a_toggled_focused_unpressed_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.toggled.hover.bg",
+                         a_toggled_hover_unfocused_tmp, TRUE,
+                         a_toggled_unfocused_unpressed_tmp);
+
+
+    /* now do individual buttons, if specified */
+
+    /* max button */
+    read_button_colors(db, inst, theme, theme->btn_max, "max");
+
+    /* bases:  unpressed, pressed, disabled */
+    READ_APPEARANCE_COPY("window.active.button.max.unpressed.bg",
+                         theme->btn_max->a_focused_unpressed, TRUE,
+                         a_focused_unpressed_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.max.unpressed.bg",
+                         theme->btn_max->a_unfocused_unpressed, TRUE,
+                         a_unfocused_unpressed_tmp);
+    READ_APPEARANCE_COPY("window.active.button.max.pressed.bg",
+                         theme->btn_max->a_focused_pressed, TRUE,
+                         a_focused_pressed_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.max.pressed.bg",
+                         theme->btn_max->a_unfocused_pressed, TRUE,
+                         a_unfocused_pressed_tmp);
+    READ_APPEARANCE_COPY("window.active.button.max.disabled.bg",
+                         theme->btn_max->a_disabled_focused, TRUE,
+                         a_disabled_focused_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.max.disabled.bg",
+                         theme->btn_max->a_disabled_unfocused, TRUE,
+                         a_disabled_unfocused_tmp);
+
+    /* hover */
+    READ_APPEARANCE_COPY("window.active.button.max.hover.bg",
+                         theme->btn_max->a_hover_focused, TRUE,
+                         theme->btn_max->a_focused_unpressed);
+    READ_APPEARANCE_COPY("window.inactive.button.max.hover.bg",
+                         theme->btn_max->a_hover_unfocused, TRUE,
+                         theme->btn_max->a_unfocused_unpressed);
+
+    /* toggled unpressed */
+    READ_APPEARANCE_("window.active.button.max.toggled.unpressed.bg",
+                     "window.active.button.max.toggled.bg",
+                     theme->btn_max->a_toggled_focused_unpressed, TRUE,
+                     theme->btn_max->a_focused_pressed);
+    READ_APPEARANCE_("window.inactive.button.max.toggled.unpressed.bg",
+                     "window.inactive.button.max.toggled.bg",
+                     theme->btn_max->a_toggled_unfocused_unpressed, TRUE,
+                     theme->btn_max->a_unfocused_pressed);
+
+    /* toggled pressed */
+    READ_APPEARANCE_COPY("window.active.button.max.toggled.pressed.bg",
+                         theme->btn_max->a_toggled_focused_pressed, TRUE,
+                         theme->btn_max->a_focused_pressed);
+    READ_APPEARANCE_COPY("window.inactive.button.max.toggled.pressed.bg",
+                         theme->btn_max->a_toggled_unfocused_pressed, TRUE,
+                         theme->btn_max->a_unfocused_pressed);
+
+    /* toggled hover */
+    READ_APPEARANCE_COPY("window.active.button.max.toggled.hover.bg",
+                         theme->btn_max->a_toggled_hover_focused, TRUE,
+                         theme->btn_max->a_toggled_focused_unpressed);
+    READ_APPEARANCE_COPY("window.inactive.button.max.toggled.hover.bg",
+                         theme->btn_max->a_toggled_hover_unfocused, TRUE,
+                         theme->btn_max->a_toggled_unfocused_unpressed);
+
+    /* close button */
+    read_button_colors(db, inst, theme, theme->btn_close, "close");
+
+    READ_APPEARANCE_COPY("window.active.button.close.unpressed.bg",
+                         theme->btn_close->a_focused_unpressed, TRUE,
+                         a_focused_unpressed_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.close.unpressed.bg",
+                         theme->btn_close->a_unfocused_unpressed, TRUE,
+                         a_unfocused_unpressed_tmp);
+    READ_APPEARANCE_COPY("window.active.button.close.pressed.bg",
+                         theme->btn_close->a_focused_pressed, TRUE,
+                         a_focused_pressed_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.close.pressed.bg",
+                         theme->btn_close->a_unfocused_pressed, TRUE,
+                         a_unfocused_pressed_tmp);
+    READ_APPEARANCE_COPY("window.active.button.close.disabled.bg",
+                         theme->btn_close->a_disabled_focused, TRUE,
+                         a_disabled_focused_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.close.disabled.bg",
+                         theme->btn_close->a_disabled_unfocused, TRUE,
+                         a_disabled_unfocused_tmp);
+    READ_APPEARANCE_COPY("window.active.button.close.hover.bg",
+                         theme->btn_close->a_hover_focused, TRUE,
+                         theme->btn_close->a_focused_unpressed);
+    READ_APPEARANCE_COPY("window.inactive.button.close.hover.bg",
+                         theme->btn_close->a_hover_unfocused, TRUE,
+                         theme->btn_close->a_unfocused_unpressed);
+
+    /* desk button */
+    read_button_colors(db, inst, theme, theme->btn_desk, "desk");
+
+    /* bases:  unpressed, pressed, disabled */
+    READ_APPEARANCE_COPY("window.active.button.desk.unpressed.bg",
+                         theme->btn_desk->a_focused_unpressed, TRUE,
+                         a_focused_unpressed_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.desk.unpressed.bg",
+                         theme->btn_desk->a_unfocused_unpressed, TRUE,
+                         a_unfocused_unpressed_tmp);
+    READ_APPEARANCE_COPY("window.active.button.desk.pressed.bg",
+                         theme->btn_desk->a_focused_pressed, TRUE,
+                         a_focused_pressed_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.desk.pressed.bg",
+                         theme->btn_desk->a_unfocused_pressed, TRUE,
+                         a_unfocused_pressed_tmp);
+    READ_APPEARANCE_COPY("window.active.button.desk.disabled.bg",
+                         theme->btn_desk->a_disabled_focused, TRUE,
+                         a_disabled_focused_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.desk.disabled.bg",
+                         theme->btn_desk->a_disabled_unfocused, TRUE,
+                         a_disabled_unfocused_tmp);
+
+    /* hover */
+    READ_APPEARANCE_COPY("window.active.button.desk.hover.bg",
+                         theme->btn_desk->a_hover_focused, TRUE,
+                         theme->btn_desk->a_focused_unpressed);
+    READ_APPEARANCE_COPY("window.inactive.button.desk.hover.bg",
+                         theme->btn_desk->a_hover_unfocused, TRUE,
+                         theme->btn_desk->a_unfocused_unpressed);
+
+    /* toggled unpressed */
+    READ_APPEARANCE_("window.active.button.desk.toggled.unpressed.bg",
+                     "window.active.button.desk.toggled.bg",
+                     theme->btn_desk->a_toggled_focused_unpressed, TRUE,
+                     theme->btn_desk->a_focused_pressed);
+    READ_APPEARANCE_("window.inactive.button.desk.toggled.unpressed.bg",
+                     "window.inactive.button.desk.toggled.bg",
+                     theme->btn_desk->a_toggled_unfocused_unpressed, TRUE,
+                     theme->btn_desk->a_unfocused_pressed);
+
+    /* toggled pressed */
+    READ_APPEARANCE_COPY("window.active.button.desk.toggled.pressed.bg",
+                         theme->btn_desk->a_toggled_focused_pressed, TRUE,
+                         theme->btn_desk->a_focused_pressed);
+    READ_APPEARANCE_COPY("window.inactive.button.desk.toggled.pressed.bg",
+                         theme->btn_desk->a_toggled_unfocused_pressed, TRUE,
+                         theme->btn_desk->a_unfocused_pressed);
+
+    /* toggled hover */
+    READ_APPEARANCE_COPY("window.active.button.desk.toggled.hover.bg",
+                         theme->btn_desk->a_toggled_hover_focused, TRUE,
+                         theme->btn_desk->a_toggled_focused_unpressed);
+    READ_APPEARANCE_COPY("window.inactive.button.desk.toggled.hover.bg",
+                         theme->btn_desk->a_toggled_hover_unfocused, TRUE,
+                         theme->btn_desk->a_toggled_unfocused_unpressed);
+
+    /* shade button */
+    read_button_colors(db, inst, theme, theme->btn_shade, "shade");
+
+    /* bases:  unpressed, pressed, disabled */
+    READ_APPEARANCE_COPY("window.active.button.shade.unpressed.bg",
+                         theme->btn_shade->a_focused_unpressed, TRUE,
+                         a_focused_unpressed_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.shade.unpressed.bg",
+                         theme->btn_shade->a_unfocused_unpressed, TRUE,
+                         a_unfocused_unpressed_tmp);
+    READ_APPEARANCE_COPY("window.active.button.shade.pressed.bg",
+                         theme->btn_shade->a_focused_pressed, TRUE,
+                         a_focused_pressed_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.shade.pressed.bg",
+                         theme->btn_shade->a_unfocused_pressed, TRUE,
+                         a_unfocused_pressed_tmp);
+    READ_APPEARANCE_COPY("window.active.button.shade.disabled.bg",
+                         theme->btn_shade->a_disabled_focused, TRUE,
+                         a_disabled_focused_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.shade.disabled.bg",
+                         theme->btn_shade->a_disabled_unfocused, TRUE,
+                         a_disabled_unfocused_tmp);
+
+    /* hover */
+    READ_APPEARANCE_COPY("window.active.button.shade.hover.bg",
+                         theme->btn_shade->a_hover_focused, TRUE,
+                         theme->btn_shade->a_focused_unpressed);
+    READ_APPEARANCE_COPY("window.inactive.button.shade.hover.bg",
+                         theme->btn_shade->a_hover_unfocused, TRUE,
+                         theme->btn_shade->a_unfocused_unpressed);
+
+    /* toggled unpressed */
+    READ_APPEARANCE_("window.active.button.shade.toggled.unpressed.bg",
+                     "window.active.button.shade.toggled.bg",
+                     theme->btn_shade->a_toggled_focused_unpressed, TRUE,
+                     theme->btn_shade->a_focused_pressed);
+    READ_APPEARANCE_("window.inactive.button.shade.toggled.unpressed.bg",
+                     "window.inactive.button.shade.toggled.bg",
+                     theme->btn_shade->a_toggled_unfocused_unpressed, TRUE,
+                     theme->btn_shade->a_unfocused_pressed);
+
+    /* toggled pressed */
+    READ_APPEARANCE_COPY("window.active.button.shade.toggled.pressed.bg",
+                         theme->btn_shade->a_toggled_focused_pressed, TRUE,
+                         theme->btn_shade->a_focused_pressed);
+    READ_APPEARANCE_COPY("window.inactive.button.shade.toggled.pressed.bg",
+                         theme->btn_shade->a_toggled_unfocused_pressed, TRUE,
+                         theme->btn_shade->a_unfocused_pressed);
+
+    /* toggled hover */
+    READ_APPEARANCE_COPY("window.active.button.shade.toggled.hover.bg",
+                         theme->btn_shade->a_toggled_hover_focused, TRUE,
+                         theme->btn_shade->a_toggled_focused_unpressed);
+    READ_APPEARANCE_COPY("window.inactive.button.shade.toggled.hover.bg",
+                         theme->btn_shade->a_toggled_hover_unfocused, TRUE,
+                         theme->btn_shade->a_toggled_unfocused_unpressed);
+
+    /* iconify button */
+    read_button_colors(db, inst, theme, theme->btn_iconify, "iconify");
+
+    READ_APPEARANCE_COPY("window.active.button.iconify.unpressed.bg",
+                         theme->btn_iconify->a_focused_unpressed, TRUE,
+                         a_focused_unpressed_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.iconify.unpressed.bg",
+                         theme->btn_iconify->a_unfocused_unpressed, TRUE,
+                         a_unfocused_unpressed_tmp);
+    READ_APPEARANCE_COPY("window.active.button.iconify.pressed.bg",
+                         theme->btn_iconify->a_focused_pressed, TRUE,
+                         a_focused_pressed_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.iconify.pressed.bg",
+                         theme->btn_iconify->a_unfocused_pressed, TRUE,
+                         a_unfocused_pressed_tmp);
+    READ_APPEARANCE_COPY("window.active.button.iconify.disabled.bg",
+                         theme->btn_iconify->a_disabled_focused, TRUE,
+                         a_disabled_focused_tmp);
+    READ_APPEARANCE_COPY("window.inactive.button.iconify.disabled.bg",
+                         theme->btn_iconify->a_disabled_unfocused, TRUE,
+                         a_disabled_unfocused_tmp);
+    READ_APPEARANCE_COPY("window.active.button.iconify.hover.bg",
+                         theme->btn_iconify->a_hover_focused, TRUE,
+                         theme->btn_iconify->a_focused_unpressed);
+    READ_APPEARANCE_COPY("window.inactive.button.iconify.hover.bg",
+                         theme->btn_iconify->a_hover_unfocused, TRUE,
+                         theme->btn_iconify->a_unfocused_unpressed);
+
+    /* osd buttons */
+    READ_APPEARANCE_COPY("osd.button.unpressed.bg", theme->osd_unpressed_button, TRUE, a_focused_unpressed_tmp);
+    READ_APPEARANCE_COPY_TEXTURES("osd.button.pressed.bg", theme->osd_pressed_button, TRUE, a_focused_pressed_tmp, 5);
+    READ_APPEARANCE_COPY_TEXTURES("osd.button.focused.bg", theme->osd_focused_button, TRUE, a_focused_unpressed_tmp, 5);

     theme->a_icon->surface.grad =
         theme->a_clear->surface.grad =
@@ -1035,10 +996,7 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
             theme->a_focused_label->texture[0].data.text.shadow_offset_y;
         if (theme->title_focused_shadow_color)
             theme->osd_text_active_shadow_color =
-                RrColorNew(inst,
-                           theme->title_focused_shadow_color->r,
-                           theme->title_focused_shadow_color->g,
-                           theme->title_focused_shadow_color->b);
+                RrColorCopy(theme->title_focused_shadow_color);
         else
             theme->osd_text_active_shadow_color = RrColorNew(inst, 0, 0, 0);
         theme->osd_text_active_shadow_alpha =
@@ -1051,18 +1009,18 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
         theme->osd_text_active_shadow_alpha;

     theme->osd_unpressed_button->texture[0].type =
-    theme->osd_pressed_button->texture[0].type =
-    theme->osd_focused_button->texture[0].type =
+        theme->osd_pressed_button->texture[0].type =
+        theme->osd_focused_button->texture[0].type =
         RR_TEXTURE_TEXT;

     theme->osd_unpressed_button->texture[0].data.text.justify =
-    theme->osd_pressed_button->texture[0].data.text.justify =
-    theme->osd_focused_button->texture[0].data.text.justify =
+        theme->osd_pressed_button->texture[0].data.text.justify =
+        theme->osd_focused_button->texture[0].data.text.justify =
         RR_JUSTIFY_CENTER;

     theme->osd_unpressed_button->texture[0].data.text.font =
-    theme->osd_pressed_button->texture[0].data.text.font =
-    theme->osd_focused_button->texture[0].data.text.font =
+        theme->osd_pressed_button->texture[0].data.text.font =
+        theme->osd_focused_button->texture[0].data.text.font =
         theme->osd_font_hilite;

     theme->osd_unpressed_button->texture[0].data.text.color =
@@ -1073,15 +1031,15 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
         theme->osd_focused_color;

     theme->osd_pressed_button->texture[1].data.lineart.color =
-    theme->osd_pressed_button->texture[2].data.lineart.color =
-    theme->osd_pressed_button->texture[3].data.lineart.color =
-    theme->osd_pressed_button->texture[4].data.lineart.color =
+        theme->osd_pressed_button->texture[2].data.lineart.color =
+        theme->osd_pressed_button->texture[3].data.lineart.color =
+        theme->osd_pressed_button->texture[4].data.lineart.color =
         theme->osd_pressed_lineart;

     theme->osd_focused_button->texture[1].data.lineart.color =
-    theme->osd_focused_button->texture[2].data.lineart.color =
-    theme->osd_focused_button->texture[3].data.lineart.color =
-    theme->osd_focused_button->texture[4].data.lineart.color =
+        theme->osd_focused_button->texture[2].data.lineart.color =
+        theme->osd_focused_button->texture[3].data.lineart.color =
+        theme->osd_focused_button->texture[4].data.lineart.color =
         theme->osd_focused_lineart;

     theme->a_unfocused_label->texture[0].type = RR_TEXTURE_TEXT;
@@ -1162,10 +1120,7 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
             theme->a_unfocused_label->texture[0].data.text.shadow_offset_y;
         if (theme->title_unfocused_shadow_color)
             theme->osd_text_inactive_shadow_color =
-                RrColorNew(inst,
-                           theme->title_unfocused_shadow_color->r,
-                           theme->title_unfocused_shadow_color->g,
-                           theme->title_unfocused_shadow_color->b);
+                RrColorCopy(theme->title_unfocused_shadow_color);
         else
             theme->osd_text_inactive_shadow_color = RrColorNew(inst, 0, 0, 0);
         theme->osd_text_inactive_shadow_alpha =
@@ -1304,233 +1259,277 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
     theme->a_menu_text_disabled_selected->texture[0].data.text.shadow_alpha =
         theme->menu_text_disabled_shadow_alpha;

-    theme->a_disabled_focused_max->texture[0].type =
-        theme->a_disabled_unfocused_max->texture[0].type =
-        theme->a_hover_focused_max->texture[0].type =
-        theme->a_hover_unfocused_max->texture[0].type =
-        theme->a_toggled_hover_focused_max->texture[0].type =
-        theme->a_toggled_hover_unfocused_max->texture[0].type =
-        theme->a_toggled_focused_unpressed_max->texture[0].type =
-        theme->a_toggled_unfocused_unpressed_max->texture[0].type =
-        theme->a_toggled_focused_pressed_max->texture[0].type =
-        theme->a_toggled_unfocused_pressed_max->texture[0].type =
-        theme->a_focused_unpressed_max->texture[0].type =
-        theme->a_focused_pressed_max->texture[0].type =
-        theme->a_unfocused_unpressed_max->texture[0].type =
-        theme->a_unfocused_pressed_max->texture[0].type =
-        theme->a_disabled_focused_close->texture[0].type =
-        theme->a_disabled_unfocused_close->texture[0].type =
-        theme->a_hover_focused_close->texture[0].type =
-        theme->a_hover_unfocused_close->texture[0].type =
-        theme->a_focused_unpressed_close->texture[0].type =
-        theme->a_focused_pressed_close->texture[0].type =
-        theme->a_unfocused_unpressed_close->texture[0].type =
-        theme->a_unfocused_pressed_close->texture[0].type =
-        theme->a_disabled_focused_desk->texture[0].type =
-        theme->a_disabled_unfocused_desk->texture[0].type =
-        theme->a_hover_focused_desk->texture[0].type =
-        theme->a_hover_unfocused_desk->texture[0].type =
-        theme->a_toggled_hover_focused_desk->texture[0].type =
-        theme->a_toggled_hover_unfocused_desk->texture[0].type =
-        theme->a_toggled_focused_unpressed_desk->texture[0].type =
-        theme->a_toggled_unfocused_unpressed_desk->texture[0].type =
-        theme->a_toggled_focused_pressed_desk->texture[0].type =
-        theme->a_toggled_unfocused_pressed_desk->texture[0].type =
-        theme->a_focused_unpressed_desk->texture[0].type =
-        theme->a_focused_pressed_desk->texture[0].type =
-        theme->a_unfocused_unpressed_desk->texture[0].type =
-        theme->a_unfocused_pressed_desk->texture[0].type =
-        theme->a_disabled_focused_shade->texture[0].type =
-        theme->a_disabled_unfocused_shade->texture[0].type =
-        theme->a_hover_focused_shade->texture[0].type =
-        theme->a_hover_unfocused_shade->texture[0].type =
-        theme->a_toggled_hover_focused_shade->texture[0].type =
-        theme->a_toggled_hover_unfocused_shade->texture[0].type =
-        theme->a_toggled_focused_unpressed_shade->texture[0].type =
-        theme->a_toggled_unfocused_unpressed_shade->texture[0].type =
-        theme->a_toggled_focused_pressed_shade->texture[0].type =
-        theme->a_toggled_unfocused_pressed_shade->texture[0].type =
-        theme->a_focused_unpressed_shade->texture[0].type =
-        theme->a_focused_pressed_shade->texture[0].type =
-        theme->a_unfocused_unpressed_shade->texture[0].type =
-        theme->a_unfocused_pressed_shade->texture[0].type =
-        theme->a_disabled_focused_iconify->texture[0].type =
-        theme->a_disabled_unfocused_iconify->texture[0].type =
-        theme->a_hover_focused_iconify->texture[0].type =
-        theme->a_hover_unfocused_iconify->texture[0].type =
-        theme->a_focused_unpressed_iconify->texture[0].type =
-        theme->a_focused_pressed_iconify->texture[0].type =
-        theme->a_unfocused_unpressed_iconify->texture[0].type =
-        theme->a_unfocused_pressed_iconify->texture[0].type =
+    theme->btn_max->a_disabled_focused->texture[0].type =
+        theme->btn_max->a_disabled_unfocused->texture[0].type =
+        theme->btn_max->a_hover_focused->texture[0].type =
+        theme->btn_max->a_hover_unfocused->texture[0].type =
+        theme->btn_max->a_toggled_hover_focused->texture[0].type =
+        theme->btn_max->a_toggled_hover_unfocused->texture[0].type =
+        theme->btn_max->a_toggled_focused_unpressed->texture[0].type =
+        theme->btn_max->a_toggled_unfocused_unpressed->texture[0].type =
+        theme->btn_max->a_toggled_focused_pressed->texture[0].type =
+        theme->btn_max->a_toggled_unfocused_pressed->texture[0].type =
+        theme->btn_max->a_focused_unpressed->texture[0].type =
+        theme->btn_max->a_focused_pressed->texture[0].type =
+        theme->btn_max->a_unfocused_unpressed->texture[0].type =
+        theme->btn_max->a_unfocused_pressed->texture[0].type =
+        theme->btn_close->a_disabled_focused->texture[0].type =
+        theme->btn_close->a_disabled_unfocused->texture[0].type =
+        theme->btn_close->a_hover_focused->texture[0].type =
+        theme->btn_close->a_hover_unfocused->texture[0].type =
+        theme->btn_close->a_focused_unpressed->texture[0].type =
+        theme->btn_close->a_focused_pressed->texture[0].type =
+        theme->btn_close->a_unfocused_unpressed->texture[0].type =
+        theme->btn_close->a_unfocused_pressed->texture[0].type =
+        theme->btn_desk->a_disabled_focused->texture[0].type =
+        theme->btn_desk->a_disabled_unfocused->texture[0].type =
+        theme->btn_desk->a_hover_focused->texture[0].type =
+        theme->btn_desk->a_hover_unfocused->texture[0].type =
+        theme->btn_desk->a_toggled_hover_focused->texture[0].type =
+        theme->btn_desk->a_toggled_hover_unfocused->texture[0].type =
+        theme->btn_desk->a_toggled_focused_unpressed->texture[0].type =
+        theme->btn_desk->a_toggled_unfocused_unpressed->texture[0].type =
+        theme->btn_desk->a_toggled_focused_pressed->texture[0].type =
+        theme->btn_desk->a_toggled_unfocused_pressed->texture[0].type =
+        theme->btn_desk->a_focused_unpressed->texture[0].type =
+        theme->btn_desk->a_focused_pressed->texture[0].type =
+        theme->btn_desk->a_unfocused_unpressed->texture[0].type =
+        theme->btn_desk->a_unfocused_pressed->texture[0].type =
+        theme->btn_shade->a_disabled_focused->texture[0].type =
+        theme->btn_shade->a_disabled_unfocused->texture[0].type =
+        theme->btn_shade->a_hover_focused->texture[0].type =
+        theme->btn_shade->a_hover_unfocused->texture[0].type =
+        theme->btn_shade->a_toggled_hover_focused->texture[0].type =
+        theme->btn_shade->a_toggled_hover_unfocused->texture[0].type =
+        theme->btn_shade->a_toggled_focused_unpressed->texture[0].type =
+        theme->btn_shade->a_toggled_unfocused_unpressed->texture[0].type =
+        theme->btn_shade->a_toggled_focused_pressed->texture[0].type =
+        theme->btn_shade->a_toggled_unfocused_pressed->texture[0].type =
+        theme->btn_shade->a_focused_unpressed->texture[0].type =
+        theme->btn_shade->a_focused_pressed->texture[0].type =
+        theme->btn_shade->a_unfocused_unpressed->texture[0].type =
+        theme->btn_shade->a_unfocused_pressed->texture[0].type =
+        theme->btn_iconify->a_disabled_focused->texture[0].type =
+        theme->btn_iconify->a_disabled_unfocused->texture[0].type =
+        theme->btn_iconify->a_hover_focused->texture[0].type =
+        theme->btn_iconify->a_hover_unfocused->texture[0].type =
+        theme->btn_iconify->a_focused_unpressed->texture[0].type =
+        theme->btn_iconify->a_focused_pressed->texture[0].type =
+        theme->btn_iconify->a_unfocused_unpressed->texture[0].type =
+        theme->btn_iconify->a_unfocused_pressed->texture[0].type =
         theme->a_menu_bullet_normal->texture[0].type =
         theme->a_menu_bullet_selected->texture[0].type = RR_TEXTURE_MASK;

-    theme->a_disabled_focused_max->texture[0].data.mask.mask =
-        theme->a_disabled_unfocused_max->texture[0].data.mask.mask =
-        theme->max_disabled_mask;
-    theme->a_hover_focused_max->texture[0].data.mask.mask =
-        theme->a_hover_unfocused_max->texture[0].data.mask.mask =
-        theme->max_hover_mask;
-    theme->a_focused_pressed_max->texture[0].data.mask.mask =
-        theme->a_unfocused_pressed_max->texture[0].data.mask.mask =
-        theme->max_pressed_mask;
-    theme->a_focused_unpressed_max->texture[0].data.mask.mask =
-        theme->a_unfocused_unpressed_max->texture[0].data.mask.mask =
-        theme->max_mask;
-    theme->a_toggled_hover_focused_max->texture[0].data.mask.mask =
-        theme->a_toggled_hover_unfocused_max->texture[0].data.mask.mask =
-        theme->max_toggled_hover_mask;
-    theme->a_toggled_focused_unpressed_max->texture[0].data.mask.mask =
-        theme->a_toggled_unfocused_unpressed_max->texture[0].data.mask.mask =
-        theme->max_toggled_mask;
-    theme->a_toggled_focused_pressed_max->texture[0].data.mask.mask =
-        theme->a_toggled_unfocused_pressed_max->texture[0].data.mask.mask =
-        theme->max_toggled_pressed_mask;
-    theme->a_disabled_focused_close->texture[0].data.mask.mask =
-        theme->a_disabled_unfocused_close->texture[0].data.mask.mask =
-        theme->close_disabled_mask;
-    theme->a_hover_focused_close->texture[0].data.mask.mask =
-        theme->a_hover_unfocused_close->texture[0].data.mask.mask =
-        theme->close_hover_mask;
-    theme->a_focused_pressed_close->texture[0].data.mask.mask =
-        theme->a_unfocused_pressed_close->texture[0].data.mask.mask =
-        theme->close_pressed_mask;
-    theme->a_focused_unpressed_close->texture[0].data.mask.mask =
-        theme->a_unfocused_unpressed_close->texture[0].data.mask.mask =
-        theme->close_mask;
-    theme->a_disabled_focused_desk->texture[0].data.mask.mask =
-        theme->a_disabled_unfocused_desk->texture[0].data.mask.mask =
-        theme->desk_disabled_mask;
-    theme->a_hover_focused_desk->texture[0].data.mask.mask =
-        theme->a_hover_unfocused_desk->texture[0].data.mask.mask =
-        theme->desk_hover_mask;
-    theme->a_focused_pressed_desk->texture[0].data.mask.mask =
-        theme->a_unfocused_pressed_desk->texture[0].data.mask.mask =
-        theme->desk_pressed_mask;
-    theme->a_focused_unpressed_desk->texture[0].data.mask.mask =
-        theme->a_unfocused_unpressed_desk->texture[0].data.mask.mask =
-        theme->desk_mask;
-    theme->a_toggled_hover_focused_desk->texture[0].data.mask.mask =
-        theme->a_toggled_hover_unfocused_desk->texture[0].data.mask.mask =
-        theme->desk_toggled_hover_mask;
-    theme->a_toggled_focused_unpressed_desk->texture[0].data.mask.mask =
-        theme->a_toggled_unfocused_unpressed_desk->texture[0].data.mask.mask =
-        theme->desk_toggled_mask;
-    theme->a_toggled_focused_pressed_desk->texture[0].data.mask.mask =
-        theme->a_toggled_unfocused_pressed_desk->texture[0].data.mask.mask =
-        theme->desk_toggled_pressed_mask;
-    theme->a_disabled_focused_shade->texture[0].data.mask.mask =
-        theme->a_disabled_unfocused_shade->texture[0].data.mask.mask =
-        theme->shade_disabled_mask;
-    theme->a_hover_focused_shade->texture[0].data.mask.mask =
-        theme->a_hover_unfocused_shade->texture[0].data.mask.mask =
-        theme->shade_hover_mask;
-    theme->a_focused_pressed_shade->texture[0].data.mask.mask =
-        theme->a_unfocused_pressed_shade->texture[0].data.mask.mask =
-        theme->shade_pressed_mask;
-    theme->a_focused_unpressed_shade->texture[0].data.mask.mask =
-        theme->a_unfocused_unpressed_shade->texture[0].data.mask.mask =
-        theme->shade_mask;
-    theme->a_toggled_hover_focused_shade->texture[0].data.mask.mask =
-        theme->a_toggled_hover_unfocused_shade->texture[0].data.mask.mask =
-        theme->shade_toggled_hover_mask;
-    theme->a_toggled_focused_unpressed_shade->texture[0].data.mask.mask =
-        theme->a_toggled_unfocused_unpressed_shade->texture[0].data.mask.mask =
-        theme->shade_toggled_mask;
-    theme->a_toggled_focused_pressed_shade->texture[0].data.mask.mask =
-        theme->a_toggled_unfocused_pressed_shade->texture[0].data.mask.mask =
-        theme->shade_toggled_pressed_mask;
-    theme->a_disabled_focused_iconify->texture[0].data.mask.mask =
-        theme->a_disabled_unfocused_iconify->texture[0].data.mask.mask =
-        theme->iconify_disabled_mask;
-    theme->a_hover_focused_iconify->texture[0].data.mask.mask =
-        theme->a_hover_unfocused_iconify->texture[0].data.mask.mask =
-        theme->iconify_hover_mask;
-    theme->a_focused_pressed_iconify->texture[0].data.mask.mask =
-        theme->a_unfocused_pressed_iconify->texture[0].data.mask.mask =
-        theme->iconify_pressed_mask;
-    theme->a_focused_unpressed_iconify->texture[0].data.mask.mask =
-        theme->a_unfocused_unpressed_iconify->texture[0].data.mask.mask =
-        theme->iconify_mask;
+    theme->btn_max->a_disabled_focused->texture[0].data.mask.mask =
+        theme->btn_max->a_disabled_unfocused->texture[0].data.mask.mask =
+        theme->btn_max->disabled_mask;
+    theme->btn_max->a_hover_focused->texture[0].data.mask.mask =
+        theme->btn_max->a_hover_unfocused->texture[0].data.mask.mask =
+        theme->btn_max->hover_mask;
+    theme->btn_max->a_focused_pressed->texture[0].data.mask.mask =
+        theme->btn_max->a_unfocused_pressed->texture[0].data.mask.mask =
+        theme->btn_max->pressed_mask;
+    theme->btn_max->a_focused_unpressed->texture[0].data.mask.mask =
+        theme->btn_max->a_unfocused_unpressed->texture[0].data.mask.mask =
+        theme->btn_max->mask;
+    theme->btn_max->a_toggled_hover_focused->texture[0].data.mask.mask =
+        theme->btn_max->a_toggled_hover_unfocused->texture[0].data.mask.mask =
+        theme->btn_max->toggled_hover_mask;
+    theme->btn_max->a_toggled_focused_unpressed->texture[0].data.mask.mask =
+        theme->btn_max->a_toggled_unfocused_unpressed->
+        texture[0].data.mask.mask = theme->btn_max->toggled_mask;
+    theme->btn_max->a_toggled_focused_pressed->texture[0].data.mask.mask =
+        theme->btn_max->a_toggled_unfocused_pressed->texture[0].data.mask.mask
+        = theme->btn_max->toggled_pressed_mask;
+    theme->btn_close->a_disabled_focused->texture[0].data.mask.mask =
+        theme->btn_close->a_disabled_unfocused->texture[0].data.mask.mask =
+        theme->btn_close->disabled_mask;
+    theme->btn_close->a_hover_focused->texture[0].data.mask.mask =
+        theme->btn_close->a_hover_unfocused->texture[0].data.mask.mask =
+        theme->btn_close->hover_mask;
+    theme->btn_close->a_focused_pressed->texture[0].data.mask.mask =
+        theme->btn_close->a_unfocused_pressed->texture[0].data.mask.mask =
+        theme->btn_close->pressed_mask;
+    theme->btn_close->a_focused_unpressed->texture[0].data.mask.mask =
+        theme->btn_close->a_unfocused_unpressed->texture[0].data.mask.mask =
+        theme->btn_close->mask;
+    theme->btn_desk->a_disabled_focused->texture[0].data.mask.mask =
+        theme->btn_desk->a_disabled_unfocused->texture[0].data.mask.mask =
+        theme->btn_desk->disabled_mask;
+    theme->btn_desk->a_hover_focused->texture[0].data.mask.mask =
+        theme->btn_desk->a_hover_unfocused->texture[0].data.mask.mask =
+        theme->btn_desk->hover_mask;
+    theme->btn_desk->a_focused_pressed->texture[0].data.mask.mask =
+        theme->btn_desk->a_unfocused_pressed->texture[0].data.mask.mask =
+        theme->btn_desk->pressed_mask;
+    theme->btn_desk->a_focused_unpressed->texture[0].data.mask.mask =
+        theme->btn_desk->a_unfocused_unpressed->texture[0].data.mask.mask =
+        theme->btn_desk->mask;
+    theme->btn_desk->a_toggled_hover_focused->texture[0].data.mask.mask =
+        theme->btn_desk->a_toggled_hover_unfocused->texture[0].data.mask.mask =
+        theme->btn_desk->toggled_hover_mask;
+    theme->btn_desk->a_toggled_focused_unpressed->texture[0].data.mask.mask =
+        theme->btn_desk->a_toggled_unfocused_unpressed->
+        texture[0].data.mask.mask = theme->btn_desk->toggled_mask;
+    theme->btn_desk->a_toggled_focused_pressed->texture[0].data.mask.mask =
+        theme->btn_desk->a_toggled_unfocused_pressed->texture[0].data.mask.mask
+        = theme->btn_desk->toggled_pressed_mask;
+    theme->btn_shade->a_disabled_focused->texture[0].data.mask.mask =
+        theme->btn_shade->a_disabled_unfocused->texture[0].data.mask.mask =
+        theme->btn_shade->disabled_mask;
+    theme->btn_shade->a_hover_focused->texture[0].data.mask.mask =
+        theme->btn_shade->a_hover_unfocused->texture[0].data.mask.mask =
+        theme->btn_shade->hover_mask;
+    theme->btn_shade->a_focused_pressed->texture[0].data.mask.mask =
+        theme->btn_shade->a_unfocused_pressed->texture[0].data.mask.mask =
+        theme->btn_shade->pressed_mask;
+    theme->btn_shade->a_focused_unpressed->texture[0].data.mask.mask =
+        theme->btn_shade->a_unfocused_unpressed->texture[0].data.mask.mask =
+        theme->btn_shade->mask;
+    theme->btn_shade->a_toggled_hover_focused->texture[0].data.mask.mask =
+        theme->btn_shade->a_toggled_hover_unfocused->texture[0].data.mask.mask
+        = theme->btn_shade->toggled_hover_mask;
+    theme->btn_shade->a_toggled_focused_unpressed->texture[0].data.mask.mask =
+        theme->btn_shade->a_toggled_unfocused_unpressed->
+        texture[0].data.mask.mask = theme->btn_shade->toggled_mask;
+    theme->btn_shade->a_toggled_focused_pressed->texture[0].data.mask.mask =
+        theme->btn_shade->a_toggled_unfocused_pressed->
+        texture[0].data.mask.mask = theme->btn_shade->toggled_pressed_mask;
+    theme->btn_iconify->a_disabled_focused->texture[0].data.mask.mask =
+        theme->btn_iconify->a_disabled_unfocused->texture[0].data.mask.mask =
+        theme->btn_iconify->disabled_mask;
+    theme->btn_iconify->a_hover_focused->texture[0].data.mask.mask =
+        theme->btn_iconify->a_hover_unfocused->texture[0].data.mask.mask =
+        theme->btn_iconify->hover_mask;
+    theme->btn_iconify->a_focused_pressed->texture[0].data.mask.mask =
+        theme->btn_iconify->a_unfocused_pressed->texture[0].data.mask.mask =
+        theme->btn_iconify->pressed_mask;
+    theme->btn_iconify->a_focused_unpressed->texture[0].data.mask.mask =
+        theme->btn_iconify->a_unfocused_unpressed->texture[0].data.mask.mask =
+        theme->btn_iconify->mask;
     theme->a_menu_bullet_normal->texture[0].data.mask.mask =
     theme->a_menu_bullet_selected->texture[0].data.mask.mask =
         theme->menu_bullet_mask;
-    theme->a_disabled_focused_max->texture[0].data.mask.color =
-        theme->a_disabled_focused_close->texture[0].data.mask.color =
-        theme->a_disabled_focused_desk->texture[0].data.mask.color =
-        theme->a_disabled_focused_shade->texture[0].data.mask.color =
-        theme->a_disabled_focused_iconify->texture[0].data.mask.color =
-        theme->titlebut_disabled_focused_color;
-    theme->a_disabled_unfocused_max->texture[0].data.mask.color =
-        theme->a_disabled_unfocused_close->texture[0].data.mask.color =
-        theme->a_disabled_unfocused_desk->texture[0].data.mask.color =
-        theme->a_disabled_unfocused_shade->texture[0].data.mask.color =
-        theme->a_disabled_unfocused_iconify->texture[0].data.mask.color =
-        theme->titlebut_disabled_unfocused_color;
-    theme->a_hover_focused_max->texture[0].data.mask.color =
-        theme->a_hover_focused_close->texture[0].data.mask.color =
-        theme->a_hover_focused_desk->texture[0].data.mask.color =
-        theme->a_hover_focused_shade->texture[0].data.mask.color =
-        theme->a_hover_focused_iconify->texture[0].data.mask.color =
-        theme->titlebut_hover_focused_color;
-    theme->a_hover_unfocused_max->texture[0].data.mask.color =
-        theme->a_hover_unfocused_close->texture[0].data.mask.color =
-        theme->a_hover_unfocused_desk->texture[0].data.mask.color =
-        theme->a_hover_unfocused_shade->texture[0].data.mask.color =
-        theme->a_hover_unfocused_iconify->texture[0].data.mask.color =
-        theme->titlebut_hover_unfocused_color;
-    theme->a_toggled_hover_focused_max->texture[0].data.mask.color =
-        theme->a_toggled_hover_focused_desk->texture[0].data.mask.color =
-        theme->a_toggled_hover_focused_shade->texture[0].data.mask.color =
-        theme->titlebut_toggled_hover_focused_color;
-    theme->a_toggled_hover_unfocused_max->texture[0].data.mask.color =
-        theme->a_toggled_hover_unfocused_desk->texture[0].data.mask.color =
-        theme->a_toggled_hover_unfocused_shade->texture[0].data.mask.color =
-        theme->titlebut_toggled_hover_unfocused_color;
-    theme->a_toggled_focused_unpressed_max->texture[0].data.mask.color =
-        theme->a_toggled_focused_unpressed_desk->texture[0].data.mask.color =
-        theme->a_toggled_focused_unpressed_shade->texture[0].data.mask.color =
-        theme->titlebut_toggled_focused_unpressed_color;
-    theme->a_toggled_unfocused_unpressed_max->texture[0].data.mask.color =
-        theme->a_toggled_unfocused_unpressed_desk->texture[0].data.mask.color =
-        theme->a_toggled_unfocused_unpressed_shade->texture[0].data.mask.color=
-        theme->titlebut_toggled_unfocused_unpressed_color;
-    theme->a_toggled_focused_pressed_max->texture[0].data.mask.color =
-        theme->a_toggled_focused_pressed_desk->texture[0].data.mask.color =
-        theme->a_toggled_focused_pressed_shade->texture[0].data.mask.color =
-        theme->titlebut_toggled_focused_pressed_color;
-    theme->a_toggled_unfocused_pressed_max->texture[0].data.mask.color =
-        theme->a_toggled_unfocused_pressed_desk->texture[0].data.mask.color =
-        theme->a_toggled_unfocused_pressed_shade->texture[0].data.mask.color =
-        theme->titlebut_toggled_unfocused_pressed_color;
-    theme->a_focused_unpressed_max->texture[0].data.mask.color =
-        theme->a_focused_unpressed_close->texture[0].data.mask.color =
-        theme->a_focused_unpressed_desk->texture[0].data.mask.color =
-        theme->a_focused_unpressed_shade->texture[0].data.mask.color =
-        theme->a_focused_unpressed_iconify->texture[0].data.mask.color =
-        theme->titlebut_focused_unpressed_color;
-    theme->a_focused_pressed_max->texture[0].data.mask.color =
-        theme->a_focused_pressed_close->texture[0].data.mask.color =
-        theme->a_focused_pressed_desk->texture[0].data.mask.color =
-        theme->a_focused_pressed_shade->texture[0].data.mask.color =
-        theme->a_focused_pressed_iconify->texture[0].data.mask.color =
-        theme->titlebut_focused_pressed_color;
-    theme->a_unfocused_unpressed_max->texture[0].data.mask.color =
-        theme->a_unfocused_unpressed_close->texture[0].data.mask.color =
-        theme->a_unfocused_unpressed_desk->texture[0].data.mask.color =
-        theme->a_unfocused_unpressed_shade->texture[0].data.mask.color =
-        theme->a_unfocused_unpressed_iconify->texture[0].data.mask.color =
-        theme->titlebut_unfocused_unpressed_color;
-    theme->a_unfocused_pressed_max->texture[0].data.mask.color =
-        theme->a_unfocused_pressed_close->texture[0].data.mask.color =
-        theme->a_unfocused_pressed_desk->texture[0].data.mask.color =
-        theme->a_unfocused_pressed_shade->texture[0].data.mask.color =
-        theme->a_unfocused_pressed_iconify->texture[0].data.mask.color =
-        theme->titlebut_unfocused_pressed_color;
+    theme->btn_max->a_disabled_focused->texture[0].data.mask.color =
+        theme->btn_max->disabled_focused_color;
+    theme->btn_close->a_disabled_focused->texture[0].data.mask.color =
+        theme->btn_close->disabled_focused_color;
+    theme->btn_desk->a_disabled_focused->texture[0].data.mask.color =
+        theme->btn_desk->disabled_focused_color;
+    theme->btn_shade->a_disabled_focused->texture[0].data.mask.color =
+        theme->btn_shade->disabled_focused_color;
+    theme->btn_iconify->a_disabled_focused->texture[0].data.mask.color =
+        theme->btn_iconify->disabled_focused_color;
+    theme->btn_max->a_disabled_unfocused->texture[0].data.mask.color =
+        theme->btn_max->disabled_unfocused_color;
+    theme->btn_close->a_disabled_unfocused->texture[0].data.mask.color =
+        theme->btn_close->disabled_unfocused_color;
+    theme->btn_desk->a_disabled_unfocused->texture[0].data.mask.color =
+        theme->btn_desk->disabled_unfocused_color;
+    theme->btn_shade->a_disabled_unfocused->texture[0].data.mask.color =
+        theme->btn_shade->disabled_unfocused_color;
+    theme->btn_iconify->a_disabled_unfocused->texture[0].data.mask.color =
+        theme->btn_iconify->disabled_unfocused_color;
+    theme->btn_max->a_hover_focused->texture[0].data.mask.color =
+        theme->btn_max->hover_focused_color;
+    theme->btn_close->a_hover_focused->texture[0].data.mask.color =
+        theme->btn_close->hover_focused_color;
+    theme->btn_desk->a_hover_focused->texture[0].data.mask.color =
+        theme->btn_desk->hover_focused_color;
+    theme->btn_shade->a_hover_focused->texture[0].data.mask.color =
+        theme->btn_shade->hover_focused_color;
+    theme->btn_iconify->a_hover_focused->texture[0].data.mask.color =
+        theme->btn_iconify->hover_focused_color;
+    theme->btn_max->a_hover_unfocused->texture[0].data.mask.color =
+        theme->btn_max->hover_unfocused_color;
+    theme->btn_close->a_hover_unfocused->texture[0].data.mask.color =
+        theme->btn_close->hover_unfocused_color;
+    theme->btn_desk->a_hover_unfocused->texture[0].data.mask.color =
+        theme->btn_desk->hover_unfocused_color;
+    theme->btn_shade->a_hover_unfocused->texture[0].data.mask.color =
+        theme->btn_shade->hover_unfocused_color;
+    theme->btn_iconify->a_hover_unfocused->texture[0].data.mask.color =
+        theme->btn_iconify->hover_unfocused_color;
+    theme->btn_max->a_toggled_hover_focused->texture[0].data.mask.color =
+        theme->btn_max->toggled_hover_focused_color;
+    theme->btn_desk->a_toggled_hover_focused->texture[0].data.mask.color =
+        theme->btn_desk->toggled_hover_focused_color;
+    theme->btn_shade->a_toggled_hover_focused->texture[0].data.mask.color =
+        theme->btn_shade->toggled_hover_focused_color;
+    theme->btn_max->a_toggled_hover_unfocused->texture[0].data.mask.color =
+        theme->btn_max->toggled_hover_unfocused_color;
+    theme->btn_desk->a_toggled_hover_unfocused->texture[0].data.mask.color =
+        theme->btn_desk->toggled_hover_unfocused_color;
+    theme->btn_shade->a_toggled_hover_unfocused->texture[0].data.mask.color =
+        theme->btn_shade->toggled_hover_unfocused_color;
+    theme->btn_max->a_toggled_focused_unpressed->texture[0].data.mask.color =
+        theme->btn_max->toggled_focused_unpressed_color;
+    theme->btn_desk->a_toggled_focused_unpressed->texture[0].data.mask.color =
+        theme->btn_desk->toggled_focused_unpressed_color;
+    theme->btn_shade->a_toggled_focused_unpressed->texture[0].data.mask.color =
+        theme->btn_shade->toggled_focused_unpressed_color;
+    theme->btn_max->a_toggled_unfocused_unpressed->texture[0].data.mask.color =
+        theme->btn_max->toggled_unfocused_unpressed_color;
+    theme->btn_desk->a_toggled_unfocused_unpressed->texture[0].data.mask.color
+        = theme->btn_desk->toggled_unfocused_unpressed_color;
+    theme->btn_shade->a_toggled_unfocused_unpressed->texture[0].data.mask.color
+        = theme->btn_shade->toggled_unfocused_unpressed_color;
+    theme->btn_max->a_toggled_focused_pressed->texture[0].data.mask.color =
+        theme->btn_max->toggled_focused_pressed_color;
+    theme->btn_desk->a_toggled_focused_pressed->texture[0].data.mask.color =
+        theme->btn_desk->toggled_focused_pressed_color;
+    theme->btn_shade->a_toggled_focused_pressed->texture[0].data.mask.color =
+        theme->btn_shade->toggled_focused_pressed_color;
+    theme->btn_max->a_toggled_unfocused_pressed->texture[0].data.mask.color =
+        theme->btn_max->toggled_unfocused_pressed_color;
+    theme->btn_desk->a_toggled_unfocused_pressed->texture[0].data.mask.color =
+        theme->btn_desk->toggled_unfocused_pressed_color;
+    theme->btn_shade->a_toggled_unfocused_pressed->texture[0].data.mask.color =
+        theme->btn_shade->toggled_unfocused_pressed_color;
+    theme->btn_max->a_focused_unpressed->texture[0].data.mask.color =
+        theme->btn_max->focused_unpressed_color;
+    theme->btn_close->a_focused_unpressed->texture[0].data.mask.color =
+        theme->btn_close->focused_unpressed_color;
+    theme->btn_desk->a_focused_unpressed->texture[0].data.mask.color =
+        theme->btn_desk->focused_unpressed_color;
+    theme->btn_shade->a_focused_unpressed->texture[0].data.mask.color =
+        theme->btn_shade->focused_unpressed_color;
+    theme->btn_iconify->a_focused_unpressed->texture[0].data.mask.color =
+        theme->btn_iconify->focused_unpressed_color;
+    theme->btn_max->a_focused_pressed->texture[0].data.mask.color =
+        theme->btn_max->focused_pressed_color;
+    theme->btn_close->a_focused_pressed->texture[0].data.mask.color =
+        theme->btn_close->focused_pressed_color;
+    theme->btn_desk->a_focused_pressed->texture[0].data.mask.color =
+        theme->btn_desk->focused_pressed_color;
+    theme->btn_shade->a_focused_pressed->texture[0].data.mask.color =
+        theme->btn_shade->focused_pressed_color;
+    theme->btn_iconify->a_focused_pressed->texture[0].data.mask.color =
+        theme->btn_iconify->focused_pressed_color;
+    theme->btn_max->a_unfocused_unpressed->texture[0].data.mask.color =
+        theme->btn_max->unfocused_unpressed_color;
+    theme->btn_close->a_unfocused_unpressed->texture[0].data.mask.color =
+        theme->btn_close->unfocused_unpressed_color;
+    theme->btn_desk->a_unfocused_unpressed->texture[0].data.mask.color =
+        theme->btn_desk->unfocused_unpressed_color;
+    theme->btn_shade->a_unfocused_unpressed->texture[0].data.mask.color =
+        theme->btn_shade->unfocused_unpressed_color;
+    theme->btn_iconify->a_unfocused_unpressed->texture[0].data.mask.color =
+        theme->btn_iconify->unfocused_unpressed_color;
+    theme->btn_max->a_unfocused_pressed->texture[0].data.mask.color =
+        theme->btn_max->unfocused_pressed_color;
+    theme->btn_close->a_unfocused_pressed->texture[0].data.mask.color =
+        theme->btn_close->unfocused_pressed_color;
+    theme->btn_desk->a_unfocused_pressed->texture[0].data.mask.color =
+        theme->btn_desk->unfocused_pressed_color;
+    theme->btn_shade->a_unfocused_pressed->texture[0].data.mask.color =
+        theme->btn_shade->unfocused_pressed_color;
+    theme->btn_iconify->a_unfocused_pressed->texture[0].data.mask.color =
+        theme->btn_iconify->unfocused_pressed_color;
     theme->a_menu_bullet_normal->texture[0].data.mask.color =
-        theme->menu_color;
+        theme->menu_bullet_color;
     theme->a_menu_bullet_selected->texture[0].data.mask.color =
-        theme->menu_selected_color;
+        theme->menu_bullet_selected_color;

     g_free(path);
     XrmDestroyDatabase(db);
@@ -1581,6 +1580,21 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
     theme->button_size = theme->label_height - 2;
     theme->grip_width = 25;

+    RrAppearanceFree(a_disabled_focused_tmp);
+    RrAppearanceFree(a_disabled_unfocused_tmp);
+    RrAppearanceFree(a_hover_focused_tmp);
+    RrAppearanceFree(a_hover_unfocused_tmp);
+    RrAppearanceFree(a_focused_unpressed_tmp);
+    RrAppearanceFree(a_focused_pressed_tmp);
+    RrAppearanceFree(a_unfocused_unpressed_tmp);
+    RrAppearanceFree(a_unfocused_pressed_tmp);
+    RrAppearanceFree(a_toggled_hover_focused_tmp);
+    RrAppearanceFree(a_toggled_hover_unfocused_tmp);
+    RrAppearanceFree(a_toggled_focused_unpressed_tmp);
+    RrAppearanceFree(a_toggled_focused_pressed_tmp);
+    RrAppearanceFree(a_toggled_unfocused_unpressed_tmp);
+    RrAppearanceFree(a_toggled_unfocused_pressed_tmp);
+
     return theme;
 }

@@ -1589,10 +1603,18 @@ void RrThemeFree(RrTheme *theme)
     if (theme) {
         g_free(theme->name);

+        RrButtonFree(theme->btn_max);
+        RrButtonFree(theme->btn_close);
+        RrButtonFree(theme->btn_desk);
+        RrButtonFree(theme->btn_shade);
+        RrButtonFree(theme->btn_iconify);
+
         RrColorFree(theme->menu_border_color);
         RrColorFree(theme->osd_border_color);
         RrColorFree(theme->frame_focused_border_color);
+        RrColorFree(theme->frame_undecorated_focused_border_color);
         RrColorFree(theme->frame_unfocused_border_color);
+        RrColorFree(theme->frame_undecorated_unfocused_border_color);
         RrColorFree(theme->title_separator_focused_color);
         RrColorFree(theme->title_separator_unfocused_color);
         RrColorFree(theme->cb_unfocused_color);
@@ -1616,6 +1638,8 @@ void RrThemeFree(RrTheme *theme)
         RrColorFree(theme->menu_title_color);
         RrColorFree(theme->menu_sep_color);
         RrColorFree(theme->menu_color);
+        RrColorFree(theme->menu_bullet_color);
+        RrColorFree(theme->menu_bullet_selected_color);
         RrColorFree(theme->menu_selected_color);
         RrColorFree(theme->menu_disabled_color);
         RrColorFree(theme->menu_disabled_selected_color);
@@ -1637,36 +1661,7 @@ void RrThemeFree(RrTheme *theme)
         RrColorFree(theme->menu_text_disabled_selected_shadow_color);

         g_free(theme->def_win_icon);
-
-        RrPixmapMaskFree(theme->max_mask);
-        RrPixmapMaskFree(theme->max_toggled_mask);
-        RrPixmapMaskFree(theme->max_toggled_hover_mask);
-        RrPixmapMaskFree(theme->max_toggled_pressed_mask);
-        RrPixmapMaskFree(theme->max_disabled_mask);
-        RrPixmapMaskFree(theme->max_hover_mask);
-        RrPixmapMaskFree(theme->max_pressed_mask);
-        RrPixmapMaskFree(theme->desk_mask);
-        RrPixmapMaskFree(theme->desk_toggled_mask);
-        RrPixmapMaskFree(theme->desk_toggled_hover_mask);
-        RrPixmapMaskFree(theme->desk_toggled_pressed_mask);
-        RrPixmapMaskFree(theme->desk_disabled_mask);
-        RrPixmapMaskFree(theme->desk_hover_mask);
-        RrPixmapMaskFree(theme->desk_pressed_mask);
-        RrPixmapMaskFree(theme->shade_mask);
-        RrPixmapMaskFree(theme->shade_toggled_mask);
-        RrPixmapMaskFree(theme->shade_toggled_hover_mask);
-        RrPixmapMaskFree(theme->shade_toggled_pressed_mask);
-        RrPixmapMaskFree(theme->shade_disabled_mask);
-        RrPixmapMaskFree(theme->shade_hover_mask);
-        RrPixmapMaskFree(theme->shade_pressed_mask);
-        RrPixmapMaskFree(theme->iconify_mask);
-        RrPixmapMaskFree(theme->iconify_disabled_mask);
-        RrPixmapMaskFree(theme->iconify_hover_mask);
-        RrPixmapMaskFree(theme->iconify_pressed_mask);
-        RrPixmapMaskFree(theme->close_mask);
-        RrPixmapMaskFree(theme->close_disabled_mask);
-        RrPixmapMaskFree(theme->close_hover_mask);
-        RrPixmapMaskFree(theme->close_pressed_mask);
+
         RrPixmapMaskFree(theme->menu_bullet_mask);
         RrPixmapMaskFree(theme->down_arrow_mask);
         RrPixmapMaskFree(theme->up_arrow_mask);
@@ -1678,64 +1673,6 @@ void RrThemeFree(RrTheme *theme)
         RrFontClose(theme->osd_font_hilite);
         RrFontClose(theme->osd_font_unhilite);

-        RrAppearanceFree(theme->a_disabled_focused_max);
-        RrAppearanceFree(theme->a_disabled_unfocused_max);
-        RrAppearanceFree(theme->a_hover_focused_max);
-        RrAppearanceFree(theme->a_hover_unfocused_max);
-        RrAppearanceFree(theme->a_toggled_hover_focused_max);
-        RrAppearanceFree(theme->a_toggled_hover_unfocused_max);
-        RrAppearanceFree(theme->a_toggled_focused_unpressed_max);
-        RrAppearanceFree(theme->a_toggled_focused_pressed_max);
-        RrAppearanceFree(theme->a_toggled_unfocused_unpressed_max);
-        RrAppearanceFree(theme->a_toggled_unfocused_pressed_max);
-        RrAppearanceFree(theme->a_focused_unpressed_max);
-        RrAppearanceFree(theme->a_focused_pressed_max);
-        RrAppearanceFree(theme->a_unfocused_unpressed_max);
-        RrAppearanceFree(theme->a_unfocused_pressed_max);
-        RrAppearanceFree(theme->a_disabled_focused_close);
-        RrAppearanceFree(theme->a_disabled_unfocused_close);
-        RrAppearanceFree(theme->a_hover_focused_close);
-        RrAppearanceFree(theme->a_hover_unfocused_close);
-        RrAppearanceFree(theme->a_focused_unpressed_close);
-        RrAppearanceFree(theme->a_focused_pressed_close);
-        RrAppearanceFree(theme->a_unfocused_unpressed_close);
-        RrAppearanceFree(theme->a_unfocused_pressed_close);
-        RrAppearanceFree(theme->a_disabled_focused_desk);
-        RrAppearanceFree(theme->a_disabled_unfocused_desk);
-        RrAppearanceFree(theme->a_hover_focused_desk);
-        RrAppearanceFree(theme->a_hover_unfocused_desk);
-        RrAppearanceFree(theme->a_toggled_hover_focused_desk);
-        RrAppearanceFree(theme->a_toggled_hover_unfocused_desk);
-        RrAppearanceFree(theme->a_toggled_focused_unpressed_desk);
-        RrAppearanceFree(theme->a_toggled_focused_pressed_desk);
-        RrAppearanceFree(theme->a_toggled_unfocused_unpressed_desk);
-        RrAppearanceFree(theme->a_toggled_unfocused_pressed_desk);
-        RrAppearanceFree(theme->a_focused_unpressed_desk);
-        RrAppearanceFree(theme->a_focused_pressed_desk);
-        RrAppearanceFree(theme->a_unfocused_unpressed_desk);
-        RrAppearanceFree(theme->a_unfocused_pressed_desk);
-        RrAppearanceFree(theme->a_disabled_focused_shade);
-        RrAppearanceFree(theme->a_disabled_unfocused_shade);
-        RrAppearanceFree(theme->a_hover_focused_shade);
-        RrAppearanceFree(theme->a_hover_unfocused_shade);
-        RrAppearanceFree(theme->a_toggled_hover_focused_shade);
-        RrAppearanceFree(theme->a_toggled_hover_unfocused_shade);
-        RrAppearanceFree(theme->a_toggled_focused_unpressed_shade);
-        RrAppearanceFree(theme->a_toggled_focused_pressed_shade);
-        RrAppearanceFree(theme->a_toggled_unfocused_unpressed_shade);
-        RrAppearanceFree(theme->a_toggled_unfocused_pressed_shade);
-        RrAppearanceFree(theme->a_focused_unpressed_shade);
-        RrAppearanceFree(theme->a_focused_pressed_shade);
-        RrAppearanceFree(theme->a_unfocused_unpressed_shade);
-        RrAppearanceFree(theme->a_unfocused_pressed_shade);
-        RrAppearanceFree(theme->a_disabled_focused_iconify);
-        RrAppearanceFree(theme->a_disabled_unfocused_iconify);
-        RrAppearanceFree(theme->a_hover_focused_iconify);
-        RrAppearanceFree(theme->a_hover_unfocused_iconify);
-        RrAppearanceFree(theme->a_focused_unpressed_iconify);
-        RrAppearanceFree(theme->a_focused_pressed_iconify);
-        RrAppearanceFree(theme->a_unfocused_unpressed_iconify);
-        RrAppearanceFree(theme->a_unfocused_pressed_iconify);
         RrAppearanceFree(theme->a_focused_grip);
         RrAppearanceFree(theme->a_unfocused_grip);
         RrAppearanceFree(theme->a_focused_title);
@@ -1860,6 +1797,7 @@ static gboolean read_string(XrmDatabase db, const gchar *rname, gchar **value)

     if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
         retvalue.addr != NULL) {
+        g_strstrip(retvalue.addr);
         *value = retvalue.addr;
         ret = TRUE;
     }
@@ -1878,7 +1816,12 @@ static gboolean read_color(XrmDatabase db, const RrInstance *inst,

     if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
         retvalue.addr != NULL) {
-        RrColor *c = RrColorParse(inst, retvalue.addr);
+        RrColor *c;
+
+        /* retvalue.addr is inside the xrdb database so we can't destroy it
+           but we can edit it in place, as g_strstrip does. */
+        g_strstrip(retvalue.addr);
+        c = RrColorParse(inst, retvalue.addr);
         if (c != NULL) {
             *value = c;
             ret = TRUE;
@@ -2116,3 +2059,111 @@ static RrPixel32* read_c_image(gint width, gint height, const guint8 *data)

     return im;
 }
+
+static void read_button_colors(XrmDatabase db, const RrInstance *inst,
+                               const RrTheme *theme, RrButton *btn,
+                               const gchar *btnname)
+{
+    gchar *name;
+
+    /* active unpressed */
+    name = g_strdup_printf("window.active.button.%s.unpressed.image.color",
+                           btnname);
+    READ_COLOR(name, btn->focused_unpressed_color,
+               RrColorCopy(theme->titlebut_focused_unpressed_color));
+    g_free(name);
+
+    /* inactive unpressed */
+    name = g_strdup_printf("window.inactive.button.%s.unpressed.image.color",
+                           btnname);
+    READ_COLOR(name, btn->unfocused_unpressed_color,
+               RrColorCopy(theme->titlebut_unfocused_unpressed_color));
+    g_free(name);
+
+    /* active pressed */
+    name = g_strdup_printf("window.active.button.%s.pressed.image.color",
+                           btnname);
+    READ_COLOR(name, btn->focused_pressed_color,
+               RrColorCopy(theme->titlebut_focused_pressed_color));
+    g_free(name);
+
+    /* inactive pressed */
+    name = g_strdup_printf("window.inactive.button.%s.pressed.image.color",
+                          btnname);
+    READ_COLOR(name, btn->unfocused_pressed_color,
+               RrColorCopy(theme->titlebut_unfocused_pressed_color));
+    g_free(name);
+
+    /* active disabled */
+    name = g_strdup_printf("window.active.button.%s.disabled.image.color",
+                           btnname);
+    READ_COLOR(name, btn->disabled_focused_color,
+               RrColorCopy(theme->titlebut_disabled_focused_color));
+    g_free(name);
+
+    /* inactive disabled */
+    name = g_strdup_printf("window.inactive.button.%s.disabled.image.color",
+                           btnname);
+    READ_COLOR(name, btn->disabled_unfocused_color,
+               RrColorCopy(theme->titlebut_disabled_unfocused_color));
+    g_free(name);
+
+    /* active hover */
+    name = g_strdup_printf("window.active.button.%s.hover.image.color",
+                           btnname);
+    READ_COLOR(name, btn->hover_focused_color,
+               RrColorCopy(theme->titlebut_hover_focused_color));
+    g_free(name);
+
+    /* inactive hover */
+    name = g_strdup_printf("window.inactive.button.%s.hover.image.color",
+                           btnname);
+    READ_COLOR(name, btn->hover_unfocused_color,
+               RrColorCopy(theme->titlebut_hover_unfocused_color));
+    g_free(name);
+
+    /* active toggled unpressed */
+    name = g_strdup_printf("window.active.button.%s.toggled."
+                          "unpressed.image.color", btnname);
+    READ_COLOR(name, btn->toggled_focused_unpressed_color,
+               RrColorCopy(theme->titlebut_toggled_focused_unpressed_color));
+    g_free(name);
+
+    /* inactive toggled unpressed */
+    name = g_strdup_printf("window.inactive.button.%s.toggled."
+                           "unpressed.image.color", btnname);
+    READ_COLOR(name, btn->toggled_unfocused_unpressed_color,
+               RrColorCopy(theme->titlebut_toggled_unfocused_unpressed_color));
+    g_free(name);
+
+    /* active toggled hover */
+    name = g_strdup_printf("window.active.button.%s.toggled.hover.image.color",
+                           btnname);
+    READ_COLOR(name, btn->toggled_hover_focused_color,
+               RrColorCopy(theme->titlebut_toggled_hover_focused_color));
+
+    g_free(name);
+
+    /* inactive toggled hover */
+    name = g_strdup_printf("window.inactive.button.%s.toggled.hover."
+                           "image.color", btnname);
+    READ_COLOR(name, btn->toggled_hover_unfocused_color,
+               RrColorCopy(theme->titlebut_toggled_hover_unfocused_color));
+    g_free(name);
+
+    /* active toggled pressed */
+    name = g_strdup_printf("window.active.button.%s.toggled.pressed."
+                           "image.color", btnname);
+    READ_COLOR(name, btn->toggled_focused_pressed_color,
+               RrColorCopy(theme->titlebut_toggled_focused_pressed_color));
+    g_free(name);
+
+    /* inactive toggled pressed */
+    name = g_strdup_printf("window.inactive.button.%s.toggled.pressed."
+                           "image.color", btnname);
+    READ_COLOR(name, btn->toggled_unfocused_pressed_color,
+               RrColorCopy(theme->titlebut_toggled_unfocused_pressed_color));
+    g_free(name);
+}
+
+
diff --git a/obrender/theme.h b/obrender/theme.h
index 2ffc637..eb9ac3f 100644
--- a/obrender/theme.h
+++ b/obrender/theme.h
@@ -44,6 +44,7 @@ struct _RrTheme {
     gint fbwidth; /*!< frame border width */
     gint mbwidth; /*!< menu border width */
     gint obwidth; /*!< osd border width */
+    gint ubwidth; /*!< undecorated frame border width */
     gint cbwidthx;
     gint cbwidthy;
     gint menu_overlap_x;
@@ -66,7 +67,9 @@ struct _RrTheme {
     RrColor *menu_border_color;
     RrColor *osd_border_color;
     RrColor *frame_focused_border_color;
+    RrColor *frame_undecorated_focused_border_color;
     RrColor *frame_unfocused_border_color;
+    RrColor *frame_undecorated_unfocused_border_color;
     RrColor *title_separator_focused_color;
     RrColor *title_separator_unfocused_color;
     RrColor *cb_focused_color;
@@ -90,6 +93,8 @@ struct _RrTheme {
     RrColor *menu_title_color;
     RrColor *menu_sep_color;
     RrColor *menu_color;
+    RrColor *menu_bullet_color;
+    RrColor *menu_bullet_selected_color;
     RrColor *menu_selected_color;
     RrColor *menu_disabled_color;
     RrColor *menu_disabled_selected_color;
@@ -125,36 +130,6 @@ struct _RrTheme {
     gint       def_win_icon_h;

     /* style settings - masks */
-    RrPixmapMask *max_mask;
-    RrPixmapMask *max_hover_mask;
-    RrPixmapMask *max_pressed_mask;
-    RrPixmapMask *max_toggled_mask;
-    RrPixmapMask *max_toggled_hover_mask;
-    RrPixmapMask *max_toggled_pressed_mask;
-    RrPixmapMask *max_disabled_mask;
-    RrPixmapMask *iconify_mask;
-    RrPixmapMask *iconify_hover_mask;
-    RrPixmapMask *iconify_pressed_mask;
-    RrPixmapMask *iconify_disabled_mask;
-    RrPixmapMask *desk_mask;
-    RrPixmapMask *desk_hover_mask;
-    RrPixmapMask *desk_pressed_mask;
-    RrPixmapMask *desk_toggled_mask;
-    RrPixmapMask *desk_toggled_hover_mask;
-    RrPixmapMask *desk_toggled_pressed_mask;
-    RrPixmapMask *desk_disabled_mask;
-    RrPixmapMask *shade_mask;
-    RrPixmapMask *shade_hover_mask;
-    RrPixmapMask *shade_pressed_mask;
-    RrPixmapMask *shade_toggled_mask;
-    RrPixmapMask *shade_toggled_hover_mask;
-    RrPixmapMask *shade_toggled_pressed_mask;
-    RrPixmapMask *shade_disabled_mask;
-    RrPixmapMask *close_mask;
-    RrPixmapMask *close_hover_mask;
-    RrPixmapMask *close_disabled_mask;
-    RrPixmapMask *close_pressed_mask;
-
     RrPixmapMask *menu_bullet_mask; /* submenu pointer */
 #if 0
     RrPixmapMask *menu_toggle_mask; /* menu boolean */
@@ -163,65 +138,14 @@ struct _RrTheme {
     RrPixmapMask *down_arrow_mask;
     RrPixmapMask *up_arrow_mask;

+    /* buttons */
+    RrButton *btn_max;
+    RrButton *btn_close;
+    RrButton *btn_desk;
+    RrButton *btn_shade;
+    RrButton *btn_iconify;
+
     /* global appearances */
-    RrAppearance *a_disabled_focused_max;
-    RrAppearance *a_disabled_unfocused_max;
-    RrAppearance *a_hover_focused_max;
-    RrAppearance *a_hover_unfocused_max;
-    RrAppearance *a_focused_unpressed_max;
-    RrAppearance *a_focused_pressed_max;
-    RrAppearance *a_unfocused_unpressed_max;
-    RrAppearance *a_unfocused_pressed_max;
-    RrAppearance *a_toggled_hover_focused_max;
-    RrAppearance *a_toggled_hover_unfocused_max;
-    RrAppearance *a_toggled_focused_unpressed_max;
-    RrAppearance *a_toggled_focused_pressed_max;
-    RrAppearance *a_toggled_unfocused_unpressed_max;
-    RrAppearance *a_toggled_unfocused_pressed_max;
-    RrAppearance *a_disabled_focused_close;
-    RrAppearance *a_disabled_unfocused_close;
-    RrAppearance *a_hover_focused_close;
-    RrAppearance *a_hover_unfocused_close;
-    RrAppearance *a_focused_unpressed_close;
-    RrAppearance *a_focused_pressed_close;
-    RrAppearance *a_unfocused_unpressed_close;
-    RrAppearance *a_unfocused_pressed_close;
-    RrAppearance *a_disabled_focused_desk;
-    RrAppearance *a_disabled_unfocused_desk;
-    RrAppearance *a_hover_focused_desk;
-    RrAppearance *a_hover_unfocused_desk;
-    RrAppearance *a_focused_unpressed_desk;
-    RrAppearance *a_focused_pressed_desk;
-    RrAppearance *a_unfocused_unpressed_desk;
-    RrAppearance *a_unfocused_pressed_desk;
-    RrAppearance *a_toggled_hover_focused_desk;
-    RrAppearance *a_toggled_hover_unfocused_desk;
-    RrAppearance *a_toggled_focused_unpressed_desk;
-    RrAppearance *a_toggled_focused_pressed_desk;
-    RrAppearance *a_toggled_unfocused_unpressed_desk;
-    RrAppearance *a_toggled_unfocused_pressed_desk;
-    RrAppearance *a_disabled_focused_shade;
-    RrAppearance *a_disabled_unfocused_shade;
-    RrAppearance *a_hover_focused_shade;
-    RrAppearance *a_hover_unfocused_shade;
-    RrAppearance *a_focused_unpressed_shade;
-    RrAppearance *a_focused_pressed_shade;
-    RrAppearance *a_unfocused_unpressed_shade;
-    RrAppearance *a_unfocused_pressed_shade;
-    RrAppearance *a_toggled_hover_focused_shade;
-    RrAppearance *a_toggled_hover_unfocused_shade;
-    RrAppearance *a_toggled_focused_unpressed_shade;
-    RrAppearance *a_toggled_focused_pressed_shade;
-    RrAppearance *a_toggled_unfocused_unpressed_shade;
-    RrAppearance *a_toggled_unfocused_pressed_shade;
-    RrAppearance *a_disabled_focused_iconify;
-    RrAppearance *a_disabled_unfocused_iconify;
-    RrAppearance *a_hover_focused_iconify;
-    RrAppearance *a_hover_unfocused_iconify;
-    RrAppearance *a_focused_unpressed_iconify;
-    RrAppearance *a_focused_pressed_iconify;
-    RrAppearance *a_unfocused_unpressed_iconify;
-    RrAppearance *a_unfocused_pressed_iconify;
     RrAppearance *a_focused_grip;
     RrAppearance *a_unfocused_grip;
     RrAppearance *a_focused_title;
diff --git a/obt/keyboard.c b/obt/keyboard.c
index 8bfdd39..ef2678b 100644
--- a/obt/keyboard.c
+++ b/obt/keyboard.c
@@ -389,12 +389,11 @@ gunichar obt_keyboard_keypress_to_unichar(ObtIC *ic, XEvent *ev)
 KeySym obt_keyboard_keypress_to_keysym(XEvent *ev)
 {
     KeySym sym;
-    gint r;

     g_return_val_if_fail(ev->type == KeyPress, None);

     sym = None;
-    r = XLookupString(&ev->xkey, NULL, 0, &sym, NULL);
+    XLookupString(&ev->xkey, NULL, 0, &sym, NULL);
     return sym;
 }

diff --git a/obt/prop.c b/obt/prop.c
index d5af6a0..638373f 100644
--- a/obt/prop.c
+++ b/obt/prop.c
@@ -107,6 +107,7 @@ void obt_prop_startup(void)
     CREATE_(NET_WM_ICON_GEOMETRY);
     CREATE_(NET_WM_PID);
     CREATE_(NET_WM_ALLOWED_ACTIONS);
+    CREATE_(NET_WM_WINDOW_OPACITY);
     CREATE_(NET_WM_USER_TIME);
 /*  CREATE_(NET_WM_USER_TIME_WINDOW); */
     CREATE_(KDE_NET_WM_FRAME_STRUT);
diff --git a/obt/prop.h b/obt/prop.h
index 9c4ace3..b30232e 100644
--- a/obt/prop.h
+++ b/obt/prop.h
@@ -148,6 +148,7 @@ typedef enum {
     OBT_PROP_NET_WM_ICON_GEOMETRY,
     OBT_PROP_NET_WM_PID,
     OBT_PROP_NET_WM_ALLOWED_ACTIONS,
+    OBT_PROP_NET_WM_WINDOW_OPACITY,
     OBT_PROP_NET_WM_USER_TIME,
 /*  OBT_PROP_NET_WM_USER_TIME_WINDOW, */
     OBT_PROP_NET_FRAME_EXTENTS,
diff --git a/openbox/actions/cyclewindows.c b/openbox/actions/cyclewindows.c
index bbcb658..5f0db27 100644
--- a/openbox/actions/cyclewindows.c
+++ b/openbox/actions/cyclewindows.c
@@ -75,6 +75,8 @@ static gpointer setup_func(xmlNodePtr node,
     if ((n = obt_xml_find_node(node, "dialog"))) {
         if (obt_xml_node_contains(n, "none"))
             o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_NONE;
+        else if (obt_xml_node_contains(n, "no"))
+            o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_NONE;
         else if (obt_xml_node_contains(n, "icons"))
             o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_ICONS;
     }
diff --git a/openbox/client.c b/openbox/client.c
index 1b010e4..f3b4bda 100644
--- a/openbox/client.c
+++ b/openbox/client.c
@@ -112,6 +112,8 @@ static gboolean client_can_steal_focus(ObClient *self,
                                        gboolean allow_other_desktop,
                                        gboolean request_from_user,
                                        Time steal_time, Time launch_time);
+static void client_setup_default_decor_and_functions(ObClient *self);
+static void client_setup_decor_undecorated(ObClient *self);

 void client_startup(gboolean reconfig)
 {
@@ -238,6 +240,18 @@ void client_manage(Window window, ObPrompt *prompt)
        that needs to be freed with g_free(). */
     settings = client_get_settings_state(self);

+    /* the session should get the last say though */
+    client_restore_session_state(self);
+
+    /* the per-app settings/session may have changed the decorations for
+       the window, so we setup decorations for that here.  this is a special
+       case because we want to place the window according to these decoration
+       changes.
+       we do this before setting up the frame so that it will reflect the
+       decorations of the window as it will be placed on screen.
+    */
+    client_setup_decor_undecorated(self);
+
     /* specify that if we exit, the window should not be destroyed and
        should be reparented back to root automatically, unless we are managing
        an internal ObPrompt window  */
@@ -253,8 +267,18 @@ void client_manage(Window window, ObPrompt *prompt)
        time now */
     grab_server(FALSE);

-    /* the session should get the last say though */
-    client_restore_session_state(self);
+    /* this needs to occur once we have a frame, since it sets a property on
+       the frame */
+    client_update_opacity(self);
+
+    /* don't put helper/modal windows on a different desktop if they are
+       related to the focused window.  */
+    if (!screen_compare_desktops(self->desktop, screen_desktop) &&
+        focus_client && client_search_transient(focus_client, self)  &&
+        (client_helper(self) || self->modal))
+    {
+        self->desktop = screen_desktop;
+    }

     /* tell startup notification that this app started */
     launch_time = sn_app_started(self->startup_id, self->class, self->name);
@@ -717,11 +741,13 @@ static gboolean client_can_steal_focus(ObClient *self,
     /* This is focus stealing prevention */
     ob_debug("Want to focus window 0x%x at time %u "
              "launched at %u (last user interaction time %u) "
-             "request from %s, allow other desktop: %s",
+             "request from %s, allow other desktop: %s, "
+             "desktop switch time %u",
              self->window, steal_time, launch_time,
              event_last_user_time,
              (request_from_user ? "user" : "other"),
-             (allow_other_desktop ? "yes" : "no"));
+             (allow_other_desktop ? "yes" : "no"),
+             screen_desktop_user_time);

     /*
       if no launch time is provided for an application, make one up.
@@ -777,18 +803,24 @@ static gboolean client_can_steal_focus(ObClient *self,
     }

     /* if it's on another desktop
-       then if allow_other_desktop is true, we don't want to let it steal
+       and if allow_other_desktop is true, we generally let it steal focus.
+       but if it didn't come from the user, don't let it steal unless it was
+       launched before the user switched desktops.
        focus, unless it was launched after we changed desktops and the request
        came from the user
      */
-    if (!(self->desktop == screen_desktop ||
-          self->desktop == DESKTOP_ALL) &&
-        (!allow_other_desktop ||
-         (request_from_user && screen_desktop_user_time &&
-          !event_time_after(launch_time, screen_desktop_user_time))))
-    {
-        steal = FALSE;
-        ob_debug("Not focusing the window because its on another desktop\n");
+    if (!screen_compare_desktops(screen_desktop, self->desktop)) {
+        /* must be allowed */
+        if (!allow_other_desktop) {
+            steal = FALSE;
+            ob_debug("Not focusing the window because its on another desktop");
+        }
+        /* if we don't know when the desktop changed, but request is from an
+           application, don't let it change desktop on you */
+        else if (!request_from_user) {
+            steal = FALSE;
+            ob_debug("Not focusing the window because non-user request");
+        }
     }
     /* If something is focused... */
     else if (focus_client) {
@@ -1156,11 +1188,8 @@ static void client_get_all(ObClient *self, gboolean real)
     client_get_type_and_transientness(self);
     client_update_normal_hints(self);

-    /* set up the decor/functions before getting the state.  the states may
-       affect which functions are available, but we want to know the maximum
-       decor/functions are available to this window, so we can then apply them
-       in client_apply_startup_state() */
-    client_setup_decor_and_functions(self, FALSE);
+    /* set up the maximum possible decor/functions */
+    client_setup_default_decor_and_functions(self);

     client_get_state(self);

@@ -1648,6 +1677,16 @@ void client_update_colormap(ObClient *self, Colormap colormap)
         self->colormap = colormap;
 }

+void client_update_opacity(ObClient *self)
+{
+    guint32 o;
+
+    if (OBT_PROP_GET32(self->window, NET_WM_WINDOW_OPACITY, CARDINAL, &o))
+        OBT_PROP_SET32(self->frame->window, NET_WM_WINDOW_OPACITY, CARDINAL, o);
+    else
+        OBT_PROP_ERASE(self->frame->window, NET_WM_WINDOW_OPACITY);
+}
+
 void client_update_normal_hints(ObClient *self)
 {
     XSizeHints size;
@@ -1704,7 +1743,7 @@ void client_update_normal_hints(ObClient *self)
         ob_debug("Normal hints: not set");
 }

-void client_setup_decor_and_functions(ObClient *self, gboolean reconfig)
+static void client_setup_default_decor_and_functions(ObClient *self)
 {
     /* start with everything (cept fullscreen) */
     self->decorations =
@@ -1837,6 +1876,23 @@ void client_setup_decor_and_functions(ObClient *self, gboolean reconfig)
         self->functions &= ~OB_CLIENT_FUNC_MAXIMIZE;
         self->decorations &= ~OB_FRAME_DECOR_MAXIMIZE;
     }
+}
+
+/*! Set up decor for a client based on its undecorated state. */
+static void client_setup_decor_undecorated(ObClient *self)
+{
+    /* If the user requested no decorations, then remove all the decorations,
+       except the border.  But don't add a border if there wasn't one. */
+    if (self->undecorated)
+        self->decorations &= (config_theme_keepborder ?
+                              OB_FRAME_DECOR_BORDER : 0);
+}
+
+void client_setup_decor_and_functions(ObClient *self, gboolean reconfig)
+{
+    client_setup_default_decor_and_functions(self);
+
+    client_setup_decor_undecorated(self);

     if (self->max_horz && self->max_vert) {
         /* once upon a time you couldn't resize maximized windows, that is not
@@ -1846,12 +1902,6 @@ void client_setup_decor_and_functions(ObClient *self, gboolean reconfig)
         self->decorations &= ~(OB_FRAME_DECOR_HANDLE | OB_FRAME_DECOR_GRIPS);
     }

-    /* finally, the user can have requested no decorations, which overrides
-       everything (but doesnt give it a border if it doesnt have one) */
-    if (self->undecorated)
-        self->decorations &= (config_theme_keepborder ?
-                              OB_FRAME_DECOR_BORDER : 0);
-
     /* if we don't have a titlebar, then we cannot shade! */
     if (!(self->decorations & OB_FRAME_DECOR_TITLEBAR))
         self->functions &= ~OB_CLIENT_FUNC_SHADE;
@@ -2783,6 +2833,9 @@ static void client_apply_startup_state(ObClient *self,
     if (fullscreen)
         client_fullscreen(self, TRUE);

+    /* make sure client_setup_decor_and_functions() is called at least once */
+    client_setup_decor_and_functions(self, FALSE);
+
     /* if the window hasn't been configured yet, then do so now, in fact the
        x,y,w,h may _not_ be the same as the area rect, which can end up
        meaning that the client isn't properly moved/resized by the fullscreen
@@ -2877,10 +2930,11 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,

     /* cap any X windows at the size of an unsigned short */
     *w = MIN(*w,
-             G_MAXUSHORT - self->frame->size.left - self->frame->size.right);
+             (gint)G_MAXUSHORT
+             - self->frame->size.left - self->frame->size.right);
     *h = MIN(*h,
-             G_MAXUSHORT - self->frame->size.top - self->frame->size.bottom);
-
+             (gint)G_MAXUSHORT
+             - self->frame->size.top - self->frame->size.bottom);

     /* gets the frame's position */
     frame_client_gravity(self->frame, x, y);
@@ -3920,6 +3974,9 @@ gboolean client_focus(ObClient *self)
         return FALSE;
     }

+    /* if we have helper windows they should be there with the window */
+    client_bring_helper_windows(self);
+
     ob_debug_type(OB_DEBUG_FOCUS,
                   "Focusing client \"%s\" (0x%x) at time %u",
                   self->title, self->window, event_time());
@@ -4012,7 +4069,7 @@ static void client_bring_windows_recursive(ObClient *self,

     if (((helpers && client_helper(self)) ||
          (modals && self->modal)) &&
-        ((self->desktop != desktop && self->desktop != DESKTOP_ALL) ||
+        (!screen_compare_desktops(self->desktop, desktop) ||
          (iconic && self->iconic)))
     {
         if (iconic && self->iconic)
diff --git a/openbox/client.h b/openbox/client.h
index b36bef5..d5b344f 100644
--- a/openbox/client.h
+++ b/openbox/client.h
@@ -616,6 +616,8 @@ void client_update_sync_request_counter(ObClient *self);
 #endif
 /*! Updates the window's colormap */
 void client_update_colormap(ObClient *self, Colormap colormap);
+/*! Updates the requested opacity for the window from the client. */
+void client_update_opacity(ObClient *self);
 /*! Updates the WMNormalHints and adjusts things if they change */
 void client_update_normal_hints(ObClient *self);

diff --git a/openbox/client_menu.c b/openbox/client_menu.c
index fd2549c..c6cdd63 100644
--- a/openbox/client_menu.c
+++ b/openbox/client_menu.c
@@ -276,7 +276,7 @@ static gboolean send_to_menu_update(ObMenuFrame *frame, gpointer data)
         if ((desk == DESKTOP_ALL && c->desktop != DESKTOP_ALL) ||
             (c->desktop == DESKTOP_ALL && desk == screen_desktop))
         {
-            e->data.normal.mask = ob_rr_theme->desk_mask;
+            e->data.normal.mask = ob_rr_theme->btn_desk->mask;
             set_icon_color(e);
         } else
             e->data.normal.mask = NULL;
@@ -392,7 +392,7 @@ void client_menu_startup(void)
     menu_add_submenu(menu, CLIENT_LAYER, LAYER_MENU_NAME);

     e = menu_add_normal(menu, CLIENT_RESTORE, _("R_estore"), NULL, TRUE);
-    e->data.normal.mask = ob_rr_theme->max_toggled_mask;
+    e->data.normal.mask = ob_rr_theme->btn_max->toggled_mask;
     set_icon_color(e);

     menu_add_normal(menu, CLIENT_MOVE, _("_Move"), NULL, TRUE);
@@ -400,15 +400,15 @@ void client_menu_startup(void)
     menu_add_normal(menu, CLIENT_RESIZE, _("Resi_ze"), NULL, TRUE);

     e = menu_add_normal(menu, CLIENT_ICONIFY, _("Ico_nify"), NULL, TRUE);
-    e->data.normal.mask = ob_rr_theme->iconify_mask;
+    e->data.normal.mask = ob_rr_theme->btn_iconify->mask;
     set_icon_color(e);

     e = menu_add_normal(menu, CLIENT_MAXIMIZE, _("Ma_ximize"), NULL, TRUE);
-    e->data.normal.mask = ob_rr_theme->max_mask;
+    e->data.normal.mask = ob_rr_theme->btn_max->mask;
     set_icon_color(e);

     e = menu_add_normal(menu, CLIENT_SHADE, _("_Roll up/down"), NULL, TRUE);
-    e->data.normal.mask = ob_rr_theme->shade_mask;
+    e->data.normal.mask = ob_rr_theme->btn_shade->mask;
     set_icon_color(e);

     menu_add_normal(menu, CLIENT_DECORATE, _("Un/_Decorate"), NULL, TRUE);
@@ -416,6 +416,6 @@ void client_menu_startup(void)
     menu_add_separator(menu, -1, NULL);

     e = menu_add_normal(menu, CLIENT_CLOSE, _("_Close"), NULL, TRUE);
-    e->data.normal.mask = ob_rr_theme->close_mask;
+    e->data.normal.mask = ob_rr_theme->btn_close->mask;
     set_icon_color(e);
 }
diff --git a/openbox/config.c b/openbox/config.c
index debd9fb..0d9eb68 100644
--- a/openbox/config.c
+++ b/openbox/config.c
@@ -111,6 +111,7 @@ ObAppSettings* config_create_app_settings(void)
     settings->type = -1;
     settings->decor = -1;
     settings->shade = -1;
+    settings->monitor_type = OB_PLACE_MONITOR_ANY;
     settings->monitor = -1;
     settings->focus = -1;
     settings->desktop = 0;
@@ -135,6 +136,7 @@ void config_app_settings_copy_non_defaults(const ObAppSettings *src,
     copy_if(type, (ObClientType)-1);
     copy_if(decor, -1);
     copy_if(shade, -1);
+    copy_if(monitor_type, OB_PLACE_MONITOR_ANY);
     copy_if(monitor, -1);
     copy_if(focus, -1);
     copy_if(desktop, 0);
@@ -200,8 +202,8 @@ void config_parse_gravity_coord(xmlNodePtr node, GravityCoord *c)

 /* Manages settings for individual applications.
    Some notes: monitor is the screen number in a multi monitor
-   (Xinerama) setup (starting from 0) or mouse, meaning the
-   monitor the pointer is on. Default: mouse.
+   (Xinerama) setup (starting from 0), or mouse: the monitor the pointer
+   is on, active: the active monitor, primary: the primary monitor.
    Layer can be three values, above (Always on top), below
    (Always on bottom) and everything else (normal behaviour).
    Positions can be an integer value or center, which will
@@ -289,12 +291,19 @@ static void parse_per_app_settings(xmlNodePtr node, gpointer d)
                         settings->pos_given = TRUE;
                     }

-                if (settings->pos_given &&
-                    (c = obt_xml_find_node(n->children, "monitor")))
+                /* monitor can be set without setting x or y */
+                if ((c = obt_xml_find_node(n->children, "monitor")))
                     if (!obt_xml_node_contains(c, "default")) {
                         gchar *s = obt_xml_node_string(c);
                         if (!g_ascii_strcasecmp(s, "mouse"))
-                            settings->monitor = 0;
+                            settings->monitor_type =
+                                    OB_PLACE_MONITOR_MOUSE;
+                        else if (!g_ascii_strcasecmp(s, "active"))
+                            settings->monitor_type =
+                                    OB_PLACE_MONITOR_ACTIVE;
+                        else if (!g_ascii_strcasecmp(s, "primary"))
+                            settings->monitor_type =
+                                    OB_PLACE_MONITOR_PRIMARY;
                         else
                             settings->monitor = obt_xml_node_int(c);
                         g_free(s);
@@ -1070,7 +1079,7 @@ void config_startup(ObtXmlInst *i)
     obt_xml_register(i, "keyboard", parse_keyboard, NULL);

     config_mouse_threshold = 8;
-    config_mouse_dclicktime = 200;
+    config_mouse_dclicktime = 500;
     config_mouse_screenedgetime = 400;
     config_mouse_screenedgewarp = FALSE;

diff --git a/openbox/config.h b/openbox/config.h
index 890b002..730dc39 100644
--- a/openbox/config.h
+++ b/openbox/config.h
@@ -49,6 +49,7 @@ struct _ObAppSettings
     gint shade;
     gint decor;
     gint focus;
+    ObPlaceMonitor monitor_type;
     gint monitor;
     gint iconic;
     gint skip_pager;
diff --git a/openbox/debug.c b/openbox/debug.c
index 358b090..ad083b1 100644
--- a/openbox/debug.c
+++ b/openbox/debug.c
@@ -38,6 +38,8 @@ static guint     rr_handler_id = 0;
 static guint     obt_handler_id = 0;
 static guint     ob_handler_id = 0;
 static guint     ob_handler_prompt_id = 0;
+static GList    *prompt_queue = NULL;
+static gboolean  allow_prompts = TRUE;

 static void log_handler(const gchar *log_domain, GLogLevelFlags log_level,
                         const gchar *message, gpointer user_data);
@@ -134,8 +136,8 @@ static void log_handler(const gchar *log_domain, GLogLevelFlags log_level,
 static void prompt_handler(const gchar *log_domain, GLogLevelFlags log_level,
                            const gchar *message, gpointer data)
 {
-    if (ob_state() == OB_STATE_RUNNING)
-        prompt_show_message(message, "Openbox", _("Close"));
+    if (ob_state() == OB_STATE_RUNNING && allow_prompts)
+        prompt_queue = g_list_prepend(prompt_queue, g_strdup(message));
     else
         log_handler(log_domain, log_level, message, data);
 }
@@ -184,3 +186,16 @@ void ob_debug_type(ObDebugType type, const gchar *a, ...)
     log_argv(type, a, vl);
     va_end(vl);
 }
+
+void ob_debug_show_prompts(void)
+{
+    if (prompt_queue) {
+        allow_prompts = FALSE; /* avoid recursive prompts */
+        while (prompt_queue) {
+            prompt_show_message(prompt_queue->data, "Openbox", _("Close"));
+            g_free(prompt_queue->data);
+            prompt_queue = g_list_delete_link(prompt_queue, prompt_queue);
+        }
+        allow_prompts = TRUE;
+    }
+}
diff --git a/openbox/debug.h b/openbox/debug.h
index a24e66e..13c5598 100644
--- a/openbox/debug.h
+++ b/openbox/debug.h
@@ -38,4 +38,6 @@ void ob_debug_type(ObDebugType type, const gchar *a, ...);

 void ob_debug_enable(ObDebugType type, gboolean enable);

+void ob_debug_show_prompts(void);
+
 #endif
diff --git a/openbox/event.c b/openbox/event.c
index 2dde132..cf089b6 100644
--- a/openbox/event.c
+++ b/openbox/event.c
@@ -700,6 +700,8 @@ static void event_process(const XEvent *ec, gpointer data)
         static guint pressed = 0;
         static Window pressed_win = None;

+        event_sourcetime = event_curtime;
+
         /* If the button press was on some non-root window, or was physically
            on the root window... */
         if (window != obt_root(ob_screen) ||
@@ -726,12 +728,17 @@ static void event_process(const XEvent *ec, gpointer data)
     else if (e->type == KeyPress || e->type == KeyRelease ||
              e->type == MotionNotify)
     {
+        event_sourcetime = event_curtime;
+
         used = event_handle_user_input(client, e);

         if (prompt && !used)
             used = event_handle_prompt(prompt, e);
     }

+    /* show any debug prompts that are queued */
+    ob_debug_show_prompts();
+
     /* if something happens and it's not from an XEvent, then we don't know
        the time, so clear it here until the next event is handled */
     event_curtime = event_sourcetime = CurrentTime;
@@ -1674,6 +1681,9 @@ static void event_handle_client(ObClient *client, XEvent *e)
                 event_last_user_time = t;
             }
         }
+        else if (msgtype == OBT_PROP_ATOM(NET_WM_WINDOW_OPACITY)) {
+            client_update_opacity(client);
+        }
 #ifdef SYNC
         else if (msgtype == OBT_PROP_ATOM(NET_WM_SYNC_REQUEST_COUNTER)) {
             /* if they are resizing right now this would cause weird behaviour.
diff --git a/openbox/frame.c b/openbox/frame.c
index 3aa3ab7..48dda24 100644
--- a/openbox/frame.c
+++ b/openbox/frame.c
@@ -348,7 +348,8 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
         self->shaded = self->client->shaded;

         if (self->decorations & OB_FRAME_DECOR_BORDER)
-            self->bwidth = ob_rr_theme->fbwidth;
+            self->bwidth = self->client->undecorated ?
+                ob_rr_theme->ubwidth : ob_rr_theme->fbwidth;
         else
             self->bwidth = 0;

diff --git a/openbox/framerender.c b/openbox/framerender.c
index 28c12ae..041e6d1 100644
--- a/openbox/framerender.c
+++ b/openbox/framerender.c
@@ -68,9 +68,13 @@ void framerender_frame(ObFrame *self)
         XSetWindowBackground(obt_display, self->innerbrb, px);
         XClearWindow(obt_display, self->innerbrb);

-        px = (self->focused ?
-              RrColorPixel(ob_rr_theme->frame_focused_border_color) :
-              RrColorPixel(ob_rr_theme->frame_unfocused_border_color));
+        px = RrColorPixel(self->focused ?
+            (self->client->undecorated ?
+             ob_rr_theme->frame_undecorated_focused_border_color :
+             ob_rr_theme->frame_focused_border_color) :
+            (self->client->undecorated ?
+             ob_rr_theme->frame_undecorated_unfocused_border_color :
+             ob_rr_theme->frame_unfocused_border_color));

         XSetWindowBackground(obt_display, self->left, px);
         XClearWindow(obt_display, self->left);
@@ -127,116 +131,116 @@ void framerender_frame(ObFrame *self)
             t = ob_rr_theme->a_focused_title;
             l = ob_rr_theme->a_focused_label;
             m = (!(self->decorations & OB_FRAME_DECOR_MAXIMIZE) ?
-                 ob_rr_theme->a_disabled_focused_max :
+                 ob_rr_theme->btn_max->a_disabled_focused :
                  (self->client->max_vert || self->client->max_horz ?
                   (self->max_press ?
-                   ob_rr_theme->a_toggled_focused_pressed_max :
+                   ob_rr_theme->btn_max->a_toggled_focused_pressed :
                    (self->max_hover ?
-                    ob_rr_theme->a_toggled_hover_focused_max :
-                    ob_rr_theme->a_toggled_focused_unpressed_max)) :
+                    ob_rr_theme->btn_max->a_toggled_hover_focused :
+                    ob_rr_theme->btn_max->a_toggled_focused_unpressed)) :
                   (self->max_press ?
-                   ob_rr_theme->a_focused_pressed_max :
+                   ob_rr_theme->btn_max->a_focused_pressed :
                    (self->max_hover ?
-                    ob_rr_theme->a_hover_focused_max :
-                    ob_rr_theme->a_focused_unpressed_max))));
+                    ob_rr_theme->btn_max->a_hover_focused :
+                    ob_rr_theme->btn_max->a_focused_unpressed))));
             n = ob_rr_theme->a_icon;
             i = (!(self->decorations & OB_FRAME_DECOR_ICONIFY) ?
-                 ob_rr_theme->a_disabled_focused_iconify :
+                 ob_rr_theme->btn_iconify->a_disabled_focused :
                  (self->iconify_press ?
-                  ob_rr_theme->a_focused_pressed_iconify :
+                  ob_rr_theme->btn_iconify->a_focused_pressed :
                   (self->iconify_hover ?
-                   ob_rr_theme->a_hover_focused_iconify :
-                   ob_rr_theme->a_focused_unpressed_iconify)));
+                   ob_rr_theme->btn_iconify->a_hover_focused :
+                   ob_rr_theme->btn_iconify->a_focused_unpressed)));
             d = (!(self->decorations & OB_FRAME_DECOR_ALLDESKTOPS) ?
-                 ob_rr_theme->a_disabled_focused_desk :
+                 ob_rr_theme->btn_desk->a_disabled_focused :
                  (self->client->desktop == DESKTOP_ALL ?
                   (self->desk_press ?
-                   ob_rr_theme->a_toggled_focused_pressed_desk :
+                   ob_rr_theme->btn_desk->a_toggled_focused_pressed :
                    (self->desk_hover ?
-                    ob_rr_theme->a_toggled_hover_focused_desk :
-                    ob_rr_theme->a_toggled_focused_unpressed_desk)) :
+                    ob_rr_theme->btn_desk->a_toggled_hover_focused :
+                    ob_rr_theme->btn_desk->a_toggled_focused_unpressed)) :
                   (self->desk_press ?
-                   ob_rr_theme->a_focused_pressed_desk :
+                   ob_rr_theme->btn_desk->a_focused_pressed :
                    (self->desk_hover ?
-                    ob_rr_theme->a_hover_focused_desk :
-                    ob_rr_theme->a_focused_unpressed_desk))));
+                    ob_rr_theme->btn_desk->a_hover_focused :
+                    ob_rr_theme->btn_desk->a_focused_unpressed))));
             s = (!(self->decorations & OB_FRAME_DECOR_SHADE) ?
-                 ob_rr_theme->a_disabled_focused_shade :
+                 ob_rr_theme->btn_shade->a_disabled_focused :
                  (self->client->shaded ?
                   (self->shade_press ?
-                   ob_rr_theme->a_toggled_focused_pressed_shade :
+                   ob_rr_theme->btn_shade->a_toggled_focused_pressed :
                    (self->shade_hover ?
-                    ob_rr_theme->a_toggled_hover_focused_shade :
-                    ob_rr_theme->a_toggled_focused_unpressed_shade)) :
+                    ob_rr_theme->btn_shade->a_toggled_hover_focused :
+                    ob_rr_theme->btn_shade->a_toggled_focused_unpressed)) :
                   (self->shade_press ?
-                   ob_rr_theme->a_focused_pressed_shade :
+                   ob_rr_theme->btn_shade->a_focused_pressed :
                    (self->shade_hover ?
-                    ob_rr_theme->a_hover_focused_shade :
-                    ob_rr_theme->a_focused_unpressed_shade))));
+                    ob_rr_theme->btn_shade->a_hover_focused :
+                    ob_rr_theme->btn_shade->a_focused_unpressed))));
             c = (!(self->decorations & OB_FRAME_DECOR_CLOSE) ?
-                 ob_rr_theme->a_disabled_focused_close :
+                 ob_rr_theme->btn_close->a_disabled_focused :
                  (self->close_press ?
-                  ob_rr_theme->a_focused_pressed_close :
+                  ob_rr_theme->btn_close->a_focused_pressed :
                   (self->close_hover ?
-                   ob_rr_theme->a_hover_focused_close :
-                   ob_rr_theme->a_focused_unpressed_close)));
+                   ob_rr_theme->btn_close->a_hover_focused :
+                   ob_rr_theme->btn_close->a_focused_unpressed)));
         } else {
             t = ob_rr_theme->a_unfocused_title;
             l = ob_rr_theme->a_unfocused_label;
             m = (!(self->decorations & OB_FRAME_DECOR_MAXIMIZE) ?
-                 ob_rr_theme->a_disabled_unfocused_max :
+                 ob_rr_theme->btn_max->a_disabled_unfocused :
                  (self->client->max_vert || self->client->max_horz ?
                   (self->max_press ?
-                   ob_rr_theme->a_toggled_unfocused_pressed_max :
+                   ob_rr_theme->btn_max->a_toggled_unfocused_pressed :
                    (self->max_hover ?
-                    ob_rr_theme->a_toggled_hover_unfocused_max :
-                    ob_rr_theme->a_toggled_unfocused_unpressed_max)) :
+                    ob_rr_theme->btn_max->a_toggled_hover_unfocused :
+                    ob_rr_theme->btn_max->a_toggled_unfocused_unpressed)) :
                   (self->max_press ?
-                   ob_rr_theme->a_unfocused_pressed_max :
+                   ob_rr_theme->btn_max->a_unfocused_pressed :
                    (self->max_hover ?
-                    ob_rr_theme->a_hover_unfocused_max :
-                    ob_rr_theme->a_unfocused_unpressed_max))));
+                    ob_rr_theme->btn_max->a_hover_unfocused :
+                    ob_rr_theme->btn_max->a_unfocused_unpressed))));
             n = ob_rr_theme->a_icon;
             i = (!(self->decorations & OB_FRAME_DECOR_ICONIFY) ?
-                 ob_rr_theme->a_disabled_unfocused_iconify :
+                 ob_rr_theme->btn_iconify->a_disabled_unfocused :
                  (self->iconify_press ?
-                  ob_rr_theme->a_unfocused_pressed_iconify :
+                  ob_rr_theme->btn_iconify->a_unfocused_pressed :
                   (self->iconify_hover ?
-                   ob_rr_theme->a_hover_unfocused_iconify :
-                   ob_rr_theme->a_unfocused_unpressed_iconify)));
+                   ob_rr_theme->btn_iconify->a_hover_unfocused :
+                   ob_rr_theme->btn_iconify->a_unfocused_unpressed)));
             d = (!(self->decorations & OB_FRAME_DECOR_ALLDESKTOPS) ?
-                 ob_rr_theme->a_disabled_unfocused_desk :
+                 ob_rr_theme->btn_desk->a_disabled_unfocused :
                  (self->client->desktop == DESKTOP_ALL ?
                   (self->desk_press ?
-                   ob_rr_theme->a_toggled_unfocused_pressed_desk :
+                   ob_rr_theme->btn_desk->a_toggled_unfocused_pressed :
                    (self->desk_hover ?
-                    ob_rr_theme->a_toggled_hover_unfocused_desk :
-                    ob_rr_theme->a_toggled_unfocused_unpressed_desk)) :
+                    ob_rr_theme->btn_desk->a_toggled_hover_unfocused :
+                    ob_rr_theme->btn_desk->a_toggled_unfocused_unpressed)) :
                   (self->desk_press ?
-                   ob_rr_theme->a_unfocused_pressed_desk :
+                   ob_rr_theme->btn_desk->a_unfocused_pressed :
                    (self->desk_hover ?
-                    ob_rr_theme->a_hover_unfocused_desk :
-                    ob_rr_theme->a_unfocused_unpressed_desk))));
+                    ob_rr_theme->btn_desk->a_hover_unfocused :
+                    ob_rr_theme->btn_desk->a_unfocused_unpressed))));
             s = (!(self->decorations & OB_FRAME_DECOR_SHADE) ?
-                 ob_rr_theme->a_disabled_unfocused_shade :
+                 ob_rr_theme->btn_shade->a_disabled_unfocused :
                  (self->client->shaded ?
                   (self->shade_press ?
-                   ob_rr_theme->a_toggled_unfocused_pressed_shade :
+                   ob_rr_theme->btn_shade->a_toggled_unfocused_pressed :
                    (self->shade_hover ?
-                    ob_rr_theme->a_toggled_hover_unfocused_shade :
-                    ob_rr_theme->a_toggled_unfocused_unpressed_shade)) :
+                    ob_rr_theme->btn_shade->a_toggled_hover_unfocused :
+                    ob_rr_theme->btn_shade->a_toggled_unfocused_unpressed)) :
                   (self->shade_press ?
-                   ob_rr_theme->a_unfocused_pressed_shade :
+                   ob_rr_theme->btn_shade->a_unfocused_pressed :
                    (self->shade_hover ?
-                    ob_rr_theme->a_hover_unfocused_shade :
-                    ob_rr_theme->a_unfocused_unpressed_shade))));
+                    ob_rr_theme->btn_shade->a_hover_unfocused :
+                    ob_rr_theme->btn_shade->a_unfocused_unpressed))));
             c = (!(self->decorations & OB_FRAME_DECOR_CLOSE) ?
-                 ob_rr_theme->a_disabled_unfocused_close :
+                 ob_rr_theme->btn_close->a_disabled_unfocused :
                  (self->close_press ?
-                  ob_rr_theme->a_unfocused_pressed_close :
+                  ob_rr_theme->btn_close->a_unfocused_pressed :
                   (self->close_hover ?
-                   ob_rr_theme->a_hover_unfocused_close :
-                   ob_rr_theme->a_unfocused_unpressed_close)));
+                   ob_rr_theme->btn_close->a_hover_unfocused :
+                   ob_rr_theme->btn_close->a_unfocused_unpressed)));
         }
         clear = ob_rr_theme->a_clear;

diff --git a/openbox/keyboard.c b/openbox/keyboard.c
index 5b8016d..8f4424e 100644
--- a/openbox/keyboard.c
+++ b/openbox/keyboard.c
@@ -313,7 +313,8 @@ void keyboard_rebind(void)

     old = keyboard_firstnode;
     keyboard_firstnode = NULL;
-    node_rebind(old);
+    if (old)
+        node_rebind(old);

     tree_destroy(old);
     set_curpos(NULL);
diff --git a/openbox/menu.c b/openbox/menu.c
index daea0b6..1294c4c 100644
--- a/openbox/menu.c
+++ b/openbox/menu.c
@@ -287,7 +287,7 @@ static void parse_menu_item(xmlNodePtr node,  gpointer data)
                 ObActionsAct *action = actions_parse(c);
                 if (action)
                     acts = g_slist_append(acts, action);
-                c = obt_xml_find_node(node->next, "action");
+                c = obt_xml_find_node(c->next, "action");
             }
             e = menu_add_normal(state->parent, -1, label, acts, TRUE);

diff --git a/openbox/mouse.c b/openbox/mouse.c
index ddf6851..2f0c8f5 100644
--- a/openbox/mouse.c
+++ b/openbox/mouse.c
@@ -211,7 +211,7 @@ gboolean mouse_event(ObClient *client, XEvent *e)
     static Time ltime;
     static guint button = 0, state = 0, lbutton = 0;
     static Window lwindow = None;
-    static gint px, py, pwx = -1, pwy = -1;
+    static gint px, py, pwx = -1, pwy = -1, lx = -10, ly = -10;
     gboolean used = FALSE;

     ObFrameContext context;
@@ -290,18 +290,24 @@ gboolean mouse_event(ObClient *client, XEvent *e)
                 if (e->xbutton.x >= (signed)-b &&
                     e->xbutton.y >= (signed)-b &&
                     e->xbutton.x < (signed)(w+b) &&
-                    e->xbutton.y < (signed)(h+b)) {
+                    e->xbutton.y < (signed)(h+b))
+                {
                     click = TRUE;
                     /* double clicks happen if there were 2 in a row! */
                     if (lbutton == button &&
                         lwindow == e->xbutton.window &&
                         e->xbutton.time - config_mouse_dclicktime <=
-                        ltime) {
+                        ltime &&
+                        ABS(e->xbutton.x - lx) < 8 &&
+                        ABS(e->xbutton.y - ly) < 8)
+                    {
                         dclick = TRUE;
                         lbutton = 0;
                     } else {
                         lbutton = button;
                         lwindow = e->xbutton.window;
+                        lx = e->xbutton.x;
+                        ly = e->xbutton.y;
                     }
                 } else {
                     lbutton = 0;
diff --git a/openbox/openbox.c b/openbox/openbox.c
index 0782794..fbc01fd 100644
--- a/openbox/openbox.c
+++ b/openbox/openbox.c
@@ -515,9 +515,9 @@ static void print_version(void)
 {
     g_print("Openbox %s\n", PACKAGE_VERSION);
     g_print(_("Copyright (c)"));
-    g_print(" 2008        Mikael Magnusson\n");
+    g_print(" 2008-2011   Mikael Magnusson\n");
     g_print(_("Copyright (c)"));
-    g_print(" 2003-2006   Dana Jansens\n\n");
+    g_print(" 2003-2011   Dana Jansens\n\n");
     g_print("This program comes with ABSOLUTELY NO WARRANTY.\n");
     g_print("This is free software, and you are welcome to redistribute it\n");
     g_print("under certain conditions. See the file COPYING for details.\n\n");
@@ -576,7 +576,7 @@ static void run_startup_cmd(void)
                        G_SPAWN_SEARCH_PATH |
                        G_SPAWN_DO_NOT_REAP_CHILD,
                        NULL, NULL, NULL, &e);
-    if (!g_shell_parse_argv(startup_cmd, NULL, &argv, &e)) {
+    if (!ok) {
         g_message("Error launching startup command: %s",
                   e->message);
         g_error_free(e);
diff --git a/openbox/place.c b/openbox/place.c
index d56adfc..2cd21bb 100644
--- a/openbox/place.c
+++ b/openbox/place.c
@@ -37,27 +37,29 @@ static Rect *pick_pointer_head(ObClient *c)

    When a window is being placed in the FOREGROUND, use a monitor chosen in
    the following order:
-   1. same monitor as parent
-   2. primary monitor if placement=PRIMARY
+   1. per-app settings
+   2. same monitor as parent
+   3. primary monitor if placement=PRIMARY
       active monitor if placement=ACTIVE
       pointer monitor if placement=MOUSE
-   3. primary monitor
-   4. other monitors where the window has group members on the same desktop
-   5. other monitors where the window has group members on other desktops
-   6. other monitors
+   4. primary monitor
+   5. other monitors where the window has group members on the same desktop
+   6. other monitors where the window has group members on other desktops
+   7. other monitors

    When a window is being placed in the BACKGROUND, use a monitor chosen in the
    following order:
-   1. same monitor as parent
-   2. other monitors where the window has group members on the same desktop
-    2a. primary monitor in this set
-    2b. other monitors in this set
-   3. other monitors where the window has group members on other desktops
+   1. per-app settings
+   2. same monitor as parent
+   3. other monitors where the window has group members on the same desktop
     3a. primary monitor in this set
     3b. other monitors in this set
-   4. other monitors
+   4. other monitors where the window has group members on other desktops
     4a. primary monitor in this set
     4b. other monitors in this set
+   5. other monitors
+    5a. primary monitor in this set
+    5b. other monitors in this set
 */

 /*! One for each possible head, used to sort them in order of precedence. */
@@ -73,6 +75,7 @@ enum {
     HEAD_PRIMARY = 1 << 2, /* primary monitor */
     HEAD_GROUP_DESK = 1 << 3, /* has a group member on the same desktop */
     HEAD_GROUP = 1 << 4, /* has a group member on another desktop */
+    HEAD_PERAPP = 1 << 5, /* chosen by per-app settings */
 };

 gint cmp_foreground(const void *a, const void *b)
@@ -83,6 +86,10 @@ gint cmp_foreground(const void *a, const void *b)

     if (h1->monitor == h2->monitor) return 0;

+    if (h1->flags & HEAD_PERAPP) --i;
+    if (h2->flags & HEAD_PERAPP) ++i;
+    if (i) return i;
+
     if (h1->flags & HEAD_PARENT) --i;
     if (h2->flags & HEAD_PARENT) ++i;
     if (i) return i;
@@ -114,6 +121,10 @@ gint cmp_background(const void *a, const void *b)

     if (h1->monitor == h2->monitor) return 0;

+    if (h1->flags & HEAD_PERAPP) --i;
+    if (h2->flags & HEAD_PERAPP) ++i;
+    if (i) return i;
+
     if (h1->flags & HEAD_PARENT) --i;
     if (h2->flags & HEAD_PARENT) ++i;
     if (i) return i;
@@ -144,7 +155,8 @@ gint cmp_background(const void *a, const void *b)
 }

 /*! Pick a monitor to place a window on. */
-static Rect *pick_head(ObClient *c, gboolean foreground)
+static Rect *pick_head(ObClient *c, gboolean foreground,
+                       ObAppSettings *settings)
 {
     Rect *area;
     ObPlaceHead *choice;
@@ -180,6 +192,33 @@ static Rect *pick_head(ObClient *c, gboolean foreground)
         choice[i].flags |= HEAD_PRIMARY;
         if (config_place_monitor == OB_PLACE_MONITOR_PRIMARY)
             choice[i].flags |= HEAD_PLACED;
+        if (settings &&
+            settings->monitor_type == OB_PLACE_MONITOR_PRIMARY)
+            choice[i].flags |= HEAD_PERAPP;
+    }
+
+    i = screen_monitor_active();
+    if (i < screen_num_monitors) {
+        if (config_place_monitor == OB_PLACE_MONITOR_ACTIVE)
+            choice[i].flags |= HEAD_PLACED;
+        if (settings &&
+            settings->monitor_type == OB_PLACE_MONITOR_ACTIVE)
+            choice[i].flags |= HEAD_PERAPP;
+    }
+
+    i = screen_monitor_pointer();
+    if (i < screen_num_monitors) {
+        if (config_place_monitor == OB_PLACE_MONITOR_MOUSE)
+            choice[i].flags |= HEAD_PLACED;
+        if (settings &&
+            settings->monitor_type == OB_PLACE_MONITOR_MOUSE)
+            choice[i].flags |= HEAD_PERAPP;
+    }
+
+    if (settings) {
+        i = settings->monitor - 1;
+        if (i < screen_num_monitors)
+            choice[i].flags |= HEAD_PERAPP;
     }

     /* direct parent takes highest precedence */
@@ -440,27 +479,15 @@ static gboolean place_under_mouse(ObClient *client, gint *x, gint *y)
     return TRUE;
 }

-static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y,
+static gboolean place_per_app_setting(ObClient *client, Rect *screen,
+                                      gint *x, gint *y,
                                       ObAppSettings *settings)
 {
-    Rect *screen = NULL;
-
     if (!settings || (settings && !settings->pos_given))
         return FALSE;

     ob_debug("placing by per-app settings");

-    /* Find which head the pointer is on */
-    if (settings->monitor == 0)
-        /* this can return NULL */
-        screen = pick_pointer_head(client);
-    else {
-        guint m = settings->monitor;
-        if (m < 1 || m > screen_num_monitors)
-            m = screen_monitor_primary(TRUE) + 1;
-        screen = screen_area(client->desktop, m - 1, NULL);
-    }
-
     if (settings->position.x.center)
         *x = screen->x + screen->width / 2 - client->area.width / 2;
     else if (settings->position.x.opposite)
@@ -481,7 +508,6 @@ static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y,
     if (settings->position.y.denom)
         *y = (*y * screen->height) / settings->position.y.denom;

-    g_slice_free(Rect, screen);
     return TRUE;
 }

@@ -548,10 +574,10 @@ gboolean place_client(ObClient *client, gboolean foreground, gint *x, gint *y,
          !(settings && settings->pos_given)))
         return FALSE;

-    area = pick_head(client, foreground);
+    area = pick_head(client, foreground, settings);

     /* try a number of methods */
-    ret = place_per_app_setting(client, x, y, settings) ||
+    ret = place_per_app_setting(client, area, x, y, settings) ||
         place_transient_splash(client, area, x, y) ||
         (config_place_policy == OB_PLACE_POLICY_MOUSE &&
          place_under_mouse(client, x, y)) ||
diff --git a/openbox/prompt.c b/openbox/prompt.c
index ebefe0a..1aa79d2 100644
--- a/openbox/prompt.c
+++ b/openbox/prompt.c
@@ -58,7 +58,7 @@ void prompt_startup(gboolean reconfig)

     prompt_a_button = RrAppearanceCopy(ob_rr_theme->osd_unpressed_button);
     prompt_a_focus = RrAppearanceCopy(ob_rr_theme->osd_focused_button);
-    prompt_a_press = RrAppearanceCopy(ob_rr_theme->osd_pressed_button);
+    prompt_a_press = RrAppearanceCopy(ob_rr_theme->osd_pressed_button);

     prompt_a_msg = RrAppearanceCopy(ob_rr_theme->osd_hilite_label);
     prompt_a_msg->texture[0].data.text.flow = TRUE;
@@ -362,7 +362,7 @@ static void render_button(ObPrompt *self, ObPromptElement *e)
 {
     RrAppearance *a;

-    if (e->pressed && e->hover)       a = prompt_a_press;
+    if (e->hover && e->pressed)       a = prompt_a_press;
     else if (self->focus == e)        a = prompt_a_focus;
     else                              a = prompt_a_button;

diff --git a/openbox/screen.c b/openbox/screen.c
index d368cab..ffe74a0 100644
--- a/openbox/screen.c
+++ b/openbox/screen.c
@@ -249,6 +249,7 @@ gboolean screen_annex(void)
     supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DIALOG);
     supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_NORMAL);
     supported[i++] = OBT_PROP_ATOM(NET_WM_ALLOWED_ACTIONS);
+    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_OPACITY);
     supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_MOVE);
     supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_RESIZE);
     supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_MINIMIZE);
@@ -479,7 +480,6 @@ void screen_shutdown(gboolean reconfig)

 void screen_resize(void)
 {
-    static gint oldw = 0, oldh = 0;
     gint w, h;
     GList *it;
     gulong geometry[2];
@@ -487,10 +487,6 @@ void screen_resize(void)
     w = WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen));
     h = HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen));

-    if (w == oldw && h == oldh) return;
-
-    oldw = w; oldh = h;
-
     /* Set the _NET_DESKTOP_GEOMETRY hint */
     screen_physical_size.width = geometry[0] = w;
     screen_physical_size.height = geometry[1] = h;
@@ -503,9 +499,10 @@ void screen_resize(void)
     /* this calls screen_update_areas(), which we need ! */
     dock_configure();

-    if (oldw)
-        for (it = client_list; it; it = g_list_next(it))
-            client_move_onscreen(it->data, FALSE);
+    for (it = client_list; it; it = g_list_next(it)) {
+        client_move_onscreen(it->data, FALSE);
+        client_reconfigure(it->data, FALSE);
+    }
 }

 void screen_set_num_desktops(guint num)
diff --git a/po/fi.po b/po/fi.po
index 7fd9a5c..7cc1e93 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -8,16 +8,17 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Openbox 3.4.7\n"
+"Project-Id-Version: Openbox 3.4.11\n"
 "Report-Msgid-Bugs-To: http://bugzilla.icculus.org\n"
 "POT-Creation-Date: 2011-08-01 18:20+0200\n"
-"PO-Revision-Date: 2008-03-17 21:26+0100\n"
+"PO-Revision-Date: 2010-03-13 21:56+0100\n"
 "Last-Translator: Lauri Hakko <aperculum@gmail.com>\n"
 "Language-Team: None\n"
 "Language: \n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"

 #: openbox/actions.c:198
 #, c-format
@@ -427,7 +428,7 @@ msgstr "Ikkunointiohjelma ruudulla %d ei sulkeudu"
 #. second one. For example,
 #. "The current session has %2$d desktops, but Openbox is configured for %1$d ..."
 #: openbox/screen.c:418
-#, fuzzy, c-format
+#, c-format
 msgid ""
 "Openbox is configured for %d desktop, but the current session has %d.  "
 "Overriding the Openbox configuration."
@@ -475,20 +476,6 @@ msgstr "Pyydettyä näppäintä \"%s\" ei ole olemassa näytöllä"
 msgid "OK"
 msgstr "OK"

-#, fuzzy
-#~ msgid "Openbox"
-#~ msgstr "Sulje Openbox"
-
-#~ msgid "--config-file requires an argument\n"
-#~ msgstr "--config-file tarvitsee argumentin\n"
-
-#~ msgid ""
-#~ "The SessionLogout action is not available since Openbox was built without "
-#~ "session management support"
-#~ msgstr ""
-#~ "SessionLogout tapahtuma ei ole suoritettavissa, koska Openbox käännettiin "
-#~ "ilman istunnon hallinnan tukea"
-
 #~ msgid "Unable to save the session to \"%s\": %s"
 #~ msgstr "Istuntoa ei voitu tallentaa hakemistoon \"%s\": %s"

@@ -501,5 +488,12 @@ msgstr "OK"
 #~ msgid "X Error: %s"
 #~ msgstr "X-virhe: %s"

+#~ msgid ""
+#~ "The SessionLogout action is not available since Openbox was built without "
+#~ "session management support"
+#~ msgstr ""
+#~ "SessionLogout tapahtuma ei ole suoritettavissa, koska Openbox käännettiin "
+#~ "ilman istunnon hallinnan tukea"
+
 #~ msgid "Failed to execute \"%s\": %s"
 #~ msgstr "Ohjelman \"%s\" suorittaminen epäonnistui: %s"
--
1.7.3.4

--- openbox-3.5.0.org/Makefile.in
+++ openbox-3.5.0/Makefile.in
@@ -133,6 +133,7 @@
 	obrender/obrender_libobrender_la-instance.lo \
 	obrender/obrender_libobrender_la-mask.lo \
 	obrender/obrender_libobrender_la-render.lo \
+	obrender/obrender_libobrender_la-button.lo \
 	obrender/obrender_libobrender_la-theme.lo
 obrender_libobrender_la_OBJECTS =  \
 	$(am_obrender_libobrender_la_OBJECTS)
@@ -630,6 +631,8 @@
 	obrender/mask.c \
 	obrender/render.h \
 	obrender/render.c \
+	obrender/button.h \
+	obrender/button.c \
 	obrender/theme.h \
 	obrender/theme.c

@@ -955,6 +958,7 @@
 	obrender/instance.h \
 	obrender/mask.h \
 	obrender/render.h \
+	obrender/button.h \
 	obrender/theme.h \
 	obrender/version.h

@@ -1173,6 +1177,8 @@
 	obrender/$(DEPDIR)/$(am__dirstamp)
 obrender/obrender_libobrender_la-render.lo: obrender/$(am__dirstamp) \
 	obrender/$(DEPDIR)/$(am__dirstamp)
+obrender/obrender_libobrender_la-button.lo: obrender/$(am__dirstamp) \
+	obrender/$(DEPDIR)/$(am__dirstamp)
 obrender/obrender_libobrender_la-theme.lo: obrender/$(am__dirstamp) \
 	obrender/$(DEPDIR)/$(am__dirstamp)
 obrender/libobrender.la: $(obrender_libobrender_la_OBJECTS) $(obrender_libobrender_la_DEPENDENCIES) obrender/$(am__dirstamp)
@@ -1798,6 +1804,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@obrender/$(DEPDIR)/obrender_libobrender_la-mask.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@obrender/$(DEPDIR)/obrender_libobrender_la-render.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@obrender/$(DEPDIR)/obrender_libobrender_la-theme.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@obrender/$(DEPDIR)/obrender_libobrender_la-button.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@obrender/$(DEPDIR)/obrender_rendertest-test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@obt/$(DEPDIR)/obt_libobt_la-ddparse.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@obt/$(DEPDIR)/obt_libobt_la-display.Plo@am__quote@
@@ -1972,6 +1979,13 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='obrender/theme.c' object='obrender/obrender_libobrender_la-theme.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(obrender_libobrender_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o obrender/obrender_libobrender_la-theme.lo `test -f 'obrender/theme.c' || echo '$(srcdir)/'`obrender/theme.c
+
+obrender/obrender_libobrender_la-button.lo: obrender/button.c
+@am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(obrender_libobrender_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT obrender/obrender_libobrender_la-button.lo -MD -MP -MF obrender/$(DEPDIR)/obrender_libobrender_la-button.Tpo -c -o obrender/obrender_libobrender_la-button.lo `test -f 'obrender/button.c' || echo '$(srcdir)/'`obrender/button.c
+@am__fastdepCC_TRUE@	$(am__mv) obrender/$(DEPDIR)/obrender_libobrender_la-button.Tpo obrender/$(DEPDIR)/obrender_libobrender_la-button.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='obrender/button.c' object='obrender/obrender_libobrender_la-button.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(obrender_libobrender_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o obrender/obrender_libobrender_la-button.lo `test -f 'obrender/button.c' || echo '$(srcdir)/'`obrender/button.c

 obt/obt_libobt_la-display.lo: obt/display.c
 @am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(obt_libobt_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT obt/obt_libobt_la-display.lo -MD -MP -MF obt/$(DEPDIR)/obt_libobt_la-display.Tpo -c -o obt/obt_libobt_la-display.lo `test -f 'obt/display.c' || echo '$(srcdir)/'`obt/display.c